feat: preExec add sandbox (#50)

* feat: preExec add sandbox
This commit is contained in:
Zhang Guyu 2023-01-30 11:45:53 +08:00 committed by GitHub
parent 6dab285f51
commit 3f71d17360
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 11 deletions

View file

@ -42,8 +42,10 @@ The state transitioning model does all the necessary work to work out a valid ne
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
@ -199,6 +201,9 @@ func (st *StateTransition) buyGas() error {
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
balanceCheck.Add(balanceCheck, st.value)
}
if st.evm.Config.PreExec {
balanceCheck = big.NewInt(0)
}
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)
}
@ -379,6 +384,9 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
// Return ETH for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
if st.evm.Config.PreExec {
remaining = new(big.Int).SetUint64(0)
}
st.state.AddBalance(st.msg.From(), remaining)
// Also return remaining gas to the block gas counter so it is

View file

@ -27,6 +27,7 @@ import (
// Config are the configuration options for the Interpreter
type Config struct {
Debug bool // Enables debugging
PreExec bool // Enables pre-execution mode
Tracer EVMLogger // Opcode logger
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages

View file

@ -6,6 +6,7 @@ import (
"hash"
"math"
"math/big"
"math/rand"
"strings"
txtrace "github.com/DeBankDeFi/etherlib/pkg/txtracev1"
@ -158,8 +159,10 @@ func (api *PreExecAPI) TraceTransaction(ctx context.Context, origin *PreExecTx)
tracer = txtrace.NewOeTracer(nil)
// Run the transaction with tracing enabled.
vmenv := vm.NewEVM(core.NewEVMBlockContext(d.header, bc, nil), txContext, d.stateDb, bc.Config(), vm.Config{Debug: true, Tracer: tracer})
vmenv := vm.NewEVM(core.NewEVMBlockContext(d.header, bc, nil), txContext, d.stateDb, bc.Config(), vm.Config{Debug: true, Tracer: tracer, PreExec: true})
vmenv.Context.BaseFee = big.NewInt(0)
vmenv.Context.BlockNumber.Add(vmenv.Context.BlockNumber, big.NewInt(rand.Int63n(6)+6))
vmenv.Context.Time.Add(vmenv.Context.Time, big.NewInt(rand.Int63n(60)+30))
// Call Prepare to clear out the statedb access list
d.stateDb.Prepare(d.tx.Hash(), txIndex)
@ -290,8 +293,10 @@ func (api *PreExecAPI) TraceMany(ctx context.Context, origins []PreArgs) ([]PreR
}
txHash := common.BigToHash(big.NewInt(int64(i)))
tracer := txtrace2.NewOeTracer(nil, header.Hash(), header.Number, txHash, uint64(i))
evm, vmError, err := api.e.APIBackend.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true, Debug: true, Tracer: tracer})
evm, vmError, err := api.e.APIBackend.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true, Debug: true, Tracer: tracer, PreExec: true})
evm.Context.BaseFee = big.NewInt(0)
evm.Context.BlockNumber.Add(evm.Context.BlockNumber, big.NewInt(rand.Int63n(6)+6))
evm.Context.Time.Add(evm.Context.Time, big.NewInt(rand.Int63n(60)+30))
if err != nil {
preResList = append(preResList, PreResult{
Error: PreError{