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 3) Create a new state object if the recipient is \0*32
4) Value transfer 4) Value transfer
== If contract creation == == If contract creation ==
4a) Attempt to run transaction data 4a) Attempt to run transaction data
4b) If valid, use result as code for the new state object 4b) If valid, use result as code for the new state object
== end == == end ==
5) Run Script section 5) Run Script section
6) Derive new state root 6) Derive new state root
@ -199,6 +201,9 @@ func (st *StateTransition) buyGas() error {
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap) balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
balanceCheck.Add(balanceCheck, st.value) 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 { 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) 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. // Return ETH for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) 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) st.state.AddBalance(st.msg.From(), remaining)
// Also return remaining gas to the block gas counter so it is // 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 // Config are the configuration options for the Interpreter
type Config struct { type Config struct {
Debug bool // Enables debugging Debug bool // Enables debugging
PreExec bool // Enables pre-execution mode
Tracer EVMLogger // Opcode logger Tracer EVMLogger // Opcode logger
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages

View file

@ -6,6 +6,7 @@ import (
"hash" "hash"
"math" "math"
"math/big" "math/big"
"math/rand"
"strings" "strings"
txtrace "github.com/DeBankDeFi/etherlib/pkg/txtracev1" txtrace "github.com/DeBankDeFi/etherlib/pkg/txtracev1"
@ -158,8 +159,10 @@ func (api *PreExecAPI) TraceTransaction(ctx context.Context, origin *PreExecTx)
tracer = txtrace.NewOeTracer(nil) tracer = txtrace.NewOeTracer(nil)
// Run the transaction with tracing enabled. // 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.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 // Call Prepare to clear out the statedb access list
d.stateDb.Prepare(d.tx.Hash(), txIndex) 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))) txHash := common.BigToHash(big.NewInt(int64(i)))
tracer := txtrace2.NewOeTracer(nil, header.Hash(), header.Number, txHash, uint64(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.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 { if err != nil {
preResList = append(preResList, PreResult{ preResList = append(preResList, PreResult{
Error: PreError{ Error: PreError{