Skip to content

Commit

Permalink
feat: new eth call (ethereum#210)
Browse files Browse the repository at this point in the history
* changes

* stuff we may do

* ethcall: debugging progress

* Fix sync w ben

* Remove some unnecessary logs

* Fix debug logs

* vm: revert error message

Co-authored-by: Ben Jones <ben@pseudonym.party>
Co-authored-by: Kelvin Fichter <kelvinfichter@gmail.com>
  • Loading branch information
3 people authored Feb 23, 2021
1 parent fda94ce commit 30264cf
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 47 deletions.
4 changes: 3 additions & 1 deletion core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo

if vm.UsingOVM {
// OVM_ENABLED
st.msg, err = toExecutionManagerRun(st.evm, st.msg)
if st.evm.EthCallSender == nil {
st.msg, err = toExecutionManagerRun(st.evm, st.msg)
}
st.data = st.msg.Data()
if err != nil {
return nil, 0, false, err
Expand Down
31 changes: 19 additions & 12 deletions core/state_transition_ovm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/rollup/dump"
)

var ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000")
Expand Down Expand Up @@ -134,26 +134,33 @@ func asOvmMessage(tx *types.Transaction, signer types.Signer, decompressor commo
return outmsg, nil
}

func EncodeFakeMessage(
msg Message,
account abi.ABI,
) (Message, error) {
var input = []interface{}{
func EncodeSimulatedMessage(msg Message, timestamp, blockNumber *big.Int, executionManager, stateManager dump.OvmDumpAccount) (Message, error) {
tx := ovmTransaction{
timestamp,
blockNumber, // TODO (what's the correct block number?)
uint8(msg.QueueOrigin().Uint64()),
*msg.L1MessageSender(),
*msg.To(),
big.NewInt(int64(msg.Gas())),
msg.To(),
msg.Data(),
}

output, err := account.Pack("qall", input...)
from := msg.From()
var args = []interface{}{
tx,
from,
stateManager.Address,
}

output, err := executionManager.ABI.Pack("simulateMessage", args...)
if err != nil {
return nil, err
return nil, fmt.Errorf("Cannot pack simulateMessage: %w", err)
}

from := msg.From()
return modMessage(
msg,
from,
&from,
common.Address{},
&executionManager.Address,
output,
msg.Gas(),
)
Expand Down
28 changes: 5 additions & 23 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.Context.OriginalTargetReached = true
isTarget = true
}
// Handle eth_call
if evm.Context.EthCallSender != nil && (caller.Address() == common.Address{}) {
evm.Context.OriginalTargetReached = true
isTarget = true
}
}

if evm.vmConfig.NoRecursion && evm.depth > 0 {
Expand Down Expand Up @@ -322,34 +327,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
}

var prevCode []byte
if UsingOVM {
// OVM_ENABLED
if evm.Context.EthCallSender != nil && *evm.Context.EthCallSender == addr {
// We have to handle eth_call in a special manner as it doesn't stem from a signed
// transaction and therefore can't go through the standard EOA contract. When we detect
// this case, we temporarily insert some mock code that allows the user to pass through
// the EOA without a signature. EthCallSender should *never* be made non-nil outside
// of an eth_call. We store the old code here so that we're able to reset the code to
// the original code for the remainder of the transaction.
prevCode = evm.StateDB.GetCode(addr)
evm.StateDB.SetCode(addr, common.FromHex(evm.Context.OvmMockAccount.Code))
}
}

// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))

if UsingOVM {
// OVM_ENABLED
if evm.Context.EthCallSender != nil && *evm.Context.EthCallSender == addr {
// Reset the code once it's been loaded into the contract object.
evm.StateDB.SetCode(addr, prevCode)
}
}

// Even if the account has no code, we need to continue because it might be a precompile
start := time.Now()

Expand Down
6 changes: 3 additions & 3 deletions core/vm/ovm_state_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func callStateManager(input []byte, evm *EVM, contract *Contract) (ret []byte, e

method, err := abi.MethodById(input)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot find method id %s: %w", input, err)
}

var inputArgs = make(map[string]interface{})
Expand All @@ -55,12 +55,12 @@ func callStateManager(input []byte, evm *EVM, contract *Contract) (ret []byte, e

outputArgs, err := fn(evm, contract, inputArgs)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot execute state manager function: %w", err)
}

returndata, err := method.Outputs.PackValues(outputArgs)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot pack returndata: %w", err)
}

return returndata, nil
Expand Down
7 changes: 5 additions & 2 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,9 +958,12 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
msg = types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, false, &addr, nil, types.QueueOriginSequencer, 0)
if vm.UsingOVM {
cfg := b.ChainConfig()
account := cfg.StateDump.Accounts["mockOVM_ECDSAContractAccount"].ABI
executionManager := cfg.StateDump.Accounts["OVM_ExecutionManager"]
stateManager := cfg.StateDump.Accounts["OVM_StateManager"]
var err error
msg, err = core.EncodeFakeMessage(msg, account)
blockNumber := header.Number
timestamp := new(big.Int).SetUint64(header.Time)
msg, err = core.EncodeSimulatedMessage(msg, timestamp, blockNumber, executionManager, stateManager)
if err != nil {
return nil, 0, false, err
}
Expand Down
12 changes: 6 additions & 6 deletions rollup/sync_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *co
q = strconv.FormatUint(*queueIndex, 10)
}
log.Info("Initialized Eth Context", "index", i, "queue-index", q)
}

// The sequencer needs to sync to the tip at start up
// By setting the sync status to true, it will prevent RPC calls.
// Be sure this is set to false later.
if !service.verifier {
service.setSyncStatus(true)
// The sequencer needs to sync to the tip at start up
// By setting the sync status to true, it will prevent RPC calls.
// Be sure this is set to false later.
if !service.verifier {
service.setSyncStatus(true)
}
}

return &service, nil
Expand Down
1 change: 1 addition & 0 deletions scripts/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ cmd="$cmd --dev"
cmd="$cmd --chainid $CHAIN_ID"
cmd="$cmd --rpcaddr 0.0.0.0"
cmd="$cmd --rpcport $RPC_PORT"
cmd="$cmd --rpcvhosts '*'"
cmd="$cmd --rpccorsdomain '*'"
cmd="$cmd --wsaddr 0.0.0.0"
cmd="$cmd --wsport 8546"
Expand Down

0 comments on commit 30264cf

Please sign in to comment.