Skip to content

fix(sdk): auto-refresh chain hash and retry on 401 invalid signature#60

Open
kalyan02 wants to merge 1 commit into
mainfrom
kn/auto-refresh-chain-hash-on-401
Open

fix(sdk): auto-refresh chain hash and retry on 401 invalid signature#60
kalyan02 wants to merge 1 commit into
mainfrom
kn/auto-refresh-chain-hash-on-401

Conversation

@kalyan02
Copy link
Copy Markdown

@kalyan02 kalyan02 commented May 13, 2026

Why

When the rollup is redeployed with a new genesis state, the chain hash changes. Clients that started before the redeploy are signing transactions with the old hash — every tx fails with 401 until they restart.

Happened on mainnet today: rollup redeployed ~11:51 UTC, chain hash changed from 3718f342...a14f50e6..., causing ~90 invalid_signature failures/s sustained for hours.

What

Add send_call_message on Client: builds, signs, submits, and if the server returns 401 invalid-signature (schema already refreshed by existing submit_tx_api_error logic), re-signs with the new hash and retries once.

The retry path submits directly (bypassing submit_tx_api_error) so a second 401 returns ApiError, not TransactionOutdated — callers can't get stuck in a retry loop.

All five trading convenience methods now go through send_call_message. WASM sendCallMessage delegates to the same path.


Note

Medium Risk
Touches transaction signing/submission flow and changes the error behavior on 401 invalid signatures, which could impact all order-placement paths if the retry logic is wrong.

Overview
Adds Client::send_call_message to build+sign+submit a CallMessage, and on 401 Invalid signature automatically refreshes the schema/chain hash, re-signs, and retries once (then surfaces a real ApiError to avoid retry loops).

Updates Rust trading convenience methods (place_orders, cancel_*, amend_orders) and the WASM sendCallMessage wrapper to use this new resilient path instead of manually building a Transaction and calling send_transaction.

Reviewed by Cursor Bugbot for commit da176cf. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Auto-refreshes the chain hash and retries once on 401 Invalid signature so clients keep working after a rollup redeploy without a restart. All trading calls now re-sign with the new hash via a safe path.

  • Bug Fixes
    • Added Client::send_call_message to build, sign, submit, and on 401 refresh schema, re-sign, and retry once.
    • Retry bypasses submit_tx_api_error so a second 401 returns ApiError (prevents retry loops).
    • Updated trading convenience methods (place_orders, cancel_*, amend_orders) and WASM sendCallMessage to use this path.
    • Fixed open orders query to pass Some(symbol) into query_open_orders.

Written for commit da176cf. Summary will update on new commits.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

if the rollup is redeployed (new chain hash), clients signed against the
old hash get 401s until they restart. add send_call_message which retries
once after a schema refresh so the caller never has to handle this case.

the retry path bypasses submit_tx_api_error so a second 401 returns
ApiError rather than TransactionOutdated, preventing caller retry loops.

all trading convenience methods (place/cancel/amend orders) now go
through send_call_message. wasm sendCallMessage delegates to the same path.
@kalyan02 kalyan02 force-pushed the kn/auto-refresh-chain-hash-on-401 branch from 5470665 to da176cf Compare May 13, 2026 13:43
Copy link
Copy Markdown
Contributor

@0xtristan 0xtristan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea - JS SDK has the same pattern

// chain hash was refreshed; re-sign with the new hash and retry once.
// submit directly so a second 401 comes back as ApiError, not TransactionOutdated
let signed =
Transaction::builder().call_message(call_message).client(self).build()?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this automaticaly fetch the new schema/hash?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants