-
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
system_accountNextIndex
alternative?
#156
Comments
The more I think about this, the more I realize that there is no ideal solution to this problem:
It appears that any solution we choose will be suboptimal in some way. Thoughts? 🙏 |
Using the same account from two different clients at the same time is fundamentally a wrong thing to do. There's fundamentally no way to work around the fact that if you send a transaction from two places at once at the same time, they will both use the same nonce. It is inherently subject to race conditions. Information takes time to go from point A to point B. If you send transaction with nonce 1 from A, then wait a bit, then send transaction with nonce 2 from B, it will be work 99% of the time but note that it's also not a strictly robust solution. It is important that the next block producer receives either only transaction 1 or both transactions 1 and 2. If it receives only transaction 2, it will be rejected for bad nonce. Since you don't know what the next block producer is, the only way you can somewhat guarantee that is to send both transactions 1 and 2 from the same client, as the two transactions will be sent to the same nodes. Basically, the system is not designed to 100% reliably handle more than one transaction per account per block. If you send more than one transaction per account per block, there's always a possibility (even tiny) for a transaction to be rejected due to bad nonce. So, to summarize:
The only situation where what PolkadotJS does could be useful is when people open two browser tabs, then they submit a transaction from the first tab, wait one or two seconds, then submit a transaction from the second tab. However, given that light clients do not receive transactions, what PolkadotJS does can't work on top of a light client. We specifically don't want light clients to download transactions, since that's very much the definition of a light client: a light client should be |
What I suggest you do in my opinion is:
|
We already have this feature, and it has led to some user complaints. They encountered issues when handling the logic for auto-incrementing the nonce, which resulted in race conditions. While these race conditions are easily avoidable, from the users' perspective, they had to implement logic they didn't need before when using PJS. Consequently, they find our current API more complicated and error-prone.
We already have this as well. In fact, we also offer an option to create "optimistic" transactions. This means that if you have observed a block that changes the state favorably for your needs, you can create a transaction against that block. The nonce, mortality, and initial validation will occur against that block. If that block gets pruned, your transaction will be reported as "invalid." This behavior is desirable for use cases where the transaction should only be included if the block becomes part of the canonical chain.
Initially, I was unsure whether this was worth adding. However, after reading your comments and thinking about it further, I agree that we should include this option. We will implement it, and in the documentation, we will prominently highlight the risks and trade-offs associated with using this feature. |
That's why it's "advanced". |
The legacy JSON-RPC API provides the
system_accountNextIndex
RPC endpoint, which considers the transactions present in the pool.Additionally, PJS offers a useful shorthand allowing users to pass
-1
as the nonce. This signals PJS to obtain the nonce from thesystem_accountNextIndex
endpoint.Using the new JSON-RPC API, we can utilize the
AccountNonceApi_account_nonce
runtime call against the most recently seen block to get the latest nonce. However, if there are transactions in the pool, the resulting transaction will eventually become invalid because it won't have the latest nonce.I am concerned that there is no way to accomplish the same with the new JSON-RPC API. As a library author trying to provide an alternative to PJS, my users are experiencing issues because they must manually track the latest nonce when sending multiple transactions in parallel.
I am seeking advice on the following:
Any guidance or suggestions would be greatly appreciated.
cc: @tomaka @jsdw @bkchr
The text was updated successfully, but these errors were encountered: