diff --git a/op-e2e/actions/interop/dsl/emitter.go b/op-e2e/actions/interop/dsl/emitter.go index 62ffc0c7fe33c..a766fc4e2875b 100644 --- a/op-e2e/actions/interop/dsl/emitter.go +++ b/op-e2e/actions/interop/dsl/emitter.go @@ -2,7 +2,7 @@ package dsl import ( "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/emit" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/emit" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" diff --git a/op-e2e/actions/interop/dsl/inbox.go b/op-e2e/actions/interop/dsl/inbox.go index 0a75ce7239cc8..a2e2e89812dfd 100644 --- a/op-e2e/actions/interop/dsl/inbox.go +++ b/op-e2e/actions/interop/dsl/inbox.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/inbox" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/inbox" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/predeploys" stypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" diff --git a/op-e2e/actions/interop/dsl/message.go b/op-e2e/actions/interop/dsl/message.go index 9ed433c2755d4..667376b940675 100644 --- a/op-e2e/actions/interop/dsl/message.go +++ b/op-e2e/actions/interop/dsl/message.go @@ -2,7 +2,7 @@ package dsl import ( "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/inbox" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/inbox" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" diff --git a/op-e2e/actions/interop/dsl/transactions.go b/op-e2e/actions/interop/dsl/transactions.go index 7cdc2de7f3241..40c35f90ac4d7 100644 --- a/op-e2e/actions/interop/dsl/transactions.go +++ b/op-e2e/actions/interop/dsl/transactions.go @@ -5,7 +5,7 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/bindingspreview" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/inbox" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/inbox" stypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" diff --git a/op-e2e/actions/interop/emitter_contract_test.go b/op-e2e/actions/interop/emitter_contract_test.go index 0bd681092a6bd..d3a360b74a64c 100644 --- a/op-e2e/actions/interop/emitter_contract_test.go +++ b/op-e2e/actions/interop/emitter_contract_test.go @@ -17,8 +17,8 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/interop/dsl" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/emit" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/inbox" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/emit" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/inbox" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/event" "github.com/ethereum-optimism/optimism/op-service/eth" diff --git a/op-e2e/actions/interop/interop_test.go b/op-e2e/actions/interop/interop_test.go index 302367ab9a13d..a0280831aec82 100644 --- a/op-e2e/actions/interop/interop_test.go +++ b/op-e2e/actions/interop/interop_test.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/interop/dsl" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/emit" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/emit" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/event" "github.com/ethereum-optimism/optimism/op-node/rollup/interop/managed" diff --git a/op-e2e/actions/proofs/helpers/matrix.go b/op-e2e/actions/proofs/helpers/matrix.go index 44612f7c708b7..2fad598253fbe 100644 --- a/op-e2e/actions/proofs/helpers/matrix.go +++ b/op-e2e/actions/proofs/helpers/matrix.go @@ -135,3 +135,14 @@ var ( func NewForkMatrix(forks ...*Hardfork) ForkMatrix { return append(ForkMatrix{}, forks...) } + +func FaultProofForks() ForkMatrix { + var forks ForkMatrix + for _, hf := range Hardforks { + if hf == Regolith || hf == Canyon || hf == Delta { + continue + } + forks = append(forks, hf) + } + return forks +} diff --git a/op-e2e/actions/proofs/precompile_test.go b/op-e2e/actions/proofs/precompile_test.go index df2a9c11de641..d3f14a9b52626 100644 --- a/op-e2e/actions/proofs/precompile_test.go +++ b/op-e2e/actions/proofs/precompile_test.go @@ -3,7 +3,6 @@ package proofs import ( "context" "encoding/binary" - "slices" "strings" "sync" "testing" @@ -11,6 +10,7 @@ import ( actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/invoker" preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/op-program/client/l1" hostcommon "github.com/ethereum-optimism/optimism/op-program/host/common" @@ -24,29 +24,25 @@ import ( "github.com/stretchr/testify/require" ) -func Test_OPProgramAction_Precompiles(gt *testing.T) { +func Test_OPProgramAction_PrecompileHint(gt *testing.T) { matrix := helpers.NewMatrix[any]() defer matrix.Run(gt) - // Remove forks unsupported by the fault proof - forks := slices.DeleteFunc(helpers.Hardforks, func(hf *helpers.Hardfork) bool { - return hf == helpers.Regolith || hf == helpers.Canyon || hf == helpers.Delta - }) for _, test := range PrecompileTestFixtures { testCase := test matrix.AddTestCase( test.Name, nil, - forks, + helpers.FaultProofForks(), func(t *testing.T, testCfg *helpers.TestCfg[any]) { - runPrecompileTest(t, testCase, testCfg) + runPrecompileHintTest(t, testCase, testCfg) }, helpers.ExpectNoError(), ) } } -func runPrecompileTest(gt *testing.T, testCase PrecompileTestFixture, testCfg *helpers.TestCfg[any]) { +func runPrecompileHintTest(gt *testing.T, testCase PrecompileTestFixture, testCfg *helpers.TestCfg[any]) { t := actionsHelpers.NewDefaultTesting(gt) env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) @@ -155,3 +151,103 @@ func (p *precompileHintCounter) GetCount() int { defer p.RWMutex.RUnlock() return p.count } + +func Test_ProgramAction_Precompiles(gt *testing.T) { + matrix := helpers.NewMatrix[PrecompileTestFixture]() + defer matrix.Run(gt) + for _, test := range PrecompileTestFixtures { + testCase := test + matrix.AddTestCase( + testCase.Name, + testCase, + helpers.FaultProofForks(), + runPrecompileTest, + helpers.ExpectNoError(), + ) + } +} + +func runPrecompileTest(gt *testing.T, testCfg *helpers.TestCfg[PrecompileTestFixture]) { + t := actionsHelpers.NewDefaultTesting(gt) + env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) + testCase := testCfg.Custom + + // deploy invoker contract + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxCalldata(common.FromHex(invoker.InvokerMetaData.Bin))(t) + env.Alice.L2.ActMakeTx(t) + env.Sequencer.ActL2StartBlock(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + env.Alice.L2.ActCheckReceiptStatusOfLastTx(true)(t) + + invokerContract := env.Alice.L2.LastTxReceipt(t).ContractAddress + require.NotZero(t, invokerContract, "invoker contract address is zero") + abi, err := invoker.InvokerMetaData.GetAbi() + require.NoError(t, err) + invokeCalldata, err := abi.Pack("invokePrecompile", testCase.Address, testCase.Input) + require.NoError(t, err) + + // call precompile via invoker + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxToAddr(&invokerContract)(t) + env.Alice.L2.ActSetTxCalldata(invokeCalldata)(t) + env.Alice.L2.ActMakeTx(t) + env.Sequencer.ActL2StartBlock(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + env.Alice.L2.ActCheckReceiptStatusOfLastTx(true)(t) + + receipt := env.Alice.L2.LastTxReceipt(t) + receiptBlockTime := env.Engine.L2Chain().GetBlockByHash(receipt.BlockHash).Time() + rules := env.Engine.L2Chain().Config().Rules(receipt.BlockNumber, true, receiptBlockTime) + expectedResult := make([]byte, 0) + precompile, ok := vm.ActivePrecompiledContracts(rules)[testCase.Address] + if ok { + expectedResult, err = precompile.Run(testCase.Input) + require.NoError(t, err) + } + + // sanity check Invoker precompile call + require.Equal(t, receipt.Status, uint64(1), "transaction should succeed") + require.Len(t, receipt.Logs, 1) + require.Equal(t, receipt.Logs[0].Address, invokerContract) + require.Len(t, receipt.Logs[0].Topics, 2) + precompileAddress := receipt.Logs[0].Topics[1] + var out struct{ Result []byte } + err = abi.UnpackIntoInterface(&out, "PrecompileInvoked", receipt.Logs[0].Data) + precompileResult := out.Result + require.NoError(t, err) + require.Equal(t, common.HexToAddress(precompileAddress.Hex()), testCase.Address) + require.Equal(t, expectedResult, precompileResult) + + // instruct the batcher to submit the Invoker precompile tx to l1, and include the transaction. + env.Batcher.ActSubmitAll(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the batch on L1. + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + l1Head := env.Miner.L1Chain().CurrentBlock() + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + + require.Equal(t, uint64(1), l1Head.Number.Uint64()) + // Ensure the block is marked as safe before we attempt to fault prove it. + require.Equal(t, uint64(2), l2SafeHead.Number.Uint64()) + + defaultParam := helpers.WithPreInteropDefaults(t, l2SafeHead.Number.Uint64(), env.Sequencer.L2Verifier, env.Engine) + fixtureInputParams := []helpers.FixtureInputParam{defaultParam, helpers.WithL1Head(l1Head.Hash())} + var fixtureInputs helpers.FixtureInputs + for _, apply := range fixtureInputParams { + apply(&fixtureInputs) + } + + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), helpers.ExpectNoError(), fixtureInputParams...) +} diff --git a/op-e2e/e2eutils/interop/contracts/bindings/emit/emit.go b/op-e2e/e2eutils/contracts/bindings/emit/emit.go similarity index 100% rename from op-e2e/e2eutils/interop/contracts/bindings/emit/emit.go rename to op-e2e/e2eutils/contracts/bindings/emit/emit.go diff --git a/op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go b/op-e2e/e2eutils/contracts/bindings/inbox/inbox.go similarity index 100% rename from op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go rename to op-e2e/e2eutils/contracts/bindings/inbox/inbox.go diff --git a/op-e2e/e2eutils/contracts/bindings/invoker/invoker.go b/op-e2e/e2eutils/contracts/bindings/invoker/invoker.go new file mode 100644 index 0000000000000..f98cc82da6267 --- /dev/null +++ b/op-e2e/e2eutils/contracts/bindings/invoker/invoker.go @@ -0,0 +1,369 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package invoker + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// InvokerMetaData contains all meta data concerning the Invoker contract. +var InvokerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"invokePrecompile\",\"inputs\":[{\"name\":\"_precompile\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_input\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"PrecompileInvoked\",\"inputs\":[{\"name\":\"precompile\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"result\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"PrecompileCallFailed\",\"inputs\":[]}]", + Bin: "0x6080604052348015600e575f5ffd5b506102f58061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063051f3bdf1461002d575b5f5ffd5b61004061003b366004610164565b610042565b005b5f5f8373ffffffffffffffffffffffffffffffffffffffff1683604051610069919061027f565b5f604051808303815f865af19150503d805f81146100a2576040519150601f19603f3d011682016040523d82523d5f602084013e6100a7565b606091505b5091509150816100e3576040517ffd23ff6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8826040516101299190610295565b60405180910390a250505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215610175575f5ffd5b823573ffffffffffffffffffffffffffffffffffffffff81168114610198575f5ffd5b9150602083013567ffffffffffffffff8111156101b3575f5ffd5b8301601f810185136101c3575f5ffd5b803567ffffffffffffffff8111156101dd576101dd610137565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561024957610249610137565b604052818152828201602001871015610260575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168401019150509291505056fea164736f6c634300081c000a", +} + +// InvokerABI is the input ABI used to generate the binding from. +// Deprecated: Use InvokerMetaData.ABI instead. +var InvokerABI = InvokerMetaData.ABI + +// InvokerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use InvokerMetaData.Bin instead. +var InvokerBin = InvokerMetaData.Bin + +// DeployInvoker deploys a new Ethereum contract, binding an instance of Invoker to it. +func DeployInvoker(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Invoker, error) { + parsed, err := InvokerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(InvokerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Invoker{InvokerCaller: InvokerCaller{contract: contract}, InvokerTransactor: InvokerTransactor{contract: contract}, InvokerFilterer: InvokerFilterer{contract: contract}}, nil +} + +// Invoker is an auto generated Go binding around an Ethereum contract. +type Invoker struct { + InvokerCaller // Read-only binding to the contract + InvokerTransactor // Write-only binding to the contract + InvokerFilterer // Log filterer for contract events +} + +// InvokerCaller is an auto generated read-only Go binding around an Ethereum contract. +type InvokerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InvokerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type InvokerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InvokerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type InvokerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InvokerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type InvokerSession struct { + Contract *Invoker // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InvokerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type InvokerCallerSession struct { + Contract *InvokerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// InvokerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type InvokerTransactorSession struct { + Contract *InvokerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InvokerRaw is an auto generated low-level Go binding around an Ethereum contract. +type InvokerRaw struct { + Contract *Invoker // Generic contract binding to access the raw methods on +} + +// InvokerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type InvokerCallerRaw struct { + Contract *InvokerCaller // Generic read-only contract binding to access the raw methods on +} + +// InvokerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type InvokerTransactorRaw struct { + Contract *InvokerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewInvoker creates a new instance of Invoker, bound to a specific deployed contract. +func NewInvoker(address common.Address, backend bind.ContractBackend) (*Invoker, error) { + contract, err := bindInvoker(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Invoker{InvokerCaller: InvokerCaller{contract: contract}, InvokerTransactor: InvokerTransactor{contract: contract}, InvokerFilterer: InvokerFilterer{contract: contract}}, nil +} + +// NewInvokerCaller creates a new read-only instance of Invoker, bound to a specific deployed contract. +func NewInvokerCaller(address common.Address, caller bind.ContractCaller) (*InvokerCaller, error) { + contract, err := bindInvoker(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &InvokerCaller{contract: contract}, nil +} + +// NewInvokerTransactor creates a new write-only instance of Invoker, bound to a specific deployed contract. +func NewInvokerTransactor(address common.Address, transactor bind.ContractTransactor) (*InvokerTransactor, error) { + contract, err := bindInvoker(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &InvokerTransactor{contract: contract}, nil +} + +// NewInvokerFilterer creates a new log filterer instance of Invoker, bound to a specific deployed contract. +func NewInvokerFilterer(address common.Address, filterer bind.ContractFilterer) (*InvokerFilterer, error) { + contract, err := bindInvoker(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &InvokerFilterer{contract: contract}, nil +} + +// bindInvoker binds a generic wrapper to an already deployed contract. +func bindInvoker(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := InvokerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Invoker *InvokerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Invoker.Contract.InvokerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Invoker *InvokerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Invoker.Contract.InvokerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Invoker *InvokerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Invoker.Contract.InvokerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Invoker *InvokerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Invoker.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Invoker *InvokerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Invoker.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Invoker *InvokerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Invoker.Contract.contract.Transact(opts, method, params...) +} + +// InvokePrecompile is a paid mutator transaction binding the contract method 0x051f3bdf. +// +// Solidity: function invokePrecompile(address _precompile, bytes _input) returns() +func (_Invoker *InvokerTransactor) InvokePrecompile(opts *bind.TransactOpts, _precompile common.Address, _input []byte) (*types.Transaction, error) { + return _Invoker.contract.Transact(opts, "invokePrecompile", _precompile, _input) +} + +// InvokePrecompile is a paid mutator transaction binding the contract method 0x051f3bdf. +// +// Solidity: function invokePrecompile(address _precompile, bytes _input) returns() +func (_Invoker *InvokerSession) InvokePrecompile(_precompile common.Address, _input []byte) (*types.Transaction, error) { + return _Invoker.Contract.InvokePrecompile(&_Invoker.TransactOpts, _precompile, _input) +} + +// InvokePrecompile is a paid mutator transaction binding the contract method 0x051f3bdf. +// +// Solidity: function invokePrecompile(address _precompile, bytes _input) returns() +func (_Invoker *InvokerTransactorSession) InvokePrecompile(_precompile common.Address, _input []byte) (*types.Transaction, error) { + return _Invoker.Contract.InvokePrecompile(&_Invoker.TransactOpts, _precompile, _input) +} + +// InvokerPrecompileInvokedIterator is returned from FilterPrecompileInvoked and is used to iterate over the raw logs and unpacked data for PrecompileInvoked events raised by the Invoker contract. +type InvokerPrecompileInvokedIterator struct { + Event *InvokerPrecompileInvoked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *InvokerPrecompileInvokedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(InvokerPrecompileInvoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(InvokerPrecompileInvoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *InvokerPrecompileInvokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *InvokerPrecompileInvokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// InvokerPrecompileInvoked represents a PrecompileInvoked event raised by the Invoker contract. +type InvokerPrecompileInvoked struct { + Precompile common.Address + Result []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPrecompileInvoked is a free log retrieval operation binding the contract event 0xde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8. +// +// Solidity: event PrecompileInvoked(address indexed precompile, bytes result) +func (_Invoker *InvokerFilterer) FilterPrecompileInvoked(opts *bind.FilterOpts, precompile []common.Address) (*InvokerPrecompileInvokedIterator, error) { + + var precompileRule []interface{} + for _, precompileItem := range precompile { + precompileRule = append(precompileRule, precompileItem) + } + + logs, sub, err := _Invoker.contract.FilterLogs(opts, "PrecompileInvoked", precompileRule) + if err != nil { + return nil, err + } + return &InvokerPrecompileInvokedIterator{contract: _Invoker.contract, event: "PrecompileInvoked", logs: logs, sub: sub}, nil +} + +// WatchPrecompileInvoked is a free log subscription operation binding the contract event 0xde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8. +// +// Solidity: event PrecompileInvoked(address indexed precompile, bytes result) +func (_Invoker *InvokerFilterer) WatchPrecompileInvoked(opts *bind.WatchOpts, sink chan<- *InvokerPrecompileInvoked, precompile []common.Address) (event.Subscription, error) { + + var precompileRule []interface{} + for _, precompileItem := range precompile { + precompileRule = append(precompileRule, precompileItem) + } + + logs, sub, err := _Invoker.contract.WatchLogs(opts, "PrecompileInvoked", precompileRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(InvokerPrecompileInvoked) + if err := _Invoker.contract.UnpackLog(event, "PrecompileInvoked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParsePrecompileInvoked is a log parse operation binding the contract event 0xde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8. +// +// Solidity: event PrecompileInvoked(address indexed precompile, bytes result) +func (_Invoker *InvokerFilterer) ParsePrecompileInvoked(log types.Log) (*InvokerPrecompileInvoked, error) { + event := new(InvokerPrecompileInvoked) + if err := _Invoker.contract.UnpackLog(event, "PrecompileInvoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.abi b/op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.abi similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.abi rename to op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.abi diff --git a/op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.bin b/op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.bin similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.bin rename to op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.bin diff --git a/op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.json b/op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.json similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.json rename to op-e2e/e2eutils/contracts/build/ICrossL2Inbox.sol/ICrossL2Inbox.json diff --git a/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.abi b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.abi new file mode 100644 index 0000000000000..67051a1f48e2b --- /dev/null +++ b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.abi @@ -0,0 +1,44 @@ +[ + { + "type": "function", + "name": "invokePrecompile", + "inputs": [ + { + "name": "_precompile", + "type": "address", + "internalType": "address" + }, + { + "name": "_input", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "PrecompileInvoked", + "inputs": [ + { + "name": "precompile", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "result", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "PrecompileCallFailed", + "inputs": [] + } +] diff --git a/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.bin b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.bin new file mode 100644 index 0000000000000..5705b73fcbbf7 --- /dev/null +++ b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.bin @@ -0,0 +1 @@ +0x6080604052348015600e575f5ffd5b506102f58061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063051f3bdf1461002d575b5f5ffd5b61004061003b366004610164565b610042565b005b5f5f8373ffffffffffffffffffffffffffffffffffffffff1683604051610069919061027f565b5f604051808303815f865af19150503d805f81146100a2576040519150601f19603f3d011682016040523d82523d5f602084013e6100a7565b606091505b5091509150816100e3576040517ffd23ff6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8826040516101299190610295565b60405180910390a250505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215610175575f5ffd5b823573ffffffffffffffffffffffffffffffffffffffff81168114610198575f5ffd5b9150602083013567ffffffffffffffff8111156101b3575f5ffd5b8301601f810185136101c3575f5ffd5b803567ffffffffffffffff8111156101dd576101dd610137565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561024957610249610137565b604052818152828201602001871015610260575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168401019150509291505056fea164736f6c634300081c000a diff --git a/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.json b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.json new file mode 100644 index 0000000000000..be7e840ac88e8 --- /dev/null +++ b/op-e2e/e2eutils/contracts/build/Invoker.sol/Invoker.json @@ -0,0 +1 @@ +{"abi":[{"type":"function","name":"invokePrecompile","inputs":[{"name":"_precompile","type":"address","internalType":"address"},{"name":"_input","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"PrecompileInvoked","inputs":[{"name":"precompile","type":"address","indexed":true,"internalType":"address"},{"name":"result","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"error","name":"PrecompileCallFailed","inputs":[]}],"bytecode":{"object":"0x6080604052348015600e575f5ffd5b506102f58061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063051f3bdf1461002d575b5f5ffd5b61004061003b366004610164565b610042565b005b5f5f8373ffffffffffffffffffffffffffffffffffffffff1683604051610069919061027f565b5f604051808303815f865af19150503d805f81146100a2576040519150601f19603f3d011682016040523d82523d5f602084013e6100a7565b606091505b5091509150816100e3576040517ffd23ff6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8826040516101299190610295565b60405180910390a250505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215610175575f5ffd5b823573ffffffffffffffffffffffffffffffffffffffff81168114610198575f5ffd5b9150602083013567ffffffffffffffff8111156101b3575f5ffd5b8301601f810185136101c3575f5ffd5b803567ffffffffffffffff8111156101dd576101dd610137565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561024957610249610137565b604052818152828201602001871015610260575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168401019150509291505056fea164736f6c634300081c000a","sourceMap":"58:481:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063051f3bdf1461002d575b5f5ffd5b61004061003b366004610164565b610042565b005b5f5f8373ffffffffffffffffffffffffffffffffffffffff1683604051610069919061027f565b5f604051808303815f865af19150503d805f81146100a2576040519150601f19603f3d011682016040523d82523d5f602084013e6100a7565b606091505b5091509150816100e3576040517ffd23ff6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fde9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8826040516101299190610295565b60405180910390a250505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215610175575f5ffd5b823573ffffffffffffffffffffffffffffffffffffffff81168114610198575f5ffd5b9150602083013567ffffffffffffffff8111156101b3575f5ffd5b8301601f810185136101c3575f5ffd5b803567ffffffffffffffff8111156101dd576101dd610137565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561024957610249610137565b604052818152828201602001871015610260575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168401019150509291505056fea164736f6c634300081c000a","sourceMap":"58:481:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;187:350;;;;;;:::i;:::-;;:::i;:::-;;;339:12;353:19;376:11;:16;;393:6;376:24;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;338:62;;;;415:7;410:68;;445:22;;;;;;;;;;;;;;410:68;510:11;492:38;;;523:6;492:38;;;;;;:::i;:::-;;;;;;;;264:273;;187:350;;:::o;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:1259;280:6;288;341:2;329:9;320:7;316:23;312:32;309:52;;;357:1;354;347:12;309:52;396:9;383:23;446:42;439:5;435:54;428:5;425:65;415:93;;504:1;501;494:12;415:93;527:5;-1:-1:-1;583:2:1;568:18;;555:32;610:18;599:30;;596:50;;;642:1;639;632:12;596:50;665:22;;718:4;710:13;;706:27;-1:-1:-1;696:55:1;;747:1;744;737:12;696:55;787:2;774:16;813:18;805:6;802:30;799:56;;;835:18;;:::i;:::-;884:2;878:9;1031:66;1026:2;957:66;950:4;942:6;938:17;934:90;930:99;926:172;918:6;914:185;1165:6;1153:10;1150:22;1129:18;1117:10;1114:34;1111:62;1108:88;;;1176:18;;:::i;:::-;1212:2;1205:22;1236;;;1277:15;;;1294:2;1273:24;1270:37;-1:-1:-1;1267:57:1;;;1320:1;1317;1310:12;1267:57;1376:6;1371:2;1367;1363:11;1358:2;1350:6;1346:15;1333:50;1429:1;1424:2;1415:6;1407;1403:19;1399:28;1392:39;1450:6;1440:16;;;;;203:1259;;;;;:::o;1467:301::-;1596:3;1634:6;1628:13;1680:6;1673:4;1665:6;1661:17;1656:3;1650:37;1742:1;1706:16;;1731:13;;;-1:-1:-1;1706:16:1;1467:301;-1:-1:-1;1467:301:1:o;1773:475::-;1920:2;1909:9;1902:21;1883:4;1952:6;1946:13;1995:6;1990:2;1979:9;1975:18;1968:34;2054:6;2049:2;2041:6;2037:15;2032:2;2021:9;2017:18;2011:50;2110:1;2105:2;2096:6;2085:9;2081:22;2077:31;2070:42;2239:2;2169:66;2164:2;2156:6;2152:15;2148:88;2137:9;2133:104;2129:113;2121:121;;;1773:475;;;;:::o","linkReferences":{}},"methodIdentifiers":{"invokePrecompile(address,bytes)":"051f3bdf"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"PrecompileCallFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"precompile\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"result\",\"type\":\"bytes\"}],\"name\":\"PrecompileInvoked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_precompile\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_input\",\"type\":\"bytes\"}],\"name\":\"invokePrecompile\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/Invoker.sol\":\"Invoker\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"src/Invoker.sol\":{\"keccak256\":\"0xddfb3915e14861712ef66f325e48d931c06bd6f98efcc3ae7e591779dcf942af\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1b9f829106397fd5474e7ac870e18347d0762248c0c8698be25838a48d157d1a\",\"dweb:/ipfs/QmXKADnBTCewgGXyMGX9grdgyW3uz29AnLgniakKGouYBD\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.28+commit.7893614a"},"language":"Solidity","output":{"abi":[{"inputs":[],"type":"error","name":"PrecompileCallFailed"},{"inputs":[{"internalType":"address","name":"precompile","type":"address","indexed":true},{"internalType":"bytes","name":"result","type":"bytes","indexed":false}],"type":"event","name":"PrecompileInvoked","anonymous":false},{"inputs":[{"internalType":"address","name":"_precompile","type":"address"},{"internalType":"bytes","name":"_input","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"invokePrecompile"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"src/Invoker.sol":"Invoker"},"evmVersion":"cancun","libraries":{}},"sources":{"src/Invoker.sol":{"keccak256":"0xddfb3915e14861712ef66f325e48d931c06bd6f98efcc3ae7e591779dcf942af","urls":["bzz-raw://1b9f829106397fd5474e7ac870e18347d0762248c0c8698be25838a48d157d1a","dweb:/ipfs/QmXKADnBTCewgGXyMGX9grdgyW3uz29AnLgniakKGouYBD"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"src/Invoker.sol","id":40,"exportedSymbols":{"Invoker":[39]},"nodeType":"SourceUnit","src":"32:508:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:24:0","nodes":[],"literals":["solidity","^","0.8",".15"]},{"id":39,"nodeType":"ContractDefinition","src":"58:481:0","nodes":[{"id":7,"nodeType":"EventDefinition","src":"81:66:0","nodes":[],"anonymous":false,"eventSelector":"de9caeb04cbecadc4b3b08dd3b026ff047428c7c681a368b2b48d1097bf465a8","name":"PrecompileInvoked","nameLocation":"87:17:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"indexed":true,"mutability":"mutable","name":"precompile","nameLocation":"121:10:0","nodeType":"VariableDeclaration","scope":7,"src":"105:26:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2,"name":"address","nodeType":"ElementaryTypeName","src":"105:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":5,"indexed":false,"mutability":"mutable","name":"result","nameLocation":"139:6:0","nodeType":"VariableDeclaration","scope":7,"src":"133:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":4,"name":"bytes","nodeType":"ElementaryTypeName","src":"133:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"104:42:0"}},{"id":9,"nodeType":"ErrorDefinition","src":"152:29:0","nodes":[],"errorSelector":"fd23ff64","name":"PrecompileCallFailed","nameLocation":"158:20:0","parameters":{"id":8,"nodeType":"ParameterList","parameters":[],"src":"178:2:0"}},{"id":38,"nodeType":"FunctionDefinition","src":"187:350:0","nodes":[],"body":{"id":37,"nodeType":"Block","src":"264:273:0","nodes":[],"statements":[{"assignments":[17,19],"declarations":[{"constant":false,"id":17,"mutability":"mutable","name":"success","nameLocation":"344:7:0","nodeType":"VariableDeclaration","scope":37,"src":"339:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":16,"name":"bool","nodeType":"ElementaryTypeName","src":"339:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":19,"mutability":"mutable","name":"result","nameLocation":"366:6:0","nodeType":"VariableDeclaration","scope":37,"src":"353:19:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":18,"name":"bytes","nodeType":"ElementaryTypeName","src":"353:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":24,"initialValue":{"arguments":[{"id":22,"name":"_input","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":13,"src":"393:6:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"id":20,"name":"_precompile","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":11,"src":"376:11:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":21,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"388:4:0","memberName":"call","nodeType":"MemberAccess","src":"376:16:0","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":23,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"376:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"VariableDeclarationStatement","src":"338:62:0"},{"condition":{"id":26,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"414:8:0","subExpression":{"id":25,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":17,"src":"415:7:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":31,"nodeType":"IfStatement","src":"410:68:0","trueBody":{"id":30,"nodeType":"Block","src":"424:54:0","statements":[{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":27,"name":"PrecompileCallFailed","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":9,"src":"445:20:0","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$_t_error_$","typeString":"function () pure returns (error)"}},"id":28,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"445:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_error","typeString":"error"}},"id":29,"nodeType":"RevertStatement","src":"438:29:0"}]}},{"eventCall":{"arguments":[{"id":33,"name":"_precompile","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":11,"src":"510:11:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":34,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":19,"src":"523:6:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":32,"name":"PrecompileInvoked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":7,"src":"492:17:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,bytes memory)"}},"id":35,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"492:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":36,"nodeType":"EmitStatement","src":"487:43:0"}]},"functionSelector":"051f3bdf","implemented":true,"kind":"function","modifiers":[],"name":"invokePrecompile","nameLocation":"196:16:0","parameters":{"id":14,"nodeType":"ParameterList","parameters":[{"constant":false,"id":11,"mutability":"mutable","name":"_precompile","nameLocation":"221:11:0","nodeType":"VariableDeclaration","scope":38,"src":"213:19:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":10,"name":"address","nodeType":"ElementaryTypeName","src":"213:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":13,"mutability":"mutable","name":"_input","nameLocation":"247:6:0","nodeType":"VariableDeclaration","scope":38,"src":"234:19:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":12,"name":"bytes","nodeType":"ElementaryTypeName","src":"234:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"212:42:0"},"returnParameters":{"id":15,"nodeType":"ParameterList","parameters":[],"src":"264:0:0"},"scope":39,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Invoker","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[39],"name":"Invoker","nameLocation":"67:7:0","scope":40,"usedErrors":[9],"usedEvents":[7]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.abi b/op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.abi similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.abi rename to op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.abi diff --git a/op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.bin b/op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.bin similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.bin rename to op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.bin diff --git a/op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.json b/op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.json similarity index 100% rename from op-e2e/e2eutils/interop/contracts/build/emit.sol/EmitEvent.json rename to op-e2e/e2eutils/contracts/build/emit.sol/EmitEvent.json diff --git a/op-e2e/e2eutils/interop/contracts/foundry.toml b/op-e2e/e2eutils/contracts/foundry.toml similarity index 100% rename from op-e2e/e2eutils/interop/contracts/foundry.toml rename to op-e2e/e2eutils/contracts/foundry.toml diff --git a/op-e2e/e2eutils/interop/contracts/generate.sh b/op-e2e/e2eutils/contracts/generate.sh similarity index 69% rename from op-e2e/e2eutils/interop/contracts/generate.sh rename to op-e2e/e2eutils/contracts/generate.sh index 124deb1913166..2f4feea492145 100755 --- a/op-e2e/e2eutils/interop/contracts/generate.sh +++ b/op-e2e/e2eutils/contracts/generate.sh @@ -19,3 +19,11 @@ cd ../.. mkdir -p bindings/inbox abigen --abi ./build/ICrossL2Inbox.sol/ICrossL2Inbox.abi --bin ./build/ICrossL2Inbox.sol/ICrossL2Inbox.bin --pkg inbox --out ./bindings/inbox/inbox.go + +cd build/Invoker.sol +cat Invoker.json | jq -r '.bytecode.object' > Invoker.bin +cat Invoker.json | jq '.abi' > Invoker.abi +cd ../../ + +mkdir -p bindings/invoker +abigen --abi ./build/Invoker.sol/Invoker.abi --bin ./build/Invoker.sol/Invoker.bin --pkg invoker --out ./bindings/invoker/invoker.go diff --git a/op-e2e/e2eutils/interop/contracts/src/ICrossL2Inbox.sol b/op-e2e/e2eutils/contracts/src/ICrossL2Inbox.sol similarity index 100% rename from op-e2e/e2eutils/interop/contracts/src/ICrossL2Inbox.sol rename to op-e2e/e2eutils/contracts/src/ICrossL2Inbox.sol diff --git a/op-e2e/e2eutils/contracts/src/Invoker.sol b/op-e2e/e2eutils/contracts/src/Invoker.sol new file mode 100644 index 0000000000000..6a8118ddb2265 --- /dev/null +++ b/op-e2e/e2eutils/contracts/src/Invoker.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +contract Invoker { + event PrecompileInvoked(address indexed precompile, bytes result); + error PrecompileCallFailed(); + + function invokePrecompile(address _precompile, bytes memory _input) external { + // Call the precompile contract with the provided input + (bool success, bytes memory result) = _precompile.call(_input); + if (!success) { + revert PrecompileCallFailed(); + } + emit PrecompileInvoked(_precompile, result); + } +} diff --git a/op-e2e/e2eutils/interop/contracts/src/emit.sol b/op-e2e/e2eutils/contracts/src/emit.sol similarity index 100% rename from op-e2e/e2eutils/interop/contracts/src/emit.sol rename to op-e2e/e2eutils/contracts/src/emit.sol diff --git a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi b/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi deleted file mode 100644 index 79170e79f968e..0000000000000 --- a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "type": "function", - "name": "emitData", - "inputs": [ - { - "name": "data", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "event", - "name": "DataEmitted", - "inputs": [ - { - "name": "data", - "type": "bytes", - "indexed": true, - "internalType": "bytes" - } - ], - "anonymous": false - } -] diff --git a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin b/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin deleted file mode 100644 index f4c15ab05dca7..0000000000000 --- a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin +++ /dev/null @@ -1 +0,0 @@ -0x6080604052348015600e575f80fd5b5060ff8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a diff --git a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.json b/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.json deleted file mode 100644 index 422f62ea73242..0000000000000 --- a/op-e2e/e2eutils/interop/contracts/test-artifacts/emit.sol/EmitEvent.json +++ /dev/null @@ -1 +0,0 @@ -{"abi":[{"type":"function","name":"emitData","inputs":[{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"DataEmitted","inputs":[{"name":"data","type":"bytes","indexed":true,"internalType":"bytes"}],"anonymous":false}],"bytecode":{"object":"0x6080604052348015600e575f80fd5b5060ff8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a","sourceMap":"58:275:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a","sourceMap":"58:275:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:87;;;;;;:::i;:::-;;:::i;:::-;;;319:4;;307:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;244:87;;:::o;14:591:1:-;84:6;92;145:2;133:9;124:7;120:23;116:32;113:52;;;161:1;158;151:12;113:52;201:9;188:23;230:18;271:2;263:6;260:14;257:34;;;287:1;284;277:12;257:34;325:6;314:9;310:22;300:32;;370:7;363:4;359:2;355:13;351:27;341:55;;392:1;389;382:12;341:55;432:2;419:16;458:2;450:6;447:14;444:34;;;474:1;471;464:12;444:34;519:7;514:2;505:6;501:2;497:15;493:24;490:37;487:57;;;540:1;537;530:12;487:57;571:2;563:11;;;;;593:6;;-1:-1:-1;14:591:1;;-1:-1:-1;;;;14:591:1:o;610:271::-;793:6;785;780:3;767:33;749:3;819:16;;844:13;;;819:16;610:271;-1:-1:-1;610:271:1:o","linkReferences":{}},"methodIdentifiers":{"emitData(bytes)":"d836083e"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"DataEmitted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"emitData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/emit.sol\":\"EmitEvent\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"src/emit.sol\":{\"keccak256\":\"0xdee458d231a8b41e5ba097be7258a6da27501fafb2a6f865705953458aecafbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://912d125138604114be66c8d044a39ef83861e6dc2d5fe3be32a1a4e014ea2763\",\"dweb:/ipfs/QmUx5NRsTXzujjwU1SXMSNp5Wjys3v5PDLuhdpoAyCy7nx\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"bytes","name":"data","type":"bytes","indexed":true}],"type":"event","name":"DataEmitted","anonymous":false},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"emitData"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"src/emit.sol":"EmitEvent"},"evmVersion":"cancun","libraries":{}},"sources":{"src/emit.sol":{"keccak256":"0xdee458d231a8b41e5ba097be7258a6da27501fafb2a6f865705953458aecafbf","urls":["bzz-raw://912d125138604114be66c8d044a39ef83861e6dc2d5fe3be32a1a4e014ea2763","dweb:/ipfs/QmUx5NRsTXzujjwU1SXMSNp5Wjys3v5PDLuhdpoAyCy7nx"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"src/emit.sol","id":17,"exportedSymbols":{"EmitEvent":[16]},"nodeType":"SourceUnit","src":"32:302:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:24:0","nodes":[],"literals":["solidity","^","0.8",".15"]},{"id":16,"nodeType":"ContractDefinition","src":"58:275:0","nodes":[{"id":5,"nodeType":"EventDefinition","src":"133:38:0","nodes":[],"anonymous":false,"eventSelector":"e00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c","name":"DataEmitted","nameLocation":"139:11:0","parameters":{"id":4,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"indexed":true,"mutability":"mutable","name":"data","nameLocation":"165:4:0","nodeType":"VariableDeclaration","scope":5,"src":"151:18:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":2,"name":"bytes","nodeType":"ElementaryTypeName","src":"151:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"150:20:0"}},{"id":15,"nodeType":"FunctionDefinition","src":"244:87:0","nodes":[],"body":{"id":14,"nodeType":"Block","src":"292:39:0","nodes":[],"statements":[{"eventCall":{"arguments":[{"id":11,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":7,"src":"319:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":10,"name":"DataEmitted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":5,"src":"307:11:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory)"}},"id":12,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"307:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":13,"nodeType":"EmitStatement","src":"302:22:0"}]},"functionSelector":"d836083e","implemented":true,"kind":"function","modifiers":[],"name":"emitData","nameLocation":"253:8:0","parameters":{"id":8,"nodeType":"ParameterList","parameters":[{"constant":false,"id":7,"mutability":"mutable","name":"data","nameLocation":"277:4:0","nodeType":"VariableDeclaration","scope":15,"src":"262:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":6,"name":"bytes","nodeType":"ElementaryTypeName","src":"262:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"261:21:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[],"src":"292:0:0"},"scope":16,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"EmitEvent","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[16],"name":"EmitEvent","nameLocation":"67:9:0","scope":17,"usedErrors":[],"usedEvents":[5]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index 29497b9ee6b6d..056226c623e2c 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -31,10 +31,10 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/emit" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/inbox" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/emit" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/interop/contracts/bindings/inbox" "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer" "github.com/ethereum-optimism/optimism/op-service/client"