You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm a bit confused with some errors I am running into with decoding of func types, and I am wondering if this might be a problem with the Candid implementation in Rust. Here's more info in the forum: https://forum.dfinity.org/t/candid-func-types-as-parameters/12857
It seems like the Rust func types don't have enough information to serialize/deserialize correctly. If I just give the Rust func struct a principal and a method name, how can it handle func types with parameters and return types? It seems there is a mismatch somewhere in the Candid serialization/deserialization process where my funcs are of type func () -> () even though my Candid file (the file I generate my Rust types from) has parameters and return types.
Example Candid:
type GetBlocksArgs = record {
"start": nat64;
"length": nat64;
};
type TransferArgs = record {
"memo": nat64;
"amount": Tokens;
"fee": Tokens;
"from_subaccount": opt vec nat8;
"to": vec nat8;
"created_at_time": opt TimeStamp;
};
type AccountBalanceArgs = record {
"account": vec nat8;
};
type TransferFeeArg = record {
};
type Tokens = record {
"e8s": nat64;
};
type TransferFee = record {
"transfer_fee": Tokens;
};
type QueryBlocksResponse = record {
"chain_length": nat64;
"certificate": opt vec nat8;
"blocks": vec Block;
"first_block_index": nat64;
"archived_blocks": vec record { "start": nat64; "length": nat64; "callback": QueryArchiveFn; };
};
type SymbolResult = record {
"symbol": text;
};
type NameResult = record {
"name": text;
};
type DecimalsResult = record {
"decimals": nat32;
};
type Archives = record {
"archives": vec Archive;
};
type TimeStamp = record {
"timestamp_nanos": nat64;
};
type Block = record {
"parent_hash": opt vec nat8;
"transaction": Transaction;
"timestamp": TimeStamp;
};
type Transaction = record {
"memo": nat64;
"operation": opt Operation;
"created_at_time": TimeStamp;
};
type Archive = record {
"canister_id": principal;
};
type BlockRange = record {
"blocks": vec Block;
};
type ExecuteTransferResult = variant { "ok": TransferResult; "err": text };
type GetAccountBalanceResult = variant { "ok": Tokens; "err": text };
type GetTransferFeeResult = variant { "ok": TransferFee; "err": text };
type GetBlocksResult = variant { "ok": QueryBlocksResponse; "err": text };
type GetSymbolResult = variant { "ok": text; "err": text };
type GetNameResult = variant { "ok": text; "err": text };
type GetDecimalsResult = variant { "ok": nat32; "err": text };
type GetArchivesResult = variant { "ok": Archives; "err": text };
type TransferResult = variant { "Ok": nat64; "Err": TransferError };
type QueryArchiveResult = variant { "Ok": BlockRange; "Err": QueryArchiveError };
type TransferError = variant { "BadFee": record { "expected_fee": Tokens; }; "InsufficientFunds": record { "balance": Tokens; }; "TxTooOld": record { "allowed_window_nanos": nat64; }; "TxCreatedInFuture": null; "TxDuplicate": record { "duplicate_of": nat64; } };
type Operation = variant { "Mint": record { "to": vec nat8; "amount": Tokens; }; "Burn": record { "from": vec nat8; "amount": Tokens; }; "Transfer": record { "from": vec nat8; "to": vec nat8; "amount": Tokens; "fee": Tokens; } };
type QueryArchiveError = variant { "BadFirstBlockIndex": record { "requested_index": nat64; "first_valid_index": nat64; }; "Other": record { "error_code": nat64; "error_message": text; } };
type QueryArchiveFn = func (GetBlocksArgs) -> (QueryArchiveResult) query;
service: {
"execute_transfer": (text, nat64, nat64, opt nat64) -> (ExecuteTransferResult);
"get_account_balance": (text) -> (GetAccountBalanceResult);
"get_transfer_fee": () -> (GetTransferFeeResult);
"get_blocks": (GetBlocksArgs) -> (GetBlocksResult);
"get_symbol": () -> (GetSymbolResult);
"get_name": () -> (GetNameResult);
"get_decimals": () -> (GetDecimalsResult);
"get_archives": () -> (GetArchivesResult);
}
When calling get_blocks I get this error:
test get_blocks failed Error: Call was rejected:en Completed in 2ms
Request ID: 11e5e1bf1c1156a4ea9a32ba0b301a731bf01da8dd37d10d4f9ed082ba5ee6ee
Reject code: 5
Reject text: Canister rrkah-fqaaa-aaaaa-aaaaq-cai trapped explicitly: Custom(Fail to decode argument 0 from table0 to record {
certificate : opt vec nat8;
blocks : vec record {
transaction : record {
memo : nat64;
operation : opt variant {
Burn : record { from : vec nat8; amount : record { e8s : nat64 } };
Mint : record { to : vec nat8; amount : record { e8s : nat64 } };
Transfer : record {
to : vec nat8;
fee : record { e8s : nat64 };
from : vec nat8;
amount : record { e8s : nat64 };
};
};
created_at_time : record { timestamp_nanos : nat64 };
};
timestamp : record { timestamp_nanos : nat64 };
parent_hash : opt vec nat8;
};
chain_length : nat64;
first_block_index : nat64;
archived_blocks : vec record {
callback :func () -> ();
start : nat64;
length : nat64;
};
}
Caused by:
0: input: 4449444c156c0597928bda010186dda8bf0a03a4c7a8ce0c7891fb95920d7883f4f4c40f0c6e026d7b6d046c03dec389dc0405d6a9bbae0a0bc39c99ad0f016c03ba89e5c20478a78882820a0682f3f3910c0b6b03ef80e5df0207c2f5d5990309cbd6fda00b0a6c02eaca8a9e0402d8a38ca80d086c01e0a9b302786c02fbca0102d8a38ca80d086c04fbca0102c6fcb60208eaca8a9e0402d8a38ca80d086c01d6f68e8001786d0d6c03c5b39af8070ee2e8ada00878e6a99ef809786a010f011001016c02e2e8ada00878e6a99ef809786b02bc8a0111c5fed201126c0186dda8bf0a036b02b0ad8cd40413b0ad8fcd0c146c02c1a482a6057880d5dbdd05786c0290c6c1960571c498b1b50d780100_000100000000000000000120082ecf2e3f647ac600f43f38a68342fba5b8e68b085f02592b77f39808a8d2b500e8764817000000766ea381dad1ed16766ea381dad1ed16000100000000000000000000000000000000
table: type table0 = record {
457_361_687 : table1;
2_817_142_406 : table3;
3_385_467_812 : nat64;
3_527_769_489 : nat64;
4_171_053_571 : table12;
}
type table1 = opt table2
type table10 = record {
25_979 : table2;
5_094_982 : table8;
1_136_829_802 : table2;
3_573_748_184 : table8;
}
type table11 = record { 268_680_022 : nat64 }
type table12 = vec table13
type table13 = record { 2_131_139_013 : table14; 2_215_343_202 : nat64; 2_668_074_214 : nat64 }
type table14 = func (table15) -> (table16) query
type table15 = record { 2_215_343_202 : nat64; 2_668_074_214 : nat64 }
type table16 = variant { 17_724 : table17; 3_456_837 : table18 }
type table17 = record { 2_817_142_406 : table3 }
type table18 = variant { 1_250_105_008 : table19; 3_382_957_744 : table20 }
type table19 = record { 1_421_906_497 : nat64; 1_538_714_240 : nat64 }
type table2 = vec nat8
type table20 = record { 1_389_388_560 : text; 3_601_615_940 : nat64 }
type table3 = vec table4
type table4 = record {
1_266_835_934 : table5;
2_781_795_542 : table11;
4_121_316_931 : table1;
}
type table5 = record {
1_213_809_850 : nat64;
2_688_582_695 : table6;
3_258_775_938 : table11;
}
type table6 = variant { 737_755_247 : table7; 859_142_850 : table9; 3_021_957_963 : table10 }
type table7 = record { 1_136_829_802 : table2; 3_573_748_184 : table8 }
type table8 = record { 5_035_232 : nat64 }
type table9 = record { 25_979 : table2; 3_573_748_184 : table8 }
wire_type: table0, expect_type: record {
certificate : opt vec nat8;
blocks : vec record {
transaction : record {
memo : nat64;
operation : opt variant {
Burn : record { from : vec nat8; amount : record { e8s : nat64 } };
Mint : record { to : vec nat8; amount : record { e8s : nat64 } };
Transfer : record {
to : vec nat8;
fee : record { e8s : nat64 };
from : vec nat8;
amount : record { e8s : nat64 };
};
};
created_at_time : record { timestamp_nanos : nat64 };
};
timestamp : record { timestamp_nanos : nat64 };
parent_hash : opt vec nat8;
};
chain_length : nat64;
first_block_index : nat64;
archived_blocks : vec record {
callback :func () -> ();
start : nat64;
length : nat64;
};
}
1: table0 is not a subtype of record {
certificate : opt vec nat8;
blocks : vec record {
transaction : record {
memo : nat64;
operation : opt variant {
Burn : record { from : vec nat8; amount : record { e8s : nat64 } };
Mint : record { to : vec nat8; amount : record { e8s : nat64 } };
Transfer : record {
to : vec nat8;
fee : record { e8s : nat64 };
from : vec nat8;
amount : record { e8s : nat64 };
};
};
created_at_time : record { timestamp_nanos : nat64 };
};
timestamp : record { timestamp_nanos : nat64 };
parent_hash : opt vec nat8;
};
chain_length : nat64;
first_block_index : nat64;
archived_blocks : vec record {
callback :func () -> ();
start : nat64;
length : nat64;
};
}
2: Record field archived_blocks: table12 is not a subtype of vec record { callback :func () -> (); start : nat64; length : nat64 }
3: Record field callback: table14 is not a subtype of func () -> ()
4: Function mode mismatch)
Notice that archived_blocks.callback is just func () -> ()...why doesn't it have the correct type information?
The text was updated successfully, but these errors were encountered:
I'm a bit confused with some errors I am running into with decoding of
func
types, and I am wondering if this might be a problem with the Candid implementation in Rust. Here's more info in the forum: https://forum.dfinity.org/t/candid-func-types-as-parameters/12857It seems like the Rust func types don't have enough information to serialize/deserialize correctly. If I just give the Rust
func
struct a principal and a method name, how can it handlefunc
types with parameters and return types? It seems there is a mismatch somewhere in the Candid serialization/deserialization process where my funcs are of typefunc () -> ()
even though my Candid file (the file I generate my Rust types from) has parameters and return types.Example Candid:
When calling
get_blocks
I get this error:Notice that
archived_blocks
.callback is justfunc () -> ()
...why doesn't it have the correct type information?The text was updated successfully, but these errors were encountered: