mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
Merge pull request #9 from eth-infinitism/merge-master-jun-4
Merge master jun 4
This commit is contained in:
commit
726c7df365
5 changed files with 98 additions and 25 deletions
|
|
@ -208,6 +208,19 @@ func (s *StateDB) StartPrefetcher(namespace string) {
|
||||||
}
|
}
|
||||||
if s.snap != nil {
|
if s.snap != nil {
|
||||||
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace)
|
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace)
|
||||||
|
|
||||||
|
// With the switch to the Proof-of-Stake consensus algorithm, block production
|
||||||
|
// rewards are now handled at the consensus layer. Consequently, a block may
|
||||||
|
// have no state transitions if it contains no transactions and no withdrawals.
|
||||||
|
// In such cases, the account trie won't be scheduled for prefetching, leading
|
||||||
|
// to unnecessary error logs.
|
||||||
|
//
|
||||||
|
// To prevent this, the account trie is always scheduled for prefetching once
|
||||||
|
// the prefetcher is constructed. For more details, see:
|
||||||
|
// https://github.com/ethereum/go-ethereum/issues/29880
|
||||||
|
if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, nil); err != nil {
|
||||||
|
log.Error("Failed to prefetch account trie", "root", s.originalRoot, "err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1198,8 +1211,8 @@ func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) {
|
||||||
}
|
}
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
updates[obj.addrHash] = update
|
updates[obj.addrHash] = update
|
||||||
lock.Unlock()
|
|
||||||
s.StorageCommits = time.Since(start) // overwrite with the longest storage commit runtime
|
s.StorageCommits = time.Since(start) // overwrite with the longest storage commit runtime
|
||||||
|
lock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1199,10 +1199,16 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
State: state,
|
State: state,
|
||||||
ErrorRatio: estimateGasErrorRatio,
|
ErrorRatio: estimateGasErrorRatio,
|
||||||
}
|
}
|
||||||
|
// Set any required transaction default, but make sure the gas cap itself is not messed with
|
||||||
|
// if it was not specified in the original argument list.
|
||||||
|
if args.Gas == nil {
|
||||||
|
args.Gas = new(hexutil.Uint64)
|
||||||
|
}
|
||||||
if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil {
|
if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
call := args.ToMessage(header.BaseFee)
|
call := args.ToMessage(header.BaseFee)
|
||||||
|
|
||||||
// Run the gas estimation and wrap any revertals into a custom return
|
// Run the gas estimation and wrap any revertals into a custom return
|
||||||
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,8 @@ func runProcess(t *testContext, aatxs []*types.Rip7560AccountAbstractionTx) erro
|
||||||
}
|
}
|
||||||
txs = append(txs, tx3)
|
txs = append(txs, tx3)
|
||||||
|
|
||||||
b := types.NewBlock(blockchain.CurrentBlock(), txs, nil, nil, trie.NewStackTrie(nil))
|
body := types.Body{Transactions: txs}
|
||||||
|
b := types.NewBlock(blockchain.CurrentBlock(), &body, nil, trie.NewStackTrie(nil))
|
||||||
_, _, _, err = blockchain.Processor().Process(b, state.StateDB, vm.Config{})
|
_, _, _, err = blockchain.Processor().Process(b, state.StateDB, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ type nodeIteratorState struct {
|
||||||
node node // Trie node being iterated
|
node node // Trie node being iterated
|
||||||
parent common.Hash // Hash of the first full ancestor node (nil if current is the root)
|
parent common.Hash // Hash of the first full ancestor node (nil if current is the root)
|
||||||
index int // Child to be processed next
|
index int // Child to be processed next
|
||||||
pathlen int // Length of the path to this node
|
pathlen int // Length of the path to the parent node
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodeIterator struct {
|
type nodeIterator struct {
|
||||||
|
|
@ -304,6 +304,7 @@ func (it *nodeIterator) seek(prefix []byte) error {
|
||||||
// The path we're looking for is the hex encoded key without terminator.
|
// The path we're looking for is the hex encoded key without terminator.
|
||||||
key := keybytesToHex(prefix)
|
key := keybytesToHex(prefix)
|
||||||
key = key[:len(key)-1]
|
key = key[:len(key)-1]
|
||||||
|
|
||||||
// Move forward until we're just before the closest match to key.
|
// Move forward until we're just before the closest match to key.
|
||||||
for {
|
for {
|
||||||
state, parentIndex, path, err := it.peekSeek(key)
|
state, parentIndex, path, err := it.peekSeek(key)
|
||||||
|
|
@ -311,7 +312,7 @@ func (it *nodeIterator) seek(prefix []byte) error {
|
||||||
return errIteratorEnd
|
return errIteratorEnd
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return seekError{prefix, err}
|
return seekError{prefix, err}
|
||||||
} else if bytes.Compare(path, key) >= 0 {
|
} else if reachedPath(path, key) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
it.push(state, parentIndex, path)
|
it.push(state, parentIndex, path)
|
||||||
|
|
@ -339,7 +340,6 @@ func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, er
|
||||||
// If we're skipping children, pop the current node first
|
// If we're skipping children, pop the current node first
|
||||||
it.pop()
|
it.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue iteration to the next child
|
// Continue iteration to the next child
|
||||||
for len(it.stack) > 0 {
|
for len(it.stack) > 0 {
|
||||||
parent := it.stack[len(it.stack)-1]
|
parent := it.stack[len(it.stack)-1]
|
||||||
|
|
@ -372,7 +372,6 @@ func (it *nodeIterator) peekSeek(seekKey []byte) (*nodeIteratorState, *int, []by
|
||||||
// If we're skipping children, pop the current node first
|
// If we're skipping children, pop the current node first
|
||||||
it.pop()
|
it.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue iteration to the next child
|
// Continue iteration to the next child
|
||||||
for len(it.stack) > 0 {
|
for len(it.stack) > 0 {
|
||||||
parent := it.stack[len(it.stack)-1]
|
parent := it.stack[len(it.stack)-1]
|
||||||
|
|
@ -449,16 +448,18 @@ func (it *nodeIterator) findChild(n *fullNode, index int, ancestor common.Hash)
|
||||||
state *nodeIteratorState
|
state *nodeIteratorState
|
||||||
childPath []byte
|
childPath []byte
|
||||||
)
|
)
|
||||||
for ; index < len(n.Children); index++ {
|
for ; index < len(n.Children); index = nextChildIndex(index) {
|
||||||
if n.Children[index] != nil {
|
if n.Children[index] != nil {
|
||||||
child = n.Children[index]
|
child = n.Children[index]
|
||||||
hash, _ := child.cache()
|
hash, _ := child.cache()
|
||||||
|
|
||||||
state = it.getFromPool()
|
state = it.getFromPool()
|
||||||
state.hash = common.BytesToHash(hash)
|
state.hash = common.BytesToHash(hash)
|
||||||
state.node = child
|
state.node = child
|
||||||
state.parent = ancestor
|
state.parent = ancestor
|
||||||
state.index = -1
|
state.index = -1
|
||||||
state.pathlen = len(path)
|
state.pathlen = len(path)
|
||||||
|
|
||||||
childPath = append(childPath, path...)
|
childPath = append(childPath, path...)
|
||||||
childPath = append(childPath, byte(index))
|
childPath = append(childPath, byte(index))
|
||||||
return child, state, childPath, index
|
return child, state, childPath, index
|
||||||
|
|
@ -471,8 +472,8 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
|
||||||
switch node := parent.node.(type) {
|
switch node := parent.node.(type) {
|
||||||
case *fullNode:
|
case *fullNode:
|
||||||
// Full node, move to the first non-nil child.
|
// Full node, move to the first non-nil child.
|
||||||
if child, state, path, index := it.findChild(node, parent.index+1, ancestor); child != nil {
|
if child, state, path, index := it.findChild(node, nextChildIndex(parent.index), ancestor); child != nil {
|
||||||
parent.index = index - 1
|
parent.index = prevChildIndex(index)
|
||||||
return state, path, true
|
return state, path, true
|
||||||
}
|
}
|
||||||
case *shortNode:
|
case *shortNode:
|
||||||
|
|
@ -498,23 +499,23 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H
|
||||||
switch n := parent.node.(type) {
|
switch n := parent.node.(type) {
|
||||||
case *fullNode:
|
case *fullNode:
|
||||||
// Full node, move to the first non-nil child before the desired key position
|
// Full node, move to the first non-nil child before the desired key position
|
||||||
child, state, path, index := it.findChild(n, parent.index+1, ancestor)
|
child, state, path, index := it.findChild(n, nextChildIndex(parent.index), ancestor)
|
||||||
if child == nil {
|
if child == nil {
|
||||||
// No more children in this fullnode
|
// No more children in this fullnode
|
||||||
return parent, it.path, false
|
return parent, it.path, false
|
||||||
}
|
}
|
||||||
// If the child we found is already past the seek position, just return it.
|
// If the child we found is already past the seek position, just return it.
|
||||||
if bytes.Compare(path, key) >= 0 {
|
if reachedPath(path, key) {
|
||||||
parent.index = index - 1
|
parent.index = prevChildIndex(index)
|
||||||
return state, path, true
|
return state, path, true
|
||||||
}
|
}
|
||||||
// The child is before the seek position. Try advancing
|
// The child is before the seek position. Try advancing
|
||||||
for {
|
for {
|
||||||
nextChild, nextState, nextPath, nextIndex := it.findChild(n, index+1, ancestor)
|
nextChild, nextState, nextPath, nextIndex := it.findChild(n, nextChildIndex(index), ancestor)
|
||||||
// If we run out of children, or skipped past the target, return the
|
// If we run out of children, or skipped past the target, return the
|
||||||
// previous one
|
// previous one
|
||||||
if nextChild == nil || bytes.Compare(nextPath, key) >= 0 {
|
if nextChild == nil || reachedPath(nextPath, key) {
|
||||||
parent.index = index - 1
|
parent.index = prevChildIndex(index)
|
||||||
return state, path, true
|
return state, path, true
|
||||||
}
|
}
|
||||||
// We found a better child closer to the target
|
// We found a better child closer to the target
|
||||||
|
|
@ -541,7 +542,7 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []
|
||||||
it.path = path
|
it.path = path
|
||||||
it.stack = append(it.stack, state)
|
it.stack = append(it.stack, state)
|
||||||
if parentIndex != nil {
|
if parentIndex != nil {
|
||||||
*parentIndex++
|
*parentIndex = nextChildIndex(*parentIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,8 +551,54 @@ func (it *nodeIterator) pop() {
|
||||||
it.path = it.path[:last.pathlen]
|
it.path = it.path[:last.pathlen]
|
||||||
it.stack[len(it.stack)-1] = nil
|
it.stack[len(it.stack)-1] = nil
|
||||||
it.stack = it.stack[:len(it.stack)-1]
|
it.stack = it.stack[:len(it.stack)-1]
|
||||||
// last is now unused
|
|
||||||
it.putInPool(last)
|
it.putInPool(last) // last is now unused
|
||||||
|
}
|
||||||
|
|
||||||
|
// reachedPath normalizes a path by truncating a terminator if present, and
|
||||||
|
// returns true if it is greater than or equal to the target. Using this,
|
||||||
|
// the path of a value node embedded a full node will compare less than the
|
||||||
|
// full node's children.
|
||||||
|
func reachedPath(path, target []byte) bool {
|
||||||
|
if hasTerm(path) {
|
||||||
|
path = path[:len(path)-1]
|
||||||
|
}
|
||||||
|
return bytes.Compare(path, target) >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// A value embedded in a full node occupies the last slot (16) of the array of
|
||||||
|
// children. In order to produce a pre-order traversal when iterating children,
|
||||||
|
// we jump to this last slot first, then go back iterate the child nodes (and
|
||||||
|
// skip the last slot at the end):
|
||||||
|
|
||||||
|
// prevChildIndex returns the index of a child in a full node which precedes
|
||||||
|
// the given index when performing a pre-order traversal.
|
||||||
|
func prevChildIndex(index int) int {
|
||||||
|
switch index {
|
||||||
|
case 0: // We jumped back to iterate the children, from the value slot
|
||||||
|
return 16
|
||||||
|
case 16: // We jumped to the embedded value slot at the end, from the placeholder index
|
||||||
|
return -1
|
||||||
|
case 17: // We skipped the value slot after iterating all the children
|
||||||
|
return 15
|
||||||
|
default: // We are iterating the children in sequence
|
||||||
|
return index - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nextChildIndex returns the index of a child in a full node which follows
|
||||||
|
// the given index when performing a pre-order traversal.
|
||||||
|
func nextChildIndex(index int) int {
|
||||||
|
switch index {
|
||||||
|
case -1: // Jump from the placeholder index to the embedded value slot
|
||||||
|
return 16
|
||||||
|
case 15: // Skip the value slot after iterating the children
|
||||||
|
return 17
|
||||||
|
case 16: // From the embedded value slot, jump back to iterate the children
|
||||||
|
return 0
|
||||||
|
default: // Iterate children in sequence
|
||||||
|
return index + 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareNodes(a, b NodeIterator) int {
|
func compareNodes(a, b NodeIterator) int {
|
||||||
|
|
|
||||||
|
|
@ -182,14 +182,14 @@ func testNodeIteratorCoverage(t *testing.T, scheme string) {
|
||||||
type kvs struct{ k, v string }
|
type kvs struct{ k, v string }
|
||||||
|
|
||||||
var testdata1 = []kvs{
|
var testdata1 = []kvs{
|
||||||
|
{"bar", "b"},
|
||||||
{"barb", "ba"},
|
{"barb", "ba"},
|
||||||
{"bard", "bc"},
|
{"bard", "bc"},
|
||||||
{"bars", "bb"},
|
{"bars", "bb"},
|
||||||
{"bar", "b"},
|
|
||||||
{"fab", "z"},
|
{"fab", "z"},
|
||||||
|
{"foo", "a"},
|
||||||
{"food", "ab"},
|
{"food", "ab"},
|
||||||
{"foos", "aa"},
|
{"foos", "aa"},
|
||||||
{"foo", "a"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var testdata2 = []kvs{
|
var testdata2 = []kvs{
|
||||||
|
|
@ -218,7 +218,7 @@ func TestIteratorSeek(t *testing.T) {
|
||||||
|
|
||||||
// Seek to a non-existent key.
|
// Seek to a non-existent key.
|
||||||
it = NewIterator(trie.MustNodeIterator([]byte("barc")))
|
it = NewIterator(trie.MustNodeIterator([]byte("barc")))
|
||||||
if err := checkIteratorOrder(testdata1[1:], it); err != nil {
|
if err := checkIteratorOrder(testdata1[2:], it); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,6 +227,12 @@ func TestIteratorSeek(t *testing.T) {
|
||||||
if err := checkIteratorOrder(nil, it); err != nil {
|
if err := checkIteratorOrder(nil, it); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seek to a key for which a prefixing key exists.
|
||||||
|
it = NewIterator(trie.MustNodeIterator([]byte("food")))
|
||||||
|
if err := checkIteratorOrder(testdata1[6:], it); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkIteratorOrder(want []kvs, it *Iterator) error {
|
func checkIteratorOrder(want []kvs, it *Iterator) error {
|
||||||
|
|
@ -311,16 +317,16 @@ func TestUnionIterator(t *testing.T) {
|
||||||
|
|
||||||
all := []struct{ k, v string }{
|
all := []struct{ k, v string }{
|
||||||
{"aardvark", "c"},
|
{"aardvark", "c"},
|
||||||
|
{"bar", "b"},
|
||||||
{"barb", "ba"},
|
{"barb", "ba"},
|
||||||
{"barb", "bd"},
|
{"barb", "bd"},
|
||||||
{"bard", "bc"},
|
{"bard", "bc"},
|
||||||
{"bars", "bb"},
|
{"bars", "bb"},
|
||||||
{"bars", "be"},
|
{"bars", "be"},
|
||||||
{"bar", "b"},
|
|
||||||
{"fab", "z"},
|
{"fab", "z"},
|
||||||
|
{"foo", "a"},
|
||||||
{"food", "ab"},
|
{"food", "ab"},
|
||||||
{"foos", "aa"},
|
{"foos", "aa"},
|
||||||
{"foo", "a"},
|
|
||||||
{"jars", "d"},
|
{"jars", "d"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -512,7 +518,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool, scheme strin
|
||||||
rawdb.WriteTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, barNodeBlob, triedb.Scheme())
|
rawdb.WriteTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, barNodeBlob, triedb.Scheme())
|
||||||
}
|
}
|
||||||
// Check that iteration produces the right set of values.
|
// Check that iteration produces the right set of values.
|
||||||
if err := checkIteratorOrder(testdata1[2:], NewIterator(it)); err != nil {
|
if err := checkIteratorOrder(testdata1[3:], NewIterator(it)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue