-
Notifications
You must be signed in to change notification settings - Fork 19.8k
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
Lock when auto-filling transaction nonce #14483
Conversation
Thank you for your contribution! Your commits seem to not adhere to the repository coding standards
Please check the contribution guidelines for more details. This message was auto-generated by https://gitcop.com |
Can we improve this per your suggestion? Can we keep a map of mutexes for each account? |
Well, my suggestion was more that I thought there ought to exist, already, some form of lock primitive, perhaps based around atomic integers, which could internally use sublocks. It feels a bit clumsy to hold a map of mutexes.. and then you need an outer mutex while checking/creating the 'submutex'... |
You can use a |
Something like this which is using a type accounts struct {
mut sync.Mutex
map[common.Address]*sync.Mutex
}
func (a accounts) Lock(address common.Address) {
a.mut.Lock()
defer a.mut.Unlock()
if _, exist := a[address]; !exist {
a[address] = new(sync.Mutex)
}
a[address].Lock()
} or if you want to go fancy you could register on the account creation event, add a new mutex whenever you receive the event and remove the whole |
I suspect it's all overengineering.. so this may be over-overengineering, but how about:
|
Supersedes #14395 .
Fixes #14375 .
More context in the bug.
This solves the problems of transactions being submitted simultaneously, and getting the same nonce, due to the gap (due to signing) between nonce-issuance and nonce-update. With this PR, a lock will need to be aquired whenever a nonce is used, and released when the transaction either is submitted or errors out.
A drawback with this solution is that the lock is global, so if the caller wants to send transactions from multiple accounts, they will still have to wait on the same lock. Ideally, one could use some sort of granular lock,
granularMutex.lock(<account>)
. Didn't find any such things in the standard libs, and I'm not go-hardcore enough to build it. And it may be over-engineering anyway.