Skip to content

Commit

Permalink
Add gascap and check input on hybrid compute and add unit tests
Browse files Browse the repository at this point in the history
(cherry picked from commit 61b1e85)
  • Loading branch information
boyuan-chen authored and InoMurko committed Jan 24, 2023
1 parent 18fb852 commit 66ef4cf
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
104 changes: 104 additions & 0 deletions l2geth/boba/boba_turing_call_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package boba

import (
"errors"
"math/big"
"testing"

"github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum-optimism/optimism/l2geth/common/hexutil"
"github.com/ethereum-optimism/optimism/l2geth/core"
"github.com/ethereum-optimism/optimism/l2geth/core/rawdb"
"github.com/ethereum-optimism/optimism/l2geth/core/state"
"github.com/ethereum-optimism/optimism/l2geth/core/vm"
"github.com/ethereum-optimism/optimism/l2geth/crypto"
"github.com/ethereum-optimism/optimism/l2geth/params"
"github.com/ethereum-optimism/optimism/l2geth/tests"
)

var (
ErrTuringInputTooShort = errors.New("turing input too short")
ErrTuringEmpty = errors.New("turing replay data not found")
contractAddr = common.HexToAddress("0x00000000000000000000000000000000deadbeef")
EOAAddr = common.HexToAddress("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")
)

type ContractRef struct{}

func (ContractRef) Address() common.Address { return contractAddr }

func vmTestBlockHash(n uint64) common.Hash {
return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
}

func newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
initialCall := true
canTransfer := func(db vm.StateDB, address common.Address, amount *big.Int) bool {
if initialCall {
initialCall = false
return true
}
return core.CanTransfer(db, address, amount)
}
transfer := func(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {}
context := vm.Context{
CanTransfer: canTransfer,
Transfer: transfer,
GetHash: vmTestBlockHash,
Origin: EOAAddr,
Coinbase: EOAAddr,
BlockNumber: new(big.Int).SetUint64(0),
Time: new(big.Int).SetUint64(0),
GasLimit: 0,
Difficulty: common.Big1,
GasPrice: common.Big1,
}
vmconfig.NoRecursion = true
return vm.NewEVM(context, statedb, params.MainnetChainConfig, vmconfig)
}

func createStateDB() *state.StateDB {
alloc := core.GenesisAlloc{}
alloc[contractAddr] = core.GenesisAccount{
Nonce: 1,
Code: hexutil.MustDecode("0x63deadbeef60005263cafebabe6004601c6000F560005260206000F3"),
Balance: big.NewInt(1),
}
statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc)
return statedb
}

func TestHybridComputeShortInput(t *testing.T) {
errTuringInput := []byte{125, 147, 97, 108}
TuringInput := append(errTuringInput[:], make([]byte, 32)...)
statedb := createStateDB()
evm := newEVM(statedb, vm.Config{})
if _, _, err := evm.Call(ContractRef{}, EOAAddr, errTuringInput, 0, common.Big0); err == ErrTuringInputTooShort {
t.Fatalf("should return 'turing input too short', but got err %v", err)
}
if _, _, err := evm.Call(ContractRef{}, EOAAddr, TuringInput, 0, common.Big0); err == ErrTuringEmpty {
t.Fatalf("should return 'turing replay data not found', but got err %v", err)
}
}

func TestHybridComputeGetRandomShortInput(t *testing.T) {
errGetRandInput := []byte{73, 61, 87, 214}
getRandInputInput := append(errGetRandInput[:], make([]byte, 32)...)
statedb := createStateDB()
evm := newEVM(statedb, vm.Config{})
if _, _, err := evm.Call(ContractRef{}, EOAAddr, errGetRandInput, 0, common.Big0); err == ErrTuringInputTooShort {
t.Fatalf("should return 'turing input too short', but got err %v", err)
}
if _, _, err := evm.Call(ContractRef{}, EOAAddr, getRandInputInput, 0, common.Big0); err == ErrTuringEmpty {
t.Fatalf("should return 'turing replay data not found', but got err %v", err)
}
}

func TestShortInput(t *testing.T) {
standardInput := []byte{0, 0, 0, 0}
statedb := createStateDB()
evm := newEVM(statedb, vm.Config{})
if _, _, err := evm.Call(ContractRef{}, EOAAddr, standardInput, 0, common.Big0); err != nil {
t.Fatalf("should return nil, but got err %v", err)
}
}
1 change: 1 addition & 0 deletions l2geth/core/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ var (
ErrTuringDepth = errors.New("turing call depth exceeded")
ErrTuringEmpty = errors.New("turing replay data not found")
ErrGasUintOverflow = errors.New("gas uint64 overflow")
ErrTuringInputTooShort = errors.New("turing input too short")
)
5 changes: 5 additions & 0 deletions l2geth/core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// Sanity and depth checks
if isTuring2 || isGetRand2 {
log.Debug("TURING REQUEST START", "input", input, "len(evm.Context.Turing)", len(evm.Context.Turing))
// Check 0. the payload must be at least 36 bytes long
if len(input) < 36 {
log.Error("TURING ERROR: INPUT TOO SHORT", "input", input)
return nil, gas, ErrTuringInputTooShort
}
// Check 1. can only run Turing once anywhere in the call stack
if evm.Context.TuringDepth > 1 {
log.Error("TURING ERROR: DEPTH > 1", "evm.Context.TuringDepth", evm.Context.TuringDepth)
Expand Down
1 change: 1 addition & 0 deletions ops/scripts/geth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ exec geth \
--mine \
--miner.etherbase $BLOCK_SIGNER_ADDRESS \
--rangelimit \
--rpc.gascap ${GAS_CAP:-11000000} \
"$@"

0 comments on commit 66ef4cf

Please sign in to comment.