mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
Merge branch 'master' of github.com:berachain/bera-geth
This commit is contained in:
commit
fa6672402a
4 changed files with 167 additions and 14 deletions
|
|
@ -278,9 +278,8 @@ type BlockChain struct {
|
||||||
txLookupLock sync.RWMutex
|
txLookupLock sync.RWMutex
|
||||||
txLookupCache *lru.Cache[common.Hash, txLookup]
|
txLookupCache *lru.Cache[common.Hash, txLookup]
|
||||||
|
|
||||||
quit chan struct{} // shutdown signal, closed in Stop.
|
stopping atomic.Bool // false if chain is running, true when stopped
|
||||||
stopping atomic.Bool // false if chain is running, true when stopped
|
procInterrupt atomic.Bool // interrupt signaler for block processing
|
||||||
procInterrupt atomic.Bool // interrupt signaler for block processing
|
|
||||||
|
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
validator Validator // Block and state validator interface
|
validator Validator // Block and state validator interface
|
||||||
|
|
@ -328,7 +327,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
db: db,
|
db: db,
|
||||||
triedb: triedb,
|
triedb: triedb,
|
||||||
triegc: prque.New[int64, common.Hash](nil),
|
triegc: prque.New[int64, common.Hash](nil),
|
||||||
quit: make(chan struct{}),
|
|
||||||
chainmu: syncx.NewClosableMutex(),
|
chainmu: syncx.NewClosableMutex(),
|
||||||
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
||||||
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
|
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
|
||||||
|
|
@ -1206,7 +1204,6 @@ func (bc *BlockChain) stopWithoutSaving() {
|
||||||
bc.scope.Close()
|
bc.scope.Close()
|
||||||
|
|
||||||
// Signal shutdown to all goroutines.
|
// Signal shutdown to all goroutines.
|
||||||
close(bc.quit)
|
|
||||||
bc.StopInsert()
|
bc.StopInsert()
|
||||||
|
|
||||||
// Now wait for all chain modifications to end and persistent goroutines to exit.
|
// Now wait for all chain modifications to end and persistent goroutines to exit.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -128,6 +129,46 @@ func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func(common.Hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findTxInBlockBody traverses the given RLP-encoded block body, searching for
|
||||||
|
// the transaction specified by its hash.
|
||||||
|
func findTxInBlockBody(blockbody rlp.RawValue, target common.Hash) (*types.Transaction, uint64, error) {
|
||||||
|
txnListRLP, _, err := rlp.SplitList(blockbody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
iter, err := rlp.NewListIterator(txnListRLP)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
txIndex := uint64(0)
|
||||||
|
for iter.Next() {
|
||||||
|
if iter.Err() != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
// The preimage for the hash calculation of legacy transactions
|
||||||
|
// is just their RLP encoding. For typed (EIP-2718) transactions,
|
||||||
|
// which are encoded as byte arrays, the preimage is the content of
|
||||||
|
// the byte array, so trim their prefix here.
|
||||||
|
txRLP := iter.Value()
|
||||||
|
kind, txHashPayload, _, err := rlp.Split(txRLP)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
if kind == rlp.List { // Legacy transaction
|
||||||
|
txHashPayload = txRLP
|
||||||
|
}
|
||||||
|
if crypto.Keccak256Hash(txHashPayload) == target {
|
||||||
|
var tx types.Transaction
|
||||||
|
if err := rlp.DecodeBytes(txRLP, &tx); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
return &tx, txIndex, nil
|
||||||
|
}
|
||||||
|
txIndex++
|
||||||
|
}
|
||||||
|
return nil, 0, errors.New("transaction not found")
|
||||||
|
}
|
||||||
|
|
||||||
// ReadTransaction retrieves a specific transaction from the database, along with
|
// ReadTransaction retrieves a specific transaction from the database, along with
|
||||||
// its added positional metadata.
|
// its added positional metadata.
|
||||||
func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
|
func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
|
||||||
|
|
@ -139,18 +180,17 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com
|
||||||
if blockHash == (common.Hash{}) {
|
if blockHash == (common.Hash{}) {
|
||||||
return nil, common.Hash{}, 0, 0
|
return nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
body := ReadBody(db, blockHash, *blockNumber)
|
bodyRLP := ReadBodyRLP(db, blockHash, *blockNumber)
|
||||||
if body == nil {
|
if bodyRLP == nil {
|
||||||
log.Error("Transaction referenced missing", "number", *blockNumber, "hash", blockHash)
|
log.Error("Transaction referenced missing", "number", *blockNumber, "hash", blockHash)
|
||||||
return nil, common.Hash{}, 0, 0
|
return nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
for txIndex, tx := range body.Transactions {
|
tx, txIndex, err := findTxInBlockBody(bodyRLP, hash)
|
||||||
if tx.Hash() == hash {
|
if err != nil {
|
||||||
return tx, blockHash, *blockNumber, uint64(txIndex)
|
log.Error("Transaction not found", "number", *blockNumber, "hash", blockHash, "txhash", hash, "err", err)
|
||||||
}
|
return nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
log.Error("Transaction not found", "number", *blockNumber, "hash", blockHash, "txhash", hash)
|
return tx, blockHash, *blockNumber, txIndex
|
||||||
return nil, common.Hash{}, 0, 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadReceipt retrieves a specific transaction receipt from the database, along with
|
// ReadReceipt retrieves a specific transaction receipt from the database, along with
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,13 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/blocktest"
|
"github.com/ethereum/go-ethereum/internal/blocktest"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
var newTestHasher = blocktest.NewHasher
|
var newTestHasher = blocktest.NewHasher
|
||||||
|
|
@ -72,7 +74,15 @@ func TestLookupStorage(t *testing.T) {
|
||||||
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
|
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
|
||||||
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
|
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
|
||||||
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
|
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
|
||||||
txs := []*types.Transaction{tx1, tx2, tx3}
|
tx4 := types.NewTx(&types.DynamicFeeTx{
|
||||||
|
To: new(common.Address),
|
||||||
|
Nonce: 5,
|
||||||
|
Value: big.NewInt(5),
|
||||||
|
Gas: 5,
|
||||||
|
GasTipCap: big.NewInt(55),
|
||||||
|
GasFeeCap: big.NewInt(1055),
|
||||||
|
})
|
||||||
|
txs := []*types.Transaction{tx1, tx2, tx3, tx4}
|
||||||
|
|
||||||
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher())
|
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher())
|
||||||
|
|
||||||
|
|
@ -109,3 +119,103 @@ func TestLookupStorage(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindTxInBlockBody(t *testing.T) {
|
||||||
|
tx1 := types.NewTx(&types.LegacyTx{
|
||||||
|
Nonce: 1,
|
||||||
|
GasPrice: big.NewInt(1),
|
||||||
|
Gas: 1,
|
||||||
|
To: new(common.Address),
|
||||||
|
Value: big.NewInt(5),
|
||||||
|
Data: []byte{0x11, 0x11, 0x11},
|
||||||
|
})
|
||||||
|
tx2 := types.NewTx(&types.AccessListTx{
|
||||||
|
Nonce: 1,
|
||||||
|
GasPrice: big.NewInt(1),
|
||||||
|
Gas: 1,
|
||||||
|
To: new(common.Address),
|
||||||
|
Value: big.NewInt(5),
|
||||||
|
Data: []byte{0x11, 0x11, 0x11},
|
||||||
|
AccessList: []types.AccessTuple{
|
||||||
|
{
|
||||||
|
Address: common.Address{0x1},
|
||||||
|
StorageKeys: []common.Hash{{0x1}, {0x2}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
tx3 := types.NewTx(&types.DynamicFeeTx{
|
||||||
|
Nonce: 1,
|
||||||
|
Gas: 1,
|
||||||
|
To: new(common.Address),
|
||||||
|
Value: big.NewInt(5),
|
||||||
|
Data: []byte{0x11, 0x11, 0x11},
|
||||||
|
GasTipCap: big.NewInt(55),
|
||||||
|
GasFeeCap: big.NewInt(1055),
|
||||||
|
AccessList: []types.AccessTuple{
|
||||||
|
{
|
||||||
|
Address: common.Address{0x1},
|
||||||
|
StorageKeys: []common.Hash{{0x1}, {0x2}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
tx4 := types.NewTx(&types.BlobTx{
|
||||||
|
Nonce: 1,
|
||||||
|
Gas: 1,
|
||||||
|
To: common.Address{0x1},
|
||||||
|
Value: uint256.NewInt(5),
|
||||||
|
Data: []byte{0x11, 0x11, 0x11},
|
||||||
|
GasTipCap: uint256.NewInt(55),
|
||||||
|
GasFeeCap: uint256.NewInt(1055),
|
||||||
|
AccessList: []types.AccessTuple{
|
||||||
|
{
|
||||||
|
Address: common.Address{0x1},
|
||||||
|
StorageKeys: []common.Hash{{0x1}, {0x2}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
BlobFeeCap: uint256.NewInt(1),
|
||||||
|
BlobHashes: []common.Hash{{0x1}, {0x2}},
|
||||||
|
})
|
||||||
|
tx5 := types.NewTx(&types.SetCodeTx{
|
||||||
|
Nonce: 1,
|
||||||
|
Gas: 1,
|
||||||
|
To: common.Address{0x1},
|
||||||
|
Value: uint256.NewInt(5),
|
||||||
|
Data: []byte{0x11, 0x11, 0x11},
|
||||||
|
GasTipCap: uint256.NewInt(55),
|
||||||
|
GasFeeCap: uint256.NewInt(1055),
|
||||||
|
AccessList: []types.AccessTuple{
|
||||||
|
{
|
||||||
|
Address: common.Address{0x1},
|
||||||
|
StorageKeys: []common.Hash{{0x1}, {0x2}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AuthList: []types.SetCodeAuthorization{
|
||||||
|
{
|
||||||
|
ChainID: uint256.Int{1},
|
||||||
|
Address: common.Address{0x1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
txs := []*types.Transaction{tx1, tx2, tx3, tx4, tx5}
|
||||||
|
|
||||||
|
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher())
|
||||||
|
db := NewMemoryDatabase()
|
||||||
|
WriteBlock(db, block)
|
||||||
|
|
||||||
|
rlp := ReadBodyRLP(db, block.Hash(), block.NumberU64())
|
||||||
|
for i := 0; i < len(txs); i++ {
|
||||||
|
tx, txIndex, err := findTxInBlockBody(rlp, txs[i].Hash())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to retrieve tx, err: %v", err)
|
||||||
|
}
|
||||||
|
if txIndex != uint64(i) {
|
||||||
|
t.Fatalf("Unexpected transaction index, want: %d, got: %d", i, txIndex)
|
||||||
|
}
|
||||||
|
if tx.Hash() != txs[i].Hash() {
|
||||||
|
want := spew.Sdump(txs[i])
|
||||||
|
got := spew.Sdump(tx)
|
||||||
|
t.Fatalf("Unexpected transaction, want: %s, got: %s", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,9 @@ type BlockChain interface {
|
||||||
// InsertChain inserts a batch of blocks into the local chain.
|
// InsertChain inserts a batch of blocks into the local chain.
|
||||||
InsertChain(types.Blocks) (int, error)
|
InsertChain(types.Blocks) (int, error)
|
||||||
|
|
||||||
|
// StopInsert interrupts the inserting process.
|
||||||
|
StopInsert()
|
||||||
|
|
||||||
// InsertReceiptChain inserts a batch of blocks along with their receipts
|
// InsertReceiptChain inserts a batch of blocks along with their receipts
|
||||||
// into the local chain. Blocks older than the specified `ancientLimit`
|
// into the local chain. Blocks older than the specified `ancientLimit`
|
||||||
// are stored directly in the ancient store, while newer blocks are stored
|
// are stored directly in the ancient store, while newer blocks are stored
|
||||||
|
|
@ -634,6 +637,9 @@ func (d *Downloader) Cancel() {
|
||||||
// Terminate interrupts the downloader, canceling all pending operations.
|
// Terminate interrupts the downloader, canceling all pending operations.
|
||||||
// The downloader cannot be reused after calling Terminate.
|
// The downloader cannot be reused after calling Terminate.
|
||||||
func (d *Downloader) Terminate() {
|
func (d *Downloader) Terminate() {
|
||||||
|
// Signal to stop inserting in-flight blocks
|
||||||
|
d.blockchain.StopInsert()
|
||||||
|
|
||||||
// Close the termination channel (make sure double close is allowed)
|
// Close the termination channel (make sure double close is allowed)
|
||||||
d.quitLock.Lock()
|
d.quitLock.Lock()
|
||||||
select {
|
select {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue