Skip to content

Commit c962b80

Browse files
committed
bsip38: serialization of extension logic correction
1 parent 048452f commit c962b80

File tree

4 files changed

+91
-70
lines changed

4 files changed

+91
-70
lines changed

lib/serializer/src/SerializerValidation.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ var _my = {
2020
}
2121
return value;
2222
},
23-
23+
require_array: function(value, instance_require) {
24+
if ( !( value instanceof Array) ) {
25+
throw new Error(`array required`);
26+
}
27+
if( instance_require ){
28+
value.forEach( i =>{
29+
instance_require(i);
30+
})
31+
}
32+
return value;
33+
},
2434
require_long(value, field_name = "") {
2535
if (!Long.isLong(value)) {
2636
throw new Error(`Long value required ${field_name} ${value}`);

lib/serializer/src/operations.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ var {
2424
address,
2525
time_point_sec,
2626
optional,
27-
indexed_optional,
2827
extension
2928
} = types;
3029

@@ -487,19 +486,15 @@ export const limit_order_cancel = new Serializer("limit_order_cancel", {
487486
extensions: set(future_extensions)
488487
});
489488

490-
export const call_order_update_options = new Serializer(
491-
"call_order_update_options",
492-
{
493-
target_collateral_ratio: indexed_optional(uint16, 0)
494-
}
495-
);
496-
497489
export const call_order_update = new Serializer("call_order_update", {
498490
fee: asset,
499491
funding_account: protocol_id_type("account"),
500492
delta_collateral: asset,
501493
delta_debt: asset,
502-
extensions: extension(call_order_update_options)
494+
extensions: extension([{
495+
name: "target_collateral_ratio",
496+
type: uint16
497+
}])
503498
});
504499

505500
export const fill_order = new Serializer("fill_order", {

lib/serializer/src/types.js

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ObjectId from "../../chain/src/ObjectId";
99
import {PublicKey, Address} from "../../ecc";
1010
import {ChainConfig} from "bitsharesjs-ws";
1111

12+
import ByteBuffer from "bytebuffer";
1213
const Buffer = require("safe-buffer").Buffer;
1314

1415
var Types = {};
@@ -684,93 +685,95 @@ Types.optional = function(st_operation) {
684685
};
685686
};
686687

687-
Types.indexed_optional = function(st_operation, index) {
688-
v.required(st_operation, "st_operation");
688+
689+
Types.extension = function (fields_def) {
690+
// fields_def is an array
691+
v.require_array(fields_def, (r) => {
692+
v.string(r.name);
693+
v.required(r.type, "st_operation");
694+
});
695+
//v.required(st_operation, "st_operation");
689696
return {
690697
fromByteBuffer(b) {
691-
if (!(b.readVarint32() === index)) {
698+
let count = b.readVarint32();
699+
if (count === 0) {
692700
return undefined;
693701
}
694-
return st_operation.fromByteBuffer(b);
695-
},
696-
appendByteBuffer(b, object) {
697-
if (object !== null && object !== undefined) {
698-
b.writeVarint32(index);
699-
st_operation.appendByteBuffer(b, object);
700-
}
701-
return;
702-
},
703-
fromObject(object) {
704-
if (object === undefined) {
705-
return undefined;
702+
let o = {};
703+
if (count > fields_def.length) {
704+
throw new Error('two many fields');
706705
}
707-
return st_operation.fromObject(object);
708-
},
709-
toObject(object, debug = {}) {
710-
// toObject is only null save if use_default is true
711-
var result_object = (() => {
712-
if (!debug.use_default && object === undefined) {
713-
return undefined;
714-
} else {
715-
return st_operation.toObject(object, debug);
706+
while (count > 0) {
707+
let index = b.readVarint32();
708+
if (index >= fields_def.length) {
709+
throw new Error('index out of range');
716710
}
717-
})();
718-
719-
if (debug.annotate) {
720-
if (typeof result_object === "object") {
721-
result_object.__optional = "parent is optional";
722-
} else {
723-
result_object = {__optional: result_object};
724-
}
725-
}
726-
return result_object;
727-
}
728-
};
729-
};
730-
731-
Types.extension = function(st_operation) {
732-
v.required(st_operation, "st_operation");
733-
return {
734-
fromByteBuffer(b) {
735-
if (!(b.readVarint32() === 1)) {
736-
return undefined;
711+
let operation = fields_def[index];
712+
o[operation.name] = operation.type.fromByteBuffer(b);
713+
count--;
737714
}
738-
return st_operation.fromByteBuffer(b);
715+
return o;
716+
// return st_operation.fromByteBuffer(b);
739717
},
740718
appendByteBuffer(b, object) {
741-
if (
742-
object !== null &&
743-
object !== undefined &&
744-
!(typeof object == "object" && Object.keys(object).length == 0)
745-
) {
746-
b.writeVarint32(1);
747-
st_operation.appendByteBuffer(b, object);
748-
} else {
749-
b.writeVarint32(0);
719+
//let tempBuffer = new Buffer([]);
720+
let tempBuffer = new ByteBuffer(
721+
ByteBuffer.DEFAULT_CAPACITY,
722+
ByteBuffer.LITTLE_ENDIAN
723+
);
724+
var count = 0;
725+
if (object) {
726+
fields_def.forEach((f, i) => {
727+
if (object[f.name] !== undefined && object[f.name] !== null) {
728+
tempBuffer.writeVarint32(i);
729+
f.type.appendByteBuffer(tempBuffer, object[f.name]);
730+
count++;
731+
}
732+
});
750733
}
734+
b.writeVarint32(count);
735+
tempBuffer.flip();
736+
b.append(tempBuffer);
737+
751738
return;
752739
},
753740
fromObject(object) {
754741
if (object === undefined) {
755742
return undefined;
756743
}
744+
/*
757745
return st_operation.fromObject(object);
746+
*/
747+
var result = {};
748+
fields_def.forEach((f) => {
749+
if (object[f.name] !== undefined && object[f.name] !== null) {
750+
result[f.name] = f.type.fromObject(object[f.name]);
751+
}
752+
});
753+
return result;
758754
},
759755
toObject(object, debug = {}) {
760756
// toObject is only null save if use_default is true
761757
var result_object = (() => {
762-
if (!debug.use_default && object === undefined) {
758+
if (object === undefined) {
763759
return undefined;
764760
} else {
765-
return st_operation.toObject(object, debug);
761+
// return st_operation.toObject(object, debug);
762+
let result = {};
763+
fields_def.forEach((f) => {
764+
if (object[f.name] !== undefined && object[f.name] !== null) {
765+
result[f.name] = f.type.toObject(object[f.name], debug);
766+
}
767+
});
768+
return result;
766769
}
767770
})();
768771

769772
if (debug.annotate) {
770773
if (typeof result_object === "object") {
771774
result_object.__optional = "parent is optional";
772775
} else {
773-
result_object = {__optional: result_object};
776+
result_object = { __optional: result_object };
774777
}
775778
}
776779
return result_object;

test/serializer/all_types.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ var {
3737
var {asset, account_name_eq_lit_predicate} = ops;
3838

3939
// Must stay in sync with allTypes below.
40+
41+
let extType = extension([{
42+
name: 'f1',
43+
type: uint16
44+
}, {
45+
name: 'f2',
46+
type: string
47+
}]);
4048
let AllTypes = new Serializer("all_types", {
4149
uint8,
4250
uint16,
@@ -65,8 +73,8 @@ let AllTypes = new Serializer("all_types", {
6573
time_optional: optional(time_point_sec),
6674
time_point_sec1: time_point_sec,
6775
time_point_sec2: time_point_sec,
68-
ext1: extension(string),
69-
ext2: extension(string)
76+
ext1: extType,
77+
ext2: extType,
7078
});
7179

7280
// Must stay in sync with AllTypes above.
@@ -110,7 +118,12 @@ let allTypes = {
110118
time_optional: undefined,
111119
time_point_sec1: new Date(),
112120
time_point_sec2: Math.floor(Date.now() / 1000),
113-
ext1: "test extension"
121+
ext1: {
122+
f1: 300
123+
},
124+
ext2: {
125+
f2: "hello"
126+
}
114127
};
115128

116129
describe("Serializer", function() {

0 commit comments

Comments
 (0)