Skip to content

Commit

Permalink
Handle "VariadicValue" passed to ".methods".
Browse files Browse the repository at this point in the history
  • Loading branch information
andreibancioiu committed Apr 24, 2023
1 parent 64dd8db commit 973c823
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
52 changes: 50 additions & 2 deletions src/smartcontracts/nativeSerializer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assert } from "chai";
import { Address } from "../address";
import { NativeSerializer } from "./nativeSerializer";
import { AddressType, BigUIntType, EndpointDefinition, EndpointModifiers, EndpointParameterDefinition, ListType, NullType, OptionalType, OptionType, U32Type } from "./typesystem";
import { AbiRegistry, AddressType, BigUIntType, BooleanType, BooleanValue, EndpointDefinition, EndpointModifiers, EndpointParameterDefinition, ListType, NullType, OptionalType, OptionType, U32Type, VariadicType, VariadicValue } from "./typesystem";
import { BytesType, BytesValue } from "./typesystem/bytes";

describe("test native serializer", () => {
Expand All @@ -25,7 +25,7 @@ describe("test native serializer", () => {
const p4 = null;
const p5 = 7;

// Let's not provide "f"
// Let's not provide the last parameter
const typedValues = NativeSerializer.nativeToTypedValues([p0, p1, p2, p3, p4, p5], endpoint);

assert.deepEqual(typedValues[0].getType(), new BigUIntType());
Expand Down Expand Up @@ -66,4 +66,52 @@ describe("test native serializer", () => {
assert.deepEqual(typedValues[2].getType(), new BytesType());
assert.deepEqual(typedValues[2].valueOf(), c.valueOf());
});

it("should accept a mix between typed values and regular JavaScript objects (variadic)", async () => {
const endpoint = AbiRegistry.create({
"endpoints": [
{
"name": "foo",
"inputs": [{
"type": "bool"
}, {
"type": "optional<bool>"
}, {
"type": "variadic<bool>"
}],
"outputs": []
}
]
}).getEndpoint("foo");

// Using only native JavaScript objects
let typedValues = NativeSerializer.nativeToTypedValues([
true,
null,
true,
false,
true
], endpoint);

assert.deepEqual(typedValues[0].getType(), new BooleanType());
assert.deepEqual(typedValues[0].valueOf(), true);
assert.deepEqual(typedValues[1].getType(), new OptionalType(new BooleanType()));
assert.deepEqual(typedValues[1].valueOf(), null);
assert.deepEqual(typedValues[2].getType(), new VariadicType(new BooleanType()));
assert.deepEqual(typedValues[2].valueOf(), [true, false, true]);

// Using both native JavaScript objects and typed values
typedValues = NativeSerializer.nativeToTypedValues([
true,
null,
VariadicValue.fromItems(new BooleanValue(true), new BooleanValue(false), new BooleanValue(true)),
], endpoint);

assert.deepEqual(typedValues[0].getType(), new BooleanType());
assert.deepEqual(typedValues[0].valueOf(), true);
assert.deepEqual(typedValues[1].getType(), new OptionalType(new BooleanType()));
assert.deepEqual(typedValues[1].valueOf(), null);
assert.deepEqual(typedValues[2].getType(), new VariadicType(new BooleanType()));
assert.deepEqual(typedValues[2].valueOf(), [true, false, true]);
});
});
18 changes: 15 additions & 3 deletions src/smartcontracts/nativeSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,22 @@ export namespace NativeSerializer {
}

if (variadic) {
let lastArgIndex = parameters.length - 1;
let lastArg = args.slice(lastArgIndex);
args[lastArgIndex] = lastArg;
const lastArgIndex = parameters.length - 1;
const argAtIndex = args[lastArgIndex];
const argsAtIndexAndAfter = args.slice(lastArgIndex);

if (argAtIndex.belongsToTypesystem) {
const isVariadicValue = argAtIndex.hasClassOrSuperclass(VariadicValue.ClassName);
if (!isVariadicValue) {
throw new ErrInvalidArgument(`Wrong argument type for endpoint ${endpoint.name}: typed value provided; expected variadic type, have ${argAtIndex.getClassName()}`);
}

// Do not repack.
} else {
args[lastArgIndex] = argsAtIndexAndAfter;
}
}

return args;
}

Expand Down

0 comments on commit 973c823

Please sign in to comment.