-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transfer_from Duplicate request errors when transfering from different accounts #112
Comments
If it helps, in Motoko, this how one of the requests is made to the cycles ledger canister.
|
Thanks for reporting! We'll look into it. |
Each request is coming from the same account (initiated by the canister principal that wants to transfer the cycles from each sender to it). Each request has a different
All requests use We are not setting/using the |
@THLO 👋 Just wanted to follow up on this. |
Hey @ByronBecker , I've tested the behavior and I could not reproduce. Let me tell you what I've done so that you can tell me if I've done something wrong:
Both transfers go through successfully, no deduplication happens. The arguments of the two The code of the test is: #[test]
fn test_icrc2_transfer_from_deduplicate_sender() {
let env = TestEnv::setup();
let account1 = account(1, None);
let account2 = account(2, None);
let canister_id = env.state_machine.create_canister(None);
let spender = Account::from(canister_id);
let account_to = Account {
owner: canister_id,
subaccount: Some([1;32]),
};
let _deposit_res = env.deposit(account1, 10_000_000_000_000, None);
let _deposit_res = env.deposit(account2, 10_000_000_000_000, None);
let args = ApproveArgs {
from_subaccount: account1.subaccount,
spender,
amount: Nat::from(1_000_000_000_000u64),
expected_allowance: None,
expires_at: None,
fee: None,
memo: None,
created_at_time: None,
};
let _approve_index = env.icrc2_approve_or_trap(account1.owner, args.clone());
let args = ApproveArgs {
from_subaccount: account2.subaccount,
..args
};
let _approve_index = env.icrc2_approve_or_trap(account2.owner, args);
let args = TransferFromArgs {
spender_subaccount: spender.subaccount,
from: account1,
to: account_to,
amount: Nat::from(1u64),
fee: None,
memo: None,
created_at_time: Some(env.nanos_since_epoch_u64()),
};
let _block_index = env.icrc2_transfer_from_or_trap(spender.owner, args.clone());
let args = TransferFromArgs {
from: account2,
..args
};
let _block_index = env.icrc2_transfer_from_or_trap(spender.owner, args);
} |
A few differences that could potentially trigger this.
Here is the batching pattern we're using to make parallel async requests, as well as how we're using the memo as a de-duplication field to get around the error. Hopefully the code makes evident how we are batching Is this similar to the behavior covered by your tests?
You can imagine that each
|
@ByronBecker can you fetch the blocks created by the Ledger and print them here? Use the endpoint |
In local testing, I'm currently batching multiple
transfer_from
calls from a canister to the cycles ledger.In this simple case, I set up 16 cycle ledger developer "user" accounts, and then make calls in parallel to transfer the exact same amount of cycles from each user to an account owned by a canister (the receiver account is the same for all 16 calls).
Even though the "sender" of cycles in each case is different, I'm receiving duplication errors.
When I stringify the resulting errors (in Motoko) I see one successful transfer, and the rest recognized as duplicates.
Following these deduplication instructions and adding unique
memo
content for each request solves this problem (no deduplication errors), but it feels like if the sender and receiver are different, the payload is structurally different and this deduplication error shouldn't occur (it shouldn't require me adding a unique memo).The text was updated successfully, but these errors were encountered: