core/types: remove message #25977 (#1322)

This commit is contained in:
Daniel Liu 2025-09-09 11:23:47 +08:00 committed by GitHub
parent 19f5417121
commit be61f66cb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 275 additions and 339 deletions

View file

@ -30,8 +30,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/XDCx"
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
"github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/node"
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
@ -52,6 +50,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/event"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/node"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/rpc"
)
@ -735,18 +734,33 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
if call.Value == nil {
call.Value = new(big.Int)
}
// Set infinite balance to the fake caller account.
from := stateDB.GetOrNewStateObject(call.From)
from.SetBalance(math.MaxBig256)
// Execute the call.
msg := callMsg{call}
msg := &core.Message{
From: call.From,
To: call.To,
Value: call.Value,
GasLimit: call.Gas,
GasPrice: call.GasPrice,
GasFeeCap: call.GasFeeCap,
GasTipCap: call.GasTipCap,
Data: call.Data,
AccessList: call.AccessList,
SkipAccountChecks: true,
}
feeCapacity := state.GetTRC21FeeCapacityFromState(stateDB)
if msg.To() != nil {
if value, ok := feeCapacity[*msg.To()]; ok {
msg.CallMsg.BalanceTokenFee = value
if msg.To != nil {
if value, ok := feeCapacity[*msg.To]; ok {
msg.BalanceTokenFee = value
}
}
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
txContext := core.NewEVMTxContext(msg)
evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
// Create a new environment which holds all relevant information
@ -920,24 +934,6 @@ func (b *SimulatedBackend) BlockChain() *core.BlockChain {
return b.blockchain
}
// callMsg implements core.Message to allow passing it as a transaction simulator.
type callMsg struct {
ethereum.CallMsg
}
func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) BalanceTokenFee() *big.Int { return m.CallMsg.BalanceTokenFee }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
type filterBackend struct {

View file

@ -69,10 +69,10 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
}
// NewEVMTxContext creates a new transaction context for a single transaction.
func NewEVMTxContext(msg Message) vm.TxContext {
func NewEVMTxContext(msg *Message) vm.TxContext {
return vm.TxContext{
Origin: msg.From(),
GasPrice: new(big.Int).Set(msg.GasPrice()),
Origin: msg.From,
GasPrice: new(big.Int).Set(msg.GasPrice),
}
}

View file

@ -64,7 +64,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
return
}
// Convert the transaction into an executable message and pre-cache its sender
msg, err := tx.AsMessage(signer, nil, nil, header.BaseFee)
msg, err := TransactionToMessage(tx, signer, nil, nil, header.BaseFee)
if err != nil {
return // Also invalid block, bail out
}
@ -86,7 +86,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
// 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
// the transaction successfully, rather to warm up touched data slots.
func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
func precacheTransaction(msg *Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
// Update the evm with the new transaction context.
evm.Reset(NewEVMTxContext(msg), statedb)
// Add addresses to access list if applicable

View file

@ -246,8 +246,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
balanceFee = value
}
}
// msg, err := tx.AsMessage(types.MakeSigner(config, blockNumber), balanceFee, blockNumber)
msg, err := tx.AsMessage(types.MakeSigner(config, blockNumber), balanceFee, blockNumber, baseFee)
msg, err := TransactionToMessage(tx, types.MakeSigner(config, blockNumber), balanceFee, blockNumber, baseFee)
if err != nil {
return nil, 0, err, false
}
@ -386,7 +385,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
blockMap[9147453] = "0x3538a544021c07869c16b764424c5987409cba48"
blockMap[9147459] = "0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"
addrFrom := msg.From().Hex()
addrFrom := msg.From.Hex()
currentBlockNumber := blockNumber.Int64()
if addr, ok := blockMap[currentBlockNumber]; ok {
@ -430,7 +429,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
receipt.GasUsed = result.UsedGas
// If the transaction created a contract, store the creation address in the receipt.
if msg.To() == nil {
if msg.To == nil {
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
}
@ -441,7 +440,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
receipt.BlockNumber = blockNumber
receipt.TransactionIndex = uint(statedb.TxIndex())
if balanceFee != nil && result.Failed() {
state.PayFeeWithTRC21TxFail(statedb, msg.From(), *to)
state.PayFeeWithTRC21TxFail(statedb, msg.From, *to)
}
return receipt, result.UsedGas, err, balanceFee != nil
}
@ -466,7 +465,6 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
blockContext := NewEVMBlockContext(header, bc, author)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, XDCxState, config, cfg)
coinbaseOwner := getCoinbaseOwner(bc, statedb, header, author)
// return applyTransaction(config, tokensFee, gp, statedb, coinbaseOwner, header.Number, header.BaseFee, header.Hash(), tx, usedGas, vmenv)
return applyTransaction(config, tokensFee, gp, statedb, coinbaseOwner, header.Number, header.BaseFee, header.Hash(), tx, usedGas, vmenv)
}

View file

@ -24,64 +24,10 @@ import (
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/holiman/uint256"
)
var emptyCodeHash = crypto.Keccak256Hash(nil)
/*
The State Transitioning Model
A state transition is a change made when a transaction is applied to the current world state
The state transitioning model does all all the necessary work to work out a valid new state root.
1) Nonce handling
2) Pre pay gas
3) Create a new state object if the recipient is \0*32
4) Value transfer
== If contract creation ==
4a) Attempt to run transaction data
4b) If valid, use result as code for the new state object
== end ==
5) Run Script section
6) Derive new state root
*/
type StateTransition struct {
gp *GasPool
msg Message
gas uint64
gasPrice *big.Int
gasFeeCap *big.Int
gasTipCap *big.Int
initialGas uint64
value *big.Int
data []byte
state vm.StateDB
evm *vm.EVM
}
// Message represents a message sent to a contract.
type Message interface {
From() common.Address
To() *common.Address
GasPrice() *big.Int
GasFeeCap() *big.Int
GasTipCap() *big.Int
Gas() uint64
Value() *big.Int
Nonce() uint64
IsFake() bool
Data() []byte
BalanceTokenFee() *big.Int
AccessList() types.AccessList
}
// ExecutionResult includes all output after executing given evm
// message no matter the execution itself is successful or not.
type ExecutionResult struct {
@ -166,19 +112,64 @@ func toWordSize(size uint64) uint64 {
return (size + 31) / 32
}
// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
return &StateTransition{
gp: gp,
evm: evm,
msg: msg,
gasPrice: msg.GasPrice(),
gasFeeCap: msg.GasFeeCap(),
gasTipCap: msg.GasTipCap(),
value: msg.Value(),
data: msg.Data(),
state: evm.StateDB,
// A Message contains the data derived from a single transaction that is relevant to state
// processing.
type Message struct {
To *common.Address
From common.Address
Nonce uint64
Value *big.Int
GasLimit uint64
GasPrice *big.Int
GasFeeCap *big.Int
GasTipCap *big.Int
BalanceTokenFee *big.Int
Data []byte
AccessList types.AccessList
// When SkipAccountCheckss is true, the message nonce is not checked against the
// account nonce in state. It also disables checking that the sender is an EOA.
// This field will be set to true for operations like RPC eth_call.
SkipAccountChecks bool
}
// TransactionToMessage converts a transaction into a Message.
func TransactionToMessage(tx *types.Transaction, s types.Signer, balanceFee, blockNumber, baseFee *big.Int) (*Message, error) {
msg := &Message{
Nonce: tx.Nonce(),
GasLimit: tx.Gas(),
GasPrice: new(big.Int).Set(tx.GasPrice()),
GasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
GasTipCap: new(big.Int).Set(tx.GasTipCap()),
To: tx.To(),
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
SkipAccountChecks: false,
BalanceTokenFee: balanceFee,
}
if balanceFee != nil {
if blockNumber != nil {
if blockNumber.Cmp(common.BlockNumberGas50x) >= 0 {
msg.GasPrice = new(big.Int).Set(common.GasPrice50x)
} else if blockNumber.Cmp(common.TIPTRC21Fee) > 0 {
msg.GasPrice = new(big.Int).Set(common.TRC21GasPrice)
} else {
msg.GasPrice = new(big.Int).Set(common.TRC21GasPriceBefore)
}
}
} else if baseFee != nil {
// If baseFee provided, set gasPrice to effectiveGasPrice.
msg.GasPrice = msg.GasPrice.Add(msg.GasTipCap, baseFee)
if msg.GasPrice.Cmp(msg.GasFeeCap) > 0 {
msg.GasPrice = msg.GasFeeCap
}
}
var err error
msg.From, err = types.Sender(s, tx)
return msg, err
}
// ApplyMessage computes the new state by applying the given message
@ -188,63 +179,97 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
// the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) (*ExecutionResult, error) {
func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool, owner common.Address) (*ExecutionResult, error) {
return NewStateTransition(evm, msg, gp).TransitionDb(owner)
}
func (st *StateTransition) from() vm.AccountRef {
f := st.msg.From()
// StateTransition represents a state transition.
//
// == The State Transitioning Model
//
// A state transition is a change made when a transaction is applied to the current world
// state. The state transitioning model does all the necessary work to work out a valid new
// state root.
//
// 1. Nonce handling
// 2. Pre pay gas
// 3. Create a new state object if the recipient is nil
// 4. Value transfer
//
// == If contract creation ==
//
// 4a. Attempt to run transaction data
// 4b. If valid, use result as code for the new state object
//
// == end ==
//
// 5. Run Script section
// 6. Derive new state root
type StateTransition struct {
gp *GasPool
msg *Message
gasRemaining uint64
initialGas uint64
state vm.StateDB
evm *vm.EVM
}
// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg *Message, gp *GasPool) *StateTransition {
return &StateTransition{
gp: gp,
evm: evm,
msg: msg,
state: evm.StateDB,
}
}
func (st *StateTransition) from() common.Address {
f := st.msg.From
if !st.state.Exist(f) {
st.state.CreateAccount(f)
}
return vm.AccountRef(f)
return f
}
func (st *StateTransition) balanceTokenFee() *big.Int {
return st.msg.BalanceTokenFee()
}
func (st *StateTransition) to() vm.AccountRef {
func (st *StateTransition) to() common.Address {
if st.msg == nil {
return vm.AccountRef{}
return common.Address{}
}
to := st.msg.To()
to := st.msg.To
if to == nil {
return vm.AccountRef{} // contract creation
return common.Address{} // contract creation
}
reference := vm.AccountRef(*to)
if !st.state.Exist(*to) {
st.state.CreateAccount(*to)
}
return reference
return *to
}
func (st *StateTransition) buyGas() error {
mgval := new(big.Int).SetUint64(st.msg.Gas())
mgval = mgval.Mul(mgval, st.gasPrice)
balanceTokenFee := st.balanceTokenFee()
if balanceTokenFee == nil {
mgval := new(big.Int).SetUint64(st.msg.GasLimit)
mgval = mgval.Mul(mgval, st.msg.GasPrice)
if st.msg.BalanceTokenFee == nil {
balanceCheck := mgval
if st.gasFeeCap != nil {
balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
balanceCheck.Add(balanceCheck, st.value)
if st.msg.GasFeeCap != nil {
balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit)
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
balanceCheck.Add(balanceCheck, st.msg.Value)
}
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
}
} else if balanceTokenFee.Cmp(mgval) < 0 {
} else if st.msg.BalanceTokenFee.Cmp(mgval) < 0 {
return ErrInsufficientFunds
}
if err := st.gp.SubGas(st.msg.Gas()); err != nil {
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
return err
}
st.gas += st.msg.Gas()
st.gasRemaining += st.msg.GasLimit
st.initialGas = st.msg.Gas()
if balanceTokenFee == nil {
st.state.SubBalance(st.msg.From(), mgval)
st.initialGas = st.msg.GasLimit
if st.msg.BalanceTokenFee == nil {
st.state.SubBalance(st.msg.From, mgval)
}
return nil
}
@ -252,48 +277,48 @@ func (st *StateTransition) buyGas() error {
func (st *StateTransition) preCheck() error {
// Only check transactions that are not fake
msg := st.msg
if !msg.IsFake() {
if !msg.SkipAccountChecks {
// Make sure this transaction's nonce is correct.
stNonce := st.state.GetNonce(msg.From())
if msgNonce := msg.Nonce(); stNonce < msgNonce {
stNonce := st.state.GetNonce(msg.From)
if msgNonce := msg.Nonce; stNonce < msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
msg.From().Hex(), msgNonce, stNonce)
msg.From.Hex(), msgNonce, stNonce)
} else if stNonce > msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
msg.From().Hex(), msgNonce, stNonce)
msg.From.Hex(), msgNonce, stNonce)
} else if stNonce+1 < stNonce {
return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
msg.From().Hex(), stNonce)
msg.From.Hex(), stNonce)
}
// Make sure the sender is an EOA
if codeHash := st.state.GetCodeHash(msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
if codeHash := st.state.GetCodeHash(msg.From); codeHash != types.EmptyCodeHash && codeHash != (common.Hash{}) {
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
msg.From().Hex(), codeHash)
msg.From.Hex(), codeHash)
}
}
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
if st.evm.ChainConfig().IsEIP1559(st.evm.Context.BlockNumber) {
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
skipCheck := st.evm.Config.NoBaseFee && st.gasFeeCap.BitLen() == 0 && st.gasTipCap.BitLen() == 0
skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0
if !skipCheck {
if l := st.gasFeeCap.BitLen(); l > 256 {
if l := msg.GasFeeCap.BitLen(); l > 256 {
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
msg.From().Hex(), l)
msg.From.Hex(), l)
}
if l := st.gasTipCap.BitLen(); l > 256 {
if l := msg.GasTipCap.BitLen(); l > 256 {
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
msg.From().Hex(), l)
msg.From.Hex(), l)
}
if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
if !types.IsSpecialTx(msg.To()) && st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
if !types.IsSpecialTx(msg.To) && msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
}
}
}
@ -332,44 +357,44 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult,
if tracer := st.evm.Config.Tracer; tracer != nil {
st.evm.Config.Tracer.CaptureTxStart(st.initialGas)
defer func() {
st.evm.Config.Tracer.CaptureTxEnd(st.gas)
st.evm.Config.Tracer.CaptureTxEnd(st.gasRemaining)
}()
}
var (
msg = st.msg
sender = st.from() // err checked in preCheck
sender = vm.AccountRef(st.from())
rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber)
contractCreation = msg.To() == nil
contractCreation = msg.To == nil
)
// Check clauses 4-5, subtract intrinsic gas if everything is correct
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsEIP1559)
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsEIP1559)
if err != nil {
return nil, err
}
if st.gas < gas {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
if st.gasRemaining < gas {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
}
st.gas -= gas
st.gasRemaining -= gas
// Check whether the init code size has been exceeded.
if rules.IsEIP1559 && contractCreation && len(st.data) > params.MaxInitCodeSize {
return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize)
if rules.IsEIP1559 && contractCreation && len(msg.Data) > params.MaxInitCodeSize {
return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize)
}
// Execute the preparatory steps for state transition which includes:
// - prepare accessList(post-berlin)
// - reset transient storage(eip 1153)
st.state.Prepare(rules, msg.From(), st.evm.Context.Coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
// Check clause 6
value, overflow := uint256.FromBig(msg.Value())
value, overflow := uint256.FromBig(msg.Value)
if overflow {
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex())
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
}
if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), value.ToBig()) {
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex())
if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From, value.ToBig()) {
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
}
var (
@ -377,11 +402,11 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult,
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
)
if contractCreation {
ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value)
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, msg.Value)
} else {
// Increment the nonce for the next transaction
st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1)
ret, st.gas, vmerr = st.evm.Call(sender, st.to().Address(), st.data, st.gas, st.value)
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, msg.Value)
}
if !rules.IsEIP1559 {
// Before EIP-3529: refunds were capped to gasUsed / 2
@ -393,14 +418,14 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult,
if st.evm.Context.BlockNumber.Cmp(common.TIPTRC21Fee) > 0 {
if (owner != common.Address{}) {
st.state.AddBalance(owner, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
st.state.AddBalance(owner, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), msg.GasPrice))
}
} else {
effectiveTip := st.gasPrice
effectiveTip := msg.GasPrice
if st.evm.ChainConfig().IsEIP1559(st.evm.Context.BlockNumber) {
effectiveTip = new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee)
if effectiveTip.Cmp(st.gasTipCap) > 0 {
effectiveTip = st.gasTipCap
effectiveTip = new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee)
if effectiveTip.Cmp(msg.GasTipCap) > 0 {
effectiveTip = msg.GasTipCap
}
}
st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip))
@ -419,21 +444,19 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
}
st.gas += refund
st.gasRemaining += refund
balanceTokenFee := st.balanceTokenFee()
if balanceTokenFee == nil {
from := st.from()
if st.msg.BalanceTokenFee == nil {
// Return ETH for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
st.state.AddBalance(from.Address(), remaining)
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gasRemaining), st.msg.GasPrice)
st.state.AddBalance(st.from(), remaining)
}
// Also return remaining gas to the block gas counter so it is
// available for the next transaction.
st.gp.AddGas(st.gas)
st.gp.AddGas(st.gasRemaining)
}
// gasUsed returns the amount of gas used up by the state transition.
func (st *StateTransition) gasUsed() uint64 {
return st.initialGas - st.gas
return st.initialGas - st.gasRemaining
}

View file

@ -27,7 +27,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
"github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/log"
)
@ -38,24 +37,6 @@ const (
getDecimalFunction = "decimals"
)
// callMsg implements core.Message to allow passing it as a transaction simulator.
type callMsg struct {
ethereum.CallMsg
}
func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) BalanceTokenFee() *big.Int { return m.CallMsg.BalanceTokenFee }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
type SimulatedBackend interface {
CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, statedb *state.StateDB) ([]byte, error)
}
@ -102,18 +83,31 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext,
if call.Value == nil {
call.Value = new(big.Int)
}
// Execute the call.
msg := callMsg{call}
msg := &Message{
From: call.From,
To: call.To,
Value: call.Value,
GasLimit: call.Gas,
GasPrice: call.GasPrice,
GasFeeCap: call.GasFeeCap,
GasTipCap: call.GasTipCap,
Data: call.Data,
AccessList: call.AccessList,
SkipAccountChecks: true,
}
feeCapacity := state.GetTRC21FeeCapacityFromState(statedb)
if msg.To() != nil {
if value, ok := feeCapacity[*msg.To()]; ok {
msg.CallMsg.BalanceTokenFee = value
if msg.To != nil {
if value, ok := feeCapacity[*msg.To]; ok {
msg.BalanceTokenFee = value
}
}
txContext := NewEVMTxContext(msg)
evmContext := NewEVMBlockContext(chain.CurrentHeader(), chain, nil)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
txContext := NewEVMTxContext(msg)
evmContext := NewEVMBlockContext(chain.CurrentHeader(), chain, nil)
vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, chain.Config(), vm.Config{})
gaspool := new(GasPool).AddGas(1000000)
owner := common.Address{}

View file

@ -424,45 +424,6 @@ func (tx *Transaction) EffectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.In
return tx.inner.effectiveGasPrice(dst, baseFee)
}
// AsMessage returns the transaction as a core.Message.
func (tx *Transaction) AsMessage(s Signer, balanceFee, blockNumber, baseFee *big.Int) (Message, error) {
msg := Message{
nonce: tx.Nonce(),
gasLimit: tx.Gas(),
gasPrice: new(big.Int).Set(tx.GasPrice()),
gasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
gasTipCap: new(big.Int).Set(tx.GasTipCap()),
to: tx.To(),
amount: tx.Value(),
data: tx.Data(),
accessList: tx.AccessList(),
isFake: false,
balanceTokenFee: balanceFee,
}
if balanceFee != nil {
if blockNumber != nil {
if blockNumber.Cmp(common.BlockNumberGas50x) >= 0 {
msg.gasPrice = common.GasPrice50x
} else if blockNumber.Cmp(common.TIPTRC21Fee) > 0 {
msg.gasPrice = common.TRC21GasPrice
} else {
msg.gasPrice = common.TRC21GasPriceBefore
}
}
} else if baseFee != nil {
// If baseFee provided, set gasPrice to effectiveGasPrice.
msg.gasPrice = msg.gasPrice.Add(msg.gasTipCap, baseFee)
if msg.gasPrice.Cmp(msg.gasFeeCap) > 0 {
msg.gasPrice.Set(msg.gasFeeCap)
}
}
var err error
msg.from, err = Sender(s, tx)
return msg, err
}
// WithSignature returns a new transaction with the given signature.
// This signature needs to be in the [R || S || V] format where V is 0 or 1.
func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) {
@ -818,68 +779,6 @@ func (t *TransactionsByPriceAndNonce) Pop() {
heap.Pop(&t.heads)
}
// Message is a fully derived transaction and implements core.Message
//
// NOTE: In a future PR this will be removed.
type Message struct {
to *common.Address
from common.Address
nonce uint64
amount *big.Int
gasLimit uint64
gasPrice *big.Int
gasFeeCap *big.Int
gasTipCap *big.Int
data []byte
accessList AccessList
isFake bool
balanceTokenFee *big.Int
}
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool, balanceTokenFee *big.Int, number *big.Int) Message {
if balanceTokenFee != nil {
gasPrice = common.GetGasPrice(number)
}
return Message{
from: from,
to: to,
nonce: nonce,
amount: amount,
gasLimit: gasLimit,
gasPrice: gasPrice,
gasFeeCap: gasFeeCap,
gasTipCap: gasTipCap,
data: data,
accessList: accessList,
isFake: isFake,
balanceTokenFee: balanceTokenFee,
}
}
func (m Message) From() common.Address { return m.from }
func (m Message) BalanceTokenFee() *big.Int { return m.balanceTokenFee }
func (m Message) To() *common.Address { return m.to }
func (m Message) GasPrice() *big.Int { return m.gasPrice }
func (m Message) GasFeeCap() *big.Int { return m.gasFeeCap }
func (m Message) GasTipCap() *big.Int { return m.gasTipCap }
func (m Message) Value() *big.Int { return m.amount }
func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
func (m Message) IsFake() bool { return m.isFake }
func (m Message) AccessList() AccessList { return m.accessList }
func (m *Message) SetNonce(nonce uint64) { m.nonce = nonce }
func (m *Message) SetBalanceTokenFeeForCall() {
m.balanceTokenFee = new(big.Int).SetUint64(m.gasLimit)
m.balanceTokenFee.Mul(m.balanceTokenFee, m.gasPrice)
}
func (m *Message) SetBalanceTokenFee(balanceTokenFee *big.Int) {
m.balanceTokenFee = balanceTokenFee
}
// copyAddressPtr copies an address.
func copyAddressPtr(a *common.Address) *common.Address {
if a == nil {

View file

@ -257,12 +257,12 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
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) (*vm.EVM, func() error, error) {
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
vmError := func() error { return nil }
if vmConfig == nil {
vmConfig = b.eth.blockchain.GetVMConfig()
}
state.SetBalance(msg.From(), math.MaxBig256)
state.SetBalance(msg.From, math.MaxBig256)
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
return vm.NewEVM(context, txContext, state, XDCxState, b.eth.chainConfig, *vmConfig), vmError, nil
@ -418,7 +418,7 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re
return b.eth.StateAtBlock(ctx, block, reexec, base, readOnly, preferDisk)
}
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
}

View file

@ -190,7 +190,7 @@ func (eth *Ethereum) StateAtBlock(ctx context.Context, block *types.Block, reexe
}
// stateAtTransaction returns the execution environment of a certain transaction.
func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
// Short circuit if it's genesis block.
if block.NumberU64() == 0 {
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
@ -220,7 +220,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
}
}
// Assemble the transaction call message and return if the requested offset
msg, _ := tx.AsMessage(signer, balance, block.Number(), block.BaseFee())
msg, _ := core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
if idx == txIndex {

View file

@ -88,7 +88,7 @@ type Backend interface {
Engine() consensus.Engine
ChainDb() ethdb.Database
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error)
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
}
// API is the collection of tracing APIs exposed over the private debugging endpoint.
@ -295,7 +295,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
}
}
header := task.block.Header()
msg, _ := tx.AsMessage(signer, balance, header.Number, header.BaseFee)
msg, _ := core.TransactionToMessage(tx, signer, balance, header.Number, header.BaseFee)
txctx := &Context{
BlockHash: task.block.Hash(),
BlockNumber: task.block.Number(),
@ -541,13 +541,13 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
}
}
var (
msg, _ = tx.AsMessage(signer, balance, block.Number(), block.BaseFee())
msg, _ = core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
txContext = core.NewEVMTxContext(msg)
vmenv = vm.NewEVM(vmctx, txContext, statedb, nil, chainConfig, vm.Config{})
)
statedb.SetTxContext(tx.Hash(), i)
owner := common.Address{}
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil {
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), owner); err != nil {
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
// return the roots. Most likely, the caller already knows that a certain transaction fails to
@ -619,7 +619,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
}
}
// Generate the next state snapshot fast without tracing
msg, _ := tx.AsMessage(signer, balance, block.Number(), block.BaseFee())
msg, _ := core.TransactionToMessage(tx, signer, balance, block.Number(), block.BaseFee())
txctx := &Context{
BlockHash: blockHash,
BlockNumber: block.Number(),
@ -670,7 +670,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
}
}
header := block.Header()
msg, _ := txs[task.index].AsMessage(signer, balance, header.Number, header.BaseFee)
msg, _ := core.TransactionToMessage(txs[task.index], signer, balance, header.Number, header.BaseFee)
txctx := &Context{
BlockHash: blockHash,
BlockNumber: block.Number(),
@ -713,11 +713,11 @@ txloop:
}
// Generate the next state snapshot fast without tracing
header := block.Header()
msg, _ := tx.AsMessage(signer, balance, header.Number, header.BaseFee)
msg, _ := core.TransactionToMessage(tx, signer, balance, header.Number, header.BaseFee)
statedb.SetTxContext(tx.Hash(), i)
vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, nil, api.backend.ChainConfig(), vm.Config{})
owner := common.Address{}
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil {
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), owner); err != nil {
failed = err
break txloop
}
@ -837,7 +837,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
// traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will
// be tracer dependent.
func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
var (
tracer Tracer
err error
@ -876,7 +876,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
// Call SetTxContext to clear out the statedb access list
statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
if _, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), common.Address{}); err != nil {
if _, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit), common.Address{}); err != nil {
return nil, fmt.Errorf("tracing failed: %w", err)
}
return tracer.GetResult()

View file

@ -160,7 +160,7 @@ func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reex
return statedb, release, nil
}
func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) {
func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) {
parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
return nil, vm.BlockContext{}, nil, nil, errBlockNotFound
@ -175,7 +175,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
// Recompute transactions up to the target index.
signer := types.MakeSigner(b.chainConfig, block.Number())
for idx, tx := range block.Transactions() {
msg, _ := tx.AsMessage(signer, nil, block.Number(), block.BaseFee())
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 {

View file

@ -145,7 +145,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, nil, nil)
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}
@ -219,7 +219,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
b.Fatalf("failed to parse testcase input: %v", err)
}
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
msg, err := tx.AsMessage(signer, nil, nil, nil)
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
if err != nil {
b.Fatalf("failed to prepare transaction for tracing: %v", err)
}
@ -313,7 +313,7 @@ func TestZeroValueToNotExitCall(t *testing.T) {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, txContext, statedb, nil, params.MainnetChainConfig, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, nil, nil)
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}
@ -389,7 +389,7 @@ func testContractTracer(tracerName string, dirPath string, t *testing.T) {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, nil, nil)
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}

View file

@ -109,7 +109,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
}
evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, context.BlockNumber, context.BaseFee)
msg, err := core.TransactionToMessage(tx, signer, nil, context.BlockNumber, context.BaseFee)
if err != nil {
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
}

View file

@ -115,7 +115,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, context.BlockNumber, context.BaseFee)
msg, err := core.TransactionToMessage(tx, signer, nil, context.BlockNumber, context.BaseFee)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}

View file

@ -88,7 +88,7 @@ func BenchmarkTransactionTrace(b *testing.B) {
//EnableReturnData: false,
})
evm := vm.NewEVM(context, txContext, statedb, nil, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer})
msg, err := tx.AsMessage(signer, nil, nil, nil)
msg, err := core.TransactionToMessage(tx, signer, nil, nil, nil)
if err != nil {
b.Fatalf("failed to prepare transaction for tracing: %v", err)
}

View file

@ -1127,7 +1127,8 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
if err != nil {
return nil, err
}
msg.SetBalanceTokenFeeForCall()
msg.BalanceTokenFee = new(big.Int).SetUint64(msg.GasLimit)
msg.BalanceTokenFee.Mul(msg.BalanceTokenFee, msg.GasPrice)
// Get a new instance of the EVM.
evm, vmError, err := b.GetEVM(ctx, msg, statedb, XDCxState, header, &vm.Config{NoBaseFee: true})
@ -1154,7 +1155,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
}
if err != nil {
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas())
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.GasLimit)
}
return result, err
}
@ -1776,7 +1777,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
if value, ok := feeCapacity[to]; ok {
balanceTokenFee = value
}
msg.SetBalanceTokenFee(balanceTokenFee)
msg.BalanceTokenFee = balanceTokenFee
// Apply the transaction with the access list tracer
tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles)
@ -1786,7 +1787,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
return nil, 0, nil, err
}
// TODO: determine the value of owner
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner)
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), owner)
if err != nil {
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err)
}

View file

@ -73,7 +73,7 @@ type Backend interface {
PendingBlockAndReceipts() (*types.Block, types.Receipts)
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
GetTd(ctx context.Context, blockHash common.Hash) *big.Int
GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription

View file

@ -27,6 +27,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/rpc"
@ -228,10 +229,10 @@ type AccountBackend interface {
// ToMessage converts the transaction arguments to the Message type used by the
// core evm. This method is used in calls and traces that do not require a real
// live transaction.
func (args *TransactionArgs) ToMessage(b AccountBackend, number *big.Int, globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
func (args *TransactionArgs) ToMessage(b AccountBackend, number *big.Int, globalGasCap uint64, baseFee *big.Int) (*core.Message, error) {
// Reject invalid combinations of pre- and post-1559 fee styles
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
}
// Set sender address or use zero address if none specified.
@ -308,7 +309,19 @@ func (args *TransactionArgs) ToMessage(b AccountBackend, number *big.Int, global
accessList = *args.AccessList
}
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true, nil, number)
msg := &core.Message{
From: addr,
To: args.To,
Nonce: 0,
Value: value,
GasLimit: gas,
GasPrice: gasPrice,
GasFeeCap: gasFeeCap,
GasTipCap: gasTipCap,
Data: data,
AccessList: accessList,
SkipAccountChecks: true,
}
return msg, nil
}

View file

@ -349,7 +349,7 @@ func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int {
return nil
}
func (b *backendMock) GetEVM(context.Context, core.Message, *state.StateDB, *tradingstate.TradingStateDB, *types.Header, *vm.Config) (*vm.EVM, func() error, error) {
func (b *backendMock) GetEVM(context.Context, *core.Message, *state.StateDB, *tradingstate.TradingStateDB, *types.Header, *vm.Config) (*vm.EVM, func() error, error) {
return nil, nil, nil
}

View file

@ -214,7 +214,7 @@ func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis {
}
}
func (tx *stTransaction) toMessage(ps stPostState, number *big.Int, baseFee *big.Int) (core.Message, error) {
func (tx *stTransaction) toMessage(ps stPostState, number *big.Int, baseFee *big.Int) (*core.Message, error) {
// Derive sender from private key if present.
var from common.Address
if len(tx.PrivateKey) > 0 {
@ -284,7 +284,19 @@ func (tx *stTransaction) toMessage(ps stPostState, number *big.Int, baseFee *big
return nil, errors.New("no gas price provided")
}
msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false, nil, number)
msg := &core.Message{
From: from,
To: to,
Nonce: tx.Nonce,
Value: value,
GasLimit: gasLimit,
GasPrice: tx.GasPrice,
GasFeeCap: tx.MaxFeePerGas,
GasTipCap: tx.MaxPriorityFeePerGas,
Data: data,
AccessList: accessList,
SkipAccountChecks: false,
}
return msg, nil
}