mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
parent
19f5417121
commit
be61f66cb2
20 changed files with 275 additions and 339 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue