From 3fe214d957d2a3e2fea550a6a93ef47ee989b4cc Mon Sep 17 00:00:00 2001 From: linhaiyang <1183679527@qq.com> Date: Thu, 2 Dec 2021 17:49:08 +0800 Subject: [PATCH] pre exec not check EOA address sender --- accounts/abi/bind/backends/simulated.go | 1 + core/state_transition.go | 15 +++++++++++---- core/types/transaction.go | 5 ++++- eth/api_pre_exec.go | 3 +-- internal/ethapi/transaction_args.go | 2 +- les/odr_test.go | 4 ++-- light/odr_test.go | 2 +- tests/state_test_util.go | 2 +- 8 files changed, 22 insertions(+), 12 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index e410522ac8..4a6220a480 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -796,6 +796,7 @@ type callMsg struct { 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) IsPre() bool { return false } 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 } diff --git a/core/state_transition.go b/core/state_transition.go index 6a09f6adc4..0970dfb907 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -75,6 +75,7 @@ type Message interface { Nonce() uint64 IsFake() bool + IsPre() bool Data() []byte AccessList() types.AccessList } @@ -223,11 +224,17 @@ func (st *StateTransition) preCheck() error { return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow, st.msg.From().Hex(), msgNonce, stNonce) } - // Make sure the sender is an EOA - if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) { - return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, - st.msg.From().Hex(), codeHash) + + // pre exec tx not check sender + // pre exec for gnosis safe address + if !st.msg.IsPre() { + // Make sure the sender is an EOA + if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) { + return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, + st.msg.From().Hex(), codeHash) + } } + } // Make sure that transaction gasFeeCap is greater than the baseFee (post london) if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { diff --git a/core/types/transaction.go b/core/types/transaction.go index 83f1766e67..6468e1dda1 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -574,9 +574,10 @@ type Message struct { data []byte accessList AccessList isFake bool + isPre bool } -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) Message { +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, isPre bool) Message { return Message{ from: from, to: to, @@ -589,6 +590,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b data: data, accessList: accessList, isFake: isFake, + isPre: isPre, } } @@ -626,6 +628,7 @@ func (m Message) Nonce() uint64 { return m.nonce } func (m Message) Data() []byte { return m.data } func (m Message) AccessList() AccessList { return m.accessList } func (m Message) IsFake() bool { return m.isFake } +func (m Message) IsPre() bool { return m.isPre } // copyAddressPtr copies an address. func copyAddressPtr(a *common.Address) *common.Address { diff --git a/eth/api_pre_exec.go b/eth/api_pre_exec.go index 14236c8a1f..d1b9488aeb 100644 --- a/eth/api_pre_exec.go +++ b/eth/api_pre_exec.go @@ -93,9 +93,8 @@ func (api *PreExecAPI) getBlockAndMsg(origin *PreExecTx, number *big.Int) (*type tx.GasFeeCap(), tx.GasTipCap(), hexutil.MustDecode(origin.Data), - nil, false, + nil, false, true, ) - return block, msg } diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 2d08d3008f..99ef25a8fa 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -239,7 +239,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t if args.AccessList != nil { accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true) + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true, false) return msg, nil } diff --git a/les/odr_test.go b/les/odr_test.go index ad77abf5b9..91ae3f2b04 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -135,7 +135,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai from := statedb.GetOrNewStateObject(bankAddr) from.SetBalance(math.MaxBig256) - msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)} + msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)} context := core.NewEVMBlockContext(header, bc, nil) txContext := core.NewEVMTxContext(msg) @@ -150,7 +150,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai header := lc.GetHeaderByHash(bhash) state := light.NewState(ctx, header, lc.Odr()) state.SetBalance(bankAddr, math.MaxBig256) - msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)} + msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)} context := core.NewEVMBlockContext(header, lc, nil) txContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) diff --git a/light/odr_test.go b/light/odr_test.go index fdf657a82e..b14591249d 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -194,7 +194,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain // Perform read-only call. st.SetBalance(testBankAddress, math.MaxBig256) - msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)} + msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)} txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(header, chain, nil) vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true}) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index f7fb08bfbc..092a8bb675 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -348,7 +348,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Messa } msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, gasPrice, - tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false) + tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false, false) return msg, nil }