mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 03:35:49 +00:00
Custom binary codec fixes xrpl.js#2361 - missed param def
This commit is contained in:
@@ -2,6 +2,7 @@ import { BytesList } from '../serdes/binary-serializer'
|
||||
import { BinaryParser } from '../serdes/binary-parser'
|
||||
import bigInt = require('big-integer')
|
||||
import { Buffer } from 'buffer/'
|
||||
import { XrplDefinitionsBase } from '../enums'
|
||||
|
||||
type JSON = string | number | boolean | null | undefined | JSON[] | JsonObject
|
||||
|
||||
@@ -64,9 +65,12 @@ class SerializedType {
|
||||
/**
|
||||
* Return the JSON representation of a SerializedType
|
||||
*
|
||||
* @param _definitions rippled definitions used to parse the values of transaction types and such.
|
||||
* Unused in default, but used in STObject, STArray
|
||||
* Can be customized for sidechains and amendments.
|
||||
* @returns any type, if not overloaded returns hexString representation of bytes
|
||||
*/
|
||||
toJSON(): JSON {
|
||||
toJSON(_definitions?: XrplDefinitionsBase): JSON {
|
||||
return this.toHex()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DEFAULT_DEFINITIONS, XrplDefinitionsBase } from '../enums'
|
||||
import { SerializedType, JsonObject } from './serialized-type'
|
||||
import { STObject } from './st-object'
|
||||
import { BinaryParser } from '../serdes/binary-parser'
|
||||
@@ -51,9 +52,13 @@ class STArray extends SerializedType {
|
||||
* Construct an STArray from an Array of JSON Objects
|
||||
*
|
||||
* @param value STArray or Array of Objects to parse into an STArray
|
||||
* @param definitions optional, types and values to use to encode/decode a transaction
|
||||
* @returns An STArray object
|
||||
*/
|
||||
static from<T extends STArray | Array<JsonObject>>(value: T): STArray {
|
||||
static from<T extends STArray | Array<JsonObject>>(
|
||||
value: T,
|
||||
definitions: XrplDefinitionsBase = DEFAULT_DEFINITIONS,
|
||||
): STArray {
|
||||
if (value instanceof STArray) {
|
||||
return value
|
||||
}
|
||||
@@ -61,7 +66,7 @@ class STArray extends SerializedType {
|
||||
if (isObjects(value)) {
|
||||
const bytes: Array<Buffer> = []
|
||||
value.forEach((obj) => {
|
||||
bytes.push(STObject.from(obj).toBytes())
|
||||
bytes.push(STObject.from(obj, undefined, definitions).toBytes())
|
||||
})
|
||||
|
||||
bytes.push(ARRAY_END_MARKER)
|
||||
@@ -74,12 +79,15 @@ class STArray extends SerializedType {
|
||||
/**
|
||||
* Return the JSON representation of this.bytes
|
||||
*
|
||||
* @param definitions optional, types and values to use to encode/decode a transaction
|
||||
* @returns An Array of JSON objects
|
||||
*/
|
||||
toJSON(): Array<JsonObject> {
|
||||
toJSON(
|
||||
definitions: XrplDefinitionsBase = DEFAULT_DEFINITIONS,
|
||||
): Array<JsonObject> {
|
||||
const result: Array<JsonObject> = []
|
||||
|
||||
const arrayParser = new BinaryParser(this.toString())
|
||||
const arrayParser = new BinaryParser(this.toString(), definitions)
|
||||
|
||||
while (!arrayParser.end()) {
|
||||
const field = arrayParser.readField()
|
||||
@@ -88,7 +96,7 @@ class STArray extends SerializedType {
|
||||
}
|
||||
|
||||
const outer = {}
|
||||
outer[field.name] = STObject.fromParser(arrayParser).toJSON()
|
||||
outer[field.name] = STObject.fromParser(arrayParser).toJSON(definitions)
|
||||
result.push(outer)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
|
||||
import { BinaryParser } from '../serdes/binary-parser'
|
||||
import { BinarySerializer, BytesList } from '../serdes/binary-serializer'
|
||||
import { Buffer } from 'buffer/'
|
||||
import { STArray } from './st-array'
|
||||
|
||||
const OBJECT_END_MARKER_BYTE = Buffer.from([0xe1])
|
||||
const OBJECT_END_MARKER = 'ObjectEndMarker'
|
||||
@@ -131,9 +132,12 @@ class STObject extends SerializedType {
|
||||
}
|
||||
|
||||
sorted.forEach((field) => {
|
||||
const associatedValue = field.associatedType.from(
|
||||
xAddressDecoded[field.name],
|
||||
)
|
||||
const associatedValue =
|
||||
field.type.name === ST_OBJECT
|
||||
? this.from(xAddressDecoded[field.name], undefined, definitions)
|
||||
: field.type.name === 'STArray'
|
||||
? STArray.from(xAddressDecoded[field.name], definitions)
|
||||
: field.associatedType.from(xAddressDecoded[field.name])
|
||||
|
||||
if (associatedValue == undefined) {
|
||||
throw new TypeError(
|
||||
@@ -175,7 +179,10 @@ class STObject extends SerializedType {
|
||||
if (field.name === OBJECT_END_MARKER) {
|
||||
break
|
||||
}
|
||||
accumulator[field.name] = objectParser.readFieldValue(field).toJSON()
|
||||
|
||||
accumulator[field.name] = objectParser
|
||||
.readFieldValue(field)
|
||||
.toJSON(definitions)
|
||||
}
|
||||
|
||||
return accumulator
|
||||
|
||||
@@ -60,6 +60,66 @@ describe('encode and decode using new types as a parameter', function () {
|
||||
expect(decoded).toStrictEqual(tx)
|
||||
})
|
||||
|
||||
test('can encode and decode a new Field nested in STObject in STArray in STObject', function () {
|
||||
const tx = {
|
||||
...txJson,
|
||||
NewFieldArray: [
|
||||
{
|
||||
NewField: {
|
||||
NewFieldValue: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// Before updating the types, undefined fields will be ignored on encode
|
||||
expect(decode(encode(tx))).not.toStrictEqual(tx)
|
||||
|
||||
// Normally this would be generated directly from rippled with something like `server_definitions`.
|
||||
// Added here to make it easier to see what is actually changing in the definitions.json file.
|
||||
const definitions = JSON.parse(JSON.stringify(normalDefinitionsJson))
|
||||
|
||||
definitions.FIELDS.push([
|
||||
'NewFieldArray',
|
||||
{
|
||||
nth: 100,
|
||||
isVLEncoded: false,
|
||||
isSerialized: true,
|
||||
isSigningField: true,
|
||||
type: 'STArray',
|
||||
},
|
||||
])
|
||||
|
||||
definitions.FIELDS.push([
|
||||
'NewField',
|
||||
{
|
||||
nth: 101,
|
||||
isVLEncoded: false,
|
||||
isSerialized: true,
|
||||
isSigningField: true,
|
||||
type: 'STObject',
|
||||
},
|
||||
])
|
||||
|
||||
definitions.FIELDS.push([
|
||||
'NewFieldValue',
|
||||
{
|
||||
nth: 102,
|
||||
isVLEncoded: false,
|
||||
isSerialized: true,
|
||||
isSigningField: true,
|
||||
type: 'UInt32',
|
||||
},
|
||||
])
|
||||
|
||||
const newDefs = new XrplDefinitions(definitions)
|
||||
|
||||
const encoded = encode(tx, newDefs)
|
||||
expect(() => decode(encoded)).toThrow()
|
||||
const decoded = decode(encoded, newDefs)
|
||||
expect(decoded).toStrictEqual(tx)
|
||||
})
|
||||
|
||||
test('can encode and decode a new Type', function () {
|
||||
const tx = {
|
||||
...txJson,
|
||||
|
||||
Reference in New Issue
Block a user