mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
commit
b6c53b7ada
17 changed files with 118 additions and 79 deletions
|
|
@ -317,15 +317,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, reward, state.BalanceIncreaseRewardMineUncle)
|
||||
statedb.AddBalance(ommer.Address, reward, false, state.BalanceIncreaseRewardMineUncle)
|
||||
}
|
||||
statedb.AddBalance(pre.Env.Coinbase, minerReward, state.BalanceIncreaseRewardMineBlock)
|
||||
statedb.AddBalance(pre.Env.Coinbase, minerReward, false, 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, amount, state.BalanceIncreaseWithdrawal)
|
||||
statedb.AddBalance(w.Address, amount, false, state.BalanceIncreaseWithdrawal)
|
||||
}
|
||||
// Commit block
|
||||
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
|
|||
// Convert amount from gwei to wei.
|
||||
amount := new(big.Int).SetUint64(w.Amount)
|
||||
amount = amount.Mul(amount, big.NewInt(params.GWei))
|
||||
stateDB.AddBalance(w.Address, amount, state.BalanceIncreaseWithdrawal)
|
||||
stateDB.AddBalance(w.Address, amount, false, state.BalanceIncreaseWithdrawal)
|
||||
}
|
||||
// No block reward which is issued by consensus layer instead.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -586,10 +586,10 @@ func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, heade
|
|||
r.Sub(r, header.Number)
|
||||
r.Mul(r, blockReward)
|
||||
r.Div(r, big8)
|
||||
stateDB.AddBalance(uncle.Coinbase, r, state.BalanceIncreaseRewardMineUncle)
|
||||
stateDB.AddBalance(uncle.Coinbase, r, false, state.BalanceIncreaseRewardMineUncle)
|
||||
|
||||
r.Div(blockReward, big32)
|
||||
reward.Add(reward, r)
|
||||
}
|
||||
stateDB.AddBalance(header.Coinbase, reward, state.BalanceIncreaseRewardMineBlock)
|
||||
stateDB.AddBalance(header.Coinbase, reward, false, state.BalanceIncreaseRewardMineBlock)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,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), state.BalanceIncreaseDaoContract)
|
||||
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), false, state.BalanceIncreaseDaoContract)
|
||||
statedb.SetBalance(addr, new(big.Int), state.BalanceDecreaseDaoAccount)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,5 +137,5 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *big.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 *big.Int) {
|
||||
db.SubBalance(sender, amount, state.BalanceChangeTransfer)
|
||||
db.AddBalance(recipient, amount, state.BalanceChangeTransfer)
|
||||
db.AddBalance(recipient, amount, false, state.BalanceChangeTransfer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
|
|||
}
|
||||
for addr, account := range *ga {
|
||||
if account.Balance != nil {
|
||||
statedb.AddBalance(addr, account.Balance, state.BalanceIncreaseGenesisBalance)
|
||||
statedb.AddBalance(addr, account.Balance, false, state.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
|
|
@ -165,7 +165,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, account.Balance, state.BalanceIncreaseGenesisBalance)
|
||||
statedb.AddBalance(addr, account.Balance, false, state.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
|
|
|
|||
|
|
@ -402,8 +402,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 *big.Int, reason BalanceChangeReason) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int, checkPrecompile bool, reason BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr, checkPrecompile)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount, reason)
|
||||
}
|
||||
|
|
@ -652,27 +652,24 @@ 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.getOrNewStateObject(addr, false)
|
||||
}
|
||||
|
||||
func (s *StateDB) getOrNewStateObject(addr common.Address, checkPrecompile bool) *stateObject {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
stateObject, _ = s.createObject(addr)
|
||||
stateObject, _ = s.createObject(addr, checkPrecompile)
|
||||
}
|
||||
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) (newobj, prev *stateObject) {
|
||||
func (s *StateDB) createObject(addr common.Address, checkPrecompile bool) (newobj, prev *stateObject) {
|
||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
newobj = newObject(s, addr, nil)
|
||||
if prev == nil {
|
||||
s.journal.append(createObjectChange{account: &addr})
|
||||
if s.logger != nil {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The original account should be marked as destructed and all cached
|
||||
// account and storage data should be cleared as well. Note, it must
|
||||
|
|
@ -701,6 +698,19 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
|||
delete(s.accountsOrigin, prev.address)
|
||||
delete(s.storagesOrigin, prev.address)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
s.logger.OnNewAccount(addr)
|
||||
}
|
||||
}
|
||||
|
||||
s.setStateObject(newobj)
|
||||
if prev != nil && !prev.deleted {
|
||||
return newobj, prev
|
||||
|
|
@ -719,7 +729,7 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
|||
//
|
||||
// Carrying over the balance ensures that Ether doesn't disappear.
|
||||
func (s *StateDB) CreateAccount(addr common.Address) {
|
||||
newObj, prev := s.createObject(addr)
|
||||
newObj, prev := s.createObject(addr, false)
|
||||
if prev != nil {
|
||||
newObj.setBalance(prev.data.Balance)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,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, big.NewInt(int64(11*i)), 0x0)
|
||||
state.AddBalance(addr, big.NewInt(int64(11*i)), false, 0x0)
|
||||
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}))
|
||||
|
|
@ -273,7 +273,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
|
|||
{
|
||||
name: "AddBalance",
|
||||
fn: func(a testAction, s *StateDB) {
|
||||
s.AddBalance(addr, big.NewInt(a.args[0]), 0x0)
|
||||
s.AddBalance(addr, big.NewInt(a.args[0]), false, 0x0)
|
||||
},
|
||||
args: make([]int64, 1),
|
||||
},
|
||||
|
|
@ -536,7 +536,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(big.Int), 0x0)
|
||||
s.state.AddBalance(common.Address{}, new(big.Int), false, 0x0)
|
||||
|
||||
if len(s.state.journal.dirties) != 1 {
|
||||
t.Fatal("expected one dirty state object")
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
} else {
|
||||
fee := new(big.Int).SetUint64(st.gasUsed())
|
||||
fee.Mul(fee, effectiveTip)
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, fee, state.BalanceIncreaseRewardTransactionFee)
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, fee, false, state.BalanceIncreaseRewardTransactionFee)
|
||||
}
|
||||
|
||||
return &ExecutionResult{
|
||||
|
|
@ -471,7 +471,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) uint64 {
|
|||
|
||||
// Return ETH for remaining gas, exchanged at the original rate.
|
||||
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gasRemaining), st.msg.GasPrice)
|
||||
st.state.AddBalance(st.msg.From, remaining, state.BalanceIncreaseGasReturn)
|
||||
st.state.AddBalance(st.msg.From, remaining, false, state.BalanceIncreaseGasReturn)
|
||||
|
||||
if st.evm.Config.Tracer != nil && st.gasRemaining > 0 {
|
||||
st.evm.Config.Tracer.OnGasChange(st.gasRemaining, 0, vm.GasChangeTxLeftOverReturned)
|
||||
|
|
|
|||
|
|
@ -512,17 +512,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), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.SetNonce(crypto.PubkeyToAddress(filler.PublicKey), 3)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), big.NewInt(1000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), big.NewInt(10000000), 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), big.NewInt(1000000), false, 0x0)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), big.NewInt(10000000), false, 0x0)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -637,7 +637,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, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -737,9 +737,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, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr2, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr3, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr1, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.AddBalance(addr2, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.AddBalance(addr3, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -817,9 +817,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, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr2, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr3, big.NewInt(1_000_000_000), 0x0)
|
||||
statedb.AddBalance(addr1, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.AddBalance(addr2, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.AddBalance(addr3, big.NewInt(1_000_000_000), false, 0x0)
|
||||
statedb.Commit(0, true)
|
||||
|
||||
chain := &testBlockChain{
|
||||
|
|
@ -1210,7 +1210,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(big.Int).SetUint64(seed.balance), 0x0)
|
||||
statedb.AddBalance(addrs[acc], new(big.Int).SetUint64(seed.balance), false, 0x0)
|
||||
statedb.SetNonce(addrs[acc], seed.nonce)
|
||||
|
||||
// Sign the seed transactions and store them in the data store
|
||||
|
|
|
|||
|
|
@ -49,7 +49,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), big.NewInt(10000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(10000000000), false, 0x0)
|
||||
// Add executable ones
|
||||
for j := 0; j < int(pool.config.AccountSlots); j++ {
|
||||
executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key))
|
||||
|
|
@ -91,7 +91,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), big.NewInt(100000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), false, 0x0)
|
||||
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))
|
||||
|
|
@ -128,7 +128,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), big.NewInt(100000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), false, 0x0)
|
||||
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))
|
||||
|
|
@ -182,7 +182,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), big.NewInt(100000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), false, 0x0)
|
||||
futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 21000, big.NewInt(500), key))
|
||||
pool.addRemotesSync(futureTxs)
|
||||
}
|
||||
|
|
@ -190,7 +190,7 @@ func TestTransactionZAttack(t *testing.T) {
|
|||
overDraftTxs := types.Transactions{}
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), false, 0x0)
|
||||
for j := 0; j < int(pool.config.GlobalSlots); j++ {
|
||||
overDraftTxs = append(overDraftTxs, pricedValuedTransaction(uint64(j), 600000000000, 21000, big.NewInt(500), key))
|
||||
}
|
||||
|
|
@ -227,7 +227,7 @@ func BenchmarkFutureAttack(b *testing.B) {
|
|||
fillPool(b, pool)
|
||||
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), 0x0)
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000), false, 0x0)
|
||||
futureTxs := types.Transactions{}
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ func TestStateChangeDuringReset(t *testing.T) {
|
|||
|
||||
func testAddBalance(pool *LegacyPool, addr common.Address, amount *big.Int) {
|
||||
pool.mu.Lock()
|
||||
pool.currentState.AddBalance(addr, amount, 0x0)
|
||||
pool.currentState.AddBalance(addr, amount, false, 0x0)
|
||||
pool.mu.Unlock()
|
||||
}
|
||||
|
||||
|
|
@ -470,7 +470,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, big.NewInt(100000000000000), 0x0)
|
||||
statedb.AddBalance(addr, big.NewInt(100000000000000), false, 0x0)
|
||||
|
||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||
<-pool.requestReset(nil, nil)
|
||||
|
|
@ -499,7 +499,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, big.NewInt(100000000000000), 0x0)
|
||||
statedb.AddBalance(addr, big.NewInt(100000000000000), false, 0x0)
|
||||
|
||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||
<-pool.requestReset(nil, nil)
|
||||
|
|
@ -2662,7 +2662,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, big.NewInt(1000000), 0x0)
|
||||
pool.currentState.AddBalance(account, big.NewInt(1000000), false, 0x0)
|
||||
tx := transaction(uint64(0), 100000, key)
|
||||
batches[i] = tx
|
||||
}
|
||||
|
|
|
|||
|
|
@ -375,7 +375,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, big0, state.BalanceChangeTouchAccount)
|
||||
evm.StateDB.AddBalance(addr, big0, true, state.BalanceChangeTouchAccount)
|
||||
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
|
|
|
|||
|
|
@ -855,7 +855,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, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, false, 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)
|
||||
|
|
@ -871,7 +871,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, state.BalanceIncreaseSelfdestruct)
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, false, 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)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ type StateDB interface {
|
|||
CreateAccount(common.Address)
|
||||
|
||||
SubBalance(common.Address, *big.Int, state.BalanceChangeReason)
|
||||
AddBalance(common.Address, *big.Int, state.BalanceChangeReason)
|
||||
AddBalance(common.Address, *big.Int, bool, state.BalanceChangeReason)
|
||||
GetBalance(common.Address) *big.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ type Firehose struct {
|
|||
blockFinality *FinalityStatus
|
||||
|
||||
// Transaction state
|
||||
evm *vm.EVM
|
||||
transaction *pbeth.TransactionTrace
|
||||
transactionLogIndex uint32
|
||||
isPrecompiledAddr func(addr common.Address) bool
|
||||
|
|
@ -109,6 +110,7 @@ func (f *Firehose) resetBlock() {
|
|||
// resetTransaction resets the transaction state and the call state in one shot
|
||||
func (f *Firehose) resetTransaction() {
|
||||
f.transaction = nil
|
||||
f.evm = nil
|
||||
f.transactionLogIndex = 0
|
||||
f.isPrecompiledAddr = nil
|
||||
|
||||
|
|
@ -175,6 +177,7 @@ func (f *Firehose) CaptureTxStart(evm *vm.EVM, tx *types.Transaction, from commo
|
|||
|
||||
f.ensureInBlockAndNotInTrxAndNotInCall()
|
||||
|
||||
f.evm = evm
|
||||
var to common.Address
|
||||
if tx.To() == nil {
|
||||
to = crypto.CreateAddress(from, evm.StateDB.GetNonce(from))
|
||||
|
|
@ -409,9 +412,11 @@ func (f *Firehose) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope
|
|||
}
|
||||
|
||||
func (f *Firehose) captureInterpreterStep(activeCall *pbeth.Call, pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, rData []byte, depth int, err error) {
|
||||
if !activeCall.ExecutedCode {
|
||||
firehoseTrace("setting active call executed code to true")
|
||||
activeCall.ExecutedCode = true
|
||||
// for call, we need to process the executed code here
|
||||
// since in old firehose executed code calculation depends if the code exist
|
||||
if activeCall.CallType == pbeth.CallType_CALL && !activeCall.ExecutedCode {
|
||||
firehoseTrace("Intepreter step for callType_CALL")
|
||||
activeCall.ExecutedCode = len(activeCall.Input) > 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,6 +475,9 @@ 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)
|
||||
|
||||
// Known Firehose issue: The BeginOrdinal of the genesis block root call is never actually
|
||||
// incremented and it's always 0.
|
||||
//
|
||||
|
|
@ -496,6 +504,31 @@ 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 {
|
||||
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 &&
|
||||
(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
|
||||
}
|
||||
}
|
||||
|
||||
if precompile {
|
||||
firehoseDebug("executed code isprecompile callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
|
||||
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
|
||||
}
|
||||
|
||||
if call.CallType == pbeth.CallType_CALL {
|
||||
firehoseDebug("executed code callType_CALL")
|
||||
// calculation for executed code will happen in captureInterpreterStep
|
||||
return false
|
||||
}
|
||||
|
||||
firehoseDebug("executed code default callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
|
||||
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
|
||||
}
|
||||
|
||||
func (f *Firehose) callEnd(source string, output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
firehoseDebug("call end source=%s index=%d output=%s gasUsed=%d err=%s reverted=%t", source, f.callStack.ActiveIndex(), outputView(output), gasUsed, errorView(err), reverted)
|
||||
|
||||
|
|
@ -537,19 +570,19 @@ func (f *Firehose) callEnd(source string, output []byte, gasUsed uint64, err err
|
|||
// to false
|
||||
//
|
||||
// For precompiled address however, interpreter does not run so determine there was a bug in Firehose instrumentation where we would
|
||||
if call.ExecutedCode || f.isPrecompiledAddr(common.BytesToAddress(call.Address)) {
|
||||
// In this case, we are sure that some code executed. This translates in the old Firehose instrumentation
|
||||
// that it would have **never** emitted an `account_without_code`.
|
||||
//
|
||||
// When no `account_without_code` was executed in the previous Firehose instrumentation,
|
||||
// the `call.ExecutedCode` defaulted to the condition below
|
||||
call.ExecutedCode = call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
|
||||
} else {
|
||||
// In all other cases, we are sure that no code executed. This translates in the old Firehose instrumentation
|
||||
// that it would have emitted an `account_without_code` and it would have then forced set the `call.ExecutedCode`
|
||||
// to `false`.
|
||||
call.ExecutedCode = false
|
||||
}
|
||||
// if call.ExecutedCode || f.isPrecompiledAddr(common.BytesToAddress(call.Address)) {
|
||||
// // In this case, we are sure that some code executed. This translates in the old Firehose instrumentation
|
||||
// // that it would have **never** emitted an `account_without_code`.
|
||||
// //
|
||||
// // When no `account_without_code` was executed in the previous Firehose instrumentation,
|
||||
// // the `call.ExecutedCode` defaulted to the condition below
|
||||
// call.ExecutedCode = call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
|
||||
// } else {
|
||||
// // In all other cases, we are sure that no code executed. This translates in the old Firehose instrumentation
|
||||
// // that it would have emitted an `account_without_code` and it would have then forced set the `call.ExecutedCode`
|
||||
// // to `false`.
|
||||
// call.ExecutedCode = false
|
||||
// }
|
||||
|
||||
if reverted {
|
||||
failureReason := ""
|
||||
|
|
@ -805,10 +838,6 @@ func (f *Firehose) OnNewAccount(a common.Address) {
|
|||
return
|
||||
}
|
||||
|
||||
if f.isPrecompiledAddr(a) {
|
||||
return
|
||||
}
|
||||
|
||||
accountCreation := &pbeth.AccountCreation{
|
||||
Account: a.Bytes(),
|
||||
Ordinal: f.blockOrdinal.Next(),
|
||||
|
|
|
|||
|
|
@ -304,7 +304,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(big.Int), 0)
|
||||
statedb.AddBalance(block.Coinbase(), new(big.Int), false, 0)
|
||||
|
||||
// Commit state mutations into database.
|
||||
root, _ := statedb.Commit(block.NumberU64(), config.IsEIP158(block.Number()))
|
||||
|
|
|
|||
Loading…
Reference in a new issue