mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-08 04:53:47 +00:00
Reduce amount of changes to Geth Live Tracer to keep Firehose backward compatibility
We removed the `precompile` check on `OnNewAccount` and moved it to the Firehose tracer directly. This way, we can remove our custom logic that toggle the check at the tracing code level and we can instead move the logic of backward compatibility back `FirehoseTracer`. Refactored a bit also how precompiles are check. We moved the precompiles checker up to the block level now that `chainConfig` is available on `OnBlockStart` meaning we can extract the list of active precompiles. However, to make it work, we had to modify `OnGenesisBlock` to also receive `chainConfig` parameter, I've ask to add it to the geth codebase directly.
This commit is contained in:
parent
8767058368
commit
a46903cf0c
19 changed files with 95 additions and 88 deletions
|
|
@ -318,15 +318,15 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
reward.Sub(reward, new(big.Int).SetUint64(ommer.Delta))
|
||||
reward.Mul(reward, blockReward)
|
||||
reward.Div(reward, big.NewInt(8))
|
||||
statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward), false, state.BalanceIncreaseRewardMineUncle)
|
||||
statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward), state.BalanceIncreaseRewardMineUncle)
|
||||
}
|
||||
statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward), false, state.BalanceIncreaseRewardMineBlock)
|
||||
statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward), state.BalanceIncreaseRewardMineBlock)
|
||||
}
|
||||
// Apply withdrawals
|
||||
for _, w := range pre.Env.Withdrawals {
|
||||
// Amount is in gwei, turn into wei
|
||||
amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei))
|
||||
statedb.AddBalance(w.Address, uint256.MustFromBig(amount), false, state.BalanceIncreaseWithdrawal)
|
||||
statedb.AddBalance(w.Address, uint256.MustFromBig(amount), state.BalanceIncreaseWithdrawal)
|
||||
}
|
||||
// Commit block
|
||||
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
|
|||
// Convert amount from gwei to wei.
|
||||
amount := new(uint256.Int).SetUint64(w.Amount)
|
||||
amount = amount.Mul(amount, uint256.NewInt(params.GWei))
|
||||
stateDB.AddBalance(w.Address, amount, false, state.BalanceIncreaseWithdrawal)
|
||||
stateDB.AddBalance(w.Address, amount, state.BalanceIncreaseWithdrawal)
|
||||
}
|
||||
// No block reward which is issued by consensus layer instead.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,10 +589,10 @@ func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, heade
|
|||
r.Sub(r, hNum)
|
||||
r.Mul(r, blockReward)
|
||||
r.Div(r, u256_8)
|
||||
stateDB.AddBalance(uncle.Coinbase, r, false, state.BalanceIncreaseRewardMineUncle)
|
||||
stateDB.AddBalance(uncle.Coinbase, r, state.BalanceIncreaseRewardMineUncle)
|
||||
|
||||
r.Div(blockReward, u256_32)
|
||||
reward.Add(reward, r)
|
||||
}
|
||||
stateDB.AddBalance(header.Coinbase, reward, false, state.BalanceIncreaseRewardMineBlock)
|
||||
stateDB.AddBalance(header.Coinbase, reward, state.BalanceIncreaseRewardMineBlock)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ func ApplyDAOHardFork(statedb *state.StateDB) {
|
|||
|
||||
// Move every DAO account and extra-balance account funds into the refund contract
|
||||
for _, addr := range params.DAODrainList() {
|
||||
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), false, state.BalanceIncreaseDaoContract)
|
||||
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), state.BalanceIncreaseDaoContract)
|
||||
statedb.SetBalance(addr, new(uint256.Int), state.BalanceDecreaseDaoAccount)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ type BlockchainLogger interface {
|
|||
// `td` is the total difficulty prior to `block`.
|
||||
OnBlockStart(block *types.Block, td *big.Int, finalized *types.Header, safe *types.Header, chainConfig *params.ChainConfig)
|
||||
OnBlockEnd(err error)
|
||||
OnGenesisBlock(genesis *types.Block, alloc GenesisAlloc)
|
||||
OnGenesisBlock(genesis *types.Block, alloc GenesisAlloc, chainConfig *params.ChainConfig)
|
||||
OnBeaconBlockRootStart(root common.Hash)
|
||||
OnBeaconBlockRootEnd()
|
||||
}
|
||||
|
|
@ -462,7 +462,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
|||
return nil, fmt.Errorf("live blockchain tracer requires genesis alloc to be set")
|
||||
}
|
||||
|
||||
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc)
|
||||
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc, bc.chainConfig)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,5 +138,5 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *uint256.Int) bool {
|
|||
// Transfer subtracts amount from sender and adds amount to recipient using the given Db
|
||||
func Transfer(db vm.StateDB, sender, recipient common.Address, amount *uint256.Int) {
|
||||
db.SubBalance(sender, amount, state.BalanceChangeTransfer)
|
||||
db.AddBalance(recipient, amount, false, state.BalanceChangeTransfer)
|
||||
db.AddBalance(recipient, amount, state.BalanceChangeTransfer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
|
|||
}
|
||||
for addr, account := range *ga {
|
||||
if account.Balance != nil {
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), false, state.BalanceIncreaseGenesisBalance)
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), state.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
|
|
@ -166,7 +166,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
|
|||
if account.Balance != nil {
|
||||
// This is not actually logged via tracer because OnGenesisBlock
|
||||
// already captures the allocations.
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), false, state.BalanceIncreaseGenesisBalance)
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), state.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
|
|
|
|||
|
|
@ -405,8 +405,8 @@ func (s *StateDB) HasSelfDestructed(addr common.Address) bool {
|
|||
*/
|
||||
|
||||
// AddBalance adds amount to the account associated with addr.
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, checkPrecompile bool, reason BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObjectWithCheckPrecompiles(addr, checkPrecompile)
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, reason BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount, reason)
|
||||
}
|
||||
|
|
@ -655,32 +655,20 @@ func (s *StateDB) setStateObject(object *stateObject) {
|
|||
|
||||
// getOrNewStateObject retrieves a state object or create a new state object if nil.
|
||||
func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject {
|
||||
return s.getOrNewStateObjectWithCheckPrecompiles(addr, false)
|
||||
}
|
||||
|
||||
func (s *StateDB) getOrNewStateObjectWithCheckPrecompiles(addr common.Address, checkPrecompile bool) *stateObject {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
stateObject, _ = s.createObject(addr, checkPrecompile)
|
||||
stateObject, _ = s.createObject(addr)
|
||||
}
|
||||
return stateObject
|
||||
}
|
||||
|
||||
// createObject creates a new state object. If there is an existing account with
|
||||
// the given address, it is overwritten and returned as the second return value.
|
||||
func (s *StateDB) createObject(addr common.Address, checkPrecompile bool) (newobj, prev *stateObject) {
|
||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
newobj = newObject(s, addr, nil)
|
||||
if s.logger != nil {
|
||||
if checkPrecompile {
|
||||
// Precompiled contracts are touched during a call.
|
||||
// Make sure we avoid emitting a new account event for them.
|
||||
if _, ok := s.precompiles[addr]; !ok {
|
||||
s.logger.OnNewAccount(addr, prev != nil)
|
||||
}
|
||||
} else {
|
||||
s.logger.OnNewAccount(addr, prev != nil)
|
||||
}
|
||||
s.logger.OnNewAccount(addr, prev != nil)
|
||||
}
|
||||
if prev == nil {
|
||||
s.journal.append(createObjectChange{account: &addr})
|
||||
|
|
@ -731,7 +719,7 @@ func (s *StateDB) createObject(addr common.Address, checkPrecompile bool) (newob
|
|||
//
|
||||
// Carrying over the balance ensures that Ether doesn't disappear.
|
||||
func (s *StateDB) CreateAccount(addr common.Address) {
|
||||
newObj, prev := s.createObject(addr, false)
|
||||
newObj, prev := s.createObject(addr)
|
||||
if prev != nil {
|
||||
newObj.setBalance(prev.data.Balance)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func TestUpdateLeaks(t *testing.T) {
|
|||
// Update it with some accounts
|
||||
for i := byte(0); i < 255; i++ {
|
||||
addr := common.BytesToAddress([]byte{i})
|
||||
state.AddBalance(addr, uint256.NewInt(uint64(11*i)), false, BalanceChangeUnspecified)
|
||||
state.AddBalance(addr, uint256.NewInt(uint64(11*i)), BalanceChangeUnspecified)
|
||||
state.SetNonce(addr, uint64(42*i))
|
||||
if i%2 == 0 {
|
||||
state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
|
||||
|
|
@ -272,7 +272,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
|
|||
{
|
||||
name: "AddBalance",
|
||||
fn: func(a testAction, s *StateDB) {
|
||||
s.AddBalance(addr, uint256.NewInt(uint64(a.args[0])), false, BalanceChangeUnspecified)
|
||||
s.AddBalance(addr, uint256.NewInt(uint64(a.args[0])), BalanceChangeUnspecified)
|
||||
},
|
||||
args: make([]int64, 1),
|
||||
},
|
||||
|
|
@ -535,7 +535,7 @@ func TestTouchDelete(t *testing.T) {
|
|||
s.state, _ = New(root, s.state.db, s.state.snaps)
|
||||
|
||||
snapshot := s.state.Snapshot()
|
||||
s.state.AddBalance(common.Address{}, new(uint256.Int), false, BalanceChangeUnspecified)
|
||||
s.state.AddBalance(common.Address{}, new(uint256.Int), BalanceChangeUnspecified)
|
||||
|
||||
if len(s.state.journal.dirties) != 1 {
|
||||
t.Fatal("expected one dirty state object")
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
} else {
|
||||
fee := new(uint256.Int).SetUint64(st.gasUsed())
|
||||
fee.Mul(fee, effectiveTipU256)
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, fee, false, state.BalanceIncreaseRewardTransactionFee)
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, fee, state.BalanceIncreaseRewardTransactionFee)
|
||||
}
|
||||
|
||||
return &ExecutionResult{
|
||||
|
|
@ -488,7 +488,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) uint64 {
|
|||
// Return ETH for remaining gas, exchanged at the original rate.
|
||||
remaining := uint256.NewInt(st.gasRemaining)
|
||||
remaining = remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice))
|
||||
st.state.AddBalance(st.msg.From, remaining, false, state.BalanceIncreaseGasReturn)
|
||||
st.state.AddBalance(st.msg.From, remaining, state.BalanceIncreaseGasReturn)
|
||||
|
||||
if st.evm.Config.Tracer != nil && st.gasRemaining > 0 {
|
||||
st.evm.Config.Tracer.OnGasChange(st.gasRemaining, 0, vm.GasChangeTxLeftOverReturned)
|
||||
|
|
|
|||
|
|
@ -500,17 +500,17 @@ func TestOpenDrops(t *testing.T) {
|
|||
|
||||
// Create a blob pool out of the pre-seeded data
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.SetNonce(crypto.PubkeyToAddress(filler.PublicKey), 3)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000), state.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -625,7 +625,7 @@ func TestOpenIndex(t *testing.T) {
|
|||
|
||||
// Create a blob pool out of the pre-seeded data
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -725,9 +725,9 @@ func TestOpenHeap(t *testing.T) {
|
|||
|
||||
// Create a blob pool out of the pre-seeded data
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -805,9 +805,9 @@ func TestOpenCap(t *testing.T) {
|
|||
for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
|
||||
// Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), state.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -1198,7 +1198,7 @@ func TestAdd(t *testing.T) {
|
|||
addrs[acc] = crypto.PubkeyToAddress(keys[acc].PublicKey)
|
||||
|
||||
// Seed the state database with this acocunt
|
||||
statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance), state.BalanceChangeUnspecified)
|
||||
statedb.SetNonce(addrs[acc], seed.nonce)
|
||||
|
||||
// Sign the seed transactions and store them in the data store
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func fillPool(t testing.TB, pool *LegacyPool) {
|
|||
nonExecutableTxs := types.Transactions{}
|
||||
for i := 0; i < 384; i++ {
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(10000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(10000000000), state.BalanceChangeUnspecified)
|
||||
// Add executable ones
|
||||
for j := 0; j < int(pool.config.AccountSlots); j++ {
|
||||
executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key))
|
||||
|
|
@ -92,7 +92,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
|||
// Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), state.BalanceChangeUnspecified)
|
||||
futureTxs := types.Transactions{}
|
||||
for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ {
|
||||
futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 100000, big.NewInt(500), key))
|
||||
|
|
@ -129,7 +129,7 @@ func TestTransactionFuture1559(t *testing.T) {
|
|||
// Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), state.BalanceChangeUnspecified)
|
||||
futureTxs := types.Transactions{}
|
||||
for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ {
|
||||
futureTxs = append(futureTxs, dynamicFeeTx(1000+uint64(j), 100000, big.NewInt(200), big.NewInt(101), key))
|
||||
|
|
@ -183,7 +183,7 @@ func TestTransactionZAttack(t *testing.T) {
|
|||
for j := 0; j < int(pool.config.GlobalQueue); j++ {
|
||||
futureTxs := types.Transactions{}
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), state.BalanceChangeUnspecified)
|
||||
futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 21000, big.NewInt(500), key))
|
||||
pool.addRemotesSync(futureTxs)
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ func TestTransactionZAttack(t *testing.T) {
|
|||
overDraftTxs := types.Transactions{}
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), state.BalanceChangeUnspecified)
|
||||
for j := 0; j < int(pool.config.GlobalSlots); j++ {
|
||||
overDraftTxs = append(overDraftTxs, pricedValuedTransaction(uint64(j), 600000000000, 21000, big.NewInt(500), key))
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ func BenchmarkFutureAttack(b *testing.B) {
|
|||
fillPool(b, pool)
|
||||
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), state.BalanceChangeUnspecified)
|
||||
futureTxs := types.Transactions{}
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ func TestStateChangeDuringReset(t *testing.T) {
|
|||
|
||||
func testAddBalance(pool *LegacyPool, addr common.Address, amount *big.Int) {
|
||||
pool.mu.Lock()
|
||||
pool.currentState.AddBalance(addr, uint256.MustFromBig(amount), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(addr, uint256.MustFromBig(amount), state.BalanceChangeUnspecified)
|
||||
pool.mu.Unlock()
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +471,7 @@ func TestChainFork(t *testing.T) {
|
|||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
resetState := func() {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), state.BalanceChangeUnspecified)
|
||||
|
||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||
<-pool.requestReset(nil, nil)
|
||||
|
|
@ -500,7 +500,7 @@ func TestDoubleNonce(t *testing.T) {
|
|||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
resetState := func() {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), state.BalanceChangeUnspecified)
|
||||
|
||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||
<-pool.requestReset(nil, nil)
|
||||
|
|
@ -2663,7 +2663,7 @@ func BenchmarkMultiAccountBatchInsert(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
key, _ := crypto.GenerateKey()
|
||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||
pool.currentState.AddBalance(account, uint256.NewInt(1000000), false, state.BalanceChangeUnspecified)
|
||||
pool.currentState.AddBalance(account, uint256.NewInt(1000000), state.BalanceChangeUnspecified)
|
||||
tx := transaction(uint64(0), 100000, key)
|
||||
batches[i] = tx
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
|||
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
|
||||
// but is the correct thing to do and matters on other networks, in tests, and potential
|
||||
// future scenarios
|
||||
evm.StateDB.AddBalance(addr, new(uint256.Int), true, state.BalanceChangeTouchAccount)
|
||||
evm.StateDB.AddBalance(addr, new(uint256.Int), state.BalanceChangeTouchAccount)
|
||||
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
|
|
|
|||
|
|
@ -835,7 +835,7 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
|
|||
}
|
||||
beneficiary := scope.Stack.pop()
|
||||
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, false, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address())
|
||||
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig())
|
||||
|
|
@ -851,7 +851,7 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
|
|||
beneficiary := scope.Stack.pop()
|
||||
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
||||
interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance, state.BalanceDecreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, false, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address())
|
||||
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig())
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ type StateDB interface {
|
|||
CreateAccount(common.Address)
|
||||
|
||||
SubBalance(common.Address, *uint256.Int, state.BalanceChangeReason)
|
||||
AddBalance(common.Address, *uint256.Int, bool, state.BalanceChangeReason)
|
||||
AddBalance(common.Address, *uint256.Int, state.BalanceChangeReason)
|
||||
GetBalance(common.Address) *uint256.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
|
|
|
|||
|
|
@ -64,13 +64,14 @@ type Firehose struct {
|
|||
blockBaseFee *big.Int
|
||||
blockOrdinal *Ordinal
|
||||
blockFinality *FinalityStatus
|
||||
blockRules params.Rules
|
||||
|
||||
// Transaction state
|
||||
evm *vm.EVM
|
||||
transaction *pbeth.TransactionTrace
|
||||
transactionLogIndex uint32
|
||||
inSystemCall bool
|
||||
isPrecompiledAddr func(addr common.Address) bool
|
||||
evm *vm.EVM
|
||||
transaction *pbeth.TransactionTrace
|
||||
transactionLogIndex uint32
|
||||
inSystemCall bool
|
||||
blockIsPrecompiledAddr func(addr common.Address) bool
|
||||
|
||||
// Call state
|
||||
callStack *CallStack
|
||||
|
|
@ -106,6 +107,8 @@ func (f *Firehose) resetBlock() {
|
|||
f.blockBaseFee = nil
|
||||
f.blockOrdinal.Reset()
|
||||
f.blockFinality.Reset()
|
||||
f.blockIsPrecompiledAddr = nil
|
||||
f.blockRules = params.Rules{}
|
||||
}
|
||||
|
||||
// resetTransaction resets the transaction state and the call state in one shot
|
||||
|
|
@ -114,7 +117,6 @@ func (f *Firehose) resetTransaction() {
|
|||
f.evm = nil
|
||||
f.transactionLogIndex = 0
|
||||
f.inSystemCall = false
|
||||
f.isPrecompiledAddr = nil
|
||||
|
||||
f.callStack.Reset()
|
||||
f.latestCallStartSuicided = false
|
||||
|
|
@ -124,7 +126,8 @@ func (f *Firehose) resetTransaction() {
|
|||
func (f *Firehose) OnBlockStart(b *types.Block, td *big.Int, finalized *types.Header, safe *types.Header, chainConfig *params.ChainConfig) {
|
||||
firehoseDebug("block start number=%d hash=%s", b.NumberU64(), b.Hash())
|
||||
|
||||
f.ensureNotInBlock()
|
||||
f.blockRules = chainConfig.Rules(b.Number(), chainConfig.TerminalTotalDifficultyPassed, b.Time())
|
||||
f.blockIsPrecompiledAddr = getActivePrecompilesChecker(f.blockRules)
|
||||
|
||||
f.block = &pbeth.Block{
|
||||
Hash: b.Hash().Bytes(),
|
||||
|
|
@ -147,6 +150,20 @@ func (f *Firehose) OnBlockStart(b *types.Block, td *big.Int, finalized *types.He
|
|||
f.blockFinality.populateFromChain(finalized)
|
||||
}
|
||||
|
||||
func getActivePrecompilesChecker(rules params.Rules) func(addr common.Address) bool {
|
||||
activePrecompiles := vm.ActivePrecompiles(rules)
|
||||
|
||||
activePrecompilesMap := make(map[common.Address]bool, len(activePrecompiles))
|
||||
for _, addr := range activePrecompiles {
|
||||
activePrecompilesMap[addr] = true
|
||||
}
|
||||
|
||||
return func(addr common.Address) bool {
|
||||
_, found := activePrecompilesMap[addr]
|
||||
return found
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Firehose) OnBlockEnd(err error) {
|
||||
firehoseDebug("block ending err=%s", errorView(err))
|
||||
|
||||
|
|
@ -194,17 +211,13 @@ func (f *Firehose) CaptureTxStart(evm *vm.EVM, tx *types.Transaction, from commo
|
|||
to = *tx.To()
|
||||
}
|
||||
|
||||
isBeforeHomestead := !evm.ChainConfig().IsHomestead(big.NewInt(int64(f.block.Number)))
|
||||
|
||||
f.captureTxStart(tx, tx.Hash(), from, to, evm.IsPrecompileAddr, isBeforeHomestead)
|
||||
f.captureTxStart(tx, tx.Hash(), from, to)
|
||||
}
|
||||
|
||||
// captureTxStart is used internally a two places, in the normal "tracer" and in the "OnGenesisBlock",
|
||||
// we manually pass some override to the `tx` because genesis block has a different way of creating
|
||||
// the transaction that wraps the genesis block.
|
||||
func (f *Firehose) captureTxStart(tx *types.Transaction, hash common.Hash, from, to common.Address, isPrecompiledAddr func(common.Address) bool, isBeforeHomestead bool) {
|
||||
f.isPrecompiledAddr = isPrecompiledAddr
|
||||
|
||||
func (f *Firehose) captureTxStart(tx *types.Transaction, hash common.Hash, from, to common.Address) {
|
||||
v, r, s := tx.RawSignatureValues()
|
||||
|
||||
var blobGas *uint64
|
||||
|
|
@ -492,8 +505,7 @@ func (f *Firehose) callStart(source string, callType pbeth.CallType, from common
|
|||
GasLimit: gas,
|
||||
}
|
||||
|
||||
precompile := f.isPrecompiledAddr(common.BytesToAddress(call.Address))
|
||||
call.ExecutedCode = getExecutedCode(f.evm, precompile, call)
|
||||
call.ExecutedCode = f.getExecutedCode(f.evm, call)
|
||||
|
||||
// Known Firehose issue: The BeginOrdinal of the genesis block root call is never actually
|
||||
// incremented and it's always 0.
|
||||
|
|
@ -521,10 +533,12 @@ func (f *Firehose) callStart(source string, callType pbeth.CallType, from common
|
|||
f.callStack.Push(call)
|
||||
}
|
||||
|
||||
func getExecutedCode(evm *vm.EVM, precompile bool, call *pbeth.Call) bool {
|
||||
func (f *Firehose) getExecutedCode(evm *vm.EVM, call *pbeth.Call) bool {
|
||||
precompile := f.blockIsPrecompiledAddr(common.BytesToAddress(call.Address))
|
||||
|
||||
if evm != nil && call.CallType == pbeth.CallType_CALL {
|
||||
if !evm.StateDB.Exist(common.BytesToAddress(call.Address)) &&
|
||||
!precompile && evm.ChainConfig().Rules(evm.Context.BlockNumber, evm.Context.Random != nil, evm.Context.Time).IsEIP158 &&
|
||||
!precompile && f.blockRules.IsEIP158 &&
|
||||
(call.Value == nil || call.Value.Native().Sign() == 0) {
|
||||
firehoseDebug("executed code IsSpuriousDragon callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
|
||||
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
|
||||
|
|
@ -660,9 +674,9 @@ func (f *Firehose) CaptureKeccakPreimage(hash common.Hash, data []byte) {
|
|||
activeCall.KeccakPreimages[hex.EncodeToString(hash.Bytes())] = encodedData
|
||||
}
|
||||
|
||||
func (f *Firehose) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc) {
|
||||
f.OnBlockStart(b, big.NewInt(0), nil, nil, nil)
|
||||
f.captureTxStart(types.NewTx(&types.LegacyTx{}), emptyCommonHash, emptyCommonAddress, emptyCommonAddress, func(common.Address) bool { return false }, false)
|
||||
func (f *Firehose) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc, chainConfig *params.ChainConfig) {
|
||||
f.OnBlockStart(b, big.NewInt(0), nil, nil, chainConfig)
|
||||
f.captureTxStart(types.NewTx(&types.LegacyTx{}), emptyCommonHash, emptyCommonAddress, emptyCommonAddress)
|
||||
f.CaptureStart(emptyCommonAddress, emptyCommonAddress, false, nil, 0, nil)
|
||||
|
||||
for _, addr := range sortedKeys(alloc) {
|
||||
|
|
@ -860,6 +874,11 @@ func (f *Firehose) OnNewAccount(a common.Address, previousDataExists bool) {
|
|||
// exists in the past. For now, do nothing and keep the legacy behavior.
|
||||
_ = previousDataExists
|
||||
|
||||
if call := f.callStack.Peek(); call != nil && call.CallType == pbeth.CallType_STATIC && f.blockIsPrecompiledAddr(common.Address(call.Address)) {
|
||||
// Old Firehose ignore those, we do the same
|
||||
return
|
||||
}
|
||||
|
||||
accountCreation := &pbeth.AccountCreation{
|
||||
Account: a.Bytes(),
|
||||
Ordinal: f.blockOrdinal.Next(),
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ func (p *Printer) OnBlockEnd(err error) {
|
|||
fmt.Printf("OnBlockEnd: err=%v\n", err)
|
||||
}
|
||||
|
||||
func (p *Printer) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc) {
|
||||
func (p *Printer) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc, chainConfig *params.ChainConfig) {
|
||||
fmt.Printf("OnGenesisBlock: b=%v, allocLength=%d\n", b.NumberU64(), len(alloc))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
// - the coinbase self-destructed, or
|
||||
// - there are only 'bad' transactions, which aren't executed. In those cases,
|
||||
// the coinbase gets no txfee, so isn't created, and thus needs to be touched
|
||||
statedb.AddBalance(block.Coinbase(), new(uint256.Int), false, state.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(block.Coinbase(), new(uint256.Int), state.BalanceChangeUnspecified)
|
||||
|
||||
// Commit state mutations into database.
|
||||
root, _ := statedb.Commit(block.NumberU64(), config.IsEIP158(block.Number()))
|
||||
|
|
|
|||
Loading…
Reference in a new issue