mirror of
https://github.com/Xahau/xahau.js.git
synced 2026-08-18 22:22:53 +00:00
* fix #2911: Update OracleSet transaction model, unit, integ tests --------- Co-authored-by: Omar Khan <khancodegt@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { ValidationError } from '../../errors'
|
||||
import { PriceData } from '../common'
|
||||
import { isHex } from '../utils'
|
||||
|
||||
import {
|
||||
BaseTransaction,
|
||||
@@ -12,6 +13,8 @@ import {
|
||||
|
||||
const PRICE_DATA_SERIES_MAX_LENGTH = 10
|
||||
const SCALE_MAX = 10
|
||||
const MINIMUM_ASSET_PRICE_LENGTH = 1
|
||||
const MAXIMUM_ASSET_PRICE_LENGTH = 16
|
||||
|
||||
/**
|
||||
* Creates a new Oracle ledger entry or updates the fields of an existing one, using the Oracle ID.
|
||||
@@ -82,7 +85,7 @@ export function validateOracleSet(tx: Record<string, unknown>): void {
|
||||
|
||||
validateOptionalField(tx, 'AssetClass', isString)
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function -- necessary to validate many fields
|
||||
/* eslint-disable max-statements, max-lines-per-function -- necessary to validate many fields */
|
||||
validateRequiredField(tx, 'PriceDataSeries', (value) => {
|
||||
if (!Array.isArray(value)) {
|
||||
throw new ValidationError('OracleSet: PriceDataSeries must be an array')
|
||||
@@ -142,14 +145,32 @@ export function validateOracleSet(tx: Record<string, unknown>): void {
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type
|
||||
'AssetPrice' in priceData.PriceData &&
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type
|
||||
!isNumber(priceData.PriceData.AssetPrice)
|
||||
) {
|
||||
throw new ValidationError('OracleSet: invalid field AssetPrice')
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access, max-depth --
|
||||
we need to validate priceData.PriceData.AssetPrice value */
|
||||
if ('AssetPrice' in priceData.PriceData) {
|
||||
if (!isNumber(priceData.PriceData.AssetPrice)) {
|
||||
if (typeof priceData.PriceData.AssetPrice !== 'string') {
|
||||
throw new ValidationError(
|
||||
'OracleSet: Field AssetPrice must be a string or a number',
|
||||
)
|
||||
}
|
||||
if (!isHex(priceData.PriceData.AssetPrice)) {
|
||||
throw new ValidationError(
|
||||
'OracleSet: Field AssetPrice must be a valid hex string',
|
||||
)
|
||||
}
|
||||
if (
|
||||
priceData.PriceData.AssetPrice.length <
|
||||
MINIMUM_ASSET_PRICE_LENGTH ||
|
||||
priceData.PriceData.AssetPrice.length > MAXIMUM_ASSET_PRICE_LENGTH
|
||||
) {
|
||||
throw new ValidationError(
|
||||
`OracleSet: Length of AssetPrice field must be between ${MINIMUM_ASSET_PRICE_LENGTH} and ${MAXIMUM_ASSET_PRICE_LENGTH} characters long`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-unsafe-member-access, max-depth */
|
||||
|
||||
if (
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type
|
||||
@@ -173,4 +194,5 @@ export function validateOracleSet(tx: Record<string, unknown>): void {
|
||||
}
|
||||
return true
|
||||
})
|
||||
/* eslint-enable max-statements, max-lines-per-function */
|
||||
}
|
||||
|
||||
@@ -39,6 +39,17 @@ describe('OracleSet', function () {
|
||||
Scale: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
PriceData: {
|
||||
BaseAsset: 'XRP',
|
||||
QuoteAsset: 'INR',
|
||||
// Upper bound admissible value for AssetPrice field
|
||||
// large numeric values necessarily have to use str type in Javascript
|
||||
// number type uses double-precision floating point representation, hence represents a smaller range of values
|
||||
AssetPrice: 'ffffffffffffffff',
|
||||
Scale: 3,
|
||||
},
|
||||
},
|
||||
],
|
||||
Provider: stringToHex('chainlink'),
|
||||
URI: '6469645F6578616D706C65',
|
||||
@@ -62,12 +73,18 @@ describe('OracleSet', function () {
|
||||
assert.equal(oracle.Owner, testContext.wallet.classicAddress)
|
||||
assert.equal(oracle.AssetClass, tx.AssetClass)
|
||||
assert.equal(oracle.Provider, tx.Provider)
|
||||
assert.equal(oracle.PriceDataSeries.length, 1)
|
||||
assert.equal(oracle.PriceDataSeries.length, 2)
|
||||
assert.equal(oracle.PriceDataSeries[0].PriceData.BaseAsset, 'XRP')
|
||||
assert.equal(oracle.PriceDataSeries[0].PriceData.QuoteAsset, 'USD')
|
||||
assert.equal(oracle.PriceDataSeries[0].PriceData.AssetPrice, '2e4')
|
||||
assert.equal(oracle.PriceDataSeries[0].PriceData.Scale, 3)
|
||||
assert.equal(oracle.Flags, 0)
|
||||
|
||||
// validate the serialization of large AssetPrice values
|
||||
assert.equal(
|
||||
oracle.PriceDataSeries[1].PriceData.AssetPrice,
|
||||
'ffffffffffffffff',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
@@ -167,8 +167,24 @@ describe('OracleSet', function () {
|
||||
})
|
||||
|
||||
it(`throws w/ invalid AssetPrice of PriceDataSeries`, function () {
|
||||
tx.PriceDataSeries[0].PriceData.AssetPrice = '1234'
|
||||
const errorMessage = 'OracleSet: invalid field AssetPrice'
|
||||
// value cannot be parsed as hexadecimal number
|
||||
tx.PriceDataSeries[0].PriceData.AssetPrice = 'ghij'
|
||||
const errorMessage =
|
||||
'OracleSet: Field AssetPrice must be a valid hex string'
|
||||
assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage)
|
||||
assert.throws(() => validate(tx), ValidationError, errorMessage)
|
||||
})
|
||||
|
||||
it(`verifies valid AssetPrice of PriceDataSeries`, function () {
|
||||
// valid string which can be parsed as hexadecimal number
|
||||
tx.PriceDataSeries[0].PriceData.AssetPrice = 'ab15'
|
||||
assert.doesNotThrow(() => validate(tx))
|
||||
})
|
||||
|
||||
it(`throws w/ invalid AssetPrice type in PriceDataSeries`, function () {
|
||||
tx.PriceDataSeries[0].PriceData.AssetPrice = ['sample', 'invalid', 'type']
|
||||
const errorMessage =
|
||||
'OracleSet: Field AssetPrice must be a string or a number'
|
||||
assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage)
|
||||
assert.throws(() => validate(tx), ValidationError, errorMessage)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user