diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index abb3051762..bda0e97988 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -891,6 +891,8 @@ func (t *Tree) disklayer() *diskLayer { case *diskLayer: return layer case *diffLayer: + layer.lock.RLock() + defer layer.lock.RUnlock() return layer.origin default: panic(fmt.Sprintf("%T: undefined layer", snap)) @@ -922,7 +924,7 @@ func (t *Tree) generating() (bool, error) { return layer.genMarker != nil, nil } -// DiskRoot is a external helper function to return the disk layer root. +// DiskRoot is an external helper function to return the disk layer root. func (t *Tree) DiskRoot() common.Hash { t.lock.Lock() defer t.lock.Unlock() diff --git a/core/state/statedb.go b/core/state/statedb.go index 0dccd28bf8..e84e2d13d0 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -29,6 +29,7 @@ package state import ( "fmt" + "maps" "math/big" "sort" "time" @@ -820,18 +821,18 @@ func (s *StateDB) Copy() *StateDB { db: s.db, trie: s.db.CopyTrie(s.trie), originalRoot: s.originalRoot, - accounts: make(map[common.Hash][]byte), - storages: make(map[common.Hash]map[common.Hash][]byte), - accountsOrigin: make(map[common.Address][]byte), - storagesOrigin: make(map[common.Address]map[common.Hash][]byte), + accounts: copySet(s.accounts), + storages: copy2DSet(s.storages), + accountsOrigin: copySet(s.accountsOrigin), + storagesOrigin: copy2DSet(s.storagesOrigin), stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), - stateObjectsDestruct: make(map[common.Address]*types.StateAccount, len(s.stateObjectsDestruct)), + stateObjectsDestruct: maps.Clone(s.stateObjectsDestruct), refund: s.refund, logs: make(map[common.Hash][]*types.Log, len(s.logs)), logSize: s.logSize, - preimages: make(map[common.Hash][]byte, len(s.preimages)), + preimages: maps.Clone(s.preimages), journal: newJournal(), hasher: crypto.NewKeccakState(), @@ -873,16 +874,6 @@ func (s *StateDB) Copy() *StateDB { } state.stateObjectsDirty[addr] = struct{}{} } - // Deep copy the destruction markers. - for addr, value := range s.stateObjectsDestruct { - state.stateObjectsDestruct[addr] = value - } - // Deep copy the state changes made in the scope of block - // along with their original values. - state.accounts = copySet(s.accounts) - state.storages = copy2DSet(s.storages) - state.accountsOrigin = copySet(state.accountsOrigin) - state.storagesOrigin = copy2DSet(state.storagesOrigin) // Deep copy the logs occurred in the scope of block for hash, logs := range s.logs { @@ -893,10 +884,6 @@ func (s *StateDB) Copy() *StateDB { } state.logs[hash] = cpy } - // Deep copy the preimages occurred in the scope of block - for hash, preimage := range s.preimages { - state.preimages[hash] = preimage - } // Do we need to copy the access list and transient storage? // In practice: No. At the start of a transaction, these two lists are empty. // In practice, we only ever copy state _between_ transactions/blocks, never diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 448c2a69db..d86121c003 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -45,6 +45,10 @@ var ( errBeyondHistoricalLimit = errors.New("request beyond historical limit") ) +const ( + maxQueryLimit = 100 +) + // txGasAndReward is sorted in ascending order based on reward type txGasAndReward struct { gasUsed uint64 @@ -173,6 +177,9 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL if blocks < 1 { return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks } + if len(rewardPercentiles) > maxQueryLimit { + return common.Big0, nil, nil, nil, fmt.Errorf("%w: over the query limit %d", errInvalidPercentile, maxQueryLimit) + } if blocks > oracle.maxCallBlockHistory { log.Warn("Sanitizing fee history length", "requested", blocks, "truncated", oracle.maxCallBlockHistory) blocks = oracle.maxCallBlockHistory diff --git a/rpc/http.go b/rpc/http.go index b8670a9df8..8b18ed3895 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -250,7 +250,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos if _, err := buf.ReadFrom(resp.Body); err == nil { body = buf.Bytes() } - + resp.Body.Close() return nil, HTTPError{ Status: resp.Status, StatusCode: resp.StatusCode,