Bug: from_candid following to_candid fails.
AStepanov25 opened this issue · comments
from_candid called after to_candid produces null.
// @testmode wasi
type GlobalId = (streamId : Nat, queueNumber : Nat);
type TxOutput = { #ftTransfer : { amount : Nat; fee : Nat } };
let a = to_candid (((3, 0), #ftTransfer({ amount = 0; fee = 0 })) : (GlobalId, TxOutput));
assert (from_candid a : ?(GlobalId, TxOutput)) != null;
Minified example:
// @testmode wasi
type T = (Nat, Nat);
let a = (0, 0) : T;
assert (from_candid (to_candid (a)) : ?T) == ?a;
mops.toml:
[toolchain]
moc = "0.10.3"
wasmtime = "16.0.0"
It's a tricky question, but working as intended. from_candid
is using the top-level tuple to represent multiple values. So in your minified example, from_candid
is asking for two values, Nat and Nat, not a single tuple.
A related forum discussion: https://forum.dfinity.org/t/candid-and-tuples/17800/7?u=chenyan
Related, re-opened issue #4130 that suggest two possible enhancements.
Possible rewrite, tried in playground:
https://play.motoko.org/?tag=3119111542
actor {
public func test1() : async () { // fails
type GlobalId = (streamId : Nat, queueNumber : Nat);
type TxOutput = { #ftTransfer : { amount : Nat; fee : Nat } };
let a = to_candid (((3, 0), #ftTransfer({ amount = 0; fee = 0 })) : (GlobalId, TxOutput));
assert (from_candid a : ?(GlobalId, TxOutput)) != null;
};
public func test2() : async () { // succeeds
type GlobalId = (streamId : Nat, queueNumber : Nat);
type TxOutput = { #ftTransfer : { amount : Nat; fee : Nat } };
let a = to_candid ((3, 0) : GlobalId, #ftTransfer({ amount = 0; fee = 0 }) : TxOutput);
assert (from_candid a : ?(GlobalId, TxOutput)) != null;
}
}
Also this works:
public func test3() : async () { // succeeds
type GlobalId = (streamId : Nat, queueNumber : Nat);
type TxOutput = { #ftTransfer : { amount : Nat; fee : Nat } };
let a = to_candid ((3, 0) : GlobalId, #ftTransfer({ amount = 0; fee = 0 }) : TxOutput);
assert (from_candid a : ??(GlobalId, TxOutput)) != null;
};
And this:
// @testmode wasi
let a : (Nat, Nat) = (0, 0);
assert (from_candid to_candid (a.0, a.1) : ?(Nat, Nat)) == ?a;
assert (from_candid to_candid ((a.0, a.1)) : ??(Nat, Nat)) == ??a;
assert (from_candid to_candid ((a.0, a.1), a) : ?((Nat, Nat), (Nat, Nat))) == ?(a, a);
assert (from_candid to_candid (a) : ??(Nat, Nat)) == ??a;
let b : Blob = to_candid ((0,0) : (Nat,Nat));
let x : ?{ _0_ : Nat; _1_ : Nat } = from_candid b;