elrond-sdk-erdjs
elrond-sdk-erdjs copied to clipboard
[v13] Problem with `checkArgumentsCardinality`
Hi, with v13, I have a problem with the checkArgumentsCardinality
function.
ErrInvalidArgument [Error]: Invalid argument: Wrong number of arguments for endpoint (...)
I have something like: OptionalValue<MultiValueEncoded<CustomEnum>>
in my sc for function argument.
Now, with sdk-core v12 it works ok, but with v13 I'm getting errors from checkArgumentsCardinality
I'm not sure, but it looks like in:
src/smartcontracts/nativeSerializer.ts
getArgumentsCardinality
doesn't set the max = Infinity;
and variadic = true;
for the type "optional<variadic<CustomEnum>>"
(the string representation of the argument's type in ABI),
where CustomEnum is something like:
"CustomEnum": {
"type": "enum",
"variants": [
{
"name": "someOption0",
"discriminant": 0
},
{
"name": "someOption1",
"discriminant": 1
},
{
"name": "someOption2",
"discriminant": 2
},
(...)
]
}
It looks like TypeCardinality for that param is: { lowerBound: 0, upperBound: 1 }
, so it takes only the optional
part. Should it take the variadic
here first? Then it would be: { lowerBound: 0, upperBound: <max_upper_bound_or_in_this_case_the_length_of_the_enum_variants> }
I'm not sure if this is a bug or if the parameter definition is wrong, but it worked okay previously with the same setup.
Probably to check (haven't found time yet) last changes in:
src/smartcontracts/typesystem/typeExpressionParser.ts
@juliancwirko, thanks a lot for the report and for the provided details :raised_hands:
We'll handle this as soon as possible :pray:
in my sc for function argument.
@juliancwirko, to narrow down a bit the issue, do you think you can specify how is the function called? E.g. using the contract.methods
approach, or using the newer SmartContractTransactionsFactory
approach?
Also, how do the passed arguments look like (e.g. is the optional provided, are the variadic parameters wrapped in an array)?
We are preparing a scenario to reproduce the issue here:
https://github.com/multiversx/mx-sdk-js-core/pull/441
It is through SmartContract.call
so I think the SmartContractTransactionsFactory
is used there.
It looks like:
contract.call({
func: new ContractFunction(<fn_name>),
args: [
BytesValue.fromUTF8(...),
BytesValue.fromUTF8(...),
...customEnumNamesAsStrings.map((enumName) =>
EnumValue.fromName(
EnumType.fromJSON(<json_representation>),
enumName
)
),
],
value: TokenTransfer.egldFromAmount(...),
gasLimit: ...,
chainID: 'D',
caller: ...,
});
where json_representation
is like:
{
name: 'CustomEnum',
variants: [{ name: 'Option1', discriminant: 0 }, { name: 'Option2', discriminant: 1 }],
}
Workaround: do not unwrap the enum values.
That is, drop the ...
from ...customEnumNamesAsStrings.map((enumName)
. Actually, this should be the correct way of passing the (optional) variadic values.
We'll analyze now why the behavior differs from v12 (maybe it was a bit more permissive around this).
Oh, I see. The arguments should be like args: [arg1, arg2, [optionalVariadic1, optionalVariadic2]]
. I'll test that later. Thanks.
Yes, but in v12, it worked just as you've said (while it wouldn't have worked in the way it works for v13) - this is a breaking change (from v12 to v13) we weren't aware of, thanks for spotting it :pray:
In v12, for contract.call()
, args
could have only be an array of TypedValue
. Now, in v13, typed values can be mixed with untyped ones.
We'll analyze this a bit more, then do a fix and / or update the migration notes.
Thank you!
@juliancwirko, a more detailed analysis of the issue is here: https://github.com/multiversx/mx-sdk-js-core/pull/441.
For optional<variadic<...>>
, you might be interested into this comment - it includes several ways to tackle the issue.
Furthermore, you might want to have MultiValueEncoded<CustomEnum>
instead of OptionalValue<MultiValueEncoded<CustomEnum>>
, in your contract.
Again, thank you for spotting this!
Let us know how it goes :pray:
Sure, thanks for the detailed guides. It works great now for me. I will also modify the smart contract and update the 'legacy' code in js.
Please close the issue whenever you think it can be closed. Thanks again.
Thank you!
We will leave the issue open for ~1 month.