mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-15 17:30:44 +00:00
parent
373037032f
commit
cfca45a7eb
30 changed files with 241 additions and 137 deletions
|
|
@ -777,9 +777,10 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
evmContext := core.NewEVMBlockContext(block, b.blockchain, nil)
|
evmContext := core.NewEVMBlockContext(block, b.blockchain, nil)
|
||||||
// Create a new environment which holds all relevant information
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEVM(evmContext, txContext, stateDB, nil, b.config, vm.Config{NoBaseFee: true})
|
evm := vm.NewEVM(evmContext, stateDB, nil, b.config, vm.Config{NoBaseFee: true})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
gaspool := new(core.GasPool).AddGas(gomath.MaxUint64)
|
gaspool := new(core.GasPool).AddGas(gomath.MaxUint64)
|
||||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(common.Address{})
|
return core.NewStateTransition(evm, msg, gaspool).TransitionDb(common.Address{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTransaction updates the pending block to include the given transaction.
|
// SendTransaction updates the pending block to include the given transaction.
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,9 @@ func createBlockFromHeader(bc *core.BlockChain, customHeader *types.Header, txs
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
receipt, _, _, err := core.ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{})
|
blockContext := core.NewEVMBlockContext(&header, bc, &header.Coinbase)
|
||||||
|
evm := vm.NewEVM(blockContext, statedb, nil, bc.Config(), vm.Config{})
|
||||||
|
receipt, _, _, err := core.ApplyTransaction(bc.Config(), nil, evm, gp, statedb, &header, tx, gasUsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v when applying transaction", err)
|
return nil, fmt.Errorf("%v when applying transaction", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -901,7 +901,9 @@ func createBlockFromHeader(bc *core.BlockChain, customHeader *types.Header, txs
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
receipt, _, _, err := core.ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{})
|
blockContext := core.NewEVMBlockContext(&header, bc, &header.Coinbase)
|
||||||
|
evm := vm.NewEVM(blockContext, statedb, nil, bc.Config(), vm.Config{})
|
||||||
|
receipt, _, _, err := core.ApplyTransaction(bc.Config(), nil, evm, gp, statedb, &header, tx, gasUsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v when applying transaction", err)
|
return nil, fmt.Errorf("%v when applying transaction", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,9 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
|
||||||
}
|
}
|
||||||
feeCapacity := b.statedb.GetTRC21FeeCapacityFromState()
|
feeCapacity := b.statedb.GetTRC21FeeCapacityFromState()
|
||||||
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
||||||
receipt, gas, tokenFeeUsed, err := ApplyTransaction(b.config, feeCapacity, bc, &b.header.Coinbase, b.gasPool, b.statedb, nil, b.header, tx, &b.header.GasUsed, vmConfig)
|
blockContext := NewEVMBlockContext(b.header, bc, &b.header.Coinbase)
|
||||||
|
evm := vm.NewEVM(blockContext, b.statedb, nil, b.config, vmConfig)
|
||||||
|
receipt, gas, tokenFeeUsed, err := ApplyTransaction(b.config, feeCapacity, evm, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +237,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
if config.IsPrague(b.header.Number) {
|
if config.IsPrague(b.header.Number) {
|
||||||
// EIP-2935
|
// EIP-2935
|
||||||
blockContext := NewEVMBlockContext(b.header, chainReader, &b.header.Coinbase)
|
blockContext := NewEVMBlockContext(b.header, chainReader, &b.header.Coinbase)
|
||||||
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, config, vm.Config{})
|
evm := vm.NewEVM(blockContext, statedb, nil, config, vm.Config{})
|
||||||
ProcessParentBlockHash(b.header.ParentHash, evm, statedb)
|
ProcessParentBlockHash(b.header.ParentHash, evm, statedb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
header = block.Header()
|
header = block.Header()
|
||||||
gaspool = new(GasPool).AddGas(block.GasLimit())
|
gaspool = new(GasPool).AddGas(block.GasLimit())
|
||||||
blockContext = NewEVMBlockContext(header, p.bc, nil)
|
blockContext = NewEVMBlockContext(header, p.bc, nil)
|
||||||
evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, p.config, cfg)
|
evm = vm.NewEVM(blockContext, statedb, nil, p.config, cfg)
|
||||||
signer = types.MakeSigner(p.config, header.Number)
|
signer = types.MakeSigner(p.config, header.Number)
|
||||||
)
|
)
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
|
|
@ -69,7 +69,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
return // Also invalid block, bail out
|
return // Also invalid block, bail out
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
|
if err := precacheTransaction(msg, gaspool, evm); err != nil {
|
||||||
return // Ugh, something went horribly wrong, bail out
|
return // Ugh, something went horribly wrong, bail out
|
||||||
}
|
}
|
||||||
// If we're pre-byzantium, pre-load trie nodes for the intermediate root
|
// If we're pre-byzantium, pre-load trie nodes for the intermediate root
|
||||||
|
|
@ -86,9 +86,9 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
// precacheTransaction attempts to apply a transaction to the given state database
|
// precacheTransaction attempts to apply a transaction to the given state database
|
||||||
// and uses the input parameters for its environment. The goal is not to execute
|
// and uses the input parameters for its environment. The goal is not to execute
|
||||||
// the transaction successfully, rather to warm up touched data slots.
|
// the transaction successfully, rather to warm up touched data slots.
|
||||||
func precacheTransaction(msg *Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
|
func precacheTransaction(msg *Message, gaspool *GasPool, evm *vm.EVM) error {
|
||||||
// Update the evm with the new transaction context.
|
// Update the evm with the new transaction context.
|
||||||
evm.Reset(NewEVMTxContext(msg), statedb)
|
evm.SetTxContext(NewEVMTxContext(msg))
|
||||||
// Add addresses to access list if applicable
|
// Add addresses to access list if applicable
|
||||||
_, err := ApplyMessage(evm, msg, gaspool, common.Address{})
|
_, err := ApplyMessage(evm, msg, gaspool, common.Address{})
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra
|
||||||
totalFeeUsed := big.NewInt(0)
|
totalFeeUsed := big.NewInt(0)
|
||||||
|
|
||||||
// Apply pre-execution system calls.
|
// Apply pre-execution system calls.
|
||||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
context := NewEVMBlockContext(header, p.bc, nil)
|
||||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, tracingStateDB, tradingState, p.config, cfg)
|
evm := vm.NewEVM(context, tracingStateDB, tradingState, p.config, cfg)
|
||||||
signer := types.MakeSigner(p.config, blockNumber)
|
signer := types.MakeSigner(p.config, blockNumber)
|
||||||
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
||||||
|
|
||||||
if p.config.IsPrague(block.Number()) {
|
if p.config.IsPrague(block.Number()) {
|
||||||
ProcessParentBlockHash(block.ParentHash(), vmenv, tracingStateDB)
|
ProcessParentBlockHash(block.ParentHash(), evm, tracingStateDB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
|
|
@ -146,7 +146,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
|
|
||||||
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, balanceFee, coinbaseOwner)
|
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee, coinbaseOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||||
}
|
}
|
||||||
|
|
@ -204,13 +204,13 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply pre-execution system calls.
|
// Apply pre-execution system calls.
|
||||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
context := NewEVMBlockContext(header, p.bc, nil)
|
||||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, tracingStateDB, tradingState, p.config, cfg)
|
evm := vm.NewEVM(context, tracingStateDB, tradingState, p.config, cfg)
|
||||||
signer := types.MakeSigner(p.config, blockNumber)
|
signer := types.MakeSigner(p.config, blockNumber)
|
||||||
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
||||||
|
|
||||||
if p.config.IsPrague(block.Number()) {
|
if p.config.IsPrague(block.Number()) {
|
||||||
ProcessParentBlockHash(block.ParentHash(), vmenv, tracingStateDB)
|
ProcessParentBlockHash(block.ParentHash(), evm, tracingStateDB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
|
|
@ -253,7 +253,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
|
|
||||||
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, balanceFee, coinbaseOwner)
|
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee, coinbaseOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, err
|
return nil, nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -280,11 +280,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
||||||
// and uses the input parameters for its environment similar to ApplyTransaction. However,
|
// and uses the input parameters for its environment similar to ApplyTransaction. However,
|
||||||
// this method takes an already created EVM instance as input.
|
// this method takes an already created EVM instance as input.
|
||||||
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, balanceFee *big.Int, coinbaseOwner common.Address) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
|
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, balanceFee *big.Int, coinbaseOwner common.Address) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
|
||||||
// Initialize tracer at the beginning to ensure all transaction types
|
|
||||||
// (including non-EVM special transactions) are properly traced.
|
|
||||||
var tracingStateDB = vm.StateDB(statedb)
|
|
||||||
if hooks := evm.Config.Tracer; hooks != nil {
|
if hooks := evm.Config.Tracer; hooks != nil {
|
||||||
tracingStateDB = state.NewHookedState(statedb, hooks)
|
|
||||||
if hooks.OnTxStart != nil {
|
if hooks.OnTxStart != nil {
|
||||||
hooks.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
hooks.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
}
|
}
|
||||||
|
|
@ -314,7 +310,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo
|
||||||
|
|
||||||
// Create a new context to be used in the EVM environment
|
// Create a new context to be used in the EVM environment
|
||||||
txContext := NewEVMTxContext(msg)
|
txContext := NewEVMTxContext(msg)
|
||||||
evm.Reset(txContext, tracingStateDB)
|
evm.SetTxContext(txContext)
|
||||||
|
|
||||||
// Bypass denylist address
|
// Bypass denylist address
|
||||||
maxBlockNumber := new(big.Int).SetInt64(9147459)
|
maxBlockNumber := new(big.Int).SetInt64(9147459)
|
||||||
|
|
@ -469,7 +465,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo
|
||||||
// Update the state with pending changes.
|
// Update the state with pending changes.
|
||||||
var root []byte
|
var root []byte
|
||||||
if config.IsByzantium(blockNumber) {
|
if config.IsByzantium(blockNumber) {
|
||||||
tracingStateDB.Finalise(true)
|
evm.StateDB.Finalise(true)
|
||||||
} else {
|
} else {
|
||||||
root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes()
|
root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes()
|
||||||
}
|
}
|
||||||
|
|
@ -524,7 +520,7 @@ func getCoinbaseOwner(bc *BlockChain, statedb *state.StateDB, header *types.Head
|
||||||
// and uses the input parameters for its environment. It returns the receipt
|
// and uses the input parameters for its environment. It returns the receipt
|
||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// indicating the block was invalid.
|
||||||
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, cfg vm.Config) (*types.Receipt, uint64, bool, error) {
|
func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*big.Int, evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, bool, error) {
|
||||||
var balanceFee *big.Int
|
var balanceFee *big.Int
|
||||||
if tx.To() != nil {
|
if tx.To() != nil {
|
||||||
if value, ok := tokensFee[*tx.To()]; ok {
|
if value, ok := tokensFee[*tx.To()]; ok {
|
||||||
|
|
@ -532,16 +528,13 @@ 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)
|
|
||||||
signer := types.MakeSigner(config, header.Number)
|
signer := types.MakeSigner(config, header.Number)
|
||||||
msg, err := TransactionToMessage(tx, signer, balanceFee, header.Number, header.BaseFee)
|
msg, err := TransactionToMessage(tx, signer, balanceFee, header.Number, header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err
|
||||||
}
|
}
|
||||||
coinbaseOwner := getCoinbaseOwner(bc, statedb, header, author)
|
coinbaseOwner := statedb.GetOwner(evm.Context.Coinbase)
|
||||||
return ApplyTransactionWithEVM(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, balanceFee, coinbaseOwner)
|
return ApplyTransactionWithEVM(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, evm, balanceFee, coinbaseOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplySignTransaction(msg *Message, config *params.ChainConfig, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
|
func ApplySignTransaction(msg *Message, config *params.ChainConfig, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
|
||||||
|
|
@ -726,7 +719,7 @@ func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb vm.Stat
|
||||||
To: ¶ms.HistoryStorageAddress,
|
To: ¶ms.HistoryStorageAddress,
|
||||||
Data: prevHash.Bytes(),
|
Data: prevHash.Bytes(),
|
||||||
}
|
}
|
||||||
vmenv.Reset(NewEVMTxContext(msg), statedb)
|
vmenv.SetTxContext(NewEVMTxContext(msg))
|
||||||
statedb.AddAddressToAccessList(params.HistoryStorageAddress)
|
statedb.AddAddressToAccessList(params.HistoryStorageAddress)
|
||||||
_, _, err := vmenv.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560)
|
_, _, err := vmenv.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -467,7 +467,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
|
||||||
blockHash := genesis.Hash()
|
blockHash := genesis.Hash()
|
||||||
|
|
||||||
vmContext := NewEVMBlockContext(blockchain.CurrentBlock(), blockchain, nil)
|
vmContext := NewEVMBlockContext(blockchain.CurrentBlock(), blockchain, nil)
|
||||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, blockchain.Config(), vmConfig)
|
evm := vm.NewEVM(vmContext, statedb, nil, blockchain.Config(), vmConfig)
|
||||||
|
|
||||||
// Apply transaction
|
// Apply transaction
|
||||||
var usedGas uint64
|
var usedGas uint64
|
||||||
|
|
@ -493,6 +493,81 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApplyTransactionWithEVMStateChangeHooks(t *testing.T) {
|
||||||
|
var (
|
||||||
|
config = ¶ms.ChainConfig{
|
||||||
|
ChainID: big.NewInt(1),
|
||||||
|
HomesteadBlock: big.NewInt(0),
|
||||||
|
EIP150Block: big.NewInt(0),
|
||||||
|
EIP155Block: big.NewInt(0),
|
||||||
|
EIP158Block: big.NewInt(0),
|
||||||
|
ByzantiumBlock: big.NewInt(0),
|
||||||
|
ConstantinopleBlock: big.NewInt(0),
|
||||||
|
PetersburgBlock: big.NewInt(0),
|
||||||
|
IstanbulBlock: big.NewInt(0),
|
||||||
|
BerlinBlock: big.NewInt(0),
|
||||||
|
LondonBlock: big.NewInt(0),
|
||||||
|
Eip1559Block: big.NewInt(0),
|
||||||
|
Ethash: new(params.EthashConfig),
|
||||||
|
}
|
||||||
|
signer = types.LatestSigner(config)
|
||||||
|
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
sender = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
|
recipient = common.HexToAddress("0x1234567890123456789012345678901234567890")
|
||||||
|
hookInvoked bool
|
||||||
|
)
|
||||||
|
|
||||||
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
gspec := &Genesis{
|
||||||
|
Config: config,
|
||||||
|
Alloc: types.GenesisAlloc{
|
||||||
|
sender: {
|
||||||
|
Balance: big.NewInt(1000000000000000000),
|
||||||
|
Nonce: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
genesis := gspec.MustCommit(db)
|
||||||
|
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
|
||||||
|
defer blockchain.Stop()
|
||||||
|
|
||||||
|
statedb, err := blockchain.State()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to get state: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := types.NewTransaction(0, recipient, big.NewInt(1), 21000, big.NewInt(20000000000), nil)
|
||||||
|
signedTx, err := types.SignTx(tx, signer, testKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to sign tx: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks := &tracing.Hooks{
|
||||||
|
OnBalanceChange: func(addr common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) {
|
||||||
|
hookInvoked = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
hookedState := state.NewHookedState(statedb, hooks)
|
||||||
|
|
||||||
|
vmContext := NewEVMBlockContext(blockchain.CurrentBlock(), blockchain, nil)
|
||||||
|
evmenv := vm.NewEVM(vmContext, hookedState, nil, blockchain.Config(), vm.Config{Tracer: hooks})
|
||||||
|
|
||||||
|
msg, err := TransactionToMessage(signedTx, signer, nil, big.NewInt(1), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to build message: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gasPool := new(GasPool).AddGas(1000000)
|
||||||
|
var usedGas uint64
|
||||||
|
_, _, _, err = ApplyTransactionWithEVM(msg, config, gasPool, statedb, big.NewInt(1), genesis.Hash(), signedTx, &usedGas, evmenv, nil, common.Address{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ApplyTransactionWithEVM failed: %v", err)
|
||||||
|
}
|
||||||
|
if !hookInvoked {
|
||||||
|
t.Fatal("expected OnBalanceChange to be invoked, but it was not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestProcessParentBlockHash(t *testing.T) {
|
func TestProcessParentBlockHash(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
chainConfig = params.MergedTestChainConfig
|
chainConfig = params.MergedTestChainConfig
|
||||||
|
|
@ -508,11 +583,11 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
statedb.IntermediateRoot(true)
|
statedb.IntermediateRoot(true)
|
||||||
|
|
||||||
vmContext := NewEVMBlockContext(header, nil, &coinbase)
|
vmContext := NewEVMBlockContext(header, nil, &coinbase)
|
||||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{})
|
evm := vm.NewEVM(vmContext, statedb, nil, chainConfig, vm.Config{})
|
||||||
ProcessParentBlockHash(header.ParentHash, evm, statedb)
|
ProcessParentBlockHash(header.ParentHash, evm, statedb)
|
||||||
|
|
||||||
vmContext = NewEVMBlockContext(parent, nil, &coinbase)
|
vmContext = NewEVMBlockContext(parent, nil, &coinbase)
|
||||||
evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{})
|
evm = vm.NewEVM(vmContext, statedb, nil, chainConfig, vm.Config{})
|
||||||
ProcessParentBlockHash(parent.ParentHash, evm, statedb)
|
ProcessParentBlockHash(parent.ParentHash, evm, statedb)
|
||||||
|
|
||||||
// make sure that the state is correct
|
// make sure that the state is correct
|
||||||
|
|
@ -548,8 +623,8 @@ func TestProcessParentBlockHashPragueGuard(t *testing.T) {
|
||||||
BaseFee: nil,
|
BaseFee: nil,
|
||||||
Random: &random,
|
Random: &random,
|
||||||
}
|
}
|
||||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
evm := vm.NewEVM(blockContext, statedb, nil, &config, vm.Config{})
|
||||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
ProcessParentBlockHash(common.Hash{0x01}, evm, statedb)
|
||||||
|
|
||||||
if code := statedb.GetCode(params.HistoryStorageAddress); len(code) != 0 {
|
if code := statedb.GetCode(params.HistoryStorageAddress); len(code) != 0 {
|
||||||
t.Fatalf("unexpected history contract code predeploy: %x", code)
|
t.Fatalf("unexpected history contract code predeploy: %x", code)
|
||||||
|
|
@ -586,8 +661,8 @@ func TestProcessParentBlockHashBackfillMissingHistory(t *testing.T) {
|
||||||
BaseFee: nil,
|
BaseFee: nil,
|
||||||
Random: &random,
|
Random: &random,
|
||||||
}
|
}
|
||||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
evm := vm.NewEVM(blockContext, statedb, nil, &config, vm.Config{})
|
||||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
ProcessParentBlockHash(common.Hash{0x01}, evm, statedb)
|
||||||
|
|
||||||
if have := getParentBlockHash(statedb, 1); have != available[1] {
|
if have := getParentBlockHash(statedb, 1); have != available[1] {
|
||||||
t.Fatalf("expected hash at slot 1, have %v", have)
|
t.Fatalf("expected hash at slot 1, have %v", have)
|
||||||
|
|
@ -619,14 +694,14 @@ func TestProcessParentBlockHashCodeMismatchPanics(t *testing.T) {
|
||||||
BaseFee: nil,
|
BaseFee: nil,
|
||||||
Random: &random,
|
Random: &random,
|
||||||
}
|
}
|
||||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
evm := vm.NewEVM(blockContext, statedb, nil, &config, vm.Config{})
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if recover() == nil {
|
if recover() == nil {
|
||||||
t.Fatal("expected panic on history storage code mismatch")
|
t.Fatal("expected panic on history storage code mismatch")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
ProcessParentBlockHash(common.Hash{0x01}, evm, statedb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash {
|
func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash {
|
||||||
|
|
|
||||||
|
|
@ -110,9 +110,10 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext,
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
txContext := NewEVMTxContext(msg)
|
txContext := NewEVMTxContext(msg)
|
||||||
evmContext := NewEVMBlockContext(chain.CurrentHeader(), chain, nil)
|
evmContext := NewEVMBlockContext(chain.CurrentHeader(), chain, nil)
|
||||||
vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, chain.Config(), vm.Config{})
|
evm := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
gaspool := new(GasPool).AddGas(1000000)
|
gaspool := new(GasPool).AddGas(1000000)
|
||||||
result, err := NewStateTransition(vmenv, msg, gaspool).TransitionDb(common.Address{})
|
result, err := NewStateTransition(evm, msg, gaspool).TransitionDb(common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,12 +132,13 @@ type EVM struct {
|
||||||
returnData []byte // Last CALL's return data for subsequent reuse
|
returnData []byte // Last CALL's return data for subsequent reuse
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
// NewEVM constructs an EVM instance with the supplied block context, state
|
||||||
// only ever be used *once*.
|
// database and several configs. It is meant to be used throughout the entire
|
||||||
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, tradingStateDB *tradingstate.TradingStateDB, chainConfig *params.ChainConfig, config Config) *EVM {
|
// state transition of a block, with the transaction context switched as
|
||||||
|
// needed by calling evm.SetTxContext.
|
||||||
|
func NewEVM(blockCtx BlockContext, statedb StateDB, tradingStateDB *tradingstate.TradingStateDB, chainConfig *params.ChainConfig, config Config) *EVM {
|
||||||
evm := &EVM{
|
evm := &EVM{
|
||||||
Context: blockCtx,
|
Context: blockCtx,
|
||||||
TxContext: txCtx,
|
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
tradingStateDB: tradingStateDB,
|
tradingStateDB: tradingStateDB,
|
||||||
Config: config,
|
Config: config,
|
||||||
|
|
@ -198,6 +199,11 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, tradingStat
|
||||||
return evm
|
return evm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTracer sets the tracer for following state transition.
|
||||||
|
func (evm *EVM) SetTracer(tracer *tracing.Hooks) {
|
||||||
|
evm.Config.Tracer = tracer
|
||||||
|
}
|
||||||
|
|
||||||
// SetPrecompiles sets the precompiled contracts for the EVM.
|
// SetPrecompiles sets the precompiled contracts for the EVM.
|
||||||
// This method is only used through RPC calls.
|
// This method is only used through RPC calls.
|
||||||
// It is not thread-safe.
|
// It is not thread-safe.
|
||||||
|
|
@ -205,11 +211,10 @@ func (evm *EVM) SetPrecompiles(precompiles PrecompiledContracts) {
|
||||||
evm.precompiles = precompiles
|
evm.precompiles = precompiles
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets the EVM with a new transaction context.Reset
|
// SetTxContext updates the EVM with a new transaction context.
|
||||||
// This is not threadsafe and should only be done very cautiously.
|
// This is not threadsafe and should only be done very cautiously.
|
||||||
func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) {
|
func (evm *EVM) SetTxContext(txCtx TxContext) {
|
||||||
evm.TxContext = txCtx
|
evm.TxContext = txCtx
|
||||||
evm.StateDB = statedb
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel cancels any running EVM operation. This may be called concurrently and
|
// Cancel cancels any running EVM operation. This may be called concurrently and
|
||||||
|
|
|
||||||
|
|
@ -96,16 +96,16 @@ func TestEIP2200(t *testing.T) {
|
||||||
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
|
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
|
||||||
Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {},
|
Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {},
|
||||||
}
|
}
|
||||||
vmenv := NewEVM(vmctx, TxContext{}, statedb, nil, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
|
evm := NewEVM(vmctx, statedb, nil, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
|
||||||
|
|
||||||
_, gas, err := vmenv.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int))
|
_, gas, err := evm.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int))
|
||||||
if !errors.Is(err, tt.failure) {
|
if !errors.Is(err, tt.failure) {
|
||||||
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
|
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
|
||||||
}
|
}
|
||||||
if used := tt.gaspool - gas; used != tt.used {
|
if used := tt.gaspool - gas; used != tt.used {
|
||||||
t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used)
|
t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used)
|
||||||
}
|
}
|
||||||
if refund := vmenv.StateDB.GetRefund(); refund != tt.refund {
|
if refund := evm.StateDB.GetRefund(); refund != tt.refund {
|
||||||
t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund)
|
t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,9 +151,9 @@ func TestCreateGas(t *testing.T) {
|
||||||
config.ExtraEips = []int{3860}
|
config.ExtraEips = []int{3860}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := NewEVM(vmctx, TxContext{}, statedb, nil, params.AllEthashProtocolChanges, config)
|
evm := NewEVM(vmctx, statedb, nil, params.AllEthashProtocolChanges, config)
|
||||||
var startGas = uint64(testGas)
|
var startGas = uint64(testGas)
|
||||||
ret, gas, err := vmenv.Call(common.Address{}, address, nil, startGas, new(uint256.Int))
|
ret, gas, err := evm.Call(common.Address{}, address, nil, startGas, new(uint256.Int))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func init() {
|
||||||
|
|
||||||
func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
|
func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -196,7 +196,7 @@ func TestSAR(t *testing.T) {
|
||||||
|
|
||||||
func TestAddMod(t *testing.T) {
|
func TestAddMod(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -239,7 +239,7 @@ func TestWriteExpectedValues(t *testing.T) {
|
||||||
// getResult is a convenience function to generate the expected values
|
// getResult is a convenience function to generate the expected values
|
||||||
getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
|
getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -289,7 +289,7 @@ func TestJsonTestcases(t *testing.T) {
|
||||||
|
|
||||||
func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
|
func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
scope = &ScopeContext{nil, stack, nil}
|
scope = &ScopeContext{nil, stack, nil}
|
||||||
)
|
)
|
||||||
|
|
@ -526,7 +526,7 @@ func BenchmarkOpIsZero(b *testing.B) {
|
||||||
|
|
||||||
func TestOpMstore(t *testing.T) {
|
func TestOpMstore(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
)
|
)
|
||||||
|
|
@ -550,7 +550,7 @@ func TestOpMstore(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkOpMstore(bench *testing.B) {
|
func BenchmarkOpMstore(bench *testing.B) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
)
|
)
|
||||||
|
|
@ -570,7 +570,7 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||||
func TestOpTstore(t *testing.T) {
|
func TestOpTstore(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, statedb, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, statedb, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
caller = common.Address{}
|
caller = common.Address{}
|
||||||
|
|
@ -609,7 +609,7 @@ func TestOpTstore(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkOpKeccak256(bench *testing.B) {
|
func BenchmarkOpKeccak256(bench *testing.B) {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
)
|
)
|
||||||
|
|
@ -710,7 +710,7 @@ func TestRandom(t *testing.T) {
|
||||||
{name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})},
|
{name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})},
|
||||||
} {
|
} {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{Random: &tt.random}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{Random: &tt.random}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -750,7 +750,7 @@ func TestBlobHash(t *testing.T) {
|
||||||
{name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil},
|
{name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil},
|
||||||
} {
|
} {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -853,7 +853,7 @@ func TestOpMCopy(t *testing.T) {
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var (
|
var (
|
||||||
evm = NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
@ -909,7 +909,7 @@ func TestOpMCopy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOpCLZ(t *testing.T) {
|
func TestOpCLZ(t *testing.T) {
|
||||||
evm := NewEVM(BlockContext{}, TxContext{}, nil, nil, params.TestChainConfig, Config{})
|
evm := NewEVM(BlockContext{}, nil, nil, params.TestChainConfig, Config{})
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
inputHex string
|
inputHex string
|
||||||
|
|
|
||||||
|
|
@ -39,5 +39,7 @@ func NewEnv(cfg *Config) *vm.EVM {
|
||||||
Random: cfg.Random,
|
Random: cfg.Random,
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.NewEVM(blockContext, txContext, cfg.State, nil, cfg.ChainConfig, cfg.EVMConfig)
|
evm := vm.NewEVM(blockContext, cfg.State, nil, cfg.ChainConfig, cfg.EVMConfig)
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
|
return evm
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||||
"github.com/XinFinOrg/XDPoSChain/contracts"
|
"github.com/XinFinOrg/XDPoSChain/contracts"
|
||||||
|
|
@ -40,7 +39,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/bloombits"
|
"github.com/XinFinOrg/XDPoSChain/core/bloombits"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/tracing"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/txpool"
|
"github.com/XinFinOrg/XDPoSChain/core/txpool"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||||
|
|
@ -264,20 +262,18 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(hash)
|
return b.eth.blockchain.GetTdByHash(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error, error) {
|
func (b *EthAPIBackend) GetEVM(ctx context.Context, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error, error) {
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
if vmConfig == nil {
|
if vmConfig == nil {
|
||||||
vmConfig = b.eth.blockchain.GetVMConfig()
|
vmConfig = b.eth.blockchain.GetVMConfig()
|
||||||
}
|
}
|
||||||
state.SetBalance(msg.From, math.MaxBig256, tracing.BalanceChangeUnspecified)
|
|
||||||
txContext := core.NewEVMTxContext(msg)
|
|
||||||
var context vm.BlockContext
|
var context vm.BlockContext
|
||||||
if blockCtx != nil {
|
if blockCtx != nil {
|
||||||
context = *blockCtx
|
context = *blockCtx
|
||||||
} else {
|
} else {
|
||||||
context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
||||||
}
|
}
|
||||||
return vm.NewEVM(context, txContext, state, XDCxState, b.eth.chainConfig, *vmConfig), vmError, nil
|
return vm.NewEVM(context, state, XDCxState, b.eth.chainConfig, *vmConfig), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,8 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio
|
||||||
if msgContext.GasPrice.Sign() == 0 {
|
if msgContext.GasPrice.Sign() == 0 {
|
||||||
evmContext.BaseFee = new(big.Int)
|
evmContext.BaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(evmContext, msgContext, dirtyState, nil, opts.Config, vm.Config{NoBaseFee: true})
|
evm := vm.NewEVM(evmContext, dirtyState, nil, opts.Config, vm.Config{NoBaseFee: true})
|
||||||
|
evm.SetTxContext(msgContext)
|
||||||
// Monitor the outer context and interrupt the EVM upon cancellation. To avoid
|
// Monitor the outer context and interrupt the EVM upon cancellation. To avoid
|
||||||
// a dangling goroutine until the outer estimation finishes, create an internal
|
// a dangling goroutine until the outer estimation finishes, create an internal
|
||||||
// context for the lifetime of this method call.
|
// context for the lifetime of this method call.
|
||||||
|
|
|
||||||
|
|
@ -206,11 +206,11 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, err
|
return nil, vm.BlockContext{}, nil, nil, err
|
||||||
}
|
}
|
||||||
|
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||||
|
evm := vm.NewEVM(context, statedb, nil, eth.blockchain.Config(), vm.Config{})
|
||||||
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
||||||
if eth.blockchain.Config().IsPrague(block.Number()) {
|
if eth.blockchain.Config().IsPrague(block.Number()) {
|
||||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
core.ProcessParentBlockHash(block.ParentHash(), evm, statedb)
|
||||||
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, nil, eth.blockchain.Config(), vm.Config{})
|
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb)
|
|
||||||
}
|
}
|
||||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||||
return nil, vm.BlockContext{}, statedb, release, nil
|
return nil, vm.BlockContext{}, statedb, release, nil
|
||||||
|
|
@ -219,6 +219,9 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
|
signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
|
||||||
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
|
if idx == txIndex {
|
||||||
|
return tx, context, statedb, release, nil
|
||||||
|
}
|
||||||
var balance *big.Int
|
var balance *big.Int
|
||||||
if tx.To() != nil {
|
if tx.To() != nil {
|
||||||
if value, ok := feeCapacity[*tx.To()]; ok {
|
if value, ok := feeCapacity[*tx.To()]; ok {
|
||||||
|
|
@ -228,19 +231,16 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
// Assemble the transaction call message and return if the requested offset
|
// Assemble the transaction call message and return if the requested offset
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
|
||||||
txContext := core.NewEVMTxContext(msg)
|
txContext := core.NewEVMTxContext(msg)
|
||||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
evm.SetTxContext(txContext)
|
||||||
if idx == txIndex {
|
|
||||||
return tx, context, statedb, release, nil
|
|
||||||
}
|
|
||||||
// Not yet the searched for transaction, execute on top of the current state
|
// Not yet the searched for transaction, execute on top of the current state
|
||||||
vmenv := vm.NewEVM(context, txContext, statedb, nil, eth.blockchain.Config(), vm.Config{})
|
|
||||||
statedb.SetTxContext(tx.Hash(), idx)
|
statedb.SetTxContext(tx.Hash(), idx)
|
||||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{}); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{}); err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
// Ensure any modifications are committed to the state
|
// Ensure any modifications are committed to the state
|
||||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||||
}
|
}
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -382,8 +382,8 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
// Insert parent hash in history contract.
|
// Insert parent hash in history contract.
|
||||||
if api.backend.ChainConfig().IsPrague(next.Number()) {
|
if api.backend.ChainConfig().IsPrague(next.Number()) {
|
||||||
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
|
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
|
||||||
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
evm := vm.NewEVM(context, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
||||||
core.ProcessParentBlockHash(next.ParentHash(), vmenv, statedb)
|
core.ProcessParentBlockHash(next.ParentHash(), evm, statedb)
|
||||||
}
|
}
|
||||||
// Clean out any pending release functions of trace state. Note this
|
// Clean out any pending release functions of trace state. Note this
|
||||||
// step must be done after constructing tracing state, because the
|
// step must be done after constructing tracing state, because the
|
||||||
|
|
@ -519,8 +519,9 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||||
)
|
)
|
||||||
|
evm := vm.NewEVM(vmctx, statedb, nil, chainConfig, vm.Config{})
|
||||||
if chainConfig.IsPrague(block.Number()) {
|
if chainConfig.IsPrague(block.Number()) {
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), vm.NewEVM(vmctx, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{}), statedb)
|
core.ProcessParentBlockHash(block.ParentHash(), evm, statedb)
|
||||||
}
|
}
|
||||||
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
|
|
@ -540,10 +541,10 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
var (
|
var (
|
||||||
msg, _ = core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
|
msg, _ = core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
|
||||||
txContext = core.NewEVMTxContext(msg)
|
txContext = core.NewEVMTxContext(msg)
|
||||||
vmenv = vm.NewEVM(vmctx, txContext, statedb, nil, chainConfig, vm.Config{})
|
|
||||||
)
|
)
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{}); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{}); err != nil {
|
||||||
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
|
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
|
||||||
// We intentionally don't return the error here: if we do, then the RPC server will not
|
// We intentionally don't return the error here: if we do, then the RPC server will not
|
||||||
// return the roots. Most likely, the caller already knows that a certain transaction fails to
|
// return the roots. Most likely, the caller already knows that a certain transaction fails to
|
||||||
|
|
@ -587,9 +588,9 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
|
evm := vm.NewEVM(blockCtx, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
||||||
if api.backend.ChainConfig().IsPrague(block.Number()) {
|
if api.backend.ChainConfig().IsPrague(block.Number()) {
|
||||||
vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
core.ProcessParentBlockHash(block.ParentHash(), evm, statedb)
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS tracers have high overhead. In this case run a parallel
|
// JS tracers have high overhead. In this case run a parallel
|
||||||
|
|
@ -692,6 +693,8 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
||||||
var failed error
|
var failed error
|
||||||
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
|
evm := vm.NewEVM(blockCtx, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
||||||
|
|
||||||
txloop:
|
txloop:
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
// Send the trace task over for execution
|
// Send the trace task over for execution
|
||||||
|
|
@ -717,14 +720,14 @@ txloop:
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, balance, header.Number, header.BaseFee)
|
msg, _ := core.TransactionToMessage(tx, signer, balance, header.Number, header.BaseFee)
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{}); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{}); err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break txloop
|
break txloop
|
||||||
}
|
}
|
||||||
// Finalize the state so any modifications are written to the trie
|
// Finalize the state so any modifications are written to the trie
|
||||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||||
}
|
}
|
||||||
|
|
||||||
close(jobs)
|
close(jobs)
|
||||||
|
|
@ -894,7 +897,8 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The actual TxContext will be created as part of ApplyTransactionWithEVM.
|
// The actual TxContext will be created as part of ApplyTransactionWithEVM.
|
||||||
vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice}, statedb, nil, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true})
|
evm := vm.NewEVM(vmctx, statedb, nil, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true})
|
||||||
|
evm.SetTxContext(vm.TxContext{GasPrice: message.GasPrice})
|
||||||
|
|
||||||
// Define a meaningful timeout of a single transaction trace
|
// Define a meaningful timeout of a single transaction trace
|
||||||
if config.Timeout != nil {
|
if config.Timeout != nil {
|
||||||
|
|
@ -908,7 +912,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
|
||||||
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
|
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
|
||||||
tracer.Stop(errors.New("execution timeout"))
|
tracer.Stop(errors.New("execution timeout"))
|
||||||
// Stop evm execution. Note cancellation is not necessarily immediate.
|
// Stop evm execution. Note cancellation is not necessarily immediate.
|
||||||
vmenv.Cancel()
|
evm.Cancel()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
@ -923,7 +927,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
|
||||||
|
|
||||||
// Call SetTxContext to clear out the statedb access list
|
// Call SetTxContext to clear out the statedb access list
|
||||||
statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
|
statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
|
||||||
_, _, _, err = core.ApplyTransactionWithEVM(message, api.backend.ChainConfig(), new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, vmenv, balance, common.Address{})
|
_, _, _, err = core.ApplyTransactionWithEVM(message, api.backend.ChainConfig(), new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, evm, balance, common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("tracing failed: %w", err)
|
return nil, fmt.Errorf("tracing failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,18 +174,19 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
||||||
}
|
}
|
||||||
// Recompute transactions up to the target index.
|
// Recompute transactions up to the target index.
|
||||||
signer := types.MakeSigner(b.chainConfig, block.Number())
|
signer := types.MakeSigner(b.chainConfig, block.Number())
|
||||||
|
context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
|
||||||
|
evm := vm.NewEVM(context, statedb, nil, b.chainConfig, vm.Config{})
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, nil, block.Number(), block.BaseFee())
|
|
||||||
txContext := core.NewEVMTxContext(msg)
|
|
||||||
context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
|
|
||||||
if idx == txIndex {
|
if idx == txIndex {
|
||||||
return tx, context, statedb, release, nil
|
return tx, context, statedb, release, nil
|
||||||
}
|
}
|
||||||
vmenv := vm.NewEVM(context, txContext, statedb, nil, b.chainConfig, vm.Config{})
|
msg, _ := core.TransactionToMessage(tx, signer, nil, block.Number(), block.BaseFee())
|
||||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{}); err != nil {
|
txContext := core.NewEVMTxContext(msg)
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{}); err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||||
}
|
}
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,8 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), logState, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(context, logState, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -228,13 +229,17 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
||||||
state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
|
state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
evm := vm.NewEVM(context, state, nil, test.Genesis.Config, vm.Config{})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
|
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
|
snap := state.Snapshot()
|
||||||
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to create call tracer: %v", err)
|
b.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, txContext, state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
evm.Config.Tracer = tracer.Hooks
|
||||||
snap := state.Snapshot()
|
|
||||||
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if _, err = st.TransitionDb(common.Address{}); err != nil {
|
if _, err = st.TransitionDb(common.Address{}); err != nil {
|
||||||
b.Fatalf("failed to execute transaction: %v", err)
|
b.Fatalf("failed to execute transaction: %v", err)
|
||||||
|
|
@ -379,7 +384,8 @@ func TestInternals(t *testing.T) {
|
||||||
Origin: origin,
|
Origin: origin,
|
||||||
GasPrice: tx.GasPrice(),
|
GasPrice: tx.GasPrice(),
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, txContext, logState, nil, config, vm.Config{Tracer: tc.tracer.Hooks})
|
evm := vm.NewEVM(context, logState, nil, config, vm.Config{Tracer: tc.tracer.Hooks})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
msg, err := core.TransactionToMessage(tx, signer, nil, nil, big.NewInt(0))
|
msg, err := core.TransactionToMessage(tx, signer, nil, nil, big.NewInt(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %v: failed to create message: %v", tc.name, err)
|
t.Fatalf("test %v: failed to create message: %v", tc.name, err)
|
||||||
|
|
@ -459,7 +465,8 @@ func testContractTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, txContext, state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(context, state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
|
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,8 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(context, state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,8 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(context, state, nil, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()), common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,13 @@ func testCtx() *vmContext {
|
||||||
|
|
||||||
func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
|
func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
|
||||||
var (
|
var (
|
||||||
evm = vm.NewEVM(vmctx.ctx, vmctx.txContext, &dummyStatedb{}, nil, chaincfg, vm.Config{Tracer: tracer.Hooks})
|
evm = vm.NewEVM(vmctx.ctx, &dummyStatedb{}, nil, chaincfg, vm.Config{Tracer: tracer.Hooks})
|
||||||
gasLimit uint64 = 31000
|
gasLimit uint64 = 31000
|
||||||
startGas uint64 = 10000
|
startGas uint64 = 10000
|
||||||
value = new(uint256.Int)
|
value = new(uint256.Int)
|
||||||
contract = vm.NewContract(common.Address{}, common.Address{}, value, startGas, nil)
|
contract = vm.NewContract(common.Address{}, common.Address{}, value, startGas, nil)
|
||||||
)
|
)
|
||||||
|
evm.SetTxContext(vmctx.txContext)
|
||||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
||||||
if contractCode != nil {
|
if contractCode != nil {
|
||||||
contract.Code = contractCode
|
contract.Code = contractCode
|
||||||
|
|
@ -178,8 +179,9 @@ func TestHaltBetweenSteps(t *testing.T) {
|
||||||
scope := &vm.ScopeContext{
|
scope := &vm.ScopeContext{
|
||||||
Contract: vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 0, nil),
|
Contract: vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 0, nil),
|
||||||
}
|
}
|
||||||
env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
||||||
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(1)})
|
||||||
|
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
||||||
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 0, big.NewInt(0))
|
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 0, big.NewInt(0))
|
||||||
tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil)
|
tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil)
|
||||||
timeout := errors.New("stahp")
|
timeout := errors.New("stahp")
|
||||||
|
|
@ -201,8 +203,9 @@ func TestNoStepExec(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
||||||
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(100)})
|
||||||
|
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
||||||
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 1000, big.NewInt(0))
|
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 1000, big.NewInt(0))
|
||||||
tracer.OnExit(0, nil, 0, nil, false)
|
tracer.OnExit(0, nil, 0, nil, false)
|
||||||
ret, err := tracer.GetResult()
|
ret, err := tracer.GetResult()
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func (*dummyStatedb) SetState(_ common.Address, _ common.Hash, _ common.Hash) co
|
||||||
func TestStoreCapture(t *testing.T) {
|
func TestStoreCapture(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
logger = NewStructLogger(nil)
|
logger = NewStructLogger(nil)
|
||||||
evm = vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, &dummyStatedb{}, nil, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()})
|
evm = vm.NewEVM(vm.BlockContext{}, &dummyStatedb{}, nil, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()})
|
||||||
contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 100000, nil)
|
contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 100000, nil)
|
||||||
)
|
)
|
||||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
|
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,8 @@ func BenchmarkTransactionTrace(b *testing.B) {
|
||||||
//EnableMemory: false,
|
//EnableMemory: false,
|
||||||
//EnableReturnData: false,
|
//EnableReturnData: false,
|
||||||
})
|
})
|
||||||
evm := vm.NewEVM(context, txContext, state, nil, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer.Hooks()})
|
evm := vm.NewEVM(context, state, nil, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer.Hooks()})
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
msg, err := core.TransactionToMessage(tx, signer, nil, nil, context.BaseFee)
|
msg, err := core.TransactionToMessage(tx, signer, nil, nil, context.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -1274,7 +1274,8 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s
|
||||||
if msg.GasPrice.Sign() == 0 {
|
if msg.GasPrice.Sign() == 0 {
|
||||||
blockContext.BaseFee = new(big.Int)
|
blockContext.BaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
evm, vmError, err := b.GetEVM(ctx, msg, state, XDCxState, header, vmConfig, blockContext)
|
state.SetBalance(msg.From, math.MaxBig256, tracing.BalanceChangeUnspecified)
|
||||||
|
evm, vmError, err := b.GetEVM(ctx, state, XDCxState, header, vmConfig, blockContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1284,7 +1285,7 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s
|
||||||
if precompiles != nil {
|
if precompiles != nil {
|
||||||
evm.SetPrecompiles(precompiles)
|
evm.SetPrecompiles(precompiles)
|
||||||
}
|
}
|
||||||
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
res, err := applyMessageWithEVM(ctx, evm, msg, timeout, gp)
|
res, err := applyMessageWithEVM(ctx, evm, msg, timeout, gp)
|
||||||
// If an internal state error occurred, let that have precedence. Otherwise,
|
// If an internal state error occurred, let that have precedence. Otherwise,
|
||||||
// a "trie root missing" type of error will masquerade as e.g. "insufficient gas"
|
// a "trie root missing" type of error will masquerade as e.g. "insufficient gas"
|
||||||
|
|
@ -1888,16 +1889,18 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
||||||
// Apply the transaction with the access list tracer
|
// Apply the transaction with the access list tracer
|
||||||
tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles)
|
tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles)
|
||||||
config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}
|
config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}
|
||||||
vmenv, _, err := b.GetEVM(ctx, msg, statedb, XDCxState, header, &config, nil)
|
statedb.SetBalance(msg.From, math.MaxBig256, tracing.BalanceChangeUnspecified)
|
||||||
|
evm, _, err := b.GetEVM(ctx, statedb, XDCxState, header, &config, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, err
|
return nil, 0, nil, err
|
||||||
}
|
}
|
||||||
// Lower the basefee to 0 to avoid breaking EVM
|
// Lower the basefee to 0 to avoid breaking EVM
|
||||||
// invariants (basefee < feecap).
|
// invariants (basefee < feecap).
|
||||||
if msg.GasPrice.Sign() == 0 {
|
if msg.GasPrice.Sign() == 0 {
|
||||||
vmenv.Context.BaseFee = new(big.Int)
|
evm.Context.BaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{})
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
|
res, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit), common.Address{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction(types.LegacyTxType).Hash(), err)
|
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction(types.LegacyTxType).Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ type Backend interface {
|
||||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||||
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
||||||
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
||||||
GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error, error)
|
GetEVM(ctx context.Context, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error, error)
|
||||||
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
|
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
|
||||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||||
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
|
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
|
||||||
|
|
|
||||||
|
|
@ -175,12 +175,12 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
NoBaseFee: !sim.validate,
|
NoBaseFee: !sim.validate,
|
||||||
Tracer: tracer.Hooks(),
|
Tracer: tracer.Hooks(),
|
||||||
}
|
}
|
||||||
evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, sim.state, nil, sim.chainConfig, *vmConfig)
|
|
||||||
)
|
)
|
||||||
var tracingStateDB = vm.StateDB(sim.state)
|
var tracingStateDB = vm.StateDB(sim.state)
|
||||||
if hooks := tracer.Hooks(); hooks != nil {
|
if hooks := tracer.Hooks(); hooks != nil {
|
||||||
tracingStateDB = state.NewHookedState(sim.state, hooks)
|
tracingStateDB = state.NewHookedState(sim.state, hooks)
|
||||||
}
|
}
|
||||||
|
evm := vm.NewEVM(blockContext, tracingStateDB, nil, sim.chainConfig, *vmConfig)
|
||||||
// It is possible to override precompiles with EVM bytecode, or
|
// It is possible to override precompiles with EVM bytecode, or
|
||||||
// move them to another address.
|
// move them to another address.
|
||||||
if precompiles != nil {
|
if precompiles != nil {
|
||||||
|
|
@ -198,7 +198,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
tracer.reset(tx.Hash(), uint(i))
|
tracer.reset(tx.Hash(), uint(i))
|
||||||
// EoA check is always skipped, even in validation mode.
|
// EoA check is always skipped, even in validation mode.
|
||||||
msg := call.ToMessage(sim.b, header.BaseFee, !sim.validate, true)
|
msg := call.ToMessage(sim.b, header.BaseFee, !sim.validate, true)
|
||||||
evm.Reset(core.NewEVMTxContext(msg), tracingStateDB)
|
evm.SetTxContext(core.NewEVMTxContext(msg))
|
||||||
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
txErr := txValidationError(err)
|
txErr := txValidationError(err)
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backendMock) GetEVM(context.Context, *core.Message, *state.StateDB, *tradingstate.TradingStateDB, *types.Header, *vm.Config, *vm.BlockContext) (*vm.EVM, func() error, error) {
|
func (b *backendMock) GetEVM(context.Context, *state.StateDB, *tradingstate.TradingStateDB, *types.Header, *vm.Config, *vm.BlockContext) (*vm.EVM, func() error, error) {
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,14 +86,15 @@ type Agent interface {
|
||||||
type Work struct {
|
type Work struct {
|
||||||
config *params.ChainConfig
|
config *params.ChainConfig
|
||||||
signer types.Signer
|
signer types.Signer
|
||||||
|
state *state.StateDB // apply state changes here
|
||||||
|
tcount int // tx count in cycle
|
||||||
|
evm *vm.EVM
|
||||||
|
|
||||||
state *state.StateDB // apply state changes here
|
|
||||||
parentState *state.StateDB
|
parentState *state.StateDB
|
||||||
tradingState *tradingstate.TradingStateDB
|
tradingState *tradingstate.TradingStateDB
|
||||||
lendingState *lendingstate.LendingStateDB
|
lendingState *lendingstate.LendingStateDB
|
||||||
ancestors mapset.Set[common.Hash] // ancestor set (used for checking uncle parent validity)
|
ancestors mapset.Set[common.Hash] // ancestor set (used for checking uncle parent validity)
|
||||||
family mapset.Set[common.Hash] // family set (used for checking uncle invalidity)
|
family mapset.Set[common.Hash] // family set (used for checking uncle invalidity)
|
||||||
tcount int // tx count in cycle
|
|
||||||
|
|
||||||
Block *types.Block // the new block
|
Block *types.Block // the new block
|
||||||
|
|
||||||
|
|
@ -636,6 +637,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
|
||||||
ancestors: mapset.NewSet[common.Hash](),
|
ancestors: mapset.NewSet[common.Hash](),
|
||||||
family: mapset.NewSet[common.Hash](),
|
family: mapset.NewSet[common.Hash](),
|
||||||
header: header,
|
header: header,
|
||||||
|
evm: vm.NewEVM(core.NewEVMBlockContext(header, w.chain, &header.Coinbase), state, XDCxState, w.config, vm.Config{}),
|
||||||
uncles: make(map[common.Hash]*types.Header),
|
uncles: make(map[common.Hash]*types.Header),
|
||||||
createdAt: time.Now(),
|
createdAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
@ -788,9 +790,7 @@ func (w *worker) commitNewWork() {
|
||||||
work.state.DeleteAddress(common.BlockSignersBinary)
|
work.state.DeleteAddress(common.BlockSignersBinary)
|
||||||
}
|
}
|
||||||
if w.config.IsPrague(header.Number) {
|
if w.config.IsPrague(header.Number) {
|
||||||
context := core.NewEVMBlockContext(header, w.chain, nil)
|
core.ProcessParentBlockHash(header.ParentHash, work.evm, work.state)
|
||||||
vmenv := vm.NewEVM(context, vm.TxContext{}, w.current.state, nil, w.config, vm.Config{})
|
|
||||||
core.ProcessParentBlockHash(header.ParentHash, vmenv, w.current.state)
|
|
||||||
}
|
}
|
||||||
// won't grasp txs at checkpoint
|
// won't grasp txs at checkpoint
|
||||||
var (
|
var (
|
||||||
|
|
@ -1049,7 +1049,7 @@ func (w *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Addr
|
||||||
log.Trace("Skipping account with special transaction invalid nonce", "sender", from, "nonce", nonce, "tx nonce ", tx.Nonce(), "to", to)
|
log.Trace("Skipping account with special transaction invalid nonce", "sender", from, "nonce", nonce, "tx nonce ", tx.Nonce(), "to", to)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logs, tokenFeeUsed, gas, err := w.commitTransaction(balanceFee, tx, bc, coinbase, gp)
|
logs, tokenFeeUsed, gas, err := w.commitTransaction(balanceFee, tx, gp)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, core.ErrNonceTooLow):
|
case errors.Is(err, core.ErrNonceTooLow):
|
||||||
// New head notification data race between the transaction pool and miner, shift
|
// New head notification data race between the transaction pool and miner, shift
|
||||||
|
|
@ -1159,7 +1159,7 @@ func (w *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Addr
|
||||||
txs.Pop()
|
txs.Pop()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logs, tokenFeeUsed, gas, err := w.commitTransaction(balanceFee, tx, bc, coinbase, gp)
|
logs, tokenFeeUsed, gas, err := w.commitTransaction(balanceFee, tx, gp)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, core.ErrGasLimitReached):
|
case errors.Is(err, core.ErrGasLimitReached):
|
||||||
// Pop the current out-of-gas transaction without shifting in the next from the account
|
// Pop the current out-of-gas transaction without shifting in the next from the account
|
||||||
|
|
@ -1222,10 +1222,10 @@ func (w *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Work) commitTransaction(balanceFee map[common.Address]*big.Int, tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) ([]*types.Log, bool, uint64, error) {
|
func (w *Work) commitTransaction(balanceFee map[common.Address]*big.Int, tx *types.Transaction, gp *core.GasPool) ([]*types.Log, bool, uint64, error) {
|
||||||
snap := w.state.Snapshot()
|
snap := w.state.Snapshot()
|
||||||
|
|
||||||
receipt, gas, tokenFeeUsed, err := core.ApplyTransaction(w.config, balanceFee, bc, &coinbase, gp, w.state, w.tradingState, w.header, tx, &w.header.GasUsed, vm.Config{})
|
receipt, gas, tokenFeeUsed, err := core.ApplyTransaction(w.config, balanceFee, w.evm, gp, w.state, w.header, tx, &w.header.GasUsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.state.RevertToSnapshot(snap)
|
w.state.RevertToSnapshot(snap)
|
||||||
return nil, false, 0, err
|
return nil, false, 0, err
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,8 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
||||||
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
|
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
|
||||||
context.GetHash = vmTestBlockHash
|
context.GetHash = vmTestBlockHash
|
||||||
context.BaseFee = baseFee
|
context.BaseFee = baseFee
|
||||||
evm := vm.NewEVM(context, txContext, statedb, nil, config, vmconfig)
|
evm := vm.NewEVM(context, statedb, nil, config, vmconfig)
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
|
|
||||||
// Execute the message.
|
// Execute the message.
|
||||||
snapshot := statedb.Snapshot()
|
snapshot := statedb.Snapshot()
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,9 @@ func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
|
||||||
GasLimit: t.json.Env.GasLimit,
|
GasLimit: t.json.Env.GasLimit,
|
||||||
Difficulty: t.json.Env.Difficulty,
|
Difficulty: t.json.Env.Difficulty,
|
||||||
}
|
}
|
||||||
return vm.NewEVM(context, txContext, statedb, nil, params.MainnetChainConfig, vmconfig)
|
evm := vm.NewEVM(context, statedb, nil, params.MainnetChainConfig, vmconfig)
|
||||||
|
evm.SetTxContext(txContext)
|
||||||
|
return evm
|
||||||
}
|
}
|
||||||
|
|
||||||
func vmTestBlockHash(n uint64) common.Hash {
|
func vmTestBlockHash(n uint64) common.Hash {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue