core, all: split vm.Context into BlockContext and TxContext (#21672)
* all: core: split vm.Config into BlockConfig and TxConfig * core: core/vm: reset EVM between tx in block instead of creating new * core/vm: added docs
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							6f4cccf8d2
						
					
				
				
					commit
					2045a2bba3
				
			| @@ -65,10 +65,16 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg | ||||
| 	if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { | ||||
| 		misc.ApplyDAOHardFork(statedb) | ||||
| 	} | ||||
| 	blockContext := NewEVMBlockContext(header, p.bc, nil) | ||||
| 	vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) | ||||
| 	// Iterate over and process the individual transactions | ||||
| 	for i, tx := range block.Transactions() { | ||||
| 		msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number)) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, 0, err | ||||
| 		} | ||||
| 		statedb.Prepare(tx.Hash(), block.Hash(), i) | ||||
| 		receipt, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) | ||||
| 		receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, 0, err | ||||
| 		} | ||||
| @@ -81,34 +87,25 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg | ||||
| 	return receipts, allLogs, *usedGas, nil | ||||
| } | ||||
|  | ||||
| // ApplyTransaction attempts to apply a transaction to the given state database | ||||
| // and uses the input parameters for its environment. It returns the receipt | ||||
| // for the transaction, gas used and an error if the transaction failed, | ||||
| // indicating the block was invalid. | ||||
| func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { | ||||
| 	msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) { | ||||
| 	// Create a new context to be used in the EVM environment | ||||
| 	context := NewEVMContext(msg, header, bc, author) | ||||
| 	// Create a new environment which holds all relevant information | ||||
| 	// about the transaction and calling mechanisms. | ||||
| 	vmenv := vm.NewEVM(context, statedb, config, cfg) | ||||
|  | ||||
| 	txContext := NewEVMTxContext(msg) | ||||
| 	// Add addresses to access list if applicable | ||||
| 	if config.IsYoloV2(header.Number) { | ||||
| 		statedb.AddAddressToAccessList(msg.From()) | ||||
| 		if dst := msg.To(); dst != nil { | ||||
| 			statedb.AddAddressToAccessList(*dst) | ||||
| 			// If it's a create-tx, the destination will be added inside evm.create | ||||
| 		} | ||||
| 		for _, addr := range vmenv.ActivePrecompiles() { | ||||
| 		for _, addr := range evm.ActivePrecompiles() { | ||||
| 			statedb.AddAddressToAccessList(addr) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Update the evm with the new transaction context. | ||||
| 	evm.Reset(txContext, statedb) | ||||
| 	// Apply the transaction to the current state (included in the env) | ||||
| 	result, err := ApplyMessage(vmenv, msg, gp) | ||||
| 	result, err := ApplyMessage(evm, msg, gp) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -128,7 +125,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo | ||||
| 	receipt.GasUsed = result.UsedGas | ||||
| 	// if the transaction created a contract, store the creation address in the receipt. | ||||
| 	if msg.To() == nil { | ||||
| 		receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) | ||||
| 		receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) | ||||
| 	} | ||||
| 	// Set the receipt logs and create a bloom for filtering | ||||
| 	receipt.Logs = statedb.GetLogs(tx.Hash()) | ||||
| @@ -139,3 +136,18 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo | ||||
|  | ||||
| 	return receipt, err | ||||
| } | ||||
|  | ||||
| // ApplyTransaction attempts to apply a transaction to the given state database | ||||
| // and uses the input parameters for its environment. It returns the receipt | ||||
| // for the transaction, gas used and an error if the transaction failed, | ||||
| // indicating the block was invalid. | ||||
| func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { | ||||
| 	msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Create a new context to be used in the EVM environment | ||||
| 	blockContext := NewEVMBlockContext(header, bc, author) | ||||
| 	vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg) | ||||
| 	return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user