added lock to originStorage, pendingStorage and dirtyStorage in GetCommittedState function to fix 'concurrent map writes' (#1176)

This commit is contained in:
Pratik Patil 2024-03-05 21:40:41 +05:30 committed by GitHub
parent 32a55dd72b
commit de45e3f54e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -21,6 +21,7 @@ import (
"fmt"
"io"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
@ -73,6 +74,7 @@ type stateObject struct {
trie Trie // storage trie, which becomes non-nil on first access
code Code // contract bytecode, which gets set when code is loaded
storageMutex sync.Mutex
originStorage Storage // Storage cache of original entries to dedup rewrites
pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block
dirtyStorage Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction
@ -175,6 +177,8 @@ func (s *stateObject) GetState(key common.Hash) common.Hash {
// GetCommittedState retrieves a value from the committed account storage trie.
func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
s.storageMutex.Lock()
defer s.storageMutex.Unlock()
// If we have a pending write or clean cached, return that
if value, pending := s.pendingStorage[key]; pending {
return value
@ -183,6 +187,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
if value, cached := s.originStorage[key]; cached {
return value
}
// If the object was destructed in *this* block (and potentially resurrected),
// the storage has been cleared out, and we should *not* consult the previous
// database about any storage values. The only possible alternatives are: