From d0e1908e7fbdcb774aa095c10804a4cb78d221df Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 27 Sep 2024 18:29:41 +0800 Subject: [PATCH] all: removed blockhash from statedb (#23126) --- consensus/tests/engine_v1_tests/helper.go | 2 +- consensus/tests/engine_v2_tests/helper.go | 2 +- core/chain_makers.go | 2 +- core/state/statedb.go | 32 +++--- core/state/statedb_test.go | 4 +- core/state_processor.go | 117 +++++++++++----------- eth/api_tracer.go | 6 +- miner/worker.go | 4 +- 8 files changed, 85 insertions(+), 84 deletions(-) diff --git a/consensus/tests/engine_v1_tests/helper.go b/consensus/tests/engine_v1_tests/helper.go index 52baa648e00be..a393f457b715d 100644 --- a/consensus/tests/engine_v1_tests/helper.go +++ b/consensus/tests/engine_v1_tests/helper.go @@ -382,7 +382,7 @@ func createBlockFromHeader(bc *BlockChain, customHeader *types.Header, txs []*ty var gasUsed = new(uint64) var receipts types.Receipts for i, tx := range txs { - statedb.Prepare(tx.Hash(), header.Hash(), i) + statedb.Prepare(tx.Hash(), i) receipt, _, err, _ := ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{}) if err != nil { return nil, fmt.Errorf("%v when applying transaction", err) diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index 454f482d7172c..5ea44d6d480c9 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -699,7 +699,7 @@ func createBlockFromHeader(bc *BlockChain, customHeader *types.Header, txs []*ty var gasUsed = new(uint64) var receipts types.Receipts for i, tx := range txs { - statedb.Prepare(tx.Hash(), header.Hash(), i) + statedb.Prepare(tx.Hash(), i) receipt, _, err, _ := ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{}) if err != nil { return nil, fmt.Errorf("%v when applying transaction", err) diff --git a/core/chain_makers.go b/core/chain_makers.go index 7a4012945f7d0..2df2366fbf15e 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -100,7 +100,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { b.SetCoinbase(common.Address{}) } feeCapacity := state.GetTRC21FeeCapacityFromState(b.statedb) - b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) + b.statedb.Prepare(tx.Hash(), len(b.txs)) receipt, gas, err, tokenFeeUsed := ApplyTransaction(b.config, feeCapacity, bc, &b.header.Coinbase, b.gasPool, b.statedb, nil, b.header, tx, &b.header.GasUsed, vm.Config{}) if err != nil { panic(err) diff --git a/core/state/statedb.go b/core/state/statedb.go index bac5106f5b964..37bcc85c5a358 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -67,10 +67,10 @@ type StateDB struct { // The refund counter, also used by state transitioning. refund uint64 - thash, bhash common.Hash - txIndex int - logs map[common.Hash][]*types.Log - logSize uint + thash common.Hash + txIndex int + logs map[common.Hash][]*types.Log + logSize uint preimages map[common.Hash][]byte @@ -150,7 +150,6 @@ func (self *StateDB) Reset(root common.Hash) error { self.stateObjects = make(map[common.Address]*stateObject) self.stateObjectsDirty = make(map[common.Address]struct{}) self.thash = common.Hash{} - self.bhash = common.Hash{} self.txIndex = 0 self.logs = make(map[common.Hash][]*types.Log) self.logSize = 0 @@ -164,15 +163,18 @@ func (self *StateDB) AddLog(log *types.Log) { self.journal = append(self.journal, addLogChange{txhash: self.thash}) log.TxHash = self.thash - log.BlockHash = self.bhash log.TxIndex = uint(self.txIndex) log.Index = self.logSize self.logs[self.thash] = append(self.logs[self.thash], log) self.logSize++ } -func (self *StateDB) GetLogs(hash common.Hash) []*types.Log { - return self.logs[hash] +func (s *StateDB) GetLogs(hash common.Hash, blockHash common.Hash) []*types.Log { + logs := s.logs[hash] + for _, l := range logs { + l.BlockHash = blockHash + } + return logs } func (self *StateDB) Logs() []*types.Log { @@ -249,11 +251,6 @@ func (self *StateDB) TxIndex() int { return self.txIndex } -// BlockHash returns the current block hash set by Prepare. -func (self *StateDB) BlockHash() common.Hash { - return self.bhash -} - func (self *StateDB) GetCode(addr common.Address) []byte { stateObject := self.getStateObject(addr) if stateObject != nil { @@ -651,11 +648,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // Prepare sets the current transaction hash and index and block hash which is // used when the EVM emits new state logs. -func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { - self.thash = thash - self.bhash = bhash - self.txIndex = ti - self.accessList = newAccessList() +func (s *StateDB) Prepare(thash common.Hash, ti int) { + s.thash = thash + s.txIndex = ti + s.accessList = newAccessList() } // DeleteSuicides flags the suicided objects for deletion so that it diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 15533ec5a0862..35e7affafda84 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -419,9 +419,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", state.GetRefund(), checkstate.GetRefund()) } - if !reflect.DeepEqual(state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) { + if !reflect.DeepEqual(state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{})) { return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v", - state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) + state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{})) } return nil } diff --git a/core/state_processor.go b/core/state_processor.go index 292538c39d7d5..7462d0680fecf 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -69,17 +69,19 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // transactions failed to execute due to insufficient gas it will return an error. func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) { var ( - receipts types.Receipts - usedGas = new(uint64) - header = block.Header() - allLogs []*types.Log - gp = new(GasPool).AddGas(block.GasLimit()) + receipts types.Receipts + usedGas = new(uint64) + header = block.Header() + blockHash = block.Hash() + blockNumber = block.Number() + allLogs []*types.Log + gp = new(GasPool).AddGas(block.GasLimit()) ) // Mutate the the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } - if common.TIPSigning.Cmp(header.Number) == 0 { + if common.TIPSigning.Cmp(blockNumber) == 0 { statedb.DeleteAddress(common.BlockSignersBinary) } parentState := statedb.Copy() @@ -94,11 +96,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra if (block.Number().Uint64() >= common.BlackListHFNumber) && !common.IsTestnet { // check if sender is in black list if tx.From() != nil && common.Blacklist[*tx.From()] { - return nil, nil, 0, fmt.Errorf("Block contains transaction with sender in black-list: %v", tx.From().Hex()) + return nil, nil, 0, fmt.Errorf("block contains transaction with sender in black-list: %v", tx.From().Hex()) } // check if receiver is in black list if tx.To() != nil && common.Blacklist[*tx.To()] { - return nil, nil, 0, fmt.Errorf("Block contains transaction with receiver in black-list: %v", tx.To().Hex()) + return nil, nil, 0, fmt.Errorf("block contains transaction with receiver in black-list: %v", tx.To().Hex()) } } // validate minFee slot for XDCZ @@ -115,8 +117,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra return nil, nil, 0, err } } - statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, gas, err, tokenFeeUsed := applyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, tradingState, header, tx, usedGas, vmenv) + statedb.Prepare(tx.Hash(), i) + receipt, gas, err, tokenFeeUsed := applyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, header, blockNumber, blockHash, tx, usedGas, vmenv) if err != nil { return nil, nil, 0, err } @@ -138,17 +140,19 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) { block := cBlock.block var ( - receipts types.Receipts - usedGas = new(uint64) - header = block.Header() - allLogs []*types.Log - gp = new(GasPool).AddGas(block.GasLimit()) + receipts types.Receipts + usedGas = new(uint64) + header = block.Header() + blockHash = block.Hash() + blockNumber = block.Number() + allLogs []*types.Log + gp = new(GasPool).AddGas(block.GasLimit()) ) // Mutate the the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } - if common.TIPSigning.Cmp(header.Number) == 0 { + if common.TIPSigning.Cmp(blockNumber) == 0 { statedb.DeleteAddress(common.BlockSignersBinary) } if cBlock.stop { @@ -192,8 +196,8 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated return nil, nil, 0, err } } - statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, gas, err, tokenFeeUsed := applyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, tradingState, header, tx, usedGas, vmenv) + statedb.Prepare(tx.Hash(), i) + receipt, gas, err, tokenFeeUsed := applyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, header, blockNumber, blockHash, tx, usedGas, vmenv) if err != nil { return nil, nil, 0, err } @@ -215,23 +219,24 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated return receipts, allLogs, *usedGas, nil } -func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*big.Int, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, uint64, error, bool) { +func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*big.Int, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, uint64, error, bool) { to := tx.To() - if to != nil && *to == common.BlockSignersBinary && config.IsTIPSigning(header.Number) { - return ApplySignTransaction(config, statedb, header, tx, usedGas) - } - if to != nil && *to == common.TradingStateAddrBinary && config.IsTIPXDCXReceiver(header.Number) { - return ApplyEmptyTransaction(config, statedb, header, tx, usedGas) - } - if to != nil && *to == common.XDCXLendingAddressBinary && config.IsTIPXDCXReceiver(header.Number) { - return ApplyEmptyTransaction(config, statedb, header, tx, usedGas) + if to != nil { + if *to == common.BlockSignersBinary && config.IsTIPSigning(blockNumber) { + return ApplySignTransaction(config, statedb, blockNumber, blockHash, tx, usedGas) + } + if *to == common.TradingStateAddrBinary && config.IsTIPXDCXReceiver(blockNumber) { + return ApplyEmptyTransaction(config, statedb, blockNumber, blockHash, tx, usedGas) + } + if *to == common.XDCXLendingAddressBinary && config.IsTIPXDCXReceiver(blockNumber) { + return ApplyEmptyTransaction(config, statedb, blockNumber, blockHash, tx, usedGas) + } } - if tx.IsTradingTransaction() && config.IsTIPXDCXReceiver(header.Number) { - return ApplyEmptyTransaction(config, statedb, header, tx, usedGas) + if tx.IsTradingTransaction() && config.IsTIPXDCXReceiver(blockNumber) { + return ApplyEmptyTransaction(config, statedb, blockNumber, blockHash, tx, usedGas) } - - if tx.IsLendingFinalizedTradeTransaction() && config.IsTIPXDCXReceiver(header.Number) { - return ApplyEmptyTransaction(config, statedb, header, tx, usedGas) + if tx.IsLendingFinalizedTradeTransaction() && config.IsTIPXDCXReceiver(blockNumber) { + return ApplyEmptyTransaction(config, statedb, blockNumber, blockHash, tx, usedGas) } var balanceFee *big.Int @@ -240,7 +245,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* balanceFee = value } } - msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), balanceFee, header.Number) + msg, err := tx.AsMessage(types.MakeSigner(config, blockNumber), balanceFee, blockNumber) if err != nil { return nil, 0, err, false } @@ -263,7 +268,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // Bypass blacklist address maxBlockNumber := new(big.Int).SetInt64(9147459) - if header.Number.Cmp(maxBlockNumber) <= 0 { + if blockNumber.Cmp(maxBlockNumber) <= 0 { addrMap := make(map[string]string) addrMap["0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"] = "29410" addrMap["0x5ac26105b35ea8935be382863a70281ec7a985e9"] = "23551" @@ -391,7 +396,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* addrFrom := msg.From().Hex() - currentBlockNumber := header.Number.Int64() + currentBlockNumber := blockNumber.Int64() if addr, ok := blockMap[currentBlockNumber]; ok { if strings.ToLower(addr) == strings.ToLower(addrFrom) { bal := addrMap[addr] @@ -414,10 +419,10 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // Update the state with pending changes. var root []byte - if config.IsByzantium(header.Number) { + if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } *usedGas += gas @@ -438,10 +443,10 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* } // Set the receipt logs and create the bloom filter. - receipt.Logs = statedb.GetLogs(tx.Hash()) + receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - receipt.BlockHash = statedb.BlockHash() - receipt.BlockNumber = header.Number + receipt.BlockHash = blockHash + receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) if balanceFee != nil && failed { state.PayFeeWithTRC21TxFail(statedb, msg.From(), *to) @@ -457,18 +462,18 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // Create a new context to be used in the EVM environment blockContext := NewEVMBlockContext(header, bc, author) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, XDCxState, config, cfg) - return applyTransaction(config, tokensFee, bc, author, gp, statedb, XDCxState, header, tx , usedGas, vmenv) + return applyTransaction(config, tokensFee, bc, author, gp, statedb, header, header.Number, header.Hash(), tx, usedGas, vmenv) } -func ApplySignTransaction(config *params.ChainConfig, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error, bool) { +func ApplySignTransaction(config *params.ChainConfig, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error, bool) { // Update the state with pending changes var root []byte - if config.IsByzantium(header.Number) { + if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } - from, err := types.Sender(types.MakeSigner(config, header.Number), tx) + from, err := types.Sender(types.MakeSigner(config, blockNumber), tx) if err != nil { return nil, 0, err, false } @@ -488,23 +493,23 @@ func ApplySignTransaction(config *params.ChainConfig, statedb *state.StateDB, he // Set the receipt logs and create a bloom for filtering log := &types.Log{} log.Address = common.BlockSignersBinary - log.BlockNumber = header.Number.Uint64() + log.BlockNumber = blockNumber.Uint64() statedb.AddLog(log) - receipt.Logs = statedb.GetLogs(tx.Hash()) + receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - receipt.BlockHash = statedb.BlockHash() - receipt.BlockNumber = header.Number + receipt.BlockHash = blockHash + receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) return receipt, 0, nil, false } -func ApplyEmptyTransaction(config *params.ChainConfig, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error, bool) { +func ApplyEmptyTransaction(config *params.ChainConfig, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error, bool) { // Update the state with pending changes var root []byte - if config.IsByzantium(header.Number) { + if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx // based on the eip phase, we're passing wether the root touch-delete accounts. @@ -515,12 +520,12 @@ func ApplyEmptyTransaction(config *params.ChainConfig, statedb *state.StateDB, h // Set the receipt logs and create a bloom for filtering log := &types.Log{} log.Address = *tx.To() - log.BlockNumber = header.Number.Uint64() + log.BlockNumber = blockNumber.Uint64() statedb.AddLog(log) - receipt.Logs = statedb.GetLogs(tx.Hash()) + receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - receipt.BlockHash = statedb.BlockHash() - receipt.BlockNumber = header.Number + receipt.BlockHash = blockHash + receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) return receipt, 0, nil, false } diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 3277dd7e08704..1c79c33acf537 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -520,7 +520,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, // Generate the next state snapshot fast without tracing msg, _ := tx.AsMessage(signer, balacne, block.Number()) txContext := core.NewEVMTxContext(msg) - statedb.Prepare(tx.Hash(), block.Hash(), i) + statedb.Prepare(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, txContext, statedb, XDCxState, api.config, vm.Config{}) owner := common.Address{} @@ -740,7 +740,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, t vmenv := vm.NewEVM(vmctx, txContext, statedb, nil, api.config, vm.Config{Debug: true, Tracer: tracer}) // Call Prepare to clear out the statedb access list - statedb.Prepare(txctx.TxHash, txctx.BlockHash, txctx.TxIndex) + statedb.Prepare(txctx.TxHash, txctx.TxIndex) owner := common.Address{} ret, gas, failed, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) @@ -792,7 +792,7 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree usedGas := new(uint64) // Iterate over and process the individual transactions for idx, tx := range block.Transactions() { - statedb.Prepare(tx.Hash(), block.Hash(), idx) + statedb.Prepare(tx.Hash(), idx) if idx == txIndex { var balanceFee *big.Int if tx.To() != nil { diff --git a/miner/worker.go b/miner/worker.go index 0e341636d2432..a312d902ba657 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -911,7 +911,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad } } // Start executing the transaction - env.state.Prepare(hash, common.Hash{}, env.tcount) + env.state.Prepare(hash, env.tcount) nonce := env.state.GetNonce(from) if nonce != tx.Nonce() && !tx.IsSkipNonceTransaction() { @@ -1012,7 +1012,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad continue } // Start executing the transaction - env.state.Prepare(hash, common.Hash{}, env.tcount) + env.state.Prepare(hash, env.tcount) nonce := env.state.GetNonce(from) if nonce > tx.Nonce() { // New head notification data race between the transaction pool and miner, shift