From ca56bf303baee55df9d8a8e93e8e1acf7a118f73 Mon Sep 17 00:00:00 2001 From: tclemos Date: Wed, 6 Mar 2024 15:56:45 -0300 Subject: [PATCH 1/2] add log0 debug trace e2e tests --- test/contracts/auto/Log0.sol | 23 +++ test/contracts/bin/Log0/Log0.go | 266 ++++++++++++++++++++++++++++++ test/e2e/debug_calltracer_test.go | 3 + test/e2e/debug_shared.go | 70 ++++++++ test/e2e/debug_test.go | 5 +- 5 files changed, 366 insertions(+), 1 deletion(-) create mode 100644 test/contracts/auto/Log0.sol create mode 100644 test/contracts/bin/Log0/Log0.go diff --git a/test/contracts/auto/Log0.sol b/test/contracts/auto/Log0.sol new file mode 100644 index 0000000000..9f4a416284 --- /dev/null +++ b/test/contracts/auto/Log0.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Log0 { + // opcode 0xa0 + function opLog0() public payable { + assembly { + log0(0, 32) + } + } + + function opLog00() public payable { + assembly { + log0(0, 0) + } + } + + function opLog01() public payable { + assembly { + log0(0, 28) + } + } +} \ No newline at end of file diff --git a/test/contracts/bin/Log0/Log0.go b/test/contracts/bin/Log0/Log0.go new file mode 100644 index 0000000000..78cbc26331 --- /dev/null +++ b/test/contracts/bin/Log0/Log0.go @@ -0,0 +1,266 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package Log0 + +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 +) + +// Log0MetaData contains all meta data concerning the Log0 contract. +var Log0MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"opLog0\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"opLog00\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"opLog01\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600f57600080fd5b5060938061001e6000396000f3fe60806040526004361060305760003560e01c80633e2d0b8514603557806357e4605514603d578063ecc5544a146043575b600080fd5b603b6049565b005b603b6050565b603b6056565b601c6000a0565b600080a0565b60206000a056fea26469706673582212209aba01a729d89e6da96ac8ca0b8f1940565356ed4f7849c9af7a95f5188d22d964736f6c634300080c0033", +} + +// Log0ABI is the input ABI used to generate the binding from. +// Deprecated: Use Log0MetaData.ABI instead. +var Log0ABI = Log0MetaData.ABI + +// Log0Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Log0MetaData.Bin instead. +var Log0Bin = Log0MetaData.Bin + +// DeployLog0 deploys a new Ethereum contract, binding an instance of Log0 to it. +func DeployLog0(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Log0, error) { + parsed, err := Log0MetaData.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(Log0Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Log0{Log0Caller: Log0Caller{contract: contract}, Log0Transactor: Log0Transactor{contract: contract}, Log0Filterer: Log0Filterer{contract: contract}}, nil +} + +// Log0 is an auto generated Go binding around an Ethereum contract. +type Log0 struct { + Log0Caller // Read-only binding to the contract + Log0Transactor // Write-only binding to the contract + Log0Filterer // Log filterer for contract events +} + +// Log0Caller is an auto generated read-only Go binding around an Ethereum contract. +type Log0Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Transactor is an auto generated write-only Go binding around an Ethereum contract. +type Log0Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Log0Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Log0Session struct { + Contract *Log0 // 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 +} + +// Log0CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Log0CallerSession struct { + Contract *Log0Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Log0TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Log0TransactorSession struct { + Contract *Log0Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Log0Raw is an auto generated low-level Go binding around an Ethereum contract. +type Log0Raw struct { + Contract *Log0 // Generic contract binding to access the raw methods on +} + +// Log0CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Log0CallerRaw struct { + Contract *Log0Caller // Generic read-only contract binding to access the raw methods on +} + +// Log0TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Log0TransactorRaw struct { + Contract *Log0Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewLog0 creates a new instance of Log0, bound to a specific deployed contract. +func NewLog0(address common.Address, backend bind.ContractBackend) (*Log0, error) { + contract, err := bindLog0(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Log0{Log0Caller: Log0Caller{contract: contract}, Log0Transactor: Log0Transactor{contract: contract}, Log0Filterer: Log0Filterer{contract: contract}}, nil +} + +// NewLog0Caller creates a new read-only instance of Log0, bound to a specific deployed contract. +func NewLog0Caller(address common.Address, caller bind.ContractCaller) (*Log0Caller, error) { + contract, err := bindLog0(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Log0Caller{contract: contract}, nil +} + +// NewLog0Transactor creates a new write-only instance of Log0, bound to a specific deployed contract. +func NewLog0Transactor(address common.Address, transactor bind.ContractTransactor) (*Log0Transactor, error) { + contract, err := bindLog0(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Log0Transactor{contract: contract}, nil +} + +// NewLog0Filterer creates a new log filterer instance of Log0, bound to a specific deployed contract. +func NewLog0Filterer(address common.Address, filterer bind.ContractFilterer) (*Log0Filterer, error) { + contract, err := bindLog0(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Log0Filterer{contract: contract}, nil +} + +// bindLog0 binds a generic wrapper to an already deployed contract. +func bindLog0(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := Log0MetaData.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 (_Log0 *Log0Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Log0.Contract.Log0Caller.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 (_Log0 *Log0Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.Contract.Log0Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Log0 *Log0Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Log0.Contract.Log0Transactor.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 (_Log0 *Log0CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Log0.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 (_Log0 *Log0TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Log0 *Log0TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Log0.Contract.contract.Transact(opts, method, params...) +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0Transactor) OpLog0(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog0") +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0Session) OpLog0() (*types.Transaction, error) { + return _Log0.Contract.OpLog0(&_Log0.TransactOpts) +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0TransactorSession) OpLog0() (*types.Transaction, error) { + return _Log0.Contract.OpLog0(&_Log0.TransactOpts) +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0Transactor) OpLog00(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog00") +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0Session) OpLog00() (*types.Transaction, error) { + return _Log0.Contract.OpLog00(&_Log0.TransactOpts) +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0TransactorSession) OpLog00() (*types.Transaction, error) { + return _Log0.Contract.OpLog00(&_Log0.TransactOpts) +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0Transactor) OpLog01(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog01") +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0Session) OpLog01() (*types.Transaction, error) { + return _Log0.Contract.OpLog01(&_Log0.TransactOpts) +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0TransactorSession) OpLog01() (*types.Transaction, error) { + return _Log0.Contract.OpLog01(&_Log0.TransactOpts) +} diff --git a/test/e2e/debug_calltracer_test.go b/test/e2e/debug_calltracer_test.go index 2108884f5c..f2a8d756fe 100644 --- a/test/e2e/debug_calltracer_test.go +++ b/test/e2e/debug_calltracer_test.go @@ -104,6 +104,9 @@ func TestDebugTraceTransactionCallTracer(t *testing.T) { {name: "memory", prepare: prepareMemory, createSignedTx: createMemorySignedTx}, {name: "bridge", prepare: prepareBridge, createSignedTx: createBridgeSignedTx}, {name: "deploy create 0", createSignedTx: createDeployCreate0SignedTx}, + {name: "log0 all zeros", prepare: prepareLog0, createSignedTx: createLog0AllZeros}, + {name: "log0 empty", prepare: prepareLog0, createSignedTx: createLog0Empty}, + {name: "log0 short", prepare: prepareLog0, createSignedTx: createLog0Short}, // failed transactions {name: "sc deployment reverted", createSignedTx: createScDeployRevertedSignedTx}, diff --git a/test/e2e/debug_shared.go b/test/e2e/debug_shared.go index 08a0367ffb..f0c78ed663 100644 --- a/test/e2e/debug_shared.go +++ b/test/e2e/debug_shared.go @@ -26,6 +26,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Depth" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/EmitLog" + "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Log0" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Memory" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/OpCallAux" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Revert2" @@ -883,3 +884,72 @@ func sendEthTransfersWithoutWaiting(t *testing.T, ctx context.Context, client *e log.Debugf("sending eth transfer: %v", signedTx.Hash().String()) } } + +func prepareLog0(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client) (map[string]interface{}, error) { + _, tx, sc, err := Log0.DeployLog0(auth, client) + require.NoError(t, err) + + err = operations.WaitTxToBeMined(ctx, client, tx, operations.DefaultTimeoutTxToBeMined) + require.NoError(t, err) + + return map[string]interface{}{ + "sc": sc, + }, nil +} + +func createLog0AllZeros(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog0(&opts) + require.NoError(t, err) + + return tx, nil +} + +func createLog0Empty(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog00(&opts) + require.NoError(t, err) + + return tx, nil +} + +func createLog0Short(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog01(&opts) + require.NoError(t, err) + + return tx, nil +} diff --git a/test/e2e/debug_test.go b/test/e2e/debug_test.go index a514136ad2..50cfc6c22b 100644 --- a/test/e2e/debug_test.go +++ b/test/e2e/debug_test.go @@ -318,6 +318,9 @@ func TestDebugTraceTransaction(t *testing.T) { {name: "memory", prepare: prepareMemory, createSignedTx: createMemorySignedTx}, {name: "bridge", prepare: prepareBridge, createSignedTx: createBridgeSignedTx}, {name: "deploy create 0", createSignedTx: createDeployCreate0SignedTx}, + {name: "log0 all zeros", prepare: prepareLog0, createSignedTx: createLog0AllZeros}, + {name: "log0 empty", prepare: prepareLog0, createSignedTx: createLog0Empty}, + {name: "log0 short", prepare: prepareLog0, createSignedTx: createLog0Short}, // failed transactions {name: "sc deployment reverted", createSignedTx: createScDeployRevertedSignedTx}, @@ -453,7 +456,7 @@ func TestDebugTraceTransaction(t *testing.T) { resultForTx := convertJson(t, response.Result, debugID) results[network.Name] = resultForTx - saveTraceResultToFile(t, fmt.Sprintf("default_tracer_%v_%v", tcIdx, tc.name), network.Name, signedTx, response.Result, true) + saveTraceResultToFile(t, fmt.Sprintf("default_tracer_%v_%v", tcIdx, tc.name), network.Name, signedTx, response.Result, false) } referenceValueMap := results[l1NetworkName] From f3acd2c5a33bb603a4cbc2288cd94ef9e2567e0b Mon Sep 17 00:00:00 2001 From: tclemos Date: Wed, 6 Mar 2024 15:58:55 -0300 Subject: [PATCH 2/2] add log0 debug trace e2e tests --- test/e2e/debug_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/debug_test.go b/test/e2e/debug_test.go index 50cfc6c22b..e32802eed0 100644 --- a/test/e2e/debug_test.go +++ b/test/e2e/debug_test.go @@ -456,7 +456,7 @@ func TestDebugTraceTransaction(t *testing.T) { resultForTx := convertJson(t, response.Result, debugID) results[network.Name] = resultForTx - saveTraceResultToFile(t, fmt.Sprintf("default_tracer_%v_%v", tcIdx, tc.name), network.Name, signedTx, response.Result, false) + saveTraceResultToFile(t, fmt.Sprintf("default_tracer_%v_%v", tcIdx, tc.name), network.Name, signedTx, response.Result, true) } referenceValueMap := results[l1NetworkName]