-
Notifications
You must be signed in to change notification settings - Fork 1
Description
GM @zensh 👋
I've been digging through the anda_x402_canister code to understand how this scales under load, and I noticed two architectural things that might bite us once we start seeing real traffic.
- Sequential Blocking in Settlement (store.rs)
Location: https://github.com/ldclabs/anda-cloud/blob/main/rs/anda_x402_canister/src/store.rs#L477-L487
It looks like the settlement logic handles transfers sequentially with a hard await on the cross-canister call to the ledger:
// In store.rs
let idx = transfer_token_from(log.asset, log.from, log.to, log.value.saturating_sub(log.fee), Some(log.nonce.into()))
.await // <--- This is the bottleneck
.map_err(|err| X402Error::SettleError(format!("Failed to transfer payment fee: {}", err)))?;
The Issue: Since this is sequential, if we get a burst of agents trying to pay at once, the canister is going to lock up waiting for the Ledger to respond to each individual transfer_from. We're effectively limited by the round-trip time of the Ledger canister.
- Approval Race Condition (api_http.rs)
Location: https://github.com/ldclabs/anda-cloud/blob/main/rs/anda_x402_canister/src/api_http.rs#L302-L306
In the verification flow, we're doing the heavy CPU lifting of signature verification before checking the state of the ledger approval:
let payer = req.payment_payload.payload.verify_signature(now_ms, Some(canister_self))
.map_err(|err| (X402Error::InvalidPayloadAuthorizationSignature(err), None))?;
The Issue: There's a gap between when the agent signs the payload and when we actually try to pull the funds. In that window:
- The approval could expire.
- The agent could revoke the approval.
- Another service could drain the approved allowance.
Currently, we proceed to settlement assuming the approval is valid just because the signature is valid. This wastes cycles and could lead to messy error states if the transfer fails partway through.
Suggestion: Maybe we can peek at the allowance (via icrc2_allowance) before we commit to the settlement logic??Or at least wrap the transfer in a retry mechanism that specifically handles "Insufficient Allowance" errors??
Happy to chat about how we can refactor this!