dev: chg: more regression changes for bor after merge

This commit is contained in:
marcello33 2023-06-12 19:35:40 +02:00
parent 162af07d38
commit d3f6da90e1
47 changed files with 253 additions and 1271 deletions

View file

@ -35,7 +35,7 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
cli "github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
var ( var (

View file

@ -159,7 +159,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
t.Logf("Post-merge header: %d", block.NumberU64()) t.Logf("Post-merge header: %d", block.NumberU64())
} }
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces // Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
chain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) chain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil, nil)
defer chain.Stop() defer chain.Stop()
// Verify the blocks before the merging // Verify the blocks before the merging

View file

@ -238,7 +238,7 @@ type BlockChain struct {
vmConfig vm.Config vmConfig vm.Config
// Bor related changes // Bor related changes
borReceiptsCache *lru.Cache[common.Hash, []*types.Receipt] // Cache for the most recent bor receipt receipts per block borReceiptsCache *lru.Cache[common.Hash, *types.Receipt] // Cache for the most recent bor receipt receipts per block
stateSyncData []*types.StateSyncData // State sync data stateSyncData []*types.StateSyncData // State sync data
stateSyncFeed event.Feed // State sync feed stateSyncFeed event.Feed // State sync feed
chain2HeadFeed event.Feed // Reorg/NewHead/Fork data feed chain2HeadFeed event.Feed // Reorg/NewHead/Fork data feed
@ -295,7 +295,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
engine: engine, engine: engine,
vmConfig: vmConfig, vmConfig: vmConfig,
borReceiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit), borReceiptsCache: lru.NewCache[common.Hash, *types.Receipt](receiptsCacheLimit),
} }
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit)) bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
bc.forker = NewForkChoice(bc, shouldPreserve, checker) bc.forker = NewForkChoice(bc, shouldPreserve, checker)

View file

@ -27,7 +27,7 @@ func TestChain2HeadEvent(t *testing.T) {
signer = types.LatestSigner(gspec.Config) signer = types.LatestSigner(gspec.Config)
) )
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil) blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
defer blockchain.Stop() defer blockchain.Stop()
chain2HeadCh := make(chan Chain2HeadEvent, 64) chain2HeadCh := make(chan Chain2HeadEvent, 64)

View file

@ -9,7 +9,7 @@ import (
// GetBorReceiptByHash retrieves the bor block receipt in a given block. // GetBorReceiptByHash retrieves the bor block receipt in a given block.
func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.Receipt { func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.Receipt {
if receipt, ok := bc.borReceiptsCache.Get(hash); ok { if receipt, ok := bc.borReceiptsCache.Get(hash); ok {
return receipt.(*types.Receipt) return receipt
} }
// read header from hash // read header from hash

View file

@ -107,7 +107,7 @@ func TestGenerateWithdrawalChain(t *testing.T) {
}) })
// Import the chain. This runs all block validation rules. // Import the chain. This runs all block validation rules.
blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil) blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil, nil)
defer blockchain.Stop() defer blockchain.Stop()
if i, err := blockchain.InsertChain(chain); err != nil { if i, err := blockchain.InsertChain(chain); err != nil {

View file

@ -1,6 +1,7 @@
package core package core
import ( import (
"github.com/ethereum/go-ethereum/trie"
"math/big" "math/big"
"testing" "testing"
@ -34,10 +35,11 @@ func TestPastChainInsert(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges}
) )
hc, err := NewHeaderChain(db, params.AllEthashProtocolChanges, ethash.NewFaker(), func() bool { return false }) gspec.Commit(db, trie.NewDatabase(db))
hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false })
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -48,11 +50,11 @@ func TestPastChainInsert(t *testing.T) {
} }
validate := func(currentHeader *types.Header, chain []*types.Header) (bool, error) { validate := func(currentHeader *types.Header, chain []*types.Header) (bool, error) {
// Put all explicit conditions here // Put all explicit conditions here
// If canonical chain is empty and we're importing a chain of 64 blocks // If canonical chain is empty, and we're importing a chain of 64 blocks
if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 { if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 {
return true, nil return true, nil
} }
// If canonical chain is of len 64 and we're importing a past chain from 54-64, then accept it // If canonical chain is of len 64, and we're importing a past chain from 54-64, then accept it
if currentHeader.Number.Uint64() == uint64(64) && chain[0].Number.Uint64() == 55 && len(chain) == 10 { if currentHeader.Number.Uint64() == uint64(64) && chain[0].Number.Uint64() == 55 && len(chain) == 10 {
return true, nil return true, nil
} }
@ -64,7 +66,7 @@ func TestPastChainInsert(t *testing.T) {
mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator) mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator)
// chain A: G->A1->A2...A64 // chain A: G->A1->A2...A64
chainA := makeHeaderChain(genesis.Header(), 64, ethash.NewFaker(), db, 10) genDb, chainA := makeHeaderChainWithGenesis(gspec, 64, ethash.NewFaker(), 10)
// Inserting 64 headers on an empty chain // Inserting 64 headers on an empty chain
// expecting 1 write status with no error // expecting 1 write status with no error
@ -72,11 +74,11 @@ func TestPastChainInsert(t *testing.T) {
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain B: G->A1->A2...A44->B45->B46...B64 // chain B: G->A1->A2...A44->B45->B46...B64
chainB := makeHeaderChain(chainA[43], 20, ethash.NewFaker(), db, 10) chainB := makeHeaderChain(gspec.Config, chainA[43], 20, ethash.NewFaker(), genDb, 10)
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain C: G->A1->A2...A54->C55->C56...C64 // chain C: G->A1->A2...A54->C55->C56...C64
chainC := makeHeaderChain(chainA[53], 10, ethash.NewFaker(), db, 10) chainC := makeHeaderChain(gspec.Config, chainA[53], 10, ethash.NewFaker(), genDb, 10)
// Update the function to consider chainC with higher difficulty // Update the function to consider chainC with higher difficulty
getTd = func(hash common.Hash, number uint64) *big.Int { getTd = func(hash common.Hash, number uint64) *big.Int {
@ -104,10 +106,11 @@ func TestFutureChainInsert(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges}
) )
hc, err := NewHeaderChain(db, params.AllEthashProtocolChanges, ethash.NewFaker(), func() bool { return false }) gspec.Commit(db, trie.NewDatabase(db))
hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false })
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -134,7 +137,7 @@ func TestFutureChainInsert(t *testing.T) {
mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator) mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator)
// chain A: G->A1->A2...A64 // chain A: G->A1->A2...A64
chainA := makeHeaderChain(genesis.Header(), 64, ethash.NewFaker(), db, 10) genDb, chainA := makeHeaderChainWithGenesis(gspec, 64, ethash.NewFaker(), 10)
// Inserting 64 headers on an empty chain // Inserting 64 headers on an empty chain
// expecting 1 write status with no error // expecting 1 write status with no error
@ -142,7 +145,7 @@ func TestFutureChainInsert(t *testing.T) {
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain B: G->A1->A2...A64->B65->B66...B84 // chain B: G->A1->A2...A64->B65->B66...B84
chainB := makeHeaderChain(chainA[63], 20, ethash.NewFaker(), db, 10) chainB := makeHeaderChain(gspec.Config, chainA[63], 20, ethash.NewFaker(), genDb, 10)
// Inserting 20 headers on the canonical chain // Inserting 20 headers on the canonical chain
// expecting 0 write status with no error // expecting 0 write status with no error
@ -150,7 +153,7 @@ func TestFutureChainInsert(t *testing.T) {
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain C: G->A1->A2...A64->C65->C66...C74 // chain C: G->A1->A2...A64->C65->C66...C74
chainC := makeHeaderChain(chainA[63], 10, ethash.NewFaker(), db, 10) chainC := makeHeaderChain(gspec.Config, chainA[63], 10, ethash.NewFaker(), genDb, 10)
// Inserting 10 headers on the canonical chain // Inserting 10 headers on the canonical chain
// expecting 0 write status with no error // expecting 0 write status with no error
@ -162,10 +165,11 @@ func TestOverlappingChainInsert(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges}
) )
hc, err := NewHeaderChain(db, params.AllEthashProtocolChanges, ethash.NewFaker(), func() bool { return false }) gspec.Commit(db, trie.NewDatabase(db))
hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false })
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -192,7 +196,7 @@ func TestOverlappingChainInsert(t *testing.T) {
mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator) mockForker := NewForkChoice(mockChainReader, nil, mockChainValidator)
// chain A: G->A1->A2...A64 // chain A: G->A1->A2...A64
chainA := makeHeaderChain(genesis.Header(), 64, ethash.NewFaker(), db, 10) genDb, chainA := makeHeaderChainWithGenesis(gspec, 64, ethash.NewFaker(), 10)
// Inserting 64 headers on an empty chain // Inserting 64 headers on an empty chain
// expecting 1 write status with no error // expecting 1 write status with no error
@ -200,7 +204,7 @@ func TestOverlappingChainInsert(t *testing.T) {
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain B: G->A1->A2...A54->B55->B56...B84 // chain B: G->A1->A2...A54->B55->B56...B84
chainB := makeHeaderChain(chainA[53], 30, ethash.NewFaker(), db, 10) chainB := makeHeaderChain(gspec.Config, chainA[53], 30, ethash.NewFaker(), genDb, 10)
// Inserting 20 blocks on canonical chain // Inserting 20 blocks on canonical chain
// expecting 2 write status with no error // expecting 2 write status with no error
@ -208,7 +212,7 @@ func TestOverlappingChainInsert(t *testing.T) {
// The current chain is: G->A1->A2...A64 // The current chain is: G->A1->A2...A64
// chain C: G->A1->A2...A54->C55->C56...C74 // chain C: G->A1->A2...A54->C55->C56...C74
chainC := makeHeaderChain(chainA[53], 20, ethash.NewFaker(), db, 10) chainC := makeHeaderChain(gspec.Config, chainA[53], 20, ethash.NewFaker(), genDb, 10)
// Inserting 10 blocks on canonical chain // Inserting 10 blocks on canonical chain
// expecting 1 write status with no error // expecting 1 write status with no error

View file

@ -345,7 +345,7 @@ func TestStateProcessorErrors(t *testing.T) {
}, },
} }
genesis = gspec.MustCommit(db) genesis = gspec.MustCommit(db)
blockchain, _ = NewBlockChain(db, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil) blockchain, _ = NewBlockChain(db, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil, nil)
tooBigInitCode = [params.MaxInitCodeSize + 1]byte{} tooBigInitCode = [params.MaxInitCodeSize + 1]byte{}
smallInitCode = [320]byte{} smallInitCode = [320]byte{}
) )
@ -386,7 +386,7 @@ func TestStateProcessorErrors(t *testing.T) {
func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block { func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block {
difficulty := big.NewInt(0) difficulty := big.NewInt(0)
if !config.TerminalTotalDifficultyPassed { if !config.TerminalTotalDifficultyPassed {
difficulty = engine.CalcDifficulty(&fakeChainReader{config}, parent.Time()+10, &types.Header{ difficulty = engine.CalcDifficulty(&fakeChainReader{config: config}, parent.Time()+10, &types.Header{
Number: parent.Number(), Number: parent.Number(),
Time: parent.Time(), Time: parent.Time(),
Difficulty: parent.Difficulty(), Difficulty: parent.Difficulty(),

View file

@ -13,7 +13,7 @@
// //
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core package txpool
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
@ -28,6 +28,8 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
// TODO marcello merge this file with txpool2_test.go
func pricedValuedTransaction(nonce uint64, value int64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { func pricedValuedTransaction(nonce uint64, value int64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(value), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(value), gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
return tx return tx
@ -36,9 +38,9 @@ func pricedValuedTransaction(nonce uint64, value int64, gaslimit uint64, gaspric
func count(t *testing.T, pool *TxPool) (pending int, queued int) { func count(t *testing.T, pool *TxPool) (pending int, queued int) {
t.Helper() t.Helper()
pending, queued = pool.stats() pending, queued = pool.Stats()
if err := validateTxPoolInternals(pool); err != nil { if err := validatePoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
@ -55,7 +57,7 @@ func fillPool(t *testing.T, pool *TxPool) {
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(10000000000)) pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(10000000000))
// Add executable ones // Add executable ones
for j := 0; j < int(pool.config.AccountSlots); j++ { for j := 0; j < int(pool.config().AccountSlots); j++ {
executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key)) executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key))
} }
} }

View file

@ -53,6 +53,8 @@ import (
"github.com/JekaMas/crand" "github.com/JekaMas/crand"
) )
// TODO marcello merge this file with txpool2_test_BOR.go
var ( var (
// testTxPoolConfig is a transaction pool configuration without stateful disk // testTxPoolConfig is a transaction pool configuration without stateful disk
// sideeffects used during testing. // sideeffects used during testing.

View file

@ -1,53 +0,0 @@
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package types
import (
"errors"
"github.com/ethereum/go-ethereum/rlp"
)
// IsLegacyStoredReceipts tries to parse the RLP-encoded blob
// first as an array of v3 stored receipt, then v4 stored receipt and
// returns true if successful.
func IsLegacyStoredReceipts(raw []byte) (bool, error) {
var v3 []v3StoredReceiptRLP
if err := rlp.DecodeBytes(raw, &v3); err == nil {
return true, nil
}
var v4 []v4StoredReceiptRLP
if err := rlp.DecodeBytes(raw, &v4); err == nil {
return true, nil
}
var v5 []storedReceiptRLP
// Check to see valid fresh stored receipt
if err := rlp.DecodeBytes(raw, &v5); err == nil {
return false, nil
}
return false, errors.New("value is not a valid receipt encoding")
}
// ConvertLegacyStoredReceipts takes the RLP encoding of an array of legacy
// stored receipts and returns a fresh RLP-encoded stored receipt.
func ConvertLegacyStoredReceipts(raw []byte) ([]byte, error) {
var receipts []ReceiptForStorage
if err := rlp.DecodeBytes(raw, &receipts); err != nil {
return nil, err
}
return rlp.EncodeToBytes(&receipts)
}

View file

@ -56,7 +56,7 @@ type Transaction struct {
// caches // caches
hash atomic.Pointer[common.Hash] hash atomic.Pointer[common.Hash]
size atomic.Pointer[common.StorageSize] size atomic.Pointer[uint64]
from atomic.Pointer[sigCache] from atomic.Pointer[sigCache]
} }
@ -207,8 +207,7 @@ func (tx *Transaction) setDecoded(inner TxData, size uint64) {
tx.inner = inner tx.inner = inner
tx.time = time.Now() tx.time = time.Now()
if size > 0 { if size > 0 {
v := float64(size) tx.size.Store(&size)
tx.size.Store((*common.StorageSize)(&v))
} }
} }
@ -486,17 +485,19 @@ func (tx *Transaction) Hash() common.Hash {
// Size returns the true encoded storage size of the transaction, either by encoding // Size returns the true encoded storage size of the transaction, either by encoding
// and returning it, or returning a previously cached value. // and returning it, or returning a previously cached value.
func (tx *Transaction) Size() common.StorageSize { func (tx *Transaction) Size() uint64 {
if size := tx.size.Load(); size != nil { if size := tx.size.Load(); size != nil {
return *size return *size
} }
c := writeCounter(0) c := writeCounter(0)
rlp.Encode(&c, &tx.inner) rlp.Encode(&c, &tx.inner)
tx.size.Store((*common.StorageSize)(&c))
return common.StorageSize(c) size := uint64(c)
if tx.Type() != LegacyTxType {
size += 1 // type byte
}
tx.size.Store(&size)
return size
} }
// WithSignature returns a new transaction with the given signature. // WithSignature returns a new transaction with the given signature.

View file

@ -151,7 +151,7 @@ func TestCreateGas(t *testing.T) {
vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, config) vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, config)
var startGas = uint64(testGas) var startGas = uint64(testGas)
ret, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, startGas, new(big.Int)) ret, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, startGas, new(big.Int), nil)
if err != nil { if err != nil {
return false return false
} }

View file

@ -18,7 +18,6 @@ package vm
import ( import (
"math/big" "math/big"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )

View file

@ -3,7 +3,6 @@ package filters
import ( import (
"time" "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
@ -22,7 +21,7 @@ func (es *EventSystem) SubscribeNewDeposits(data chan *types.StateSyncData) *Sub
typ: StateSyncSubscription, typ: StateSyncSubscription,
created: time.Now(), created: time.Now(),
logs: make(chan []*types.Log), logs: make(chan []*types.Log),
hashes: make(chan []common.Hash), txs: make(chan []*types.Transaction),
headers: make(chan *types.Header), headers: make(chan *types.Header),
stateSyncData: data, stateSyncData: data,
installed: make(chan struct{}), installed: make(chan struct{}),

View file

@ -74,6 +74,7 @@ func TestBorFilters(t *testing.T) {
// Block 1 // Block 1
backend.expectBorReceiptsFromMock([]*common.Hash{nil, &hash1, &hash2, &hash3, &hash4}) backend.expectBorReceiptsFromMock([]*common.Hash{nil, &hash1, &hash2, &hash3, &hash4})
// TODO marcello regenerate ctrls for gomock to include the new methods
filter := NewBorBlockLogsRangeFilter(backend, testBorConfig, 0, 18, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) filter := NewBorBlockLogsRangeFilter(backend, testBorConfig, 0, 18, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
logs, err := filter.Logs(context.Background()) logs, err := filter.Logs(context.Background())

View file

@ -50,6 +50,12 @@ type testBackend struct {
rmLogsFeed event.Feed rmLogsFeed event.Feed
pendingLogsFeed event.Feed pendingLogsFeed event.Feed
chainFeed event.Feed chainFeed event.Feed
stateSyncFeed event.Feed
}
func (b *testBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
return b.stateSyncFeed.Subscribe(ch)
} }
func (b *testBackend) ChainConfig() *params.ChainConfig { func (b *testBackend) ChainConfig() *params.ChainConfig {

View file

@ -62,10 +62,11 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T
} }
// TODO: discuss consequences of setting preferDisk false. // TODO: discuss consequences of setting preferDisk false.
statedb, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false) statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer release()
// Execute all the transaction contained within the block concurrently // Execute all the transaction contained within the block concurrently
var ( var (
@ -77,25 +78,25 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
traceTxn := func(indx int, tx *types.Transaction, borTx bool) *TxTraceResult { traceTxn := func(indx int, tx *types.Transaction, borTx bool) *TxTraceResult {
message, _ := tx.AsMessage(signer, block.BaseFee()) message, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(message) txContext := core.NewEVMTxContext(message)
tracer := logger.NewStructLogger(config.Config) tracer := logger.NewStructLogger(config.Config)
// Run the transaction with tracing enabled. // Run the transaction with tracing enabled.
vmenv := vm.NewEVM(blockCtx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true}) vmenv := vm.NewEVM(blockCtx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer, NoBaseFee: true})
// Call Prepare to clear out the statedb access list // Call Prepare to clear out the statedb access list
// Not sure if we need to do this // Not sure if we need to do this
statedb.Prepare(tx.Hash(), indx) statedb.SetTxContext(tx.Hash(), indx)
var execRes *core.ExecutionResult var execRes *core.ExecutionResult
if borTx { if borTx {
callmsg := prepareCallMessage(message) callmsg := prepareCallMessage(*message)
execRes, err = statefull.ApplyBorMessage(*vmenv, callmsg) execRes, err = statefull.ApplyBorMessage(*vmenv, callmsg)
} else { } else {
execRes, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), nil) execRes, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit), nil)
} }
if err != nil { if err != nil {

View file

@ -1,880 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// package js is a collection of tracers written in javascript.
package js
import (
"encoding/json"
"errors"
"fmt"
"math/big"
"strings"
"sync/atomic"
"time"
"unicode"
"unsafe"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
tracers2 "github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers/js/internal/tracers"
"github.com/ethereum/go-ethereum/log"
"gopkg.in/olebedev/go-duktape.v3"
)
// camel converts a snake cased input string into a camel cased output.
func camel(str string) string {
pieces := strings.Split(str, "_")
for i := 1; i < len(pieces); i++ {
pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
}
return strings.Join(pieces, "")
}
var assetTracers = make(map[string]string)
// init retrieves the JavaScript transaction tracers included in go-ethereum.
func init() {
for _, file := range tracers.AssetNames() {
name := camel(strings.TrimSuffix(file, ".js"))
assetTracers[name] = string(tracers.MustAsset(file))
}
tracers2.RegisterLookup(true, newJsTracer)
}
// makeSlice convert an unsafe memory pointer with the given type into a Go byte
// slice.
//
// Note, the returned slice uses the same memory area as the input arguments.
// If those are duktape stack items, popping them off **will** make the slice
// contents change.
func makeSlice(ptr unsafe.Pointer, size uint) []byte {
var sl = struct {
addr uintptr
len int
cap int
}{uintptr(ptr), int(size), int(size)}
return *(*[]byte)(unsafe.Pointer(&sl))
}
// popSlice pops a buffer off the JavaScript stack and returns it as a slice.
func popSlice(ctx *duktape.Context) []byte {
blob := common.CopyBytes(makeSlice(ctx.GetBuffer(-1)))
ctx.Pop()
return blob
}
// pushBigInt create a JavaScript BigInteger in the VM.
func pushBigInt(n *big.Int, ctx *duktape.Context) {
ctx.GetGlobalString("bigInt")
ctx.PushString(n.String())
ctx.Call(1)
}
// opWrapper provides a JavaScript wrapper around OpCode.
type opWrapper struct {
op vm.OpCode
}
// pushObject assembles a JSVM object wrapping a swappable opcode and pushes it
// onto the VM stack.
func (ow *opWrapper) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushInt(int(ow.op)); return 1 })
vm.PutPropString(obj, "toNumber")
vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushString(ow.op.String()); return 1 })
vm.PutPropString(obj, "toString")
vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushBoolean(ow.op.IsPush()); return 1 })
vm.PutPropString(obj, "isPush")
}
// memoryWrapper provides a JavaScript wrapper around vm.Memory.
type memoryWrapper struct {
memory *vm.Memory
}
// slice returns the requested range of memory as a byte slice.
func (mw *memoryWrapper) slice(begin, end int64) []byte {
if end == begin {
return []byte{}
}
if end < begin || begin < 0 {
// TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go
// runtime goes belly up https://github.com/golang/go/issues/15639.
log.Warn("Tracer accessed out of bound memory", "offset", begin, "end", end)
return nil
}
if mw.memory.Len() < int(end) {
// TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go
// runtime goes belly up https://github.com/golang/go/issues/15639.
log.Warn("Tracer accessed out of bound memory", "available", mw.memory.Len(), "offset", begin, "size", end-begin)
return nil
}
return mw.memory.GetCopy(begin, end-begin)
}
// getUint returns the 32 bytes at the specified address interpreted as a uint.
func (mw *memoryWrapper) getUint(addr int64) *big.Int {
if mw.memory.Len() < int(addr)+32 || addr < 0 {
// TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go
// runtime goes belly up https://github.com/golang/go/issues/15639.
log.Warn("Tracer accessed out of bound memory", "available", mw.memory.Len(), "offset", addr, "size", 32)
return new(big.Int)
}
return new(big.Int).SetBytes(mw.memory.GetPtr(addr, 32))
}
// pushObject assembles a JSVM object wrapping a swappable memory and pushes it
// onto the VM stack.
func (mw *memoryWrapper) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
// Generate the `slice` method which takes two ints and returns a buffer
vm.PushGoFunction(func(ctx *duktape.Context) int {
blob := mw.slice(int64(ctx.GetInt(-2)), int64(ctx.GetInt(-1)))
ctx.Pop2()
ptr := ctx.PushFixedBuffer(len(blob))
copy(makeSlice(ptr, uint(len(blob))), blob)
return 1
})
vm.PutPropString(obj, "slice")
// Generate the `getUint` method which takes an int and returns a bigint
vm.PushGoFunction(func(ctx *duktape.Context) int {
offset := int64(ctx.GetInt(-1))
ctx.Pop()
pushBigInt(mw.getUint(offset), ctx)
return 1
})
vm.PutPropString(obj, "getUint")
}
// stackWrapper provides a JavaScript wrapper around vm.Stack.
type stackWrapper struct {
stack *vm.Stack
}
// peek returns the nth-from-the-top element of the stack.
func (sw *stackWrapper) peek(idx int) *big.Int {
if len(sw.stack.Data()) <= idx || idx < 0 {
// TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go
// runtime goes belly up https://github.com/golang/go/issues/15639.
log.Warn("Tracer accessed out of bound stack", "size", len(sw.stack.Data()), "index", idx)
return new(big.Int)
}
return sw.stack.Back(idx).ToBig()
}
// pushObject assembles a JSVM object wrapping a swappable stack and pushes it
// onto the VM stack.
func (sw *stackWrapper) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushInt(len(sw.stack.Data())); return 1 })
vm.PutPropString(obj, "length")
// Generate the `peek` method which takes an int and returns a bigint
vm.PushGoFunction(func(ctx *duktape.Context) int {
offset := ctx.GetInt(-1)
ctx.Pop()
pushBigInt(sw.peek(offset), ctx)
return 1
})
vm.PutPropString(obj, "peek")
}
// dbWrapper provides a JavaScript wrapper around vm.Database.
type dbWrapper struct {
db vm.StateDB
}
// pushObject assembles a JSVM object wrapping a swappable database and pushes it
// onto the VM stack.
func (dw *dbWrapper) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
// Push the wrapper for statedb.GetBalance
vm.PushGoFunction(func(ctx *duktape.Context) int {
pushBigInt(dw.db.GetBalance(common.BytesToAddress(popSlice(ctx))), ctx)
return 1
})
vm.PutPropString(obj, "getBalance")
// Push the wrapper for statedb.GetNonce
vm.PushGoFunction(func(ctx *duktape.Context) int {
ctx.PushInt(int(dw.db.GetNonce(common.BytesToAddress(popSlice(ctx)))))
return 1
})
vm.PutPropString(obj, "getNonce")
// Push the wrapper for statedb.GetCode
vm.PushGoFunction(func(ctx *duktape.Context) int {
code := dw.db.GetCode(common.BytesToAddress(popSlice(ctx)))
ptr := ctx.PushFixedBuffer(len(code))
copy(makeSlice(ptr, uint(len(code))), code)
return 1
})
vm.PutPropString(obj, "getCode")
// Push the wrapper for statedb.GetState
vm.PushGoFunction(func(ctx *duktape.Context) int {
hash := popSlice(ctx)
addr := popSlice(ctx)
state := dw.db.GetState(common.BytesToAddress(addr), common.BytesToHash(hash))
ptr := ctx.PushFixedBuffer(len(state))
copy(makeSlice(ptr, uint(len(state))), state[:])
return 1
})
vm.PutPropString(obj, "getState")
// Push the wrapper for statedb.Exists
vm.PushGoFunction(func(ctx *duktape.Context) int {
ctx.PushBoolean(dw.db.Exist(common.BytesToAddress(popSlice(ctx))))
return 1
})
vm.PutPropString(obj, "exists")
}
// contractWrapper provides a JavaScript wrapper around vm.Contract
type contractWrapper struct {
contract *vm.Contract
}
// pushObject assembles a JSVM object wrapping a swappable contract and pushes it
// onto the VM stack.
func (cw *contractWrapper) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
// Push the wrapper for contract.Caller
vm.PushGoFunction(func(ctx *duktape.Context) int {
ptr := ctx.PushFixedBuffer(20)
copy(makeSlice(ptr, 20), cw.contract.Caller().Bytes())
return 1
})
vm.PutPropString(obj, "getCaller")
// Push the wrapper for contract.Address
vm.PushGoFunction(func(ctx *duktape.Context) int {
ptr := ctx.PushFixedBuffer(20)
copy(makeSlice(ptr, 20), cw.contract.Address().Bytes())
return 1
})
vm.PutPropString(obj, "getAddress")
// Push the wrapper for contract.Value
vm.PushGoFunction(func(ctx *duktape.Context) int {
pushBigInt(cw.contract.Value(), ctx)
return 1
})
vm.PutPropString(obj, "getValue")
// Push the wrapper for contract.Input
vm.PushGoFunction(func(ctx *duktape.Context) int {
blob := cw.contract.Input
ptr := ctx.PushFixedBuffer(len(blob))
copy(makeSlice(ptr, uint(len(blob))), blob)
return 1
})
vm.PutPropString(obj, "getInput")
}
type frame struct {
typ *string
from *common.Address
to *common.Address
input []byte
gas *uint
value *big.Int
}
func newFrame() *frame {
return &frame{
typ: new(string),
from: new(common.Address),
to: new(common.Address),
gas: new(uint),
}
}
func (f *frame) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, *f.typ); return 1 })
vm.PutPropString(obj, "getType")
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, *f.from); return 1 })
vm.PutPropString(obj, "getFrom")
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, *f.to); return 1 })
vm.PutPropString(obj, "getTo")
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, f.input); return 1 })
vm.PutPropString(obj, "getInput")
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, *f.gas); return 1 })
vm.PutPropString(obj, "getGas")
vm.PushGoFunction(func(ctx *duktape.Context) int {
if f.value != nil {
pushValue(ctx, f.value)
} else {
ctx.PushUndefined()
}
return 1
})
vm.PutPropString(obj, "getValue")
}
type frameResult struct {
gasUsed *uint
output []byte
errorValue *string
}
func newFrameResult() *frameResult {
return &frameResult{
gasUsed: new(uint),
}
}
func (r *frameResult) pushObject(vm *duktape.Context) {
obj := vm.PushObject()
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, *r.gasUsed); return 1 })
vm.PutPropString(obj, "getGasUsed")
vm.PushGoFunction(func(ctx *duktape.Context) int { pushValue(ctx, r.output); return 1 })
vm.PutPropString(obj, "getOutput")
vm.PushGoFunction(func(ctx *duktape.Context) int {
if r.errorValue != nil {
pushValue(ctx, *r.errorValue)
} else {
ctx.PushUndefined()
}
return 1
})
vm.PutPropString(obj, "getError")
}
// jsTracer provides an implementation of Tracer that evaluates a Javascript
// function for each VM execution step.
type jsTracer struct {
vm *duktape.Context // Javascript VM instance
env *vm.EVM // EVM instance executing the code being traced
tracerObject int // Stack index of the tracer JavaScript object
stateObject int // Stack index of the global state to pull arguments from
opWrapper *opWrapper // Wrapper around the VM opcode
stackWrapper *stackWrapper // Wrapper around the VM stack
memoryWrapper *memoryWrapper // Wrapper around the VM memory
contractWrapper *contractWrapper // Wrapper around the contract object
dbWrapper *dbWrapper // Wrapper around the VM environment
pcValue *uint // Swappable pc value wrapped by a log accessor
gasValue *uint // Swappable gas value wrapped by a log accessor
costValue *uint // Swappable cost value wrapped by a log accessor
depthValue *uint // Swappable depth value wrapped by a log accessor
errorValue *string // Swappable error value wrapped by a log accessor
refundValue *uint // Swappable refund value wrapped by a log accessor
frame *frame // Represents entry into call frame. Fields are swappable
frameResult *frameResult // Represents exit from a call frame. Fields are swappable
ctx map[string]interface{} // Transaction context gathered throughout execution
err error // Error, if one has occurred
interrupt uint32 // Atomic flag to signal execution interruption
reason error // Textual reason for the interruption
activePrecompiles []common.Address // Updated on CaptureStart based on given rules
traceSteps bool // When true, will invoke step() on each opcode
traceCallFrames bool // When true, will invoke enter() and exit() js funcs
}
// New instantiates a new tracer instance. code specifies a Javascript snippet,
// which must evaluate to an expression returning an object with 'step', 'fault'
// and 'result' functions.
func newJsTracer(code string, ctx *tracers2.Context) (tracers2.Tracer, error) {
if c, ok := assetTracers[code]; ok {
code = c
}
if ctx == nil {
ctx = new(tracers2.Context)
}
tracer := &jsTracer{
vm: duktape.New(),
ctx: make(map[string]interface{}),
opWrapper: new(opWrapper),
stackWrapper: new(stackWrapper),
memoryWrapper: new(memoryWrapper),
contractWrapper: new(contractWrapper),
dbWrapper: new(dbWrapper),
pcValue: new(uint),
gasValue: new(uint),
costValue: new(uint),
depthValue: new(uint),
refundValue: new(uint),
frame: newFrame(),
frameResult: newFrameResult(),
}
if ctx.BlockHash != (common.Hash{}) {
tracer.ctx["blockHash"] = ctx.BlockHash
if ctx.TxHash != (common.Hash{}) {
tracer.ctx["txIndex"] = ctx.TxIndex
tracer.ctx["txHash"] = ctx.TxHash
}
}
// Set up builtins for this environment
tracer.vm.PushGlobalGoFunction("toHex", func(ctx *duktape.Context) int {
ctx.PushString(hexutil.Encode(popSlice(ctx)))
return 1
})
tracer.vm.PushGlobalGoFunction("toWord", func(ctx *duktape.Context) int {
var word common.Hash
if ptr, size := ctx.GetBuffer(-1); ptr != nil {
word = common.BytesToHash(makeSlice(ptr, size))
} else {
word = common.HexToHash(ctx.GetString(-1))
}
ctx.Pop()
copy(makeSlice(ctx.PushFixedBuffer(32), 32), word[:])
return 1
})
tracer.vm.PushGlobalGoFunction("toAddress", func(ctx *duktape.Context) int {
var addr common.Address
if ptr, size := ctx.GetBuffer(-1); ptr != nil {
addr = common.BytesToAddress(makeSlice(ptr, size))
} else {
addr = common.HexToAddress(ctx.GetString(-1))
}
ctx.Pop()
copy(makeSlice(ctx.PushFixedBuffer(20), 20), addr[:])
return 1
})
tracer.vm.PushGlobalGoFunction("toContract", func(ctx *duktape.Context) int {
var from common.Address
if ptr, size := ctx.GetBuffer(-2); ptr != nil {
from = common.BytesToAddress(makeSlice(ptr, size))
} else {
from = common.HexToAddress(ctx.GetString(-2))
}
nonce := uint64(ctx.GetInt(-1))
ctx.Pop2()
contract := crypto.CreateAddress(from, nonce)
copy(makeSlice(ctx.PushFixedBuffer(20), 20), contract[:])
return 1
})
tracer.vm.PushGlobalGoFunction("toContract2", func(ctx *duktape.Context) int {
var from common.Address
if ptr, size := ctx.GetBuffer(-3); ptr != nil {
from = common.BytesToAddress(makeSlice(ptr, size))
} else {
from = common.HexToAddress(ctx.GetString(-3))
}
// Retrieve salt hex string from js stack
salt := common.HexToHash(ctx.GetString(-2))
// Retrieve code slice from js stack
var code []byte
if ptr, size := ctx.GetBuffer(-1); ptr != nil {
code = common.CopyBytes(makeSlice(ptr, size))
} else {
code = common.FromHex(ctx.GetString(-1))
}
codeHash := crypto.Keccak256(code)
ctx.Pop3()
contract := crypto.CreateAddress2(from, salt, codeHash)
copy(makeSlice(ctx.PushFixedBuffer(20), 20), contract[:])
return 1
})
tracer.vm.PushGlobalGoFunction("isPrecompiled", func(ctx *duktape.Context) int {
addr := common.BytesToAddress(popSlice(ctx))
for _, p := range tracer.activePrecompiles {
if p == addr {
ctx.PushBoolean(true)
return 1
}
}
ctx.PushBoolean(false)
return 1
})
tracer.vm.PushGlobalGoFunction("slice", func(ctx *duktape.Context) int {
start, end := ctx.GetInt(-2), ctx.GetInt(-1)
ctx.Pop2()
blob := popSlice(ctx)
size := end - start
if start < 0 || start > end || end > len(blob) {
// TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go
// runtime goes belly up https://github.com/golang/go/issues/15639.
log.Warn("Tracer accessed out of bound memory", "available", len(blob), "offset", start, "size", size)
ctx.PushFixedBuffer(0)
return 1
}
copy(makeSlice(ctx.PushFixedBuffer(size), uint(size)), blob[start:end])
return 1
})
// Push the JavaScript tracer as object #0 onto the JSVM stack and validate it
if err := tracer.vm.PevalString("(" + code + ")"); err != nil {
log.Warn("Failed to compile tracer", "err", err)
return nil, err
}
tracer.tracerObject = 0 // yeah, nice, eval can't return the index itself
hasStep := tracer.vm.GetPropString(tracer.tracerObject, "step")
tracer.vm.Pop()
if !tracer.vm.GetPropString(tracer.tracerObject, "fault") {
return nil, fmt.Errorf("trace object must expose a function fault()")
}
tracer.vm.Pop()
if !tracer.vm.GetPropString(tracer.tracerObject, "result") {
return nil, fmt.Errorf("trace object must expose a function result()")
}
tracer.vm.Pop()
hasEnter := tracer.vm.GetPropString(tracer.tracerObject, "enter")
tracer.vm.Pop()
hasExit := tracer.vm.GetPropString(tracer.tracerObject, "exit")
tracer.vm.Pop()
if hasEnter != hasExit {
return nil, fmt.Errorf("trace object must expose either both or none of enter() and exit()")
}
tracer.traceCallFrames = hasEnter && hasExit
tracer.traceSteps = hasStep
// Tracer is valid, inject the big int library to access large numbers
tracer.vm.EvalString(bigIntegerJS)
tracer.vm.PutGlobalString("bigInt")
// Push the global environment state as object #1 into the JSVM stack
tracer.stateObject = tracer.vm.PushObject()
logObject := tracer.vm.PushObject()
tracer.opWrapper.pushObject(tracer.vm)
tracer.vm.PutPropString(logObject, "op")
tracer.stackWrapper.pushObject(tracer.vm)
tracer.vm.PutPropString(logObject, "stack")
tracer.memoryWrapper.pushObject(tracer.vm)
tracer.vm.PutPropString(logObject, "memory")
tracer.contractWrapper.pushObject(tracer.vm)
tracer.vm.PutPropString(logObject, "contract")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.pcValue); return 1 })
tracer.vm.PutPropString(logObject, "getPC")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.gasValue); return 1 })
tracer.vm.PutPropString(logObject, "getGas")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.costValue); return 1 })
tracer.vm.PutPropString(logObject, "getCost")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.depthValue); return 1 })
tracer.vm.PutPropString(logObject, "getDepth")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.refundValue); return 1 })
tracer.vm.PutPropString(logObject, "getRefund")
tracer.vm.PushGoFunction(func(ctx *duktape.Context) int {
if tracer.errorValue != nil {
ctx.PushString(*tracer.errorValue)
} else {
ctx.PushUndefined()
}
return 1
})
tracer.vm.PutPropString(logObject, "getError")
tracer.vm.PutPropString(tracer.stateObject, "log")
tracer.frame.pushObject(tracer.vm)
tracer.vm.PutPropString(tracer.stateObject, "frame")
tracer.frameResult.pushObject(tracer.vm)
tracer.vm.PutPropString(tracer.stateObject, "frameResult")
tracer.dbWrapper.pushObject(tracer.vm)
tracer.vm.PutPropString(tracer.stateObject, "db")
return tracer, nil
}
// Stop terminates execution of the tracer at the first opportune moment.
func (jst *jsTracer) Stop(err error) {
jst.reason = err
atomic.StoreUint32(&jst.interrupt, 1)
}
// call executes a method on a JS object, catching any errors, formatting and
// returning them as error objects.
func (jst *jsTracer) call(noret bool, method string, args ...string) (json.RawMessage, error) {
// Execute the JavaScript call and return any error
jst.vm.PushString(method)
for _, arg := range args {
jst.vm.GetPropString(jst.stateObject, arg)
}
code := jst.vm.PcallProp(jst.tracerObject, len(args))
defer jst.vm.Pop()
if code != 0 {
err := jst.vm.SafeToString(-1)
return nil, errors.New(err)
}
// No error occurred, extract return value and return
if noret {
return nil, nil
}
// Push a JSON marshaller onto the stack. We can't marshal from the out-
// side because duktape can crash on large nestings and we can't catch
// C++ exceptions ourselves from Go. TODO(karalabe): Yuck, why wrap?!
jst.vm.PushString("(JSON.stringify)")
jst.vm.Eval()
jst.vm.Swap(-1, -2)
if code = jst.vm.Pcall(1); code != 0 {
err := jst.vm.SafeToString(-1)
return nil, errors.New(err)
}
return json.RawMessage(jst.vm.SafeToString(-1)), nil
}
func wrapError(context string, err error) error {
return fmt.Errorf("%v in server-side tracer function '%v'", err, context)
}
// CaptureStart implements the Tracer interface to initialize the tracing operation.
func (jst *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
jst.env = env
jst.ctx["type"] = "CALL"
if create {
jst.ctx["type"] = "CREATE"
}
jst.ctx["from"] = from
jst.ctx["to"] = to
jst.ctx["input"] = input
jst.ctx["gas"] = gas
jst.ctx["gasPrice"] = env.TxContext.GasPrice
jst.ctx["value"] = value
// Initialize the context
jst.ctx["block"] = env.Context.BlockNumber.Uint64()
jst.dbWrapper.db = env.StateDB
// Update list of precompiles based on current block
rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil)
jst.activePrecompiles = vm.ActivePrecompiles(rules)
// Compute intrinsic gas
isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
isIstanbul := env.ChainConfig().IsIstanbul(env.Context.BlockNumber)
intrinsicGas, err := core.IntrinsicGas(input, nil, jst.ctx["type"] == "CREATE", isHomestead, isIstanbul)
if err != nil {
return
}
jst.ctx["intrinsicGas"] = intrinsicGas
}
// CaptureState implements the Tracer interface to trace a single step of VM execution.
func (jst *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
if !jst.traceSteps {
return
}
if jst.err != nil {
return
}
// If tracing was interrupted, set the error and stop
if atomic.LoadUint32(&jst.interrupt) > 0 {
jst.err = jst.reason
jst.env.Cancel()
return
}
jst.opWrapper.op = op
jst.stackWrapper.stack = scope.Stack
jst.memoryWrapper.memory = scope.Memory
jst.contractWrapper.contract = scope.Contract
*jst.pcValue = uint(pc)
*jst.gasValue = uint(gas)
*jst.costValue = uint(cost)
*jst.depthValue = uint(depth)
*jst.refundValue = uint(jst.env.StateDB.GetRefund())
jst.errorValue = nil
if err != nil {
jst.errorValue = new(string)
*jst.errorValue = err.Error()
}
if _, err := jst.call(true, "step", "log", "db"); err != nil {
jst.err = wrapError("step", err)
}
}
// CaptureFault implements the Tracer interface to trace an execution fault
func (jst *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
if jst.err != nil {
return
}
// Apart from the error, everything matches the previous invocation
jst.errorValue = new(string)
*jst.errorValue = err.Error()
if _, err := jst.call(true, "fault", "log", "db"); err != nil {
jst.err = wrapError("fault", err)
}
}
// CaptureEnd is called after the call finishes to finalize the tracing.
func (jst *jsTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {
jst.ctx["output"] = output
jst.ctx["time"] = t.String()
jst.ctx["gasUsed"] = gasUsed
if err != nil {
jst.ctx["error"] = err.Error()
}
}
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
func (jst *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
if !jst.traceCallFrames {
return
}
if jst.err != nil {
return
}
// If tracing was interrupted, set the error and stop
if atomic.LoadUint32(&jst.interrupt) > 0 {
jst.err = jst.reason
return
}
*jst.frame.typ = typ.String()
*jst.frame.from = from
*jst.frame.to = to
jst.frame.input = common.CopyBytes(input)
*jst.frame.gas = uint(gas)
jst.frame.value = nil
if value != nil {
jst.frame.value = new(big.Int).SetBytes(value.Bytes())
}
if _, err := jst.call(true, "enter", "frame"); err != nil {
jst.err = wrapError("enter", err)
}
}
// CaptureExit is called when EVM exits a scope, even if the scope didn't
// execute any code.
func (jst *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
if !jst.traceCallFrames {
return
}
// If tracing was interrupted, set the error and stop
if atomic.LoadUint32(&jst.interrupt) > 0 {
jst.err = jst.reason
return
}
jst.frameResult.output = common.CopyBytes(output)
*jst.frameResult.gasUsed = uint(gasUsed)
jst.frameResult.errorValue = nil
if err != nil {
jst.frameResult.errorValue = new(string)
*jst.frameResult.errorValue = err.Error()
}
if _, err := jst.call(true, "exit", "frameResult"); err != nil {
jst.err = wrapError("exit", err)
}
}
// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
func (jst *jsTracer) GetResult() (json.RawMessage, error) {
// Transform the context into a JavaScript object and inject into the state
obj := jst.vm.PushObject()
for key, val := range jst.ctx {
jst.addToObj(obj, key, val)
}
jst.vm.PutPropString(jst.stateObject, "ctx")
// Finalize the trace and return the results
result, err := jst.call(false, "result", "ctx", "db")
if err != nil {
jst.err = wrapError("result", err)
}
// Clean up the JavaScript environment
jst.vm.DestroyHeap()
jst.vm.Destroy()
return result, jst.err
}
// addToObj pushes a field to a JS object.
func (jst *jsTracer) addToObj(obj int, key string, val interface{}) {
pushValue(jst.vm, val)
jst.vm.PutPropString(obj, key)
}
func pushValue(ctx *duktape.Context, val interface{}) {
switch val := val.(type) {
case uint64:
ctx.PushUint(uint(val))
case string:
ctx.PushString(val)
case []byte:
ptr := ctx.PushFixedBuffer(len(val))
copy(makeSlice(ptr, uint(len(val))), val)
case common.Address:
ptr := ctx.PushFixedBuffer(20)
copy(makeSlice(ptr, 20), val[:])
case *big.Int:
pushBigInt(val, ctx)
case int:
ctx.PushInt(val)
case uint:
ctx.PushUint(val)
case common.Hash:
ptr := ctx.PushFixedBuffer(32)
copy(makeSlice(ptr, 32), val[:])
default:
panic(fmt.Sprintf("unsupported type: %T", val))
}
}

View file

@ -1,79 +0,0 @@
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
/*
Package native is a collection of tracers written in go.
In order to add a native tracer and have it compiled into the binary, a new
file needs to be added to this folder, containing an implementation of the
`eth.tracers.Tracer` interface.
Aside from implementing the tracer, it also needs to register itself, using the
`register` method -- and this needs to be done in the package initialization.
Example:
```golang
func init() {
register("noopTracerNative", newNoopTracer)
}
```
*/
package native
import (
"errors"
"github.com/ethereum/go-ethereum/eth/tracers"
)
// init registers itself this packages as a lookup for tracers.
func init() {
tracers.RegisterLookup(false, lookup)
}
/*
ctors is a map of package-local tracer constructors.
We cannot be certain about the order of init-functions within a package,
The go spec (https://golang.org/ref/spec#Package_initialization) says
> To ensure reproducible initialization behavior, build systems
> are encouraged to present multiple files belonging to the same
> package in lexical file name order to a compiler.
Hence, we cannot make the map in init, but must make it upon first use.
*/
var ctors map[string]func() tracers.Tracer
// register is used by native tracers to register their presence.
func register(name string, ctor func() tracers.Tracer) {
if ctors == nil {
ctors = make(map[string]func() tracers.Tracer)
}
ctors[name] = ctor
}
// lookup returns a tracer, if one can be matched to the given name.
func lookup(name string, ctx *tracers.Context) (tracers.Tracer, error) {
if ctors == nil {
ctors = make(map[string]func() tracers.Tracer)
}
if ctor, ok := ctors[name]; ok {
return ctor(), nil
}
return nil, errors.New("no tracer found")
}

View file

@ -504,6 +504,38 @@ func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
return (*big.Int)(&hex), nil return (*big.Int)(&hex), nil
} }
type feeHistoryResultMarshaling struct {
OldestBlock *hexutil.Big `json:"oldestBlock"`
Reward [][]*hexutil.Big `json:"reward,omitempty"`
BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"`
GasUsedRatio []float64 `json:"gasUsedRatio"`
}
// FeeHistory retrieves the fee market history.
func (ec *Client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*ethereum.FeeHistory, error) {
var res feeHistoryResultMarshaling
if err := ec.c.CallContext(ctx, &res, "eth_feeHistory", hexutil.Uint(blockCount), toBlockNumArg(lastBlock), rewardPercentiles); err != nil {
return nil, err
}
reward := make([][]*big.Int, len(res.Reward))
for i, r := range res.Reward {
reward[i] = make([]*big.Int, len(r))
for j, r := range r {
reward[i][j] = (*big.Int)(r)
}
}
baseFee := make([]*big.Int, len(res.BaseFee))
for i, b := range res.BaseFee {
baseFee[i] = (*big.Int)(b)
}
return &ethereum.FeeHistory{
OldestBlock: (*big.Int)(res.OldestBlock),
Reward: reward,
BaseFee: baseFee,
GasUsedRatio: res.GasUsedRatio,
}, nil
}
// EstimateGas tries to estimate the gas needed to execute a specific transaction based on // EstimateGas tries to estimate the gas needed to execute a specific transaction based on
// the current pending state of the backend blockchain. There is no guarantee that this is // the current pending state of the backend blockchain. There is no guarantee that this is
// the true gas limit requirement as other transactions may be added or removed by miners, // the true gas limit requirement as other transactions may be added or removed by miners,

View file

@ -64,7 +64,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
filterSystem := filters.NewFilterSystem(ethservice.APIBackend, filters.Config{}) filterSystem := filters.NewFilterSystem(ethservice.APIBackend, filters.Config{})
n.RegisterAPIs([]rpc.API{{ n.RegisterAPIs([]rpc.API{{
Namespace: "eth", Namespace: "eth",
Service: filters.NewFilterAPI(filterSystem, false), Service: filters.NewFilterAPI(filterSystem, false, config.BorLogs),
}}) }})
// Import the test chain. // Import the test chain.

View file

@ -385,59 +385,3 @@ func (snap *snapshot) Release() {
snap.db = nil snap.db = nil
} }
// snapshot wraps a batch of key-value entries deep copied from the in-memory
// database for implementing the Snapshot interface.
type snapshot struct {
db map[string][]byte
lock sync.RWMutex
}
// newSnapshot initializes the snapshot with the given database instance.
func newSnapshot(db *Database) *snapshot {
db.lock.RLock()
defer db.lock.RUnlock()
copied := make(map[string][]byte)
for key, val := range db.db {
copied[key] = common.CopyBytes(val)
}
return &snapshot{db: copied}
}
// Has retrieves if a key is present in the snapshot backing by a key-value
// data store.
func (snap *snapshot) Has(key []byte) (bool, error) {
snap.lock.RLock()
defer snap.lock.RUnlock()
if snap.db == nil {
return false, errSnapshotReleased
}
_, ok := snap.db[string(key)]
return ok, nil
}
// Get retrieves the given key if it's present in the snapshot backing by
// key-value data store.
func (snap *snapshot) Get(key []byte) ([]byte, error) {
snap.lock.RLock()
defer snap.lock.RUnlock()
if snap.db == nil {
return nil, errSnapshotReleased
}
if entry, ok := snap.db[string(key)]; ok {
return common.CopyBytes(entry), nil
}
return nil, errMemorydbNotFound
}
// Release releases associated resources. Release should always succeed and can
// be called multiple times without causing error.
func (snap *snapshot) Release() {
snap.lock.Lock()
defer snap.lock.Unlock()
snap.db = nil
}

View file

@ -17,7 +17,6 @@ var mainnetBor = &Chain{
HomesteadBlock: big.NewInt(0), HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil, DAOForkBlock: nil,
DAOForkSupport: true, DAOForkSupport: true,
EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
EIP150Block: big.NewInt(0), EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0), EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0), EIP158Block: big.NewInt(0),

View file

@ -17,7 +17,6 @@ var mumbaiTestnet = &Chain{
HomesteadBlock: big.NewInt(0), HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil, DAOForkBlock: nil,
DAOForkSupport: true, DAOForkSupport: true,
EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
EIP150Block: big.NewInt(0), EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0), EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0), EIP158Block: big.NewInt(0),

View file

@ -897,8 +897,8 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
{ {
n.GPO.Blocks = int(c.Gpo.Blocks) n.GPO.Blocks = int(c.Gpo.Blocks)
n.GPO.Percentile = int(c.Gpo.Percentile) n.GPO.Percentile = int(c.Gpo.Percentile)
n.GPO.MaxHeaderHistory = c.Gpo.MaxHeaderHistory n.GPO.MaxHeaderHistory = uint64(c.Gpo.MaxHeaderHistory)
n.GPO.MaxBlockHistory = c.Gpo.MaxBlockHistory n.GPO.MaxBlockHistory = uint64(c.Gpo.MaxBlockHistory)
n.GPO.MaxPrice = c.Gpo.MaxPrice n.GPO.MaxPrice = c.Gpo.MaxPrice
n.GPO.IgnorePrice = c.Gpo.IgnorePrice n.GPO.IgnorePrice = c.Gpo.IgnorePrice
} }
@ -1022,7 +1022,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
// RequiredBlocks // RequiredBlocks
{ {
n.PeerRequiredBlocks = map[uint64]common.Hash{} n.RequiredBlocks = map[uint64]common.Hash{}
for k, v := range c.RequiredBlocks { for k, v := range c.RequiredBlocks {
number, err := strconv.ParseUint(k, 0, 64) number, err := strconv.ParseUint(k, 0, 64)
if err != nil { if err != nil {
@ -1034,7 +1034,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
return nil, fmt.Errorf("invalid required block hash %s: %v", v, err) return nil, fmt.Errorf("invalid required block hash %s: %v", v, err)
} }
n.PeerRequiredBlocks[number] = hash n.RequiredBlocks[number] = hash
} }
} }

View file

@ -3,6 +3,8 @@ package server
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"io" "io"
"math/big" "math/big"
"net" "net"
@ -165,6 +167,8 @@ func NewServer(config *Config, opts ...serverOption) (*Server, error) {
// flag to set if we're authorizing consensus here // flag to set if we're authorizing consensus here
authorized := false authorized := false
var ethCfg *ethconfig.Config
// check if personal wallet endpoints are disabled or not // check if personal wallet endpoints are disabled or not
// nolint:nestif // nolint:nestif
if !config.Accounts.DisableBorWallet { if !config.Accounts.DisableBorWallet {
@ -172,7 +176,7 @@ func NewServer(config *Config, opts ...serverOption) (*Server, error) {
stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p)) stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p))
// register the ethereum backend // register the ethereum backend
ethCfg, err := config.buildEth(stack, stack.AccountManager()) ethCfg, err = config.buildEth(stack, stack.AccountManager())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -185,7 +189,7 @@ func NewServer(config *Config, opts ...serverOption) (*Server, error) {
srv.backend = backend srv.backend = backend
} else { } else {
// register the ethereum backend (with temporary created account manager) // register the ethereum backend (with temporary created account manager)
ethCfg, err := config.buildEth(stack, accountManager) ethCfg, err = config.buildEth(stack, accountManager)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -244,13 +248,15 @@ func NewServer(config *Config, opts ...serverOption) (*Server, error) {
// set the auth status in backend // set the auth status in backend
srv.backend.SetAuthorized(authorized) srv.backend.SetAuthorized(authorized)
filterSystem := utils.RegisterFilterAPI(stack, srv.backend.APIBackend, ethCfg)
// debug tracing is enabled by default // debug tracing is enabled by default
stack.RegisterAPIs(tracers.APIs(srv.backend.APIBackend)) stack.RegisterAPIs(tracers.APIs(srv.backend.APIBackend))
srv.tracerAPI = tracers.NewAPI(srv.backend.APIBackend) srv.tracerAPI = tracers.NewAPI(srv.backend.APIBackend)
// graphql is started from another place // graphql is started from another place
if config.JsonRPC.Graphql.Enabled { if config.JsonRPC.Graphql.Enabled {
if err := graphql.New(stack, srv.backend.APIBackend, config.JsonRPC.Graphql.Cors, config.JsonRPC.Graphql.VHost); err != nil { if err := graphql.New(stack, srv.backend.APIBackend, filterSystem, config.JsonRPC.Graphql.Cors, config.JsonRPC.Graphql.VHost); err != nil {
return nil, fmt.Errorf("failed to register the GraphQL service: %v", err) return nil, fmt.Errorf("failed to register the GraphQL service: %v", err)
} }
} }
@ -500,7 +506,7 @@ func setupLogger(logLevel string, loggingInfo LoggingConfig) {
} }
func (s *Server) GetLatestBlockNumber() *big.Int { func (s *Server) GetLatestBlockNumber() *big.Int {
return s.backend.BlockChain().CurrentBlock().Number() return s.backend.BlockChain().CurrentBlock().Number
} }
func (s *Server) GetGrpcAddr() string { func (s *Server) GetGrpcAddr() string {

View file

@ -47,13 +47,13 @@ func TestServer_DeveloperMode(t *testing.T) {
defer CloseMockServer(server) defer CloseMockServer(server)
// record the initial block number // record the initial block number
blockNumber := server.backend.BlockChain().CurrentBlock().Header().Number.Int64() blockNumber := server.backend.BlockChain().CurrentBlock().Number.Int64()
var i int64 = 0 var i int64 = 0
for i = 0; i < 3; i++ { for i = 0; i < 3; i++ {
// We expect the node to mine blocks every `config.Developer.Period` time period // We expect the node to mine blocks every `config.Developer.Period` time period
time.Sleep(time.Duration(config.Developer.Period) * time.Second) time.Sleep(time.Duration(config.Developer.Period) * time.Second)
currBlock := server.backend.BlockChain().CurrentBlock().Header().Number.Int64() currBlock := server.backend.BlockChain().CurrentBlock().Number.Int64()
expected := blockNumber + i + 1 expected := blockNumber + i + 1
if res := assert.Equal(t, currBlock, expected); res == false { if res := assert.Equal(t, currBlock, expected); res == false {
break break

View file

@ -197,7 +197,7 @@ func (s *Server) Status(ctx context.Context, in *proto.StatusRequest) (*proto.St
resp := &proto.StatusResponse{ resp := &proto.StatusResponse{
CurrentHeader: headerToProtoHeader(apiBackend.CurrentHeader()), CurrentHeader: headerToProtoHeader(apiBackend.CurrentHeader()),
CurrentBlock: headerToProtoHeader(apiBackend.CurrentBlock().Header()), CurrentBlock: headerToProtoHeader(apiBackend.CurrentBlock()),
NumPeers: int64(len(s.node.Server().PeersInfo())), NumPeers: int64(len(s.node.Server().PeersInfo())),
SyncMode: s.config.SyncMode, SyncMode: s.config.SyncMode,
Syncing: &proto.StatusResponse_Syncing{ Syncing: &proto.StatusResponse_Syncing{

View file

@ -168,7 +168,13 @@ func (c *PruneStateCommand) Run(args []string) int {
return 1 return 1
} }
pruner, err := pruner.NewPruner(chaindb, node.ResolvePath(""), node.ResolvePath(c.cacheTrieJournal), c.bloomfilterSize) prunerconfig := pruner.Config{
Datadir: node.ResolvePath(""),
Cachedir: node.ResolvePath(c.cacheTrieJournal),
BloomSize: c.bloomfilterSize,
}
pruner, err := pruner.NewPruner(chaindb, prunerconfig)
if err != nil { if err != nil {
log.Error("Failed to open snapshot tree", "err", err) log.Error("Failed to open snapshot tree", "err", err)
return 1 return 1

View file

@ -312,7 +312,7 @@ func Setup(ctx *cli.Context) error {
// This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name. // This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name.
// It cannot be imported because it will cause a cyclical dependency. // It cannot be imported because it will cause a cyclical dependency.
StartPProf(address, !ctx.IsSet("metrics.addr")) StartPProf(address, !ctx.IsSet("metrics.addr"))
} else if ctx.GlobalIsSet("bor-mumbai") || ctx.GlobalIsSet("bor-mainnet") { } else if ctx.IsSet("bor-mumbai") || ctx.IsSet("bor-mainnet") {
address := fmt.Sprintf("%s:%d", "0.0.0.0", 7071) address := fmt.Sprintf("%s:%d", "0.0.0.0", 7071)
StartPProf(address, !ctx.IsSet("metrics.addr")) StartPProf(address, !ctx.IsSet("metrics.addr"))
} }

View file

@ -343,3 +343,43 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
} }
func (b *backendMock) Engine() consensus.Engine { return nil } func (b *backendMock) Engine() consensus.Engine { return nil }
func (b *backendMock) RPCRpcReturnDataLimit() uint64 {
return b.RPCRpcReturnDataLimit()
}
func (b *backendMock) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
return b.SubscribeStateSyncEvent(ch)
}
func (b *backendMock) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
return b.GetRootHash(ctx, starBlockNr, endBlockNr)
}
func (b *backendMock) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
return b.GetBorBlockReceipt(ctx, hash)
}
func (b *backendMock) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
return b.GetBorBlockLogs(ctx, hash)
}
func (b *backendMock) GetBorBlockTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
return b.GetBorBlockTransaction(ctx, txHash)
}
func (b *backendMock) GetBorBlockTransactionWithBlockHash(ctx context.Context, txHash common.Hash, blockHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
return b.GetBorBlockTransactionWithBlockHash(ctx, txHash, blockHash)
}
func (b *backendMock) SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription {
return b.SubscribeChain2HeadEvent(ch)
}
func (b *backendMock) GetCheckpointWhitelist() map[uint64]common.Hash {
return b.GetCheckpointWhitelist()
}
func (b *backendMock) PurgeCheckpointWhitelist() {
b.PurgeCheckpointWhitelist()
}

View file

@ -93,7 +93,7 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit), blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
engine: engine, engine: engine,
} }
bc.forker = core.NewForkChoice(bc, nil) bc.forker = core.NewForkChoice(bc, nil, checker)
var err error var err error
bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt) bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt)
if err != nil { if err != nil {
@ -401,24 +401,6 @@ func (lc *LightChain) SetCanonical(header *types.Header) error {
return nil return nil
} }
func (lc *LightChain) InsertHeader(header *types.Header) error {
// Verify the header first before obtaining the lock
headers := []*types.Header{header}
if _, err := lc.hc.ValidateHeaderChain(headers, 100); err != nil {
return err
}
// Make sure only one thread manipulates the chain at once
lc.chainmu.Lock()
defer lc.chainmu.Unlock()
lc.wg.Add(1)
defer lc.wg.Done()
_, err := lc.hc.WriteHeaders(headers)
log.Info("Inserted header", "number", header.Number, "hash", header.Hash())
return err
}
func (lc *LightChain) SetChainHead(header *types.Header) error { func (lc *LightChain) SetChainHead(header *types.Header) error {
lc.chainmu.Lock() lc.chainmu.Lock()
defer lc.chainmu.Unlock() defer lc.chainmu.Unlock()

View file

@ -276,7 +276,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
} }
) )
// Assemble the test environment // Assemble the test environment
blockchain, _ := core.NewBlockChain(sdb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil) blockchain, _ := core.NewBlockChain(sdb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil, nil)
_, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, testChainGen) _, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, testChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -43,7 +43,7 @@ func TestNodeIterator(t *testing.T) {
BaseFee: big.NewInt(params.InitialBaseFee), BaseFee: big.NewInt(params.InitialBaseFee),
} }
) )
blockchain, _ := core.NewBlockChain(fulldb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil) blockchain, _ := core.NewBlockChain(fulldb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil, nil)
_, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, testChainGen) _, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, testChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {
panic(err) panic(err)

View file

@ -90,7 +90,7 @@ func TestTxPool(t *testing.T) {
} }
) )
// Assemble the test environment // Assemble the test environment
blockchain, _ := core.NewBlockChain(sdb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil) blockchain, _ := core.NewBlockChain(sdb, nil, gspec, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil, nil)
_, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), poolTestBlocks, txPoolTestChainGen) _, gchain, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), poolTestBlocks, txPoolTestChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {
panic(err) panic(err)

View file

@ -19,7 +19,6 @@ package miner
import ( import (
"crypto/rand" "crypto/rand"
"errors" "errors"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -50,15 +49,6 @@ import (
"github.com/ethereum/go-ethereum/tests/bor/mocks" "github.com/ethereum/go-ethereum/tests/bor/mocks"
) )
const (
// testCode is the testing contract binary code which will initialises some
// variables in constructor
testCode = "0x60806040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005534801561003457600080fd5b5060fc806100436000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80630c4dae8814603757806398a213cf146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055507fe9e44f9f7da8c559de847a3232b57364adc0354f15a2cd8dc636d54396f9587a6000546040518082815260200191505060405180910390a15056fea265627a7a723058208ae31d9424f2d0bc2a3da1a5dd659db2d71ec322a17db8f87e19e209e3a1ff4a64736f6c634300050a0032"
// testGas is the gas required for contract deployment.
testGas = 144109
)
func init() { func init() {
testTxPoolConfig = txpool.DefaultConfig testTxPoolConfig = txpool.DefaultConfig
testTxPoolConfig.Journal = "" testTxPoolConfig.Journal = ""
@ -92,15 +82,6 @@ func init() {
newTxs = append(newTxs, tx2) newTxs = append(newTxs, tx2)
} }
// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.
type testWorkerBackend struct {
db ethdb.Database
txPool *txpool.TxPool
chain *core.BlockChain
genesis *core.Genesis
uncleBlock *types.Block
}
// newTestWorker creates a new test worker with the given parameters. // newTestWorker creates a new test worker with the given parameters.
func newTestWorker(t TensingObject, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int, noempty bool, delay uint, opcodeDelay uint) (*worker, *testWorkerBackend, func()) { func newTestWorker(t TensingObject, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int, noempty bool, delay uint, opcodeDelay uint) (*worker, *testWorkerBackend, func()) {
backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks) backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks)
@ -124,63 +105,6 @@ func newTestWorker(t TensingObject, chainConfig *params.ChainConfig, engine cons
return w, backend, w.close return w, backend, w.close
} }
func newTestWorkerBackend(t TensingObject, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, n int) *testWorkerBackend {
var gspec = &core.Genesis{
Config: chainConfig,
Alloc: core.GenesisAlloc{TestBankAddress: {Balance: testBankFunds}},
}
switch e := engine.(type) {
case *bor.Bor:
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
copy(gspec.ExtraData[32:32+common.AddressLength], TestBankAddress.Bytes())
e.Authorize(TestBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
return crypto.Sign(crypto.Keccak256(data), testBankKey)
})
case *clique.Clique:
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
copy(gspec.ExtraData[32:32+common.AddressLength], TestBankAddress.Bytes())
e.Authorize(TestBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
return crypto.Sign(crypto.Keccak256(data), testBankKey)
})
case *ethash.Ethash:
default:
t.Fatalf("unexpected consensus engine type: %T", engine)
}
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec, nil, engine, vm.Config{}, nil, nil, nil)
if err != nil {
t.Fatalf("core.NewBlockChain failed: %v", err)
}
txpool := txpool.NewTxPool(testTxPoolConfig, chainConfig, chain)
// Generate a small n-block chain and an uncle block for it
var uncle *types.Block
if n > 0 {
genDb, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, func(i int, gen *core.BlockGen) {
gen.SetCoinbase(TestBankAddress)
})
if _, err := chain.InsertChain(blocks); err != nil {
t.Fatalf("failed to insert origin chain: %v", err)
}
parent := chain.GetBlockByHash(chain.CurrentBlock().ParentHash)
blocks, _ = core.GenerateChain(chainConfig, parent, engine, genDb, 1, func(i int, gen *core.BlockGen) {
gen.SetCoinbase(testUserAddress)
})
uncle = blocks[0]
} else {
_, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, 1, func(i int, gen *core.BlockGen) {
gen.SetCoinbase(testUserAddress)
})
uncle = blocks[0]
}
return &testWorkerBackend{
db: db,
chain: chain,
txPool: txpool,
genesis: gspec,
uncleBlock: uncle,
}
}
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain } func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool } func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool }
func (b *testWorkerBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) { func (b *testWorkerBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) {
@ -196,7 +120,7 @@ func (b *testWorkerBackend) newRandomUncle() (*types.Block, error) {
parent = b.chain.GetBlockByHash(b.chain.CurrentBlock().ParentHash) parent = b.chain.GetBlockByHash(b.chain.CurrentBlock().ParentHash)
} }
var err error var err error
blocks, _ := core.GenerateChain(b.chain.Config(), parent, b.chain.Engine(), b.db, 1, func(i int, gen *core.BlockGen) { blocks, _ := core.GenerateChain(b.chain.Config(), parent, b.chain.Engine(), b.DB, 1, func(i int, gen *core.BlockGen) {
var addr = make([]byte, common.AddressLength) var addr = make([]byte, common.AddressLength)
_, err = rand.Read(addr) _, err = rand.Read(addr)
if err != nil { if err != nil {
@ -302,7 +226,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool, isBor bool) {
defer w.close() defer w.close()
// This test chain imports the mined blocks. // This test chain imports the mined blocks.
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, b.genesis, nil, engine, vm.Config{}, nil, nil, nil) chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, b.Genesis, nil, engine, vm.Config{}, nil, nil, nil)
defer chain.Stop() defer chain.Stop()
// Ignore empty commit here for less noise. // Ignore empty commit here for less noise.
@ -962,7 +886,7 @@ func BenchmarkBorMining(b *testing.B) {
w, back, _ := newTestWorker(b, chainConfig, engine, db, 0, false, 0, 0) w, back, _ := newTestWorker(b, chainConfig, engine, db, 0, false, 0, 0)
defer w.close() defer w.close()
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, back.genesis, nil, engine, vm.Config{}, nil, nil, nil) chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, back.Genesis, nil, engine, vm.Config{}, nil, nil, nil)
defer chain.Stop() defer chain.Stop()
// Ignore empty commit here for less noise. // Ignore empty commit here for less noise.
@ -978,7 +902,7 @@ func BenchmarkBorMining(b *testing.B) {
var err error var err error
txInBlock := int(back.genesis.GasLimit/totalGas) + 1 txInBlock := int(back.Genesis.GasLimit/totalGas) + 1
// a bit risky // a bit risky
for i := 0; i < 2*totalBlocks*txInBlock; i++ { for i := 0; i < 2*totalBlocks*txInBlock; i++ {
@ -1004,7 +928,7 @@ func BenchmarkBorMining(b *testing.B) {
// Start mining! // Start mining!
w.start() w.start()
blockPeriod, ok := back.genesis.Config.Bor.Period["0"] blockPeriod, ok := back.Genesis.Config.Bor.Period["0"]
if !ok { if !ok {
blockPeriod = 1 blockPeriod = 1
} }

View file

@ -19,10 +19,12 @@ package node
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/p2p/enode"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"sync"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -193,6 +195,8 @@ type Config struct {
// Logger is a custom logger to use with the p2p.Server. // Logger is a custom logger to use with the p2p.Server.
Logger log.Logger `toml:",omitempty"` Logger log.Logger `toml:",omitempty"`
staticNodesWarning bool
trustedNodesWarning bool
oldGethResourceWarning bool oldGethResourceWarning bool
// AllowUnprotectedTxs allows non EIP-155 protected transactions to be send over RPC. // AllowUnprotectedTxs allows non EIP-155 protected transactions to be send over RPC.
@ -360,6 +364,50 @@ func (c *Config) ResolvePath(path string) string {
return filepath.Join(c.instanceDir(), path) return filepath.Join(c.instanceDir(), path)
} }
// StaticNodes returns a list of node enode URLs configured as static nodes.
func (c *Config) StaticNodes() []*enode.Node {
return c.parsePersistentNodes(&c.staticNodesWarning, c.ResolvePath(datadirStaticNodes))
}
// TrustedNodes returns a list of node enode URLs configured as trusted nodes.
func (c *Config) TrustedNodes() []*enode.Node {
return c.parsePersistentNodes(&c.trustedNodesWarning, c.ResolvePath(datadirTrustedNodes))
}
// parsePersistentNodes parses a list of discovery node URLs loaded from a .json
// file from within the data directory.
func (c *Config) parsePersistentNodes(w *bool, path string) []*enode.Node {
// Short circuit if no node config is present
if c.DataDir == "" {
return nil
}
if _, err := os.Stat(path); err != nil {
return nil
}
c.warnOnce(w, "Found deprecated node list file %s, please use the TOML config file instead.", path)
// Load the nodes from the config file.
var nodelist []string
if err := common.LoadJSON(path, &nodelist); err != nil {
log.Error(fmt.Sprintf("Can't load node list file: %v", err))
return nil
}
// Interpret the list as a discovery node array
var nodes []*enode.Node
for _, url := range nodelist {
if url == "" {
continue
}
node, err := enode.Parse(enode.ValidSchemes, url)
if err != nil {
log.Error(fmt.Sprintf("Node URL %s: %v\n", url, err))
continue
}
nodes = append(nodes, node)
}
return nodes
}
func (c *Config) instanceDir() string { func (c *Config) instanceDir() string {
if c.DataDir == "" { if c.DataDir == "" {
return "" return ""
@ -480,3 +528,20 @@ func getKeyStoreDir(conf *Config) (string, bool, error) {
return keydir, isEphemeral, nil return keydir, isEphemeral, nil
} }
var warnLock sync.Mutex
func (c *Config) warnOnce(w *bool, format string, args ...interface{}) {
warnLock.Lock()
defer warnLock.Unlock()
if *w {
return
}
l := c.Logger
if l == nil {
l = log.Root()
}
l.Warn(fmt.Sprintf(format, args...))
*w = true
}

View file

@ -308,7 +308,7 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error {
// Create RPC server and handler. // Create RPC server and handler.
srv := rpc.NewServer(config.executionPoolSize, config.executionPoolRequestTimeout) srv := rpc.NewServer(config.executionPoolSize, config.executionPoolRequestTimeout)
srv.SetRPCBatchLimit(h.RPCBatchLimit) srv.SetRPCBatchLimit(h.RPCBatchLimit)
if err := RegisterApis(apis, config.Modules, srv, false); err != nil { if err := RegisterApis(apis, config.Modules, srv); err != nil {
return err return err
} }
h.httpConfig = config h.httpConfig = config

View file

@ -241,7 +241,7 @@ func createAndStartServer(t *testing.T, conf *httpConfig, ws bool, wsConf *wsCon
if timeouts == nil { if timeouts == nil {
timeouts = &rpc.DefaultHTTPTimeouts timeouts = &rpc.DefaultHTTPTimeouts
} }
srv := newHTTPServer(testlog.Logger(t, log.LvlDebug), *timeouts) srv := newHTTPServer(testlog.Logger(t, log.LvlDebug), *timeouts, 100)
assert.NoError(t, srv.enableRPC(apis(), *conf)) assert.NoError(t, srv.enableRPC(apis(), *conf))
if ws { if ws {
assert.NoError(t, srv.enableWS(nil, *wsConf)) assert.NoError(t, srv.enableWS(nil, *wsConf))

View file

@ -63,6 +63,7 @@ func main() {
fatal(err) fatal(err)
} }
} }
}
func fatal(args ...interface{}) { func fatal(args ...interface{}) {
fmt.Fprintln(os.Stderr, args...) fmt.Fprintln(os.Stderr, args...)

View file

@ -167,7 +167,6 @@ func newClientTransportHTTP(endpoint string, cfg *clientConfig) reconnectFunc {
return hc, nil return hc, nil
} }
} }
}
func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error { func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error {
hc := c.writeConn.(*httpConn) hc := c.writeConn.(*httpConn)

View file

@ -214,11 +214,6 @@ func (c *jsonCodec) peerInfo() PeerInfo {
return PeerInfo{Transport: "ipc", RemoteAddr: c.remote} return PeerInfo{Transport: "ipc", RemoteAddr: c.remote}
} }
func (c *jsonCodec) peerInfo() PeerInfo {
// This returns "ipc" because all other built-in transports have a separate codec type.
return PeerInfo{Transport: "ipc", RemoteAddr: c.remote}
}
func (c *jsonCodec) remoteAddr() string { func (c *jsonCodec) remoteAddr() string {
return c.remote return c.remote
} }

View file

@ -27,8 +27,6 @@ import (
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"unicode"
"unicode/utf8"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"

View file

@ -5,6 +5,7 @@ import (
"encoding/csv" "encoding/csv"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/core/txpool"
"io/ioutil" // nolint: staticcheck "io/ioutil" // nolint: staticcheck
_log "log" _log "log"
"math/big" "math/big"
@ -16,7 +17,6 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -778,7 +778,6 @@ func InitGenesisSprintLength(t *testing.T, faucets []*ecdsa.PrivateKey, fileLoca
} }
genesis.Config.ChainID = big.NewInt(15001) genesis.Config.ChainID = big.NewInt(15001)
genesis.Config.EIP150Hash = common.Hash{}
genesis.Config.Bor.Sprint["0"] = sprintSize genesis.Config.Bor.Sprint["0"] = sprintSize
return genesis return genesis
@ -811,7 +810,7 @@ func InitMinerSprintLength(genesis *core.Genesis, privKey *ecdsa.PrivateKey, wit
SyncMode: downloader.FullSync, SyncMode: downloader.FullSync,
DatabaseCache: 256, DatabaseCache: 256,
DatabaseHandles: 256, DatabaseHandles: 256,
TxPool: core.DefaultTxPoolConfig, TxPool: txpool.DefaultConfig,
GPO: ethconfig.Defaults.GPO, GPO: ethconfig.Defaults.GPO,
Ethash: ethconfig.Defaults.Ethash, Ethash: ethconfig.Defaults.Ethash,
Miner: miner.Config{ Miner: miner.Config{

View file

@ -231,7 +231,6 @@ var Forks = map[string]*params.ChainConfig{
LondonBlock: big.NewInt(0), LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0),
Bor: params.BorUnittestChainConfig.Bor, Bor: params.BorUnittestChainConfig.Bor,
ArrowGlacierBlock: big.NewInt(0),
}, },
"ArrowGlacierToMergeAtDiffC0000": { "ArrowGlacierToMergeAtDiffC0000": {
ChainID: big.NewInt(1), ChainID: big.NewInt(1),

View file

@ -557,15 +557,6 @@ func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) {
return mustDecodeNode(n, blob), nil return mustDecodeNode(n, blob), nil
} }
func (t *Trie) resolveBlob(n hashNode, prefix []byte) ([]byte, error) {
hash := common.BytesToHash(n)
blob, _ := t.db.Node(hash)
if len(blob) != 0 {
return blob, nil
}
return nil, &MissingNodeError{NodeHash: hash, Path: prefix}
}
// Hash returns the root hash of the trie. It does not write to the // Hash returns the root hash of the trie. It does not write to the
// database and can be used even if the trie doesn't have one. // database and can be used even if the trie doesn't have one.
func (t *Trie) Hash() common.Hash { func (t *Trie) Hash() common.Hash {