├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── feature.md │ └── question.md ├── dependabot.yml ├── hooks │ └── pre-commit ├── pull_request_template.md └── workflows │ ├── codeql.yml │ ├── image-build.yml │ ├── jsonschema.yml │ ├── lint.yml │ ├── push-docker-develop.yml │ ├── push-docker-tagged.yml │ ├── release.yml │ ├── sonarqube.yml │ ├── test-e2e.yml │ ├── test-from-prover.yml │ ├── test-full-non-e2e.yml │ └── updatedeps.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yaml ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── aggregator ├── aggregator.go ├── aggregator_test.go ├── aggregator_xlayer.go ├── config.go ├── config_xlayer.go ├── interfaces.go ├── metrics │ └── metrics.go ├── mocks │ ├── mock_dbtx.go │ ├── mock_etherman.go │ ├── mock_etherman_xlayer.go │ ├── mock_ethtxmanager.go │ ├── mock_profitabilitychecker.go │ ├── mock_prover.go │ └── mock_state.go ├── profitabilitychecker.go └── prover │ ├── aggregator.pb.go │ ├── aggregator_grpc.pb.go │ └── prover.go ├── ci ├── e2e-group-dac-1 │ ├── cli_test.go │ └── datacommittee_xlayer_test.go ├── e2e-group1 │ ├── ethtransfer_test.go │ ├── preEIP155_test.go │ └── shared.go ├── e2e-group10 │ ├── forced_batches_test.go │ ├── forced_batches_vector_group2_test.go │ ├── forced_batches_vector_shared.go │ └── shared.go ├── e2e-group11 │ ├── forced_batches_vector_group3_test.go │ ├── forced_batches_vector_shared.go │ └── shared.go ├── e2e-group2 │ ├── gasless_test.go │ ├── pool_test.go │ └── shared.go ├── e2e-group3 │ ├── sc_test.go │ └── shared.go ├── e2e-group4 │ ├── jsonrpc1_test.go │ └── shared.go ├── e2e-group5 │ ├── debug_shared.go │ ├── debug_test.go │ └── shared.go ├── e2e-group6 │ └── permissionlessrpc_test.go ├── e2e-group7 │ ├── jsonrpc2_test.go │ └── shared.go ├── e2e-group8 │ ├── debug_calltracer_test.go │ ├── debug_shared.go │ └── shared.go ├── e2e-group9 │ ├── forced_batches_vector_group1_test.go │ ├── forced_batches_vector_shared.go │ └── shared.go └── vectors ├── cmd ├── approve.go ├── dumpstate.go ├── encryptkey.go ├── jsonschema.go ├── main.go ├── readme.md ├── restore.go ├── run.go ├── run_xlayer.go ├── snapshot.go └── version.go ├── config ├── apollo │ ├── apollo.go │ ├── apollo_test.go │ ├── common.go │ ├── jsonrpc.go │ ├── l2gaspricer.go │ ├── namespace.go │ ├── pool.go │ └── sequencer.go ├── cardonagenesis.go ├── config.go ├── config_test.go ├── config_xlayer.go ├── default.go ├── environments │ ├── cardona │ │ ├── example.env │ │ ├── node.config.toml │ │ ├── postgresql.conf │ │ └── prover.config.json │ ├── local │ │ ├── local.genesis.config.json │ │ └── local.node.config.toml │ ├── mainnet │ │ ├── example.env │ │ ├── node.config.toml │ │ ├── postgresql.conf │ │ └── prover.config.json │ └── testnet │ │ ├── example.env │ │ ├── node.config.toml │ │ ├── postgresql.conf │ │ └── prover.config.json ├── example.keystore ├── gen_json_schema.go ├── gen_json_schema_test.go ├── mainnetgenesis.go ├── metrics │ └── prometheus │ │ └── prometheus.yml ├── network.go ├── network_test.go ├── network_xlayer.go ├── readme.md ├── testnetgenesis.go └── types │ ├── apolloconfig.go │ ├── duration.go │ ├── duration_test.go │ └── keystore.go ├── dataavailability ├── config.go ├── dataavailability.go ├── datacommittee │ ├── datacommittee.go │ └── datacommittee_test.go └── interfaces.go ├── db ├── config.go ├── db.go ├── logger.go ├── migrations │ ├── pool │ │ ├── 0001.sql │ │ ├── 0002.sql │ │ ├── 0003.sql │ │ ├── 0004.sql │ │ ├── 0005.sql │ │ ├── 0006.sql │ │ ├── 0007.sql │ │ ├── 0008.sql │ │ ├── 0009.sql │ │ ├── 0010.sql │ │ ├── 0011.sql │ │ ├── 0011_test.go │ │ ├── 0012.sql │ │ ├── 0012_test.go │ │ ├── 0013.sql │ │ ├── 0013_test.go │ │ ├── 1001.sql │ │ ├── 1002.sql │ │ ├── 1003.sql │ │ ├── 1004.sql │ │ └── utils_test.go │ └── state │ │ ├── 0001.sql │ │ ├── 0002.sql │ │ ├── 0002_test.go │ │ ├── 0003.sql │ │ ├── 0004.sql │ │ ├── 0005.sql │ │ ├── 0006.sql │ │ ├── 0007.sql │ │ ├── 0008.sql │ │ ├── 0008_test.go │ │ ├── 0009.sql │ │ ├── 0009_test.go │ │ ├── 0010.sql │ │ ├── 0010_test.go │ │ ├── 0011.sql │ │ ├── 0011_test.go │ │ ├── 0012.sql │ │ ├── 0012_test.go │ │ ├── 0013.sql │ │ ├── 0013_test.go │ │ ├── 0014.sql │ │ ├── 0014_test.go │ │ ├── 0015.sql │ │ ├── 0015_test.go │ │ ├── 0016.sql │ │ ├── 0016_test.go │ │ ├── 0017.sql │ │ ├── 0018.sql │ │ ├── 0018_test.go │ │ ├── 0019.sql │ │ ├── 0019_test.go │ │ ├── 0020.sql │ │ ├── 0020_test.go │ │ ├── 0021.sql │ │ ├── 0021_test.go │ │ └── utils_test.go └── scripts │ ├── init_event_db.sql │ ├── init_prover_db.sql │ └── single_db_server.sql ├── docker-compose.yml ├── docs ├── architecture.drawio.png ├── ci │ ├── README.md │ ├── actions.md │ ├── dependabot.md │ ├── groups.md │ ├── ok-to-test.md │ └── opsman.md ├── components │ ├── account_keystore.md │ ├── aggregator.md │ ├── databases.md │ ├── prover.md │ ├── rpc.md │ ├── sequencer.md │ └── synchronizer.md ├── config-file │ ├── custom_network-config-doc.html │ ├── custom_network-config-doc.md │ ├── custom_network-config-schema.json │ ├── node-config-doc.html │ ├── node-config-doc.md │ ├── node-config-schema.json │ ├── schema_doc.css │ ├── schema_doc.min.js │ └── templates │ │ ├── js │ │ ├── badge_type.html │ │ ├── base.html │ │ ├── breadcrumbs_no_object.html │ │ ├── breadcrumbs_object.html │ │ ├── content.html │ │ ├── macro_restriction.html │ │ ├── schema_doc.css │ │ ├── schema_doc.js │ │ ├── schema_doc.min.js │ │ ├── section_array.html │ │ ├── section_conditional_subschema.html │ │ ├── section_description.html │ │ ├── section_examples.html │ │ ├── section_not.html │ │ ├── section_properties_2.html │ │ ├── section_properties_object.html │ │ ├── section_undocumented_required_properties.html │ │ └── tabbed_section.html │ │ └── md │ │ ├── base.md │ │ ├── breadcrumbs.md │ │ ├── content.md │ │ ├── generate_toml_example.md │ │ ├── section_array.md │ │ ├── section_conditional_subschema.md │ │ ├── section_description.md │ │ ├── section_examples.md │ │ ├── section_not.md │ │ ├── section_one_of.md │ │ ├── section_properties_details.md │ │ ├── section_undocumented_required_properties.md │ │ └── tabbed_section.md ├── configuration.md ├── design │ └── synchronizer │ │ ├── l1_sync_channels_flow_v2.drawio.png │ │ └── l1_synchronization.md ├── json-rpc-endpoints.md ├── mocks.md ├── modes.md ├── networks.md ├── production-setup.md ├── running_local.md ├── snap_restore.md ├── state-steps.drawio.png ├── upgrade_testnet_rpc_fork9.md └── zkEVM-custom-endpoints.md ├── encoding └── encoding.go ├── etherman ├── config.go ├── errors.go ├── errors_test.go ├── etherman.go ├── etherman_test.go ├── etherman_xlayer.go ├── etherscan │ ├── etherscan.go │ └── etherscan_test.go ├── ethgasstation │ ├── ethgasstation.go │ └── ethgasstation_test.go ├── metrics │ └── metrics.go ├── mock_etherman.go ├── mock_etherscan.go ├── mock_ethgasstation.go ├── properties_xlayer.go ├── simulated.go ├── smartcontracts │ ├── abi │ │ ├── dataavailabilityprotocol_xlayer.abi │ │ ├── datacommittee.abi │ │ ├── etrogpolygonzkevm.abi │ │ ├── mockpolygonrollupmanager.abi │ │ ├── mockverifier.abi │ │ ├── oldpolygonzkevm.abi │ │ ├── oldpolygonzkevmbridge.abi │ │ ├── oldpolygonzkevmglobalexitroot.abi │ │ ├── pol.abi │ │ ├── polygondatacommittee_xlayer.abi │ │ ├── polygonrollupmanager.abi │ │ ├── polygonvalidium_xlayer.abi │ │ ├── polygonzkevm.abi │ │ ├── polygonzkevmbridge.abi │ │ ├── polygonzkevmbridgel2.abi │ │ ├── polygonzkevmglobalexitroot.abi │ │ └── proxy.abi │ ├── bin │ │ ├── datacommittee.bin │ │ ├── etrogpolygonzkevm.bin │ │ ├── mockpolygonrollupmanager.bin │ │ ├── mockverifier.bin │ │ ├── oldpolygonzkevm.bin │ │ ├── oldpolygonzkevmbridge.bin │ │ ├── oldpolygonzkevmglobalexitroot.bin │ │ ├── pol.bin │ │ ├── polygondatacommittee_xlayer.bin │ │ ├── polygonrollupmanager.bin │ │ ├── polygonvalidium_xlayer.bin │ │ ├── polygonzkevm.bin │ │ ├── polygonzkevmbridge.bin │ │ ├── polygonzkevmbridgel2.bin │ │ ├── polygonzkevmglobalexitroot.bin │ │ └── proxy.bin │ ├── dataavailabilityprotocol_xlayer │ │ └── dataavailabilityprotocol.go │ ├── etrogpolygonzkevm │ │ └── etrogpolygonzkevm.go │ ├── mockpolygonrollupmanager │ │ └── mockpolygonrollupmanager.go │ ├── mockverifier │ │ └── mockverifier.go │ ├── oldpolygonzkevm │ │ └── oldpolygonzkevm.go │ ├── oldpolygonzkevmbridge │ │ └── oldpolygonzkevmbridge.go │ ├── oldpolygonzkevmglobalexitroot │ │ └── oldpolygonzkevmglobalexitroot.go │ ├── pol │ │ └── pol.go │ ├── polygondatacommittee_xlayer │ │ └── polygondatacommittee_xlayer.go │ ├── polygonrollupmanager │ │ └── polygonrollupmanager.go │ ├── polygonvalidium_xlayer │ │ └── polygonvalidium_xlayer.go │ ├── polygonzkevm │ │ └── polygonzkevm.go │ ├── polygonzkevmbridge │ │ └── polygonzkevmbridge.go │ ├── polygonzkevmglobalexitroot │ │ └── polygonzkevmglobalexitroot.go │ ├── proxy │ │ └── proxy.go │ └── script.sh ├── types.go └── types │ ├── finalproofinputs.go │ └── sequence.go ├── ethtxmanager ├── config.go ├── custodialassets_xlayer.go ├── custodialassetsconfig_xlayer.go ├── custodialassetshttp_xlayer.go ├── custodialassetshttp_xlayer_test.go ├── custodialassetshttpauth_xlayer.go ├── custodialassetshttpauth_xlayer_test.go ├── ethtxmanager.go ├── ethtxmanager_test.go ├── interfaces.go ├── metrics │ └── metrics_xlayer.go ├── mock_etherman_test.go ├── mock_etherman_xlayer_test.go ├── mock_state_test.go ├── monitoredtx.go ├── monitoredtx_test.go ├── pgstorage.go └── pgstorage_test.go ├── event ├── config.go ├── event.go ├── eventlog.go ├── eventlog_test.go ├── interfaces.go ├── nileventstorage │ └── nileventstorage.go └── pgeventstorage │ └── pgeventstorage.go ├── gasprice ├── apollo_xlayer.go ├── config.go ├── default.go ├── default_test.go ├── fixed_xlayer.go ├── fixed_xlayer_test.go ├── follower.go ├── follower_test.go ├── gaspricesuggester.go ├── interfaces.go ├── kafka_proc_xlayer.go ├── kafka_proc_xlayer_test.go ├── lastnbatches.go ├── mock_etherman.go ├── mock_pool.go └── sorter.go ├── go.mod ├── go.sum ├── hex ├── hex.go └── hex_test.go ├── jsonrpc ├── api_authentication_xlayer.go ├── api_relay_filter_xlayer.go ├── api_relay_xlayer.go ├── apollo_xlayer.go ├── client │ ├── client.go │ ├── client_xlayer.go │ ├── eth.go │ ├── zkevm.go │ └── zkevm_test.go ├── config.go ├── config_xlayer.go ├── dynamic_gas_price_xlayer.go ├── endpoints_debug.go ├── endpoints_debug_xlayer.go ├── endpoints_eth.go ├── endpoints_eth_test.go ├── endpoints_eth_xlayer.go ├── endpoints_net.go ├── endpoints_txpool.go ├── endpoints_web3.go ├── endpoints_web3_test.go ├── endpoints_zkevm.go ├── endpoints_zkevm.openrpc.json ├── endpoints_zkevm_test.go ├── endpoints_zkevm_xlayer.go ├── handler.go ├── handler_xlayer.go ├── interfaces.go ├── metrics │ ├── metrics.go │ └── metrics_xlayer.go ├── mock_storage.go ├── mocks │ ├── mock_etherman.go │ ├── mock_pool.go │ ├── mock_pool_xlayer.go │ ├── mock_state.go │ └── mock_state_xlayer.go ├── nacos │ ├── start_xlayer.go │ └── utils_xlayer.go ├── query.go ├── ratelimit_xlayer.go ├── server.go ├── server_test.go ├── server_xlayer.go ├── storage.go ├── types │ ├── codec.go │ ├── codec_test.go │ ├── errors.go │ ├── errors_test.go │ ├── interfaces.go │ ├── query.go │ ├── types.go │ ├── types_test.go │ └── types_xlayer.go └── wsconn.go ├── l1infotree ├── hash.go ├── hash_test.go ├── tree.go └── tree_test.go ├── log ├── config.go ├── log.go └── log_test.go ├── merkletree ├── client.go ├── config.go ├── hashdb │ ├── hashdb.pb.go │ └── hashdb_grpc.pb.go ├── key.go ├── key_test.go ├── leaf.go ├── split.go ├── split_test.go ├── tree.go └── types.go ├── metrics ├── api.go ├── config.go ├── prometheus.go ├── prometheus_test.go └── prometheus_xlayer.go ├── pool ├── apollo_xlayer.go ├── config.go ├── config_test.go ├── effectivegasprice.go ├── effectivegasprice_test.go ├── errors.go ├── interfaces.go ├── pgpoolstorage │ ├── pgpoolstorage.go │ └── pgpoolstorage_xlayer.go ├── pool.go ├── pool_test.go ├── pool_xlayer.go ├── trace │ └── trace.go ├── transaction.go ├── transaction_xlayer.go ├── validation.go └── validation_test.go ├── proto ├── include │ └── google │ │ └── protobuf │ │ └── empty.proto └── src │ └── proto │ ├── aggregator │ └── v1 │ │ └── aggregator.proto │ ├── datastream │ └── v1 │ │ └── datastream.proto │ ├── executor │ └── v1 │ │ └── executor.proto │ └── hashdb │ └── v1 │ └── hashdb.proto ├── sequencer ├── addrqueue.go ├── addrqueue_test.go ├── addrqueue_xlayer.go ├── apollo_xlayer.go ├── batch.go ├── closingsignalsmanager_test.go ├── config.go ├── datastreamer.go ├── dbmanager_test.go ├── errors.go ├── finalizer.go ├── finalizer_test.go ├── finalizer_xlayer.go ├── forcedbatch.go ├── interfaces.go ├── l2block.go ├── l2block_xlayer.go ├── metrics.go ├── metrics │ ├── logstatistics_xlayer.go │ ├── logstatisticsimpl_xlayer.go │ ├── logstatisticsimpl_xlayer_test.go │ ├── metrics.go │ └── metrics_xlayer.go ├── metrics_xlayer.go ├── metrics_xlayer_test.go ├── mock_dbtx.go ├── mock_etherman.go ├── mock_etherman_xlayer.go ├── mock_pool.go ├── mock_pool_xlayer.go ├── mock_state.go ├── mock_worker.go ├── mock_worker_xlayer.go ├── pooltx_counter_xlayer.go ├── sequencer.go ├── sequencer_xlayer.go ├── timeoutCond.go ├── txsorted_list.go ├── txsorted_list_test.go ├── txtracker.go ├── waitgroupcount.go ├── worker.go ├── worker_test.go └── worker_xlayer.go ├── sequencesender ├── config.go ├── interfaces.go ├── interfaces_xlayer.go ├── mock_etherman.go ├── mock_etherman_xlayer.go ├── mock_ethtxmanager.go ├── mock_state.go ├── sequencesender.go ├── sequencesender_test.go └── sequencesender_xlayer.go ├── sonar-project.properties ├── state ├── batch.go ├── batchV2.go ├── batchV2_test.go ├── block.go ├── config.go ├── converters.go ├── convertersV2.go ├── crypto.go ├── datastream.go ├── datastream │ └── datastream.pb.go ├── effectivegasprice.go ├── encoding_batch_v2.go ├── encoding_batch_v2_test.go ├── errors.go ├── fakedb.go ├── forcedbatch.go ├── forkid.go ├── genesis.go ├── globalexitroot.go ├── helper.go ├── infinite.go ├── interfaces.go ├── l1infotree.go ├── l1infotree_test.go ├── l2block.go ├── l2block_test.go ├── metrics │ └── metrics.go ├── mocks │ ├── mock_dbtx.go │ ├── mock_executor_service_client.go │ ├── mock_storage.go │ └── mock_storage_xlayer.go ├── pgstatestorage │ ├── batch.go │ ├── block.go │ ├── datastream.go │ ├── forcedbatch.go │ ├── forkid.go │ ├── forkid_external_test.go │ ├── forkid_test.go │ ├── globalexitroot.go │ ├── interfaces.go │ ├── l1infotree.go │ ├── l2block.go │ ├── l2block_xlayer.go │ ├── pgstatestorage.go │ ├── pgstatestorage_test.go │ ├── pgstatestorage_xlayer.go │ ├── proof.go │ ├── syncinginfo.go │ └── transaction.go ├── proof.go ├── queue.go ├── queue_test.go ├── reset.go ├── runtime │ ├── executor │ │ ├── client.go │ │ ├── config.go │ │ ├── errors.go │ │ ├── executor.pb.go │ │ └── executor_grpc.pb.go │ ├── fakevm │ │ ├── account.go │ │ ├── analysis.go │ │ ├── common.go │ │ ├── contract.go │ │ ├── contracts.go │ │ ├── eips.go │ │ ├── errors.go │ │ ├── fakedb.go │ │ ├── fakevm.go │ │ ├── gas.go │ │ ├── gas_table.go │ │ ├── instructions.go │ │ ├── interpreter.go │ │ ├── jump_table.go │ │ ├── logger.go │ │ ├── memory.go │ │ ├── memory_table.go │ │ ├── opcodes.go │ │ ├── operations_acl.go │ │ ├── stack.go │ │ └── stack_table.go │ ├── instrumentation │ │ ├── executortrace.go │ │ ├── intrumentation_test.go │ │ ├── js │ │ │ ├── bigint.go │ │ │ ├── goja.go │ │ │ └── internal │ │ │ │ └── tracers │ │ │ │ ├── 4byte_tracer_legacy.js │ │ │ │ ├── bigram_tracer.js │ │ │ │ ├── call_tracer_legacy.js │ │ │ │ ├── evmdis_tracer.js │ │ │ │ ├── noop_tracer_legacy.js │ │ │ │ ├── opcount_tracer.js │ │ │ │ ├── prestate_tracer_legacy.js │ │ │ │ ├── tracers.go │ │ │ │ ├── trigram_tracer.js │ │ │ │ └── unigram_tracer.js │ │ ├── storediff.go │ │ └── tracers │ │ │ ├── native │ │ │ ├── 4byte.go │ │ │ ├── call.go │ │ │ ├── call_flat.go │ │ │ ├── call_flat_xlayer.go │ │ │ ├── gen_account_json.go │ │ │ ├── gen_callframe_json.go │ │ │ ├── gen_flatcallaction_json.go │ │ │ ├── gen_flatcallresult_json.go │ │ │ ├── mux.go │ │ │ ├── noop.go │ │ │ └── prestate.go │ │ │ ├── structlogger │ │ │ └── structlogger.go │ │ │ └── tracers.go │ └── runtime.go ├── stack.go ├── state.go ├── syncinginfo.go ├── syncinginfo_test.go ├── test │ ├── forkid_common │ │ └── common.go │ ├── forkid_dragonfruit │ │ ├── dragonfruit_test.go │ │ └── genesis_test.go │ ├── forkid_etrog │ │ ├── etrog_test.go │ │ └── genesis_test.go │ ├── forkid_independent │ │ └── independent_test.go │ └── helper_test.go ├── trace.go ├── transaction.go ├── transaction_xlayer.go ├── types.go └── types_xlayer.go ├── synchronizer ├── actions │ ├── actions.go │ ├── check_l2block.go │ ├── check_l2block_processor_decorator.go │ ├── check_l2block_test.go │ ├── elderberry │ │ ├── mocks │ │ │ ├── previous_processor.go │ │ │ └── state_l1_sequence_batches_elderberry.go │ │ ├── processor_l1_initial_sequence_batches.go │ │ ├── processor_l1_sequence_batches.go │ │ └── processor_l1_sequence_batches_test.go │ ├── etrog │ │ ├── processor_l1_info_tree_update.go │ │ ├── processor_l1_info_tree_update_test.go │ │ ├── processor_l1_sequence_batches.go │ │ ├── processor_l1_sequence_batches_test.go │ │ └── processor_l1_update_etrog_sequence.go │ ├── forksids.go │ ├── incaberry │ │ ├── processor_l1_forced_batches.go │ │ ├── processor_l1_forced_batches_test.go │ │ ├── processor_l1_forkid.go │ │ ├── processor_l1_forkid_test.go │ │ ├── processor_l1_global_exit_root.go │ │ ├── processor_l1_sequence_batches.go │ │ ├── processor_l1_sequence_batches_test.go │ │ ├── processor_l1_sequence_batches_xlayer.go │ │ ├── processor_l1_sequence_force_batches.go │ │ └── processor_l1_verify_batch.go │ ├── processor_base.go │ └── processor_manager │ │ ├── processor_manager.go │ │ ├── processors_builder.go │ │ └── test │ │ ├── mock_processor.go │ │ ├── processor_manager_test.go │ │ └── processors_builder_test.go ├── common │ ├── converters.go │ ├── critical_error_halt.go │ ├── generic_cache.go │ ├── generic_cache_test.go │ ├── log_helper.go │ ├── log_helper_test.go │ ├── mock_time_provider.go │ ├── reorg_error.go │ ├── syncinterfaces │ │ ├── async_l1_block_checker.go │ │ ├── critical_error_handler.go │ │ ├── eth_tx_manager.go │ │ ├── etherman.go │ │ ├── evenlog.go │ │ ├── mocks │ │ │ ├── async_l1_block_checker.go │ │ │ ├── critical_error_handler.go │ │ │ ├── eth_tx_manager.go │ │ │ ├── etherman_full_interface.go │ │ │ ├── etherman_full_interface_xlayer.go │ │ │ ├── etherman_get_latest_batch_number.go │ │ │ ├── event_log_interface.go │ │ │ ├── l1_block_checker_integrator.go │ │ │ ├── pool_interface.go │ │ │ ├── state_begin_transaction_interface.go │ │ │ ├── state_full_interface.go │ │ │ ├── state_full_interface_xlayer.go │ │ │ ├── state_get_batch_by_number_interface.go │ │ │ ├── sync_trusted_state_executor.go │ │ │ ├── synchronizer_clean_trusted_state.go │ │ │ ├── synchronizer_flush_id_manager.go │ │ │ ├── synchronizer_full_interface.go │ │ │ ├── synchronizer_is_trusted_sequencer.go │ │ │ ├── zkevm_client_ethereum_compatible_interface.go │ │ │ ├── zkevm_client_ethereum_compatible_l2_block_getter.go │ │ │ ├── zkevm_client_get_l2_block_by_number.go │ │ │ ├── zkevm_client_global_exit_root_getter.go │ │ │ ├── zkevm_client_interface.go │ │ │ └── zkevm_client_trusted_batches_getter.go │ │ ├── pool.go │ │ ├── state.go │ │ ├── sync.go │ │ ├── sync_trusted_state_executor.go │ │ ├── zkevm_ethereum_compatible_client.go │ │ └── zkevm_rpc.go │ └── time_provider.go ├── config.go ├── control_flush_id.go ├── default_l1processors.go ├── ext_control.go ├── interfaces.go ├── l1_check_block │ ├── async.go │ ├── async_test.go │ ├── check_l1block.go │ ├── check_l1block_test.go │ ├── common.go │ ├── integration.go │ ├── integration_test.go │ ├── mocks │ │ ├── l1_block_checker.go │ │ ├── l1_requester.go │ │ ├── safe_l1_block_number_fetcher.go │ │ ├── state_for_l1_block_checker_integration.go │ │ ├── state_interfacer.go │ │ ├── state_pre_check_interfacer.go │ │ └── sync_check_reorger.go │ ├── pre_check_l1block.go │ ├── pre_check_l1block_test.go │ ├── safe_l1_block.go │ └── safe_l1_block_test.go ├── l1_parallel_sync │ ├── block_range.go │ ├── l1_common.go │ ├── l1_data_message.go │ ├── l1_etherman_interface.go │ ├── l1_filter_send_orderer_results_to_synchronizer.go │ ├── l1_filter_send_orderer_results_to_synchronizer_test.go │ ├── l1_live_block_ranges.go │ ├── l1_live_block_ranges_test.go │ ├── l1_rollup_info_consumer.go │ ├── l1_rollup_info_consumer_statistics.go │ ├── l1_rollup_info_consumer_statistics_test.go │ ├── l1_rollup_info_consumer_test.go │ ├── l1_rollup_info_producer.go │ ├── l1_rollup_info_producer_statistics.go │ ├── l1_rollup_info_producer_statistics_test.go │ ├── l1_rollup_info_producer_test.go │ ├── l1_sync_orchestration.go │ ├── l1_sync_orchestration_test.go │ ├── l1_syncstatus.go │ ├── l1_syncstatus_test.go │ ├── l1_worker_etherman.go │ ├── l1_worker_etherman_test.go │ ├── l1_workers.go │ ├── l1_workers_decorator_limit_retries_by_time.go │ ├── l1_workers_decorator_limit_retries_by_time_test.go │ ├── mock_l1_parallel_etherman_interface.go │ ├── mock_l1_rollup_consumer_interface.go │ ├── mock_l1_rollup_producer_interface.go │ ├── mock_synchronizer_process_block_range_interface.go │ ├── mock_worker.go │ └── mock_workers_interface.go ├── l1event_orders │ └── sequence_extractor.go ├── l2_sync │ ├── config.go │ ├── l2_shared │ │ ├── batch_compare.go │ │ ├── errors.go │ │ ├── mocks │ │ │ ├── batch_processor.go │ │ │ ├── l1_sync_global_exit_root_checker.go │ │ │ ├── post_closed_batch_checker.go │ │ │ ├── state_interface.go │ │ │ ├── state_post_closed_batch_check_l2_block.go │ │ │ ├── state_sync_trusted_state_executor_selector.go │ │ │ └── sync_trusted_batch_executor.go │ │ ├── post_closed_batch_check_l2block.go │ │ ├── processor_trusted_batch_selector.go │ │ ├── processor_trusted_batch_sync.go │ │ ├── tests │ │ │ ├── batch_compare_test.go │ │ │ ├── processor_trusted_batch_selector_test.go │ │ │ ├── processor_trusted_batch_sync_test.go │ │ │ └── trusted_batches_retrieve_test.go │ │ ├── trusted_batches_retrieve.go │ │ └── trusted_state.go │ ├── l2_sync_etrog │ │ ├── check_sync_status_to_process_batch.go │ │ ├── check_sync_status_to_process_batch_test.go │ │ ├── executor_trusted_batch_sync.go │ │ ├── executor_trusted_batch_sync_test.go │ │ └── mocks │ │ │ ├── state_ger_inteface.go │ │ │ └── state_interface.go │ └── l2_sync_incaberry │ │ └── sync_trusted_state.go ├── metrics │ ├── metrics.go │ └── metrics_xlayer.go ├── mock_etherman.go ├── mock_state.go ├── mocks │ └── mock_dbtx.go ├── synchronizer.go └── synchronizer_test.go ├── test ├── Makefile ├── aggregator.keystore ├── config │ ├── debug.node.config.toml │ ├── grafana │ │ ├── dashboard-dockers.json │ │ ├── dashboard-node.json │ │ ├── dashboards.yml │ │ └── datasources.yml │ ├── root-ca-cert │ ├── signer.config.toml │ ├── telegraf.conf │ ├── test-member.keystore │ ├── test.bridge.config.toml │ ├── test.da.toml │ ├── test.executor.config.json │ ├── test.genesis-v1tov2.config.json │ ├── test.genesis.config.json │ ├── test.mock.prover.config.json │ ├── test.node.config.toml │ ├── test.permissionless.prover.config.json │ ├── test.prover.config.json │ └── test.sentinel.config.json ├── constants │ ├── effective_percentage.go │ ├── environment_variables.go │ └── smart_contracts.go ├── contracts │ ├── WETH.sol │ ├── auto │ │ ├── BridgeA.sol │ │ ├── BridgeB.sol │ │ ├── BridgeC.sol │ │ ├── BridgeD.sol │ │ ├── Called.sol │ │ ├── Caller.sol │ │ ├── ChainCallLevel1.sol │ │ ├── ChainCallLevel2.sol │ │ ├── ChainCallLevel3.sol │ │ ├── ChainCallLevel4.sol │ │ ├── ConstructorMap.sol │ │ ├── Counter.sol │ │ ├── CounterAndBlock.sol │ │ ├── Creates.sol │ │ ├── DeployCreate0.sol │ │ ├── Depth.sol │ │ ├── Destruct.sol │ │ ├── Double.sol │ │ ├── ERC20.sol │ │ ├── EmitLog.sol │ │ ├── EmitLog2.sol │ │ ├── FFFFFFFF.sol │ │ ├── FailureTest.sol │ │ ├── HasOpCode.sol │ │ ├── Interaction.sol │ │ ├── Log0.sol │ │ ├── Memory.sol │ │ ├── OpCallAux.sol │ │ ├── Read.sol │ │ ├── Revert.sol │ │ ├── Revert2.sol │ │ ├── Sha.sol │ │ ├── Storage.sol │ │ ├── StorageOnDeploy.sol │ │ └── triggerErrors.sol │ ├── bin │ │ ├── BridgeA │ │ │ └── BridgeA.go │ │ ├── BridgeB │ │ │ └── BridgeB.go │ │ ├── BridgeC │ │ │ └── BridgeC.go │ │ ├── BridgeD │ │ │ └── BridgeD.go │ │ ├── Called │ │ │ └── Called.go │ │ ├── Caller │ │ │ └── Caller.go │ │ ├── ChainCallLevel1 │ │ │ └── ChainCallLevel1.go │ │ ├── ChainCallLevel2 │ │ │ └── ChainCallLevel2.go │ │ ├── ChainCallLevel3 │ │ │ └── ChainCallLevel3.go │ │ ├── ChainCallLevel4 │ │ │ └── ChainCallLevel4.go │ │ ├── ConstructorMap │ │ │ └── ConstructorMap.go │ │ ├── Counter │ │ │ └── Counter.go │ │ ├── CounterAndBlock │ │ │ └── CounterAndBlock.go │ │ ├── Creates │ │ │ └── Creates.go │ │ ├── DeployCreate0 │ │ │ └── DeployCreate0.go │ │ ├── Depth │ │ │ └── Depth.go │ │ ├── Destruct │ │ │ └── Destruct.go │ │ ├── Double │ │ │ └── Double.go │ │ ├── ERC20 │ │ │ └── ERC20.go │ │ ├── EmitLog │ │ │ └── EmitLog.go │ │ ├── EmitLog2 │ │ │ └── EmitLog2.go │ │ ├── FFFFFFFF │ │ │ └── FFFFFFFF.go │ │ ├── FailureTest │ │ │ └── FailureTest.go │ │ ├── HasOpCode │ │ │ └── HasOpCode.go │ │ ├── Interaction │ │ │ └── Interaction.go │ │ ├── Log0 │ │ │ └── Log0.go │ │ ├── Memory │ │ │ └── Memory.go │ │ ├── OpCallAux │ │ │ └── OpCallAux.go │ │ ├── Read │ │ │ └── Read.go │ │ ├── Revert │ │ │ └── Revert.go │ │ ├── Revert2 │ │ │ └── Revert2.go │ │ ├── Sha │ │ │ └── Sha.go │ │ ├── Storage │ │ │ └── Storage.go │ │ ├── StorageOnDeploy │ │ │ └── StorageOnDeploy.go │ │ ├── WETH │ │ │ └── WETH.go │ │ ├── triggerErrors │ │ │ └── triggerErrors.go │ │ └── uniswap │ │ │ └── v2 │ │ │ ├── core │ │ │ ├── UniswapV2ERC20 │ │ │ │ └── UniswapV2ERC20.go │ │ │ ├── UniswapV2Factory │ │ │ │ └── UniswapV2Factory.go │ │ │ └── UniswapV2Pair │ │ │ │ └── UniswapV2Pair.go │ │ │ ├── interface │ │ │ └── UniswapInterfaceMulticall │ │ │ │ └── UniswapInterfaceMulticall.go │ │ │ └── periphery │ │ │ ├── UniswapV2Migrator │ │ │ └── UniswapV2Migrator.go │ │ │ └── UniswapV2Router02 │ │ │ └── UniswapV2Router02.go │ ├── compiled │ │ ├── ERC20Token │ │ │ ├── ERC20Token.abi │ │ │ └── ERC20Token.bin │ │ └── MultiSigWallet │ │ │ ├── MultiSigWallet.abi │ │ │ └── MultiSigWallet.bin │ ├── index.yaml │ └── uniswap │ │ └── v2 │ │ ├── AddressStringUtil.sol │ │ ├── Babylonian.sol │ │ ├── BitMath.sol │ │ ├── FixedPoint.sol │ │ ├── FullMath.sol │ │ ├── IERC20.sol │ │ ├── IUniswapV1Exchange.sol │ │ ├── IUniswapV1Factory.sol │ │ ├── IUniswapV2Callee.sol │ │ ├── IUniswapV2ERC20.sol │ │ ├── IUniswapV2Factory.sol │ │ ├── IUniswapV2Migrator.sol │ │ ├── IUniswapV2Pair.sol │ │ ├── IUniswapV2Router01.sol │ │ ├── IUniswapV2Router02.sol │ │ ├── IWETH.sol │ │ ├── Math.sol │ │ ├── SafeERC20Namer.sol │ │ ├── SafeMath.sol │ │ ├── TransferHelper.sol │ │ ├── UQ112x112.sol │ │ ├── UniswapInterfaceMulticall.sol │ │ ├── UniswapV2ERC20.sol │ │ ├── UniswapV2Factory.sol │ │ ├── UniswapV2Library.sol │ │ ├── UniswapV2LiquidityMathLibrary.sol │ │ ├── UniswapV2Migrator.sol │ │ ├── UniswapV2OracleLibrary.sol │ │ ├── UniswapV2Pair.sol │ │ ├── UniswapV2Router01.sol │ │ └── UniswapV2Router02.sol ├── dbutils │ └── dbutils.go ├── docker-compose.yml ├── e2e │ ├── datacommittee_test.go │ ├── debug_calltracer_test.go │ ├── debug_shared.go │ ├── debug_test.go │ ├── doc.go │ ├── effectivegasprice_test.go │ ├── ethtransfer_test.go │ ├── forced_batches_test.go │ ├── forced_batches_vector_group1_test.go │ ├── forced_batches_vector_group2_test.go │ ├── forced_batches_vector_group3_test.go │ ├── forced_batches_vector_shared.go │ ├── gasless_test.go │ ├── jsonrpc1_test.go │ ├── jsonrpc2_test.go │ ├── permissionlessrpc_test.go │ ├── pool_test.go │ ├── preEIP155_test.go │ ├── sc_test.go │ ├── shared.go │ ├── state_test.go │ └── uniswap_test.go ├── operations │ ├── manager.go │ ├── manager_xlayer.go │ ├── token.go │ └── wait.go ├── package-lock.json ├── scripts │ ├── batchsender │ │ ├── README.md │ │ └── main.go │ ├── check_trace │ │ └── main.go │ ├── cmd │ │ ├── compilesc.go │ │ ├── compilesc │ │ │ └── manager.go │ │ ├── dependencies.go │ │ ├── dependencies │ │ │ ├── files.go │ │ │ ├── files_test.go │ │ │ ├── github.go │ │ │ ├── github_test.go │ │ │ ├── images.go │ │ │ ├── images_test.go │ │ │ ├── manager.go │ │ │ ├── protobuffers.go │ │ │ └── testvectors.go │ │ └── main.go │ ├── deploy_sc │ │ └── main.go │ ├── init_network │ │ └── main.go │ ├── postgres │ │ ├── prover-user.sql │ │ └── run.sh │ ├── sendForcedBatch │ │ ├── README.md │ │ └── main.go │ ├── send_transfers │ │ └── main.go │ ├── sequenceForcedBatch │ │ ├── README.md │ │ └── main.go │ ├── txsender │ │ ├── README.md │ │ └── main.go │ └── uniswap │ │ ├── main.go │ │ └── pkg │ │ ├── setup.go │ │ ├── swap.go │ │ └── types.go ├── sequencer.keystore ├── testutils │ └── utils.go ├── tracers │ ├── tracer.json │ └── tracer2.json ├── traces │ ├── op-call_1__full_trace_0.json │ ├── op-call_20__full_trace_0.json │ ├── op-call_2__full_trace_0.json │ ├── op-create_1__full_trace_0.json │ ├── op-create_2__full_trace_0.json │ ├── op-create_2__full_trace_1.json │ ├── op-create_3__full_trace_0.json │ ├── op-create_3__full_trace_1.json │ └── test-deploy_0__full_trace_0.json └── vectors │ ├── l1infotree.go │ ├── smartcontract.go │ ├── src │ ├── e2e │ │ └── e2e.json │ ├── etrog │ │ ├── balances.json │ │ ├── chain-ids.json │ │ ├── general.json │ │ ├── nonces.json │ │ └── seq-fees.json │ ├── merkle-tree │ │ ├── l1-info-tree │ │ │ ├── proof-vectors.json │ │ │ └── root-vectors.json │ │ ├── smt-full-genesis.json │ │ ├── smt-genesis.json │ │ ├── smt-hash-bytecode.json │ │ ├── smt-key-contract-code.json │ │ ├── smt-key-contract-length.json │ │ ├── smt-key-contract-storage.json │ │ ├── smt-key-eth-balance.json │ │ ├── smt-key-eth-nonce.json │ │ └── smt-raw.json │ ├── receipt-test-vectors │ │ └── receipt-vector.json │ ├── state-transition-sc.json │ ├── state-transition │ │ ├── forced-tx │ │ │ ├── group1 │ │ │ │ ├── general_0.json │ │ │ │ ├── general_1.json │ │ │ │ ├── general_2.json │ │ │ │ ├── general_3.json │ │ │ │ ├── general_4.json │ │ │ │ ├── general_5.json │ │ │ │ ├── general_6.json │ │ │ │ └── general_7.json │ │ │ ├── group2 │ │ │ │ ├── erc20_0.json │ │ │ │ ├── eth-CallEcrecoverInvalidSignature.json │ │ │ │ ├── mynft_0.json │ │ │ │ ├── test-deploy_0.json │ │ │ │ ├── test-deploy_1.json │ │ │ │ ├── test-deploy_2.json │ │ │ │ └── uniswapv2_1.json │ │ │ └── group3 │ │ │ │ ├── test-deploy_3.json │ │ │ │ ├── test-deploy_4.json │ │ │ │ ├── test-deploy_5.json │ │ │ │ ├── test-deploy_6.json │ │ │ │ ├── test-deploy_7.json │ │ │ │ ├── test-deploy_8.json │ │ │ │ └── test-deploy_9.json │ │ └── no-data │ │ │ ├── balances.json │ │ │ ├── chain-ids.json │ │ │ ├── general.json │ │ │ ├── nonces.json │ │ │ └── seq-fees.json │ ├── tools │ │ └── calldata-test-vectors │ │ │ └── calldata-test-vector.json │ └── tx-hash-ethereum │ │ ├── rlp.json │ │ ├── uniswap.json │ │ └── uniswap_formated.json │ ├── statetransition.go │ ├── statetransition_etrog.go │ ├── statetransition_v2.go │ ├── types.go │ ├── vectors.go │ ├── vectors_etrog.go │ └── vectors_v2.go ├── tools ├── datastreamer │ ├── Makefile │ ├── config │ │ ├── config.go │ │ ├── default.go │ │ └── tool.config.toml │ └── main.go ├── egp │ ├── README.md │ ├── cfg │ │ ├── egp0.config.toml │ │ ├── egp1.config.toml │ │ └── egp2.config.toml │ └── main.go ├── executor │ ├── README.md │ ├── docker-compose.yml │ ├── genesis │ │ └── default-genesis.json │ ├── main.go │ ├── prover.config.json │ └── vectors │ │ └── fail-deploy-uniswap-repeated-nonce.json ├── genesis │ └── genesisparser │ │ └── genesisparser.go ├── network │ └── network.go ├── rlp │ ├── README.md │ └── main.go ├── signer │ ├── Dockerfile │ ├── Makefile │ ├── config │ │ ├── config.go │ │ ├── default.go │ │ └── signer.config.toml │ ├── main.go │ └── service │ │ ├── service.go │ │ └── type.go └── state │ ├── README.md │ ├── control_flush_id.go │ ├── estimated_time.go │ ├── main.go │ ├── output_interface.go │ ├── output_pretty.go │ ├── reprocess_action.go │ ├── reprocess_cmd.go │ └── version.go ├── version.go └── version.mk /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | *.md @agnusmor 2 | aggregator/ @agnusmor 3 | ci/ @agnusmor @tclemos @ToniRamirezM @ARR552 4 | cmd/ @tclemos @ToniRamirezM @ARR552 5 | config/ @agnusmor @tclemos @ToniRamirezM @ARR552 6 | db/ @tclemos @ToniRamirezM @ARR552 7 | docs/ @agnusmor @joanestebanr 8 | etherman/ @ARR552 @joanestebanr 9 | ethtxmanager/ @tclemos 10 | gasprice/ @ARR552 11 | jsonrpc/ @tclemos 12 | merkletree/ @ToniRamirezM 13 | pool/ @tclemos 14 | proto/ @ToniRamirezM 15 | sequencer/ @ToniRamirezM @dpunish3r @agnusmor 16 | sequencesender/ @ToniRamirezM @dpunish3r @agnusmor 17 | state/ @ToniRamirezM @tclemos 18 | synchronizer/ @ARR552 @joanestebanr 19 | test/ @tclemos 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report a bug 3 | about: Something with Polygon zkEVM is not working as expected 4 | title: '' 5 | labels: 'type:bug' 6 | assignees: '' 7 | --- 8 | 9 | #### System information 10 | 11 | zkEVM Node version: `v0.0.X-RCXX` 12 | OS & Version: `Windows/Linux/OSX` 13 | Commit hash : (if `develop`) 14 | Network: `Mainnet/Testnet` 15 | 16 | #### Expected behaviour 17 | 18 | 19 | #### Actual behaviour 20 | 21 | 22 | #### Steps to reproduce the behaviour 23 | 24 | 25 | #### Backtrace 26 | 27 | ```` 28 | [backtrace] 29 | ```` 30 | 31 | When submitting logs: please submit them as text and not screenshots. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request a feature 3 | about: Report a missing feature - e.g. as a step before submitting a PR 4 | title: '' 5 | labels: 'type:feature' 6 | assignees: '' 7 | --- 8 | 9 | # Rationale 10 | 11 | Why should this feature exist? 12 | What are the use-cases? 13 | 14 | # Implementation 15 | 16 | Do you have ideas regarding the implementation of this feature? 17 | Are you willing to implement this feature? -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask a question 3 | about: Something is unclear 4 | title: '' 5 | labels: 'type:question' 6 | assignees: '' 7 | --- 8 | 9 | This should only be used in very rare cases e.g. if you are not 100% sure if something is a bug or asking a question that leads to improving the documentation. 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | -------------------------------------------------------------------------------- /.github/hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Only run lint if .go files changed 4 | git diff --cached --name-only | if grep --quiet ".*go$" 5 | then 6 | make lint 7 | fi 8 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Closes #. 2 | 3 | ### What does this PR do? 4 | 5 | 7 | 8 | ### Reviewers 9 | 10 | Main reviewers: 11 | 12 | 13 | 14 | - @John 15 | - @Doe 16 | 17 | Codeowner reviewers: 18 | 19 | 20 | 21 | - @-Alice 22 | - @-Bob 23 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - master 7 | - develop 8 | - update-external-dependencies 9 | - 'release/**' 10 | pull_request: 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Install Go 16 | uses: actions/setup-go@v3 17 | with: 18 | go-version: 1.21.x 19 | - name: Checkout code 20 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 21 | - name: Lint 22 | run: | 23 | make install-linter 24 | make lint 25 | -------------------------------------------------------------------------------- /.github/workflows/push-docker-develop.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - develop 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 12 | 13 | - name: Set up QEMU 14 | uses: docker/setup-qemu-action@v3 15 | 16 | - name: Set up Docker Buildx 17 | uses: docker/setup-buildx-action@v3 18 | 19 | - name: Login to DockerHub 20 | uses: docker/login-action@v3 21 | with: 22 | username: ${{ secrets.DOCKERHUB_USERNAME }} 23 | password: ${{ secrets.DOCKERHUB_TOKEN }} 24 | 25 | - name: Build and push 26 | id: docker_build 27 | uses: docker/build-push-action@v5 28 | with: 29 | platforms: linux/amd64,linux/arm64 30 | push: true 31 | tags: | 32 | hermeznetwork/zkevm-node:develop 33 | -------------------------------------------------------------------------------- /.github/workflows/push-docker-tagged.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - 'v[0-9]+.[0-9]+.[0-9]+*' # this action will only run on tags that follow semver 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 12 | 13 | - name: Set up QEMU 14 | uses: docker/setup-qemu-action@v3 15 | 16 | - name: Set up Docker Buildx 17 | uses: docker/setup-buildx-action@v3 18 | 19 | - name: Login to DockerHub 20 | uses: docker/login-action@v3 21 | with: 22 | username: ${{ secrets.DOCKERHUB_USERNAME }} 23 | password: ${{ secrets.DOCKERHUB_TOKEN }} 24 | 25 | - name: Build and push 26 | id: docker_build 27 | uses: docker/build-push-action@v5 28 | with: 29 | context: . 30 | platforms: linux/amd64,linux/arm64 31 | push: true 32 | tags: | 33 | hermeznetwork/zkevm-node:${{ github.ref_name }} 34 | -------------------------------------------------------------------------------- /.github/workflows/sonarqube.yml: -------------------------------------------------------------------------------- 1 | name: SonarQube analysis 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | - feature/sonarcloud-coverage 8 | 9 | jobs: 10 | sonarqube: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3 14 | with: 15 | # Disabling shallow clone is recommended for improving relevancy of reporting. 16 | fetch-depth: 0 17 | 18 | - name: Compile SCs 19 | run: make compile-scs 20 | working-directory: test 21 | 22 | - name: Test 23 | env: 24 | ZKPROVER_URI: 127.0.0.1 25 | run: make test-full-non-e2e 26 | working-directory: test 27 | 28 | # Triggering SonarQube analysis as results of it are required by Quality Gate check. 29 | - name: SonarQube Scan 30 | uses: sonarsource/sonarqube-scan-action@master 31 | env: 32 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 33 | SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} 34 | -------------------------------------------------------------------------------- /.github/workflows/test-e2e.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test e2e 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | - develop 9 | - update-external-dependencies 10 | - 'release/**' 11 | pull_request: 12 | 13 | jobs: 14 | test-e2e: 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | go-version: [ 1.21.x ] 19 | goarch: [ "amd64" ] 20 | e2e-group: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, dac-1 ] 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout code 24 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 25 | 26 | - name: Install Go 27 | uses: actions/setup-go@v3 28 | with: 29 | go-version: ${{ matrix.go-version }} 30 | env: 31 | GOARCH: ${{ matrix.goarch }} 32 | 33 | - name: Build Docker 34 | run: make build-docker 35 | 36 | - name: Compile SCs 37 | run: make compile-scs 38 | working-directory: test 39 | 40 | - name: Test 41 | run: make test-e2e-group-${{ matrix.e2e-group }} 42 | working-directory: test 43 | -------------------------------------------------------------------------------- /.github/workflows/test-full-non-e2e.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test non-e2e 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | - develop 9 | - update-external-dependencies 10 | - 'release/**' 11 | pull_request: 12 | 13 | jobs: 14 | test-full-non-e2e: 15 | strategy: 16 | matrix: 17 | go-version: [ 1.21.x ] 18 | goarch: [ "amd64" ] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout code 22 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 23 | 24 | - name: Install Go 25 | uses: actions/setup-go@v3 26 | with: 27 | go-version: ${{ matrix.go-version }} 28 | env: 29 | GOARCH: ${{ matrix.goarch }} 30 | 31 | - name: Compile SCs 32 | run: make compile-scs 33 | working-directory: test 34 | 35 | - name: Test 36 | env: 37 | ZKPROVER_URI: 127.0.0.1 38 | run: make test-full-non-e2e 39 | working-directory: test 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /test/e2e/keystore 3 | 4 | /test/vectors/src/**/*md 5 | /test/vectors/src/**/*js 6 | /test/vectors/src/**/*sol 7 | /test/vectors/src/**/*sh 8 | /test/vectors/src/package.json 9 | 10 | /test/contracts/bin/**/*.bin 11 | /test/contracts/bin/**/*.abi 12 | 13 | /tools/datastreamer/*.bin 14 | /test/datastreamer/*.db/* 15 | /test/*.bin 16 | /test/*.db/* 17 | 18 | **/.DS_Store 19 | .vscode 20 | .idea/ 21 | .env 22 | out.dat 23 | 24 | cmd/__debug_bin 25 | 26 | .venv 27 | 28 | *metrics.txt -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | run: 3 | timeout: 5m 4 | skip-dirs: 5 | - state/runtime/fakevm 6 | - state/runtime/instrumentation 7 | - test 8 | - ci 9 | 10 | linters: 11 | enable: 12 | - whitespace 13 | - gosec 14 | - gci 15 | - misspell 16 | - gomnd 17 | - gofmt 18 | - goimports 19 | - revive 20 | - unconvert 21 | 22 | linters-settings: 23 | revive: 24 | rules: 25 | - name: exported 26 | arguments: 27 | - disableStutteringCheck 28 | 29 | issues: 30 | include: 31 | - EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments 32 | - EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments 33 | exclude: 34 | # gosec 35 | - "G401: Use of weak cryptographic primitive" 36 | # gosec 37 | - "G501: Blocklisted import crypto/md5: weak cryptographic primitive" 38 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # .goreleaser.yaml 2 | version: 2 3 | 4 | builds: 5 | - main: ./cmd/ 6 | goos: 7 | - linux 8 | - darwin 9 | goarch: 10 | - amd64 11 | - arm64 12 | env: 13 | - CGO_ENABLED=0 14 | ldflags: 15 | - -X github.com/0xPolygonHermez/zkevm-node.Version={{.Version}} 16 | - -X github.com/0xPolygonHermez/zkevm-node.GitRev={{.Commit}} 17 | - -X github.com/0xPolygonHermez/zkevm-node.BuildDate={{.Date}} 18 | - -X github.com/0xPolygonHermez/zkevm-node.GitBranch={{.Branch}} 19 | release: 20 | # If set to auto, will mark the release as not ready for production 21 | # in case there is an indicator for this in the tag e.g. v1.0.0-rc1 22 | # If set to true, will mark the release as not ready for production. 23 | # Default is false. 24 | prerelease: true 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # CONTAINER FOR BUILDING BINARY 2 | FROM golang:1.21 AS build 3 | 4 | # INSTALL DEPENDENCIES 5 | RUN go install github.com/gobuffalo/packr/v2/packr2@v2.8.3 6 | COPY go.mod go.sum /src/ 7 | RUN cd /src && go mod download 8 | 9 | # BUILD BINARY 10 | COPY . /src 11 | RUN cd /src/db && packr2 12 | RUN cd /src && make build 13 | 14 | # CONTAINER FOR RUNNING BINARY 15 | FROM alpine:3.18.4 16 | COPY --from=build /src/dist/xlayer-node /app/xlayer-node 17 | COPY --from=build /src/config/environments/testnet/node.config.toml /app/example.config.toml 18 | RUN apk update && apk add postgresql15-client 19 | EXPOSE 8123 20 | CMD ["/bin/sh", "-c", "/app/xlayer-node run"] 21 | -------------------------------------------------------------------------------- /aggregator/config_xlayer.go: -------------------------------------------------------------------------------- 1 | package aggregator 2 | 3 | // SettlementBackend is the type of the settlement backend 4 | type SettlementBackend string 5 | 6 | const ( 7 | // AggLayer settlement backend 8 | AggLayer SettlementBackend = "agglayer" 9 | 10 | // L1 settlement backend 11 | L1 SettlementBackend = "l1" 12 | ) 13 | -------------------------------------------------------------------------------- /aggregator/mocks/mock_etherman_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v2.39.0. DO NOT EDIT. 2 | 3 | package mocks 4 | 5 | // GetRollupId provides a mock function with given fields: 6 | func (_m *Etherman) GetRollupId() uint32 { 7 | ret := _m.Called() 8 | 9 | if len(ret) == 0 { 10 | panic("no return value specified for GetRollupId") 11 | } 12 | 13 | var r0 uint32 14 | if rf, ok := ret.Get(0).(func() uint32); ok { 15 | r0 = rf() 16 | } else { 17 | r0 = ret.Get(0).(uint32) 18 | } 19 | 20 | return r0 21 | } -------------------------------------------------------------------------------- /ci/e2e-group-dac-1/datacommittee_xlayer_test.go: -------------------------------------------------------------------------------- 1 | package e2e_group_dac_1 2 | -------------------------------------------------------------------------------- /ci/e2e-group1/ethtransfer_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/ethtransfer_test.go -------------------------------------------------------------------------------- /ci/e2e-group1/preEIP155_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/preEIP155_test.go -------------------------------------------------------------------------------- /ci/e2e-group1/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group10/forced_batches_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_test.go -------------------------------------------------------------------------------- /ci/e2e-group10/forced_batches_vector_group2_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_group2_test.go -------------------------------------------------------------------------------- /ci/e2e-group10/forced_batches_vector_shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_shared.go -------------------------------------------------------------------------------- /ci/e2e-group10/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group11/forced_batches_vector_group3_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_group3_test.go -------------------------------------------------------------------------------- /ci/e2e-group11/forced_batches_vector_shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_shared.go -------------------------------------------------------------------------------- /ci/e2e-group11/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group2/gasless_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/gasless_test.go -------------------------------------------------------------------------------- /ci/e2e-group2/pool_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/pool_test.go -------------------------------------------------------------------------------- /ci/e2e-group2/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group3/sc_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/sc_test.go -------------------------------------------------------------------------------- /ci/e2e-group3/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group4/jsonrpc1_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/jsonrpc1_test.go -------------------------------------------------------------------------------- /ci/e2e-group4/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group5/debug_shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/debug_shared.go -------------------------------------------------------------------------------- /ci/e2e-group5/debug_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/debug_test.go -------------------------------------------------------------------------------- /ci/e2e-group5/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group6/permissionlessrpc_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/permissionlessrpc_test.go -------------------------------------------------------------------------------- /ci/e2e-group7/jsonrpc2_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/jsonrpc2_test.go -------------------------------------------------------------------------------- /ci/e2e-group7/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group8/debug_calltracer_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/debug_calltracer_test.go -------------------------------------------------------------------------------- /ci/e2e-group8/debug_shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/debug_shared.go -------------------------------------------------------------------------------- /ci/e2e-group8/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/e2e-group9/forced_batches_vector_group1_test.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_group1_test.go -------------------------------------------------------------------------------- /ci/e2e-group9/forced_batches_vector_shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/forced_batches_vector_shared.go -------------------------------------------------------------------------------- /ci/e2e-group9/shared.go: -------------------------------------------------------------------------------- 1 | ../../test/e2e/shared.go -------------------------------------------------------------------------------- /ci/vectors: -------------------------------------------------------------------------------- 1 | ../test/vectors -------------------------------------------------------------------------------- /cmd/jsonschema.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/config" 5 | "github.com/urfave/cli/v2" 6 | ) 7 | 8 | func genJSONSchema(cli *cli.Context) error { 9 | file_config := cli.String(config.FlagDocumentationFileType) 10 | output := cli.String(config.FlagOutputFile) 11 | switch file_config { 12 | case NODE_CONFIGFILE: 13 | { 14 | generator := config.NewNodeConfigJsonSchemaGenerater() 15 | return generator.GenerateJsonSchemaAndWriteToFile(cli, output) 16 | } 17 | case NETWORK_CONFIGFILE: 18 | { 19 | generator := config.NewNetworkConfigJsonSchemaGenerater() 20 | return generator.GenerateJsonSchemaAndWriteToFile(cli, output) 21 | } 22 | default: 23 | panic("Not supported this config file: " + file_config) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cmd/readme.md: -------------------------------------------------------------------------------- 1 | ## Create and restore snapshots 2 | 3 | ### Create snapshots 4 | ``` 5 | go run ./cmd snapshot --cfg config/environments/local/local.node.config.toml --output ./folder/ 6 | ``` 7 | 8 | ### Restore snapshots 9 | ``` 10 | go run ./cmd restore --cfg config/environments/local/local.node.config.toml -is ./folder/zkevmpubliccorestatedb_1685614455_v0.1.0_undefined.sql.tar.gz -ih ./folder/zkevmpublicstatedb_1685615051_v0.1.0_undefined.sql.tar.gz 11 | ``` -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node" 7 | "github.com/urfave/cli/v2" 8 | ) 9 | 10 | func versionCmd(*cli.Context) error { 11 | zkevm.PrintVersion(os.Stdout) 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /config/apollo/apollo_test.go: -------------------------------------------------------------------------------- 1 | package apollo 2 | 3 | import ( 4 | "testing" 5 | 6 | nodeConfig "github.com/0xPolygonHermez/zkevm-node/config" 7 | "github.com/0xPolygonHermez/zkevm-node/config/types" 8 | ) 9 | 10 | func TestApolloClient_LoadConfig(t *testing.T) { 11 | nc := &nodeConfig.Config{ 12 | Apollo: types.ApolloConfig{ 13 | IP: "", 14 | AppID: "xlayer-devnet", 15 | NamespaceName: "jsonrpc-ro.txt,jsonrpc-roHalt.properties", 16 | Enable: true, 17 | }, 18 | } 19 | client := NewClient(nc) 20 | 21 | client.LoadConfig() 22 | t.Log(nc.RPC) 23 | // time.Sleep(2 * time.Minute) 24 | t.Log(nc.RPC) 25 | } 26 | -------------------------------------------------------------------------------- /config/apollo/l2gaspricer.go: -------------------------------------------------------------------------------- 1 | package apollo 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/gasprice" 5 | "github.com/0xPolygonHermez/zkevm-node/log" 6 | "github.com/apolloconfig/agollo/v4/storage" 7 | ) 8 | 9 | func (c *Client) loadL2GasPricer(value interface{}) { 10 | dstConf, err := c.unmarshal(value) 11 | if err != nil { 12 | log.Fatalf("failed to unmarshal l2gaspricer config: %v", err) 13 | } 14 | c.config.L2GasPriceSuggester = dstConf.L2GasPriceSuggester 15 | log.Infof("loaded l2gaspricer from apollo config: %+v", value.(string)) 16 | } 17 | 18 | // fireL2GasPricer fires the l2gaspricer config change 19 | // DefaultGasPriceWei 20 | // MaxGasPriceWei 21 | // Factor 22 | // GasPriceUsdt 23 | func (c *Client) fireL2GasPricer(key string, value *storage.ConfigChange) { 24 | newConf, err := c.unmarshal(value.NewValue) 25 | if err != nil { 26 | log.Errorf("failed to unmarshal l2gaspricer config: %v error: %v", value.NewValue, err) 27 | return 28 | } 29 | log.Infof("apollo l2gaspricer old config : %+v", value.OldValue.(string)) 30 | log.Infof("apollo l2gaspricer config changed: %+v", value.NewValue.(string)) 31 | gasprice.UpdateConfig(newConf.L2GasPriceSuggester) 32 | } 33 | -------------------------------------------------------------------------------- /config/apollo/pool.go: -------------------------------------------------------------------------------- 1 | package apollo 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/log" 5 | "github.com/0xPolygonHermez/zkevm-node/pool" 6 | "github.com/apolloconfig/agollo/v4/storage" 7 | ) 8 | 9 | // loadPool loads the pool config from apollo 10 | func (c *Client) loadPool(value interface{}) { 11 | dstConf, err := c.unmarshal(value) 12 | if err != nil { 13 | log.Fatalf("failed to unmarshal pool config: %v", err) 14 | } 15 | c.config.Pool = dstConf.Pool 16 | log.Infof("loaded pool from apollo config: %+v", value.(string)) 17 | } 18 | 19 | // firePool fires the pool config change 20 | // AccountQueue 21 | // GlobalQueue 22 | // FreeGasAddress 23 | func (c *Client) firePool(key string, value *storage.ConfigChange) { 24 | newConf, err := c.unmarshal(value.NewValue) 25 | if err != nil { 26 | log.Errorf("failed to unmarshal pool config: %v error: %v", value.NewValue, err) 27 | return 28 | } 29 | log.Infof("apollo pool old config : %+v", value.OldValue.(string)) 30 | log.Infof("apollo pool config changed: %+v", value.NewValue.(string)) 31 | 32 | pool.UpdateConfig(newConf.Pool) 33 | } 34 | -------------------------------------------------------------------------------- /config/config_xlayer.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/0xPolygonHermez/zkevm-node/config/types" 9 | "github.com/ethereum/go-ethereum/accounts/keystore" 10 | ) 11 | 12 | // NewKeyFromKeystore creates a private key from a keystore file 13 | func NewKeyFromKeystore(cfg types.KeystoreFileConfig) (*ecdsa.PrivateKey, error) { 14 | if cfg.Path == "" && cfg.Password == "" { 15 | return nil, nil 16 | } 17 | keystoreEncrypted, err := os.ReadFile(filepath.Clean(cfg.Path)) 18 | if err != nil { 19 | return nil, err 20 | } 21 | key, err := keystore.DecryptKey(keystoreEncrypted, cfg.Password) 22 | if err != nil { 23 | return nil, err 24 | } 25 | return key.PrivateKey, nil 26 | } 27 | -------------------------------------------------------------------------------- /config/environments/cardona/example.env: -------------------------------------------------------------------------------- 1 | ZKEVM_NETWORK = "cardona" 2 | # URL of a JSON RPC for Goerli 3 | ZKEVM_NODE_ETHERMAN_URL = "http://your.L1node.url" 4 | # PATH WHERE THE STATEDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 5 | ZKEVM_NODE_STATEDB_DATA_DIR = "/path/to/persistent/data/statedb" 6 | # PATH WHERE THE POOLDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 7 | ZKEVM_NODE_POOLDB_DATA_DIR = "/path/to/persistent/data/pooldb" 8 | # OPTIONAL, UNCOMENT IF YOU WANT TO DO ADVANCED CONFIG 9 | # ZKEVM_ADVANCED_CONFIG_DIR = "/should/be/same/path/as/ZKEVM_CONFIG_DIR" -------------------------------------------------------------------------------- /config/environments/mainnet/example.env: -------------------------------------------------------------------------------- 1 | ZKEVM_NETWORK = "mainnet" 2 | # URL of a JSON RPC for Ethereum mainnet 3 | ZKEVM_NODE_ETHERMAN_URL = "http://your.L1node.url" 4 | # PATH WHERE THE STATEDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 5 | ZKEVM_NODE_STATEDB_DATA_DIR = "/path/to/persistent/data/statedb" 6 | # PATH WHERE THE POOLDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 7 | ZKEVM_NODE_POOLDB_DATA_DIR = "/path/to/persistent/data/pooldb" 8 | # OPTIONAL, UNCOMENT IF YOU WANT TO DO ADVANCED CONFIG 9 | # ZKEVM_ADVANCED_CONFIG_DIR = "/should/be/same/path/as/ZKEVM_CONFIG_DIR" -------------------------------------------------------------------------------- /config/environments/testnet/example.env: -------------------------------------------------------------------------------- 1 | ZKEVM_NETWORK = "testnet" 2 | # URL of a JSON RPC for Goerli 3 | ZKEVM_NODE_ETHERMAN_URL = "http://your.L1node.url" 4 | # PATH WHERE THE STATEDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 5 | ZKEVM_NODE_STATEDB_DATA_DIR = "/path/to/persistent/data/statedb" 6 | # PATH WHERE THE POOLDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA 7 | ZKEVM_NODE_POOLDB_DATA_DIR = "/path/to/persistent/data/pooldb" 8 | # OPTIONAL, UNCOMENT IF YOU WANT TO DO ADVANCED CONFIG 9 | # ZKEVM_ADVANCED_CONFIG_DIR = "/should/be/same/path/as/ZKEVM_CONFIG_DIR" -------------------------------------------------------------------------------- /config/example.keystore: -------------------------------------------------------------------------------- 1 | {"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} -------------------------------------------------------------------------------- /config/metrics/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 3s # By default, scrape targets every 15 seconds. 3 | evaluation_interval: 3s # By default, scrape targets every 15 seconds. 4 | # scrape_timeout is set to the global default (10s). 5 | 6 | scrape_configs: 7 | 8 | - job_name: zkevm-node 9 | scrape_interval: 3s 10 | metrics_path: /metrics 11 | static_configs: 12 | - targets: 13 | - xlayer-json-rpc:9091 #inside port of the zkevm-json-rpc 14 | - xlayer-sequencer:9091 #inside port of the zkevm-sequencer -------------------------------------------------------------------------------- /config/network_xlayer.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/log" 5 | "github.com/ethereum/go-ethereum/common" 6 | ) 7 | 8 | const l2BridgeSCName = "PolygonZkEVMBridge proxy" 9 | 10 | func checkAndSetBridgeAddress(cfg *NetworkConfig, genesis []genesisAccountFromJSON) { 11 | for _, account := range genesis { 12 | if account.ContractName == l2BridgeSCName { 13 | cfg.L2BridgeAddr = common.HexToAddress(account.Address) 14 | log.Infof("Get L2 bridge address from genesis: %s", cfg.L2BridgeAddr.String()) 15 | break 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /config/readme.md: -------------------------------------------------------------------------------- 1 | 2 | # List ENV variables: 3 | ``` 4 | ZKEVM_NODE_LOG_LEVEL 5 | ZKEVM_NODE_LOG_OUTPUTS 6 | ZKEVM_NODE_DATABASE_NAME 7 | ZKEVM_NODE_DATABASE_USER 8 | ZKEVM_NODE_DATABASE_PASSWORD 9 | ZKEVM_NODE_DATABASE_HOST 10 | ZKEVM_NODE_DATABASE_PORT 11 | ZKEVM_NODE_ETHERMAN_URL 12 | ZKEVM_NODE_ETHERMAN_PRIVATEKEYPATH 13 | ZKEVM_NODE_ETHERMAN_PRIVATEKEYPASSWORD 14 | ZKEVM_NODE_SYNCHRONIZER_SYNCINTERVAL 15 | ZKEVM_NODE_SEQUENCER_INTERVALTOPROPOSEBATCH 16 | ZKEVM_NODE_SEQUENCER_SYNCEDBLOCKDIF 17 | ZKEVM_NODE_SEQUENCER_STRATEGY_TX_SELECTOR_TYPE 18 | ZKEVM_NODE_SEQUENCER_STRATEGY_TX_SELECTOR_TX_SORTER_TYPE 19 | ZKEVM_NODE_SEQUENCER_STRATEGY_TX_PROFITABILITY_CHECKER_TYPE 20 | ZKEVM_NODE_SEQUENCER_STRATEGY_TX_PROFITABILITY_CHECKER_MIN_REWARD 21 | ZKEVM_NODE_SEQUENCER_STRATEGY_POSSIBLE_TIME_TO_SEND_TX 22 | ZKEVM_NODE_AGGREGATOR_INTERVALTOCONSOLIDATESTATE 23 | ZKEVM_NODE_AGGREGATOR_TX_PROFITABILITY_CHECKER_TYPE 24 | ZKEVM_NODE_AGGREGATOR_TX_PROFITABILITY_MIN_REWARD 25 | ZKEVM_NODE_PROVER_PROVERURI 26 | ``` 27 | -------------------------------------------------------------------------------- /config/types/apolloconfig.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // ApolloConfig is the config for apollo 4 | type ApolloConfig struct { 5 | Enable bool `mapstructure:"Enable"` 6 | IP string `mapstructure:"IP"` 7 | AppID string `mapstructure:"AppID"` 8 | NamespaceName string `mapstructure:"NamespaceName"` 9 | } 10 | -------------------------------------------------------------------------------- /config/types/duration.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/invopop/jsonschema" 7 | ) 8 | 9 | // Duration is a wrapper type that parses time duration from text. 10 | type Duration struct { 11 | time.Duration `validate:"required"` 12 | } 13 | 14 | // UnmarshalText unmarshalls time duration from text. 15 | func (d *Duration) UnmarshalText(data []byte) error { 16 | duration, err := time.ParseDuration(string(data)) 17 | if err != nil { 18 | return err 19 | } 20 | d.Duration = duration 21 | return nil 22 | } 23 | 24 | // NewDuration returns Duration wrapper 25 | func NewDuration(duration time.Duration) Duration { 26 | return Duration{duration} 27 | } 28 | 29 | // JSONSchema returns a custom schema to be used for the JSON Schema generation of this type 30 | func (Duration) JSONSchema() *jsonschema.Schema { 31 | return &jsonschema.Schema{ 32 | Type: "string", 33 | Title: "Duration", 34 | Description: "Duration expressed in units: [ns, us, ms, s, m, h, d]", 35 | Examples: []interface{}{ 36 | "1m", 37 | "300ms", 38 | }, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /config/types/keystore.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // KeystoreFileConfig has all the information needed to load a private key from a key store file 4 | type KeystoreFileConfig struct { 5 | // Path is the file path for the key store file 6 | Path string `mapstructure:"Path"` 7 | 8 | // Password is the password to decrypt the key store file 9 | Password string `mapstructure:"Password"` 10 | } 11 | -------------------------------------------------------------------------------- /dataavailability/config.go: -------------------------------------------------------------------------------- 1 | package dataavailability 2 | 3 | // DABackendType is the data availability protocol for the CDK 4 | type DABackendType string 5 | 6 | const ( 7 | // DataAvailabilityCommittee is the DAC protocol backend 8 | DataAvailabilityCommittee DABackendType = "DataAvailabilityCommittee" 9 | ) 10 | -------------------------------------------------------------------------------- /db/config.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | // Config provide fields to configure the pool 4 | type Config struct { 5 | // Database name 6 | Name string `mapstructure:"Name"` 7 | 8 | // Database User name 9 | User string `mapstructure:"User"` 10 | 11 | // Database Password of the user 12 | Password string `mapstructure:"Password"` 13 | 14 | // Host address of database 15 | Host string `mapstructure:"Host"` 16 | 17 | // Port Number of database 18 | Port string `mapstructure:"Port"` 19 | 20 | // EnableLog 21 | EnableLog bool `mapstructure:"EnableLog"` 22 | 23 | // MaxConns is the maximum number of connections in the pool. 24 | MaxConns int `mapstructure:"MaxConns"` 25 | } 26 | -------------------------------------------------------------------------------- /db/logger.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/log" 8 | "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | type logger struct{} 12 | 13 | func (l logger) Log(ctx context.Context, level pgx.LogLevel, msg string, data map[string]interface{}) { 14 | m := fmt.Sprintf("%s %v", msg, data) 15 | 16 | switch level { 17 | case pgx.LogLevelInfo: 18 | log.Info(m) 19 | case pgx.LogLevelWarn: 20 | log.Warn(m) 21 | case pgx.LogLevelError: 22 | log.Error(m) 23 | default: 24 | m = fmt.Sprintf("%s %s %v", level.String(), msg, data) 25 | log.Debug(m) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /db/migrations/pool/0002.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction 3 | ADD COLUMN is_wip BOOLEAN; 4 | 5 | -- +migrate Down 6 | ALTER TABLE pool.transaction 7 | DROP COLUMN is_wip; 8 | -------------------------------------------------------------------------------- /db/migrations/pool/0003.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction 3 | DROP COLUMN failed_counter; 4 | 5 | ALTER TABLE pool.transaction 6 | ADD COLUMN ip VARCHAR; 7 | 8 | -- +migrate Down 9 | ALTER TABLE pool.transaction 10 | ADD COLUMN failed_counter DECIMAL(78, 0) DEFAULT 0; 11 | 12 | ALTER TABLE pool.transaction 13 | DROP COLUMN ip; 14 | -------------------------------------------------------------------------------- /db/migrations/pool/0004.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | -- Nothing to do here fix in 0005.sql 3 | 4 | -- +migrate Down 5 | -- Nothing to do here fix in 0005.sql 6 | -------------------------------------------------------------------------------- /db/migrations/pool/0005.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | UPDATE pool.transaction 3 | SET ip = '' WHERE ip IS NULL; 4 | ALTER TABLE pool.transaction 5 | ALTER COLUMN ip SET NOT NULL; 6 | ALTER TABLE pool.transaction 7 | ALTER COLUMN ip SET DEFAULT ''; 8 | 9 | -- +migrate Down 10 | ALTER TABLE pool.transaction 11 | ALTER COLUMN ip DROP NOT NULL; 12 | ALTER TABLE pool.transaction 13 | ALTER COLUMN ip DROP DEFAULT; 14 | -------------------------------------------------------------------------------- /db/migrations/pool/0006.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction 3 | ADD COLUMN deposit_count BIGINT; 4 | 5 | -- +migrate Down 6 | ALTER TABLE pool.transaction 7 | DROP COLUMN deposit_count; 8 | -------------------------------------------------------------------------------- /db/migrations/pool/0007.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE pool.blocked 3 | ( 4 | addr varchar NOT NULL PRIMARY KEY 5 | ); 6 | 7 | -- +migrate Down 8 | DROP TABLE pool.blocked; 9 | -------------------------------------------------------------------------------- /db/migrations/pool/0008.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction ADD COLUMN failed_reason VARCHAR; 3 | 4 | -- +migrate Down 5 | ALTER TABLE pool.transaction DROP COLUMN failed_reason; 6 | -------------------------------------------------------------------------------- /db/migrations/pool/0009.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.blocked ADD COLUMN block_reason VARCHAR; 3 | CREATE INDEX idx_pool_gas_price_timestamp ON pool.gas_price (timestamp); 4 | 5 | -- +migrate Down 6 | ALTER TABLE pool.blocked DROP COLUMN block_reason; 7 | DROP INDEX IF EXISTS idx_pool_gas_price_timestamp; 8 | -------------------------------------------------------------------------------- /db/migrations/pool/0010.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction ADD COLUMN break_even_gas_price DECIMAL(78, 0); 3 | ALTER TABLE pool.gas_price ADD COLUMN l1_price DECIMAL(78, 0); 4 | 5 | 6 | -- +migrate Down 7 | ALTER TABLE pool.transaction DROP COLUMN break_even_gas_price; 8 | ALTER TABLE pool.gas_price DROP COLUMN l1_price; 9 | -------------------------------------------------------------------------------- /db/migrations/pool/0011.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE pool.whitelisted ( 3 | addr VARCHAR PRIMARY KEY 4 | ); 5 | 6 | CREATE INDEX IF NOT EXISTS idx_transaction_from_nonce ON pool.transaction (from_address, nonce); 7 | CREATE INDEX IF NOT EXISTS idx_transaction_status ON pool.transaction (status); 8 | CREATE INDEX IF NOT EXISTS idx_transaction_hash ON pool.transaction (hash); 9 | 10 | -- +migrate Down 11 | DROP TABLE pool.whitelisted; 12 | 13 | DROP INDEX IF EXISTS pool.idx_transaction_from_nonce; 14 | DROP INDEX IF EXISTS pool.idx_transaction_status; 15 | DROP INDEX IF EXISTS pool.idx_transaction_hash; 16 | -------------------------------------------------------------------------------- /db/migrations/pool/0012.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE pool.transaction 3 | ADD COLUMN l2_hash VARCHAR UNIQUE, 4 | ADD COLUMN used_sha256_hashes INTEGER DEFAULT 0; 5 | CREATE INDEX IF NOT EXISTS idx_transaction_l2_hash ON pool.transaction (l2_hash); 6 | 7 | -- +migrate Down 8 | DROP INDEX IF EXISTS pool.idx_transaction_l2_hash; 9 | ALTER TABLE pool.transaction 10 | DROP COLUMN l2_hash, 11 | DROP COLUMN used_sha256_hashes; 12 | 13 | -------------------------------------------------------------------------------- /db/migrations/pool/1001.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE INDEX IF NOT EXISTS idx_transaction_gas_price ON pool.transaction (gas_price); 3 | 4 | -- +migrate Down 5 | DROP INDEX IF EXISTS pool.idx_transaction_gas_price; -------------------------------------------------------------------------------- /db/migrations/pool/1002.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE IF NOT EXISTS pool.readytx( 3 | id SERIAL PRIMARY KEY NOT NULL, 4 | count INT, 5 | updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 6 | ); 7 | INSERT INTO pool.readytx(id, count) VALUES(1, 0) 8 | ON CONFLICT(id) do UPDATE 9 | SET count = 0; 10 | 11 | -- +migrate Down 12 | DROP TABLE IF EXISTS pool.readytx; 13 | -------------------------------------------------------------------------------- /db/migrations/pool/1003.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE IF NOT EXISTS pool.innertx ( 3 | hash VARCHAR(128) PRIMARY KEY NOT NULL, 4 | innertx text, 5 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 6 | ); 7 | 8 | -- +migrate Down 9 | DROP TABLE IF EXISTS pool.innertx; -------------------------------------------------------------------------------- /db/migrations/pool/1004.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE IF NOT EXISTS pool.free_gas ( 3 | addr varchar NOT NULL PRIMARY KEY 4 | ); 5 | 6 | -- +migrate Down 7 | DROP TABLE IF EXISTS pool.free_gas; -------------------------------------------------------------------------------- /db/migrations/state/0003.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.log 3 | ALTER COLUMN topic0 DROP NOT NULL; 4 | 5 | -- +migrate Down 6 | DELETE FROM state.log WHERE topic0 IS NULL; 7 | ALTER TABLE state.log 8 | ALTER COLUMN topic0 SET NOT NULL; -------------------------------------------------------------------------------- /db/migrations/state/0004.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE state.event 3 | ( 4 | event_type VARCHAR NOT NULL, 5 | timestamp TIMESTAMP WITH TIME ZONE NOT NULL, 6 | ip VARCHAR, 7 | tx_hash VARCHAR, 8 | payload VARCHAR 9 | ); 10 | 11 | -- +migrate Down 12 | DROP table state.event; 13 | -------------------------------------------------------------------------------- /db/migrations/state/0005.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | DROP table state.event; 3 | DROP table state.debug; 4 | 5 | -- +migrate Down 6 | CREATE TABLE IF NOT EXISTS state.event 7 | ( 8 | event_type VARCHAR NOT NULL, 9 | timestamp TIMESTAMP WITH TIME ZONE NOT NULL, 10 | ip VARCHAR, 11 | tx_hash VARCHAR, 12 | payload VARCHAR 13 | ); 14 | 15 | CREATE TABLE IF NOT EXISTS state.debug 16 | ( 17 | error_type VARCHAR, 18 | timestamp timestamp, 19 | payload VARCHAR 20 | ); 21 | -------------------------------------------------------------------------------- /db/migrations/state/0006.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.batch 3 | ADD COLUMN batch_resources JSONB, 4 | ADD COLUMN closing_reason VARCHAR; 5 | 6 | -- +migrate Down 7 | ALTER TABLE state.batch 8 | DROP COLUMN batch_resources, 9 | DROP COLUMN closing_reason; -------------------------------------------------------------------------------- /db/migrations/state/0007.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.transaction 3 | ADD COLUMN effective_percentage SMALLINT DEFAULT 255; 4 | 5 | ALTER TABLE state.receipt 6 | ADD COLUMN effective_gas_price BIGINT; 7 | 8 | -- +migrate Down 9 | ALTER TABLE state.transaction 10 | DROP COLUMN effective_percentage; 11 | 12 | ALTER TABLE state.receipt 13 | DROP COLUMN effective_gas_price; 14 | -------------------------------------------------------------------------------- /db/migrations/state/0008.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE TABLE IF NOT EXISTS state.fork_id 3 | ( 4 | fork_id BIGINT NOT NULL PRIMARY KEY, 5 | from_batch_num numeric NOT NULL, 6 | to_batch_num numeric NOT NULL, 7 | version VARCHAR, 8 | block_num BIGINT NOT NULL REFERENCES state.block (block_num) ON DELETE CASCADE 9 | ); 10 | 11 | CREATE INDEX IF NOT EXISTS receipt_block_num_idx ON state.receipt USING btree (block_num); 12 | 13 | -- +migrate Down 14 | DROP INDEX IF EXISTS state.receipt_block_num_idx; 15 | 16 | DROP TABLE IF EXISTS state.fork_id; 17 | -------------------------------------------------------------------------------- /db/migrations/state/0009.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE IF EXISTS state.fork_id DROP CONSTRAINT IF EXISTS fork_id_block_num_fkey; 3 | 4 | -- +migrate Down 5 | DELETE FROM state.fork_id f 6 | WHERE NOT EXISTS(SELECT 1 FROM state.block b WHERE b.block_num = f.block_num); 7 | 8 | ALTER TABLE IF EXISTS state.fork_id ADD CONSTRAINT fork_id_block_num_fkey 9 | FOREIGN KEY(block_num) REFERENCES state.block (block_num) ON DELETE CASCADE; 10 | -------------------------------------------------------------------------------- /db/migrations/state/0010.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE INDEX IF NOT EXISTS l2block_block_hash_idx ON state.l2block (block_hash); 3 | 4 | DELETE FROM state.sequences a USING ( 5 | SELECT MIN(ctid) as ctid, from_batch_num 6 | FROM state.sequences 7 | GROUP BY from_batch_num HAVING COUNT(*) > 1 8 | ) b 9 | WHERE a.from_batch_num = b.from_batch_num 10 | AND a.ctid <> b.ctid; 11 | 12 | ALTER TABLE state.sequences ADD PRIMARY KEY(from_batch_num); 13 | ALTER TABLE state.trusted_reorg ADD PRIMARY KEY(timestamp); 14 | ALTER TABLE state.sync_info ADD PRIMARY KEY(last_batch_num_seen, last_batch_num_consolidated, init_sync_batch); 15 | 16 | -- +migrate Down 17 | DROP INDEX IF EXISTS state.l2block_block_hash_idx; 18 | 19 | ALTER TABLE state.sequences DROP CONSTRAINT sequences_pkey; 20 | ALTER TABLE state.trusted_reorg DROP CONSTRAINT trusted_reorg_pkey; 21 | ALTER TABLE state.sync_info DROP CONSTRAINT sync_info_pkey; 22 | -------------------------------------------------------------------------------- /db/migrations/state/0011.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE INDEX IF NOT EXISTS l2block_created_at_idx ON state.l2block (created_at); 3 | 4 | CREATE INDEX IF NOT EXISTS log_log_index_idx ON state.log (log_index); 5 | CREATE INDEX IF NOT EXISTS log_topic0_idx ON state.log (topic0); 6 | CREATE INDEX IF NOT EXISTS log_topic1_idx ON state.log (topic1); 7 | CREATE INDEX IF NOT EXISTS log_topic2_idx ON state.log (topic2); 8 | CREATE INDEX IF NOT EXISTS log_topic3_idx ON state.log (topic3); 9 | 10 | ALTER TABLE state.transaction ADD COLUMN egp_log JSONB; 11 | 12 | -- +migrate Down 13 | DROP INDEX IF EXISTS state.l2block_created_at_idx; 14 | 15 | DROP INDEX IF EXISTS state.log_log_index_idx; 16 | DROP INDEX IF EXISTS state.log_topic0_idx; 17 | DROP INDEX IF EXISTS state.log_topic1_idx; 18 | DROP INDEX IF EXISTS state.log_topic2_idx; 19 | DROP INDEX IF EXISTS state.log_topic3_idx; 20 | 21 | ALTER TABLE state.transaction DROP COLUMN egp_log; -------------------------------------------------------------------------------- /db/migrations/state/0012.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.monitored_txs 3 | ADD COLUMN gas_offset DECIMAL(78, 0) NOT NULL DEFAULT 0; 4 | ALTER TABLE state.monitored_txs ALTER COLUMN gas_offset DROP DEFAULT; 5 | 6 | -- +migrate Down 7 | ALTER TABLE state.monitored_txs 8 | DROP COLUMN gas_offset; -------------------------------------------------------------------------------- /db/migrations/state/0014.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE INDEX IF NOT EXISTS idx_batch_global_exit_root ON state.batch (global_exit_root); 3 | 4 | -- +migrate Down 5 | DROP INDEX IF EXISTS state.idx_batch_global_exit_root; 6 | 7 | -------------------------------------------------------------------------------- /db/migrations/state/0015.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | CREATE INDEX IF NOT EXISTS idx_receipt_tx_index ON state.receipt (block_num, tx_index); 3 | 4 | -- +migrate Down 5 | DROP INDEX IF EXISTS state.idx_receipt_tx_index; 6 | 7 | -------------------------------------------------------------------------------- /db/migrations/state/0016.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.batch 3 | ADD COLUMN IF NOT EXISTS checked BOOLEAN NOT NULL DEFAULT TRUE; 4 | 5 | -- +migrate Down 6 | ALTER TABLE state.batch 7 | DROP COLUMN IF EXISTS checked; -------------------------------------------------------------------------------- /db/migrations/state/0017.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.receipt 3 | ADD COLUMN IF NOT EXISTS im_state_root BYTEA; 4 | 5 | UPDATE state.receipt SET im_state_root = post_state WHERE block_num >= (SELECT MIN(block_num) FROM state.l2block WHERE batch_num >= (SELECT from_batch_num FROM state.fork_id WHERE fork_id = 7)); 6 | 7 | -- +migrate Down 8 | ALTER TABLE state.receipt 9 | DROP COLUMN IF EXISTS im_state_root; 10 | -------------------------------------------------------------------------------- /db/migrations/state/0018.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.block 3 | ADD COLUMN IF NOT EXISTS checked BOOL NOT NULL DEFAULT FALSE; 4 | 5 | -- set block.checked to true for all blocks below max - 100 6 | UPDATE state.block SET checked = true WHERE block_num <= (SELECT MAX(block_num) - 1000 FROM state.block); 7 | 8 | -- +migrate Down 9 | ALTER TABLE state.block 10 | DROP COLUMN IF EXISTS checked; 11 | 12 | -------------------------------------------------------------------------------- /db/migrations/state/0019.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | 3 | -- the update below fix the wrong receipt TX indexes 4 | WITH map_fix_tx_index AS ( 5 | SELECT t.l2_block_num AS block_num 6 | , t.hash AS tx_hash 7 | , r.tx_index AS current_index 8 | , (ROW_NUMBER() OVER (PARTITION BY t.l2_block_num ORDER BY r.tx_index))-1 AS correct_index 9 | FROM state.receipt r 10 | INNER JOIN state."transaction" t 11 | ON t.hash = r.tx_hash 12 | ) 13 | UPDATE state.receipt AS r 14 | SET tx_index = m.correct_index 15 | FROM map_fix_tx_index m 16 | WHERE m.block_num = r.block_num 17 | AND m.tx_hash = r.tx_hash 18 | AND m.current_index = r.tx_index 19 | AND m.current_index != m.correct_index; 20 | 21 | 22 | -- +migrate Down 23 | 24 | -- no action is needed, the data fixed by the 25 | -- migrate up must remain fixed -------------------------------------------------------------------------------- /db/migrations/state/0020.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | 3 | -- This migration will delete all empty blocks 4 | DELETE FROM state.block 5 | WHERE NOT EXISTS (SELECT * 6 | FROM state.virtual_batch 7 | WHERE state.virtual_batch.block_num = state.block.block_num) 8 | AND NOT EXISTS (SELECT * 9 | FROM state.verified_batch 10 | WHERE state.verified_batch.block_num = state.block.block_num) 11 | AND NOT EXISTS (SELECT * 12 | FROM state.forced_batch 13 | WHERE state.forced_batch.block_num = state.block.block_num) 14 | AND NOT EXISTS (SELECT * 15 | FROM state.exit_root 16 | WHERE state.exit_root.block_num = state.block.block_num) 17 | AND NOT EXISTS (SELECT * 18 | FROM state.monitored_txs 19 | WHERE state.monitored_txs.block_num = state.block.block_num) 20 | AND NOT EXISTS (SELECT * 21 | FROM state.fork_id 22 | WHERE state.fork_id.block_num = state.block.block_num); 23 | 24 | 25 | 26 | -- +migrate Down 27 | 28 | -- no action is needed, the data must remain deleted as it is useless -------------------------------------------------------------------------------- /db/migrations/state/0021.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE state.batch 3 | ADD COLUMN high_reserved_counters JSONB; 4 | 5 | -- +migrate Down 6 | ALTER TABLE state.batch 7 | DROP COLUMN high_reserved_counters; 8 | -------------------------------------------------------------------------------- /db/scripts/init_event_db.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE level_t AS ENUM ('emerg', 'alert', 'crit', 'err', 'warning', 'notice', 'info', 'debug'); 2 | 3 | CREATE TABLE public.event ( 4 | id BIGSERIAL PRIMARY KEY, 5 | received_at timestamp WITH TIME ZONE default CURRENT_TIMESTAMP, 6 | ip_address inet, 7 | source varchar(32) not null, 8 | component varchar(32), 9 | level level_t not null, 10 | event_id varchar(32) not null, 11 | description text, 12 | data bytea, 13 | json jsonb 14 | ); 15 | -------------------------------------------------------------------------------- /db/scripts/init_prover_db.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE prover_db; 2 | \connect prover_db; 3 | 4 | CREATE SCHEMA state; 5 | 6 | CREATE TABLE state.nodes (hash BYTEA PRIMARY KEY, data BYTEA NOT NULL); 7 | CREATE TABLE state.program (hash BYTEA PRIMARY KEY, data BYTEA NOT NULL); 8 | 9 | CREATE USER prover_user with password 'prover_pass'; 10 | ALTER DATABASE prover_db OWNER TO prover_user; 11 | ALTER SCHEMA state OWNER TO prover_user; 12 | ALTER SCHEMA public OWNER TO prover_user; 13 | ALTER TABLE state.nodes OWNER TO prover_user; 14 | ALTER TABLE state.program OWNER TO prover_user; 15 | ALTER USER prover_user SET SEARCH_PATH=state; 16 | -------------------------------------------------------------------------------- /db/scripts/single_db_server.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE state_db; 2 | CREATE DATABASE pool_db; 3 | CREATE DATABASE rpc_db; 4 | 5 | CREATE DATABASE prover_db; 6 | \connect prover_db; 7 | 8 | CREATE SCHEMA state; 9 | 10 | CREATE TABLE state.nodes (hash BYTEA PRIMARY KEY, data BYTEA NOT NULL); 11 | CREATE TABLE state.program (hash BYTEA PRIMARY KEY, data BYTEA NOT NULL); 12 | 13 | CREATE USER prover_user with password 'prover_pass'; 14 | ALTER DATABASE prover_db OWNER TO prover_user; 15 | ALTER SCHEMA state OWNER TO prover_user; 16 | ALTER SCHEMA public OWNER TO prover_user; 17 | ALTER TABLE state.nodes OWNER TO prover_user; 18 | ALTER TABLE state.program OWNER TO prover_user; 19 | ALTER USER prover_user SET SEARCH_PATH=state; -------------------------------------------------------------------------------- /docs/architecture.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okx/xlayer-node/837ab57e8ea78f2a062b53ece722b0ead71e2da3/docs/architecture.drawio.png -------------------------------------------------------------------------------- /docs/ci/README.md: -------------------------------------------------------------------------------- 1 | # CI documentation 2 | 3 | * [GitHub actions](./actions.md) 4 | * [ok-to-test](./ok-to-test.md) 5 | * [Groups and parallel execution](./groups.md) 6 | * [Test operations manager](./opsman.md) 7 | * [dependabot](./dependabot.md) 8 | -------------------------------------------------------------------------------- /docs/ci/dependabot.md: -------------------------------------------------------------------------------- 1 | # dependabot 2 | 3 | We use [dependabot] to keep the golang dependencies up to date. Its settings can 4 | be found in this [configuration file]. 5 | 6 | [dependabot]: https://github.com/dependabot 7 | [configuration file]: ../../.github/dependabot.yml 8 | -------------------------------------------------------------------------------- /docs/ci/opsman.md: -------------------------------------------------------------------------------- 1 | # Test operations package 2 | 3 | We use the functionality provided by the [test operations package] in order to 4 | manage components used during tests, specially e2e. 5 | 6 | The main functionality used currently in the tests is related to managing 7 | containers, the package exposes the function `StartComponent` which takes a 8 | container name (as defined in the [docker compose file]) and a variadic parameter 9 | with a set of condition functions to check when the container can be considered 10 | as ready. So we can call it without any condition like: 11 | ```go 12 | operations.StartComponent("my-container") 13 | ``` 14 | or adding readiness conditions as: 15 | ```go 16 | operations.StartComponent("my-container", func() (done bool, err error){ 17 | // run some checks 18 | return true, nil 19 | }, func()(done bool, err error){ 20 | // run some other checks 21 | return true, nil 22 | }) 23 | ``` 24 | 25 | [test operations package]: ../../test/operations/ 26 | [docker compose file]: ../../docker-compose.yml 27 | -------------------------------------------------------------------------------- /docs/components/account_keystore.md: -------------------------------------------------------------------------------- 1 | # Generating an Account Keystore file: 2 | 3 | This file contains your Ethereum L1 private key, but it will be encrypted at rest using a password of your choice. The ZKEVM Node - depending on which operating mode it's set up - will use this file in conjunction with the password to authorize L1 transactions. 4 | 5 | ```bash 6 | docker run --rm okx/xlayer-node:latest sh -c "/app/xlayer-node encryptKey --pk=[your private key] --pw=[password to encrypt file] --output=./keystore; cat ./keystore/*" > account.keystore 7 | ``` 8 | 9 | **NOTE**: 10 | 11 | - Replace `[your private key]` with your Ethereum L1 account private key 12 | - Replace `[password to encrypt file]` with a password used for file encryption. This password must be passed to the Node later on via env variable (`XLAYER_NODE_ETHERMAN_PRIVATEKEYPASSWORD`) 13 | -------------------------------------------------------------------------------- /docs/config-file/schema_doc.min.js: -------------------------------------------------------------------------------- 1 | $(document).on("click",'a[href^="#"]',function(event){event.preventDefault();history.pushState({},"",this.href)});function flashElement(elementId){myElement=document.getElementById(elementId);myElement.classList.add("jsfh-animated-property");setTimeout(function(){myElement.classList.remove("jsfh-animated-property")},1e3)}function setAnchor(anchorLinkDestination){history.pushState({},"",anchorLinkDestination)}function anchorOnLoad(){let linkTarget=decodeURIComponent(window.location.hash.split("?")[0].split("&")[0]);if(linkTarget[0]==="#"){linkTarget=linkTarget.substr(1)}if(linkTarget.length>0){anchorLink(linkTarget)}}function anchorLink(linkTarget){const target=$("#"+linkTarget);target.parents().addBack().filter(".collapse:not(.show), .tab-pane, [role='tab']").each(function(index){if($(this).hasClass("collapse")){$(this).collapse("show")}else if($(this).hasClass("tab-pane")){const tabToShow=$("a[href='#"+$(this).attr("id")+"']");if(tabToShow){tabToShow.tab("show")}}else if($(this).attr("role")==="tab"){$(this).tab("show")}});setTimeout(function(){let targetElement=document.getElementById(linkTarget);if(targetElement){targetElement.scrollIntoView({block:"center",behavior:"smooth"});setTimeout(function(){flashElement(linkTarget)},500)}},1e3)} -------------------------------------------------------------------------------- /docs/config-file/templates/js/badge_type.html: -------------------------------------------------------------------------------- 1 | {%- if type_name == "string" -%} 2 | {%- if schema.kw_min_length -%} 3 | {{ restriction("Must be at least " ~ schema.kw_min_length.literal ~ " characters long", "min-length", schema.kw_min_length.html_id) }} 4 | {%- endif -%} 5 | {%- if schema.kw_max_length -%} 6 | {{ restriction("Must be at most " ~ schema.kw_max_length.literal ~ " characters long", "max-length", schema.kw_max_length.html_id) }} 7 | {%- endif -%} 8 | {%- endif -%} 9 | {%- if type_name in ["integer", "number"] -%} 10 | {%- set restriction_text = (schema | get_numeric_restrictions_text("", "")) -%} 11 | {%- if restriction_text -%} 12 | {{ restriction(schema | get_numeric_restrictions_text("", ""), "numeric", schema.html_id ~ "_number") }} 13 | {%- endif -%} 14 | {%- endif -%} 15 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/breadcrumbs_no_object.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/breadcrumbs_object.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/macro_restriction.html: -------------------------------------------------------------------------------- 1 | {%- macro restriction(inner_text, css_class_name, html_id) -%} 2 |

{{ inner_text }}

3 | {%- endmacro -%} -------------------------------------------------------------------------------- /docs/config-file/templates/js/section_description.html: -------------------------------------------------------------------------------- 1 | 2 | {# Display description #} 3 | {%- if description -%} 4 | {%- if not config.collapse_long_descriptions or description is description_short -%} 5 | {{ description }} 6 | {%- else -%} 7 |
8 | {{ description }} 9 |
10 |
11 | 14 |
15 | {%- endif -%} 16 | {%- endif -%} 17 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/section_examples.html: -------------------------------------------------------------------------------- 1 |
2 |
Example{% if examples|length > 1 %}s{% endif %}:
3 |
4 | 5 | {%- for example in examples -%} 6 | {%- set example_id = schema.html_id ~ "_ex" ~ loop.index -%} 7 | {%- set example_is_long = config.collapse_long_examples and example is not description_short -%} 8 | {%- if example_is_long -%} 9 | 10 | {%- endif -%} 11 |
12 | {%- if not examples_as_yaml -%} 13 | {{ example | highlight_json_example }} 14 | {%- else -%} 15 | {{ example | highlight_yaml_example }} 16 | {%- endif -%} 17 |
18 | {%- endfor -%} 19 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/section_not.html: -------------------------------------------------------------------------------- 1 |
2 |

Must not be:

3 |
4 |
5 | {{ content(schema.kw_not) }} 6 |
7 |
8 |
-------------------------------------------------------------------------------- /docs/config-file/templates/js/section_properties_2.html: -------------------------------------------------------------------------------- 1 | {% set html_id = sub_property.html_id %} 2 | 3 | {{ content(sub_property) }} 4 |
5 | -------------------------------------------------------------------------------- /docs/config-file/templates/js/section_undocumented_required_properties.html: -------------------------------------------------------------------------------- 1 | {%- set undocumented_required_properties = schema | get_undocumented_required_properties -%} 2 | {%- if undocumented_required_properties-%} 3 |
4 |

The following properties are required:

5 | 10 |
11 | {%- endif -%} -------------------------------------------------------------------------------- /docs/config-file/templates/md/base.md: -------------------------------------------------------------------------------- 1 | {% set depth = 0 %} 2 | {{ schema.keywords.get("title").literal | default("Schema Docs") | md_heading(depth) }} 3 | {% set contentBase %} 4 | {% with schema=schema, skip_headers=False, depth=depth %} 5 | {% include "content.md" %} 6 | {% endwith %} 7 | {% endset %} 8 | 9 | 10 | 11 | {{ contentBase }} 12 | 13 | ---------------------------------------------------------------------------------------------------------------------------- 14 | {% if config.with_footer -%} 15 | Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans){% if config.footer_show_time %} on {{ get_local_time() }}{% endif %} 16 | 17 | {% endif -%} 18 | -------------------------------------------------------------------------------- /docs/config-file/templates/md/breadcrumbs.md: -------------------------------------------------------------------------------- 1 | {% set my_string = [] %} 2 | {%- for node in schema.nodes_from_root -%} 3 | {%- if not loop.first -%} 4 | {%- set _ = my_string.append(node.name_for_breadcrumbs) -%} 5 | {%- endif -%} 6 | {%- endfor -%} 7 | 8 | 9 | {%- filter md_escape_for_table -%} 10 | {# 11 | {%- if config.show_breadcrumbs -%} 12 | {%- for node in schema.nodes_from_root -%} 13 | {{ node.name_for_breadcrumbs }}{%- if not loop.last %} > {% endif -%} 14 | {%- endfor -%} 15 | {%- else -%} 16 | {{ schema.name_for_breadcrumbs }} 17 | {%- endif -%} 18 | #} 19 | {%- if schema.type_name == "object" -%} 20 | [{{ my_string|join('.') }}] 21 | {%- else -%} 22 | {{ my_string|join('.') }} 23 | {%- endif -%} 24 | {%- endfilter -%} 25 | -------------------------------------------------------------------------------- /docs/config-file/templates/md/generate_toml_example.md: -------------------------------------------------------------------------------- 1 | {% set breadcumbs = [] %} 2 | {% set breadcumbs_section = [] %} 3 | {%- for node in schema.nodes_from_root -%} 4 | {%- if not loop.first -%} 5 | {%- set _ = breadcumbs.append(node.name_for_breadcrumbs) -%} 6 | {%- if node.type_name == "object" -%} 7 | {%- set _ = breadcumbs_section.append(node.name_for_breadcrumbs) -%} 8 | {%- endif -%} 9 | {%- endif -%} 10 | {%- endfor -%} 11 | 12 | {% set section_name = breadcumbs_section|join('.') %} 13 | {% set variable_name = breadcumbs|last() %} 14 | 15 | **Example setting the default value** ({{schema.default_value}}): 16 | ``` 17 | {% if section_name != "" %} 18 | [{{section_name}}] 19 | {% endif %} 20 | {{variable_name}}={{schema.default_value}} 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_conditional_subschema.md: -------------------------------------------------------------------------------- 1 | {% if schema.kw_if %} 2 | {% set first_property = schema.kw_if | get_first_property %} 3 | 4 | {% if schema.kw_then %} 5 | {%- filter md_heading(depth) -%}If ( 6 | {{- first_property.property_name | md_escape_for_table -}} 7 | {{- " = " -}} 8 | {{- first_property.kw_const.literal | python_to_json -}} 9 | ){%- endfilter -%} 10 | {% with schema=schema.kw_then, skip_headers=False, depth=depth %} 11 | {% include "content.md" %} 12 | {% endwith %} 13 | {% endif %} 14 | {% if schema.kw_else %} 15 | {%- filter md_heading(depth) -%}Else (i.e. {{ " " }} 16 | {{- first_property.property_name | md_escape_for_table -}} 17 | {{- " != " -}} 18 | {{- first_property.kw_const.literal | python_to_json -}} 19 | ){%- endfilter -%} 20 | {% with schema=schema.kw_else, skip_headers=False, depth=depth %} 21 | {% include "content.md" %} 22 | {% endwith %} 23 | {% endif %} 24 | {% endif %} -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_description.md: -------------------------------------------------------------------------------- 1 | {# Display description #} 2 | {% if description %} 3 | **Description:**{{ " " }}{{ description }} 4 | {% endif %} -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_examples.md: -------------------------------------------------------------------------------- 1 | **Example{% if examples|length > 1 %}s{% endif %}:**{{ " " }} 2 | 3 | {% for example in examples %} 4 | {%- if loop.first %}{{ "\n" }}{% endif -%} 5 | {% set example_id = schema.html_id ~ "_ex" ~ loop.index %} 6 | {%- if not examples_as_yaml -%} 7 | {{- "" }}```json 8 | {{- "\n" }}{{ example }} 9 | {{- "\n" }}``` 10 | {%- else -%} 11 | {{- "" }}```yaml 12 | {{- "\n" }}{{ example | yaml_example }} 13 | {{- "\n" }}``` 14 | {%- endif -%} 15 | {{ "\n" }} 16 | {% endfor %} 17 | -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_not.md: -------------------------------------------------------------------------------- 1 | {{ "Must **not** be" | md_heading(depth+1) }} 2 | {% with schema=schema.kw_not, skip_headers=False, depth=depth+1, skip_required=True %} 3 | {% include "content.md" %} 4 | {% endwith %} -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_one_of.md: -------------------------------------------------------------------------------- 1 | Must be one of: 2 | {% for enum_choice in schema.kw_enum.array_items %} 3 | * {{ enum_choice.literal | python_to_json }} 4 | {% endfor %} -------------------------------------------------------------------------------- /docs/config-file/templates/md/section_undocumented_required_properties.md: -------------------------------------------------------------------------------- 1 | {% set undocumented_required_properties = schema | get_undocumented_required_properties %} 2 | {% if undocumented_required_properties%} 3 | {{ "The following properties are required" | md_heading(depth+1) }} 4 | {% for required_property in undocumented_required_properties %} 5 | * {{ required_property }} 6 | {% endfor %} 7 | {% endif %} -------------------------------------------------------------------------------- /docs/config-file/templates/md/tabbed_section.md: -------------------------------------------------------------------------------- 1 | 2 | {{ current_node | md_array_items(title) | md_generate_table }} 3 | 4 | {% for node in current_node.array_items %} 5 | {% filter md_heading(depth+1, node.html_id) -%} 6 | {% if node.is_pattern_property %}Pattern{% endif %} Property `{% with schema=node %}{%- include "breadcrumbs.md" %}{% endwith %}` 7 | {%- endfilter %} 8 | {% with schema=node, skip_headers=False, depth=depth+1 %} 9 | {% include "content.md" %} 10 | {% endwith %} 11 | {% endfor %} -------------------------------------------------------------------------------- /docs/design/synchronizer/l1_sync_channels_flow_v2.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okx/xlayer-node/837ab57e8ea78f2a062b53ece722b0ead71e2da3/docs/design/synchronizer/l1_sync_channels_flow_v2.drawio.png -------------------------------------------------------------------------------- /docs/mocks.md: -------------------------------------------------------------------------------- 1 | ### Mocks 2 | 3 | Some tests are using mocks. Mocks already generated by [`mockery`](https://github.com/vektra/mockery) tool. If you need to generate it by yourself, 4 | you could use `make generate-mocks` command. Make sure, that mockery tool is installed. -------------------------------------------------------------------------------- /docs/networks.md: -------------------------------------------------------------------------------- 1 | # XLayer testnet networks 2 | 3 | | Network Name | ChainID | RPC URL | Explorer | Bridge Info | 4 | |--------------|---------|---------|----------|------------------| 5 | | Public Testnet | `1402` | https://rpc.public.xlayer-test.net | https://explorer.public.xlayer-test.net | https://public.xlayer-test.net/ -------------------------------------------------------------------------------- /docs/state-steps.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okx/xlayer-node/837ab57e8ea78f2a062b53ece722b0ead71e2da3/docs/state-steps.drawio.png -------------------------------------------------------------------------------- /docs/zkEVM-custom-endpoints.md: -------------------------------------------------------------------------------- 1 | # zkEVM custom endpoints 2 | 3 | The zkEVM Node JSON RPC server works as is when compared to the official Ethereum JSON RPC, but there are some extra information that also needs to be shared when talking about a L2 Networks, in our case we have information about Batches, Proofs, L1 transactions and much more 4 | 5 | In order to allow users to consume this information, a custom set of endpoints was created to provide this information, they are provided under the prefix `zkevm_` 6 | 7 | The endpoint documentation follows the [OpenRPC Specification](https://spec.open-rpc.org/) and can be found next to the endpoints implementation as a json file, [here](../jsonrpc/endpoints_zkevm.openrpc.json) 8 | 9 | The spec can be easily visualized using the official [OpenRPC Playground](https://playground.open-rpc.org/), just copy and paste the json content into the playground area to find a friendly UI showing the methods 10 | -------------------------------------------------------------------------------- /etherman/config.go: -------------------------------------------------------------------------------- 1 | package etherman 2 | 3 | import "github.com/0xPolygonHermez/zkevm-node/etherman/etherscan" 4 | 5 | // Config represents the configuration of the etherman 6 | type Config struct { 7 | // URL is the URL of the Ethereum node for L1 8 | URL string `mapstructure:"URL"` 9 | 10 | // ForkIDChunkSize is the max interval for each call to L1 provider to get the forkIDs 11 | ForkIDChunkSize uint64 `mapstructure:"ForkIDChunkSize"` 12 | 13 | // allow that L1 gas price calculation use multiples sources 14 | MultiGasProvider bool `mapstructure:"MultiGasProvider"` 15 | // Configuration for use Etherscan as used as gas provider, basically it needs the API-KEY 16 | Etherscan etherscan.Config 17 | } 18 | -------------------------------------------------------------------------------- /etherman/errors_test.go: -------------------------------------------------------------------------------- 1 | package etherman 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestTryParseWithExactMatch(t *testing.T) { 11 | expected := ErrTimestampMustBeInsideRange 12 | smartContractErr := expected 13 | 14 | actualErr, ok := tryParseError(smartContractErr) 15 | 16 | assert.ErrorIs(t, actualErr, expected) 17 | assert.True(t, ok) 18 | } 19 | 20 | func TestTryParseWithContains(t *testing.T) { 21 | expected := ErrTimestampMustBeInsideRange 22 | smartContractErr := fmt.Errorf(" execution reverted: ProofOfEfficiency::sequenceBatches: %s", expected) 23 | 24 | actualErr, ok := tryParseError(smartContractErr) 25 | 26 | assert.ErrorIs(t, actualErr, expected) 27 | assert.True(t, ok) 28 | } 29 | 30 | func TestTryParseWithNonExistingErr(t *testing.T) { 31 | smartContractErr := fmt.Errorf("some non-existing err") 32 | 33 | actualErr, ok := tryParseError(smartContractErr) 34 | 35 | assert.Nil(t, actualErr) 36 | assert.False(t, ok) 37 | } 38 | -------------------------------------------------------------------------------- /etherman/etherscan/etherscan_test.go: -------------------------------------------------------------------------------- 1 | package etherscan 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | 11 | "github.com/0xPolygonHermez/zkevm-node/log" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | func init() { 17 | log.Init(log.Config{ 18 | Level: "debug", 19 | Outputs: []string{"stderr"}, 20 | }) 21 | } 22 | 23 | func TestGetGasPrice(t *testing.T) { 24 | ctx := context.Background() 25 | data := `{"status":"1","message":"OK","result":{"LastBlock":"15816910","SafeGasPrice":"10","ProposeGasPrice":"11","FastGasPrice":"55","suggestBaseFee":"9.849758735","gasUsedRatio":"0.779364333333333,0.2434028,0.610012833333333,0.1246597,0.995500566666667"}}` 26 | svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 27 | fmt.Fprint(w, data) 28 | })) 29 | defer svr.Close() 30 | 31 | apiKey := "" 32 | c := NewEtherscanService(apiKey) 33 | c.config.Url = svr.URL 34 | 35 | gp, err := c.SuggestGasPrice(ctx) 36 | require.NoError(t, err) 37 | log.Debug("Etherscan GasPrice: ", gp) 38 | assert.Equal(t, big.NewInt(55000000000), gp) 39 | } 40 | -------------------------------------------------------------------------------- /etherman/ethgasstation/ethgasstation_test.go: -------------------------------------------------------------------------------- 1 | package ethgasstation 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | 11 | "github.com/0xPolygonHermez/zkevm-node/log" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | func init() { 17 | log.Init(log.Config{ 18 | Level: "debug", 19 | Outputs: []string{"stderr"}, 20 | }) 21 | } 22 | 23 | func TestGetGasPrice(t *testing.T) { 24 | ctx := context.Background() 25 | data := `{"baseFee":10,"blockNumber":15817089,"blockTime":11.88,"gasPrice":{"fast":11,"instant":66,"standard":10},"nextBaseFee":10,"priorityFee":{"fast":2,"instant":2,"standard":1}}` 26 | svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 27 | fmt.Fprint(w, data) 28 | })) 29 | defer svr.Close() 30 | c := NewEthGasStationService() 31 | c.Url = svr.URL 32 | 33 | gp, err := c.SuggestGasPrice(ctx) 34 | require.NoError(t, err) 35 | log.Debug("EthGasStation GasPrice: ", gp) 36 | assert.Equal(t, big.NewInt(66000000000), gp) 37 | } 38 | -------------------------------------------------------------------------------- /etherman/properties_xlayer.go: -------------------------------------------------------------------------------- 1 | package etherman 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // GetZkEVMAddressAndL1ChainID returns the ZkEVM address and the L1 chain ID 10 | func (etherMan *Client) GetZkEVMAddressAndL1ChainID() (common.Address, common.Address, uint64, error) { 11 | if etherMan == nil { 12 | return common.Address{}, common.Address{}, 0, fmt.Errorf("etherMan is nil") 13 | } 14 | return etherMan.l1Cfg.ZkEVMAddr, etherMan.l1Cfg.RollupManagerAddr, etherMan.l1Cfg.L1ChainID, nil 15 | } 16 | -------------------------------------------------------------------------------- /etherman/smartcontracts/abi/dataavailabilityprotocol_xlayer.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "getProcotolName", 5 | "outputs": [ 6 | { 7 | "internalType": "string", 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "stateMutability": "pure", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "bytes32", 19 | "name": "hash", 20 | "type": "bytes32" 21 | }, 22 | { 23 | "internalType": "bytes", 24 | "name": "dataAvailabilityMessage", 25 | "type": "bytes" 26 | } 27 | ], 28 | "name": "verifyMessage", 29 | "outputs": [], 30 | "stateMutability": "view", 31 | "type": "function" 32 | } 33 | ] -------------------------------------------------------------------------------- /etherman/smartcontracts/abi/mockverifier.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "bytes32[24]", 6 | "name": "proof", 7 | "type": "bytes32[24]" 8 | }, 9 | { 10 | "internalType": "uint256[1]", 11 | "name": "pubSignals", 12 | "type": "uint256[1]" 13 | } 14 | ], 15 | "name": "verifyProof", 16 | "outputs": [ 17 | { 18 | "internalType": "bool", 19 | "name": "", 20 | "type": "bool" 21 | } 22 | ], 23 | "stateMutability": "pure", 24 | "type": "function" 25 | } 26 | ] -------------------------------------------------------------------------------- /etherman/smartcontracts/bin/mockverifier.bin: -------------------------------------------------------------------------------- 1 | 608060405234801561001057600080fd5b50610158806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80639121da8a14610030575b600080fd5b61004661003e366004610089565b600192915050565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008061032080848603121561009e57600080fd5b6103008401858111156100b057600080fd5b8493508561031f8601126100c357600080fd5b604051602080820182811067ffffffffffffffff821117156100e7576100e761005a565b6040529286019281888511156100fc57600080fd5b5b8484101561011457833581529281019281016100fd565b50949790965094505050505056fea264697066735822122066b50cbb730099c9f1f258fa949f9d4e1a1ef7636af905817cebb300b2be0d2664736f6c63430008140033 -------------------------------------------------------------------------------- /etherman/smartcontracts/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | gen() { 6 | local package=$1 7 | 8 | abigen --bin bin/${package}.bin --abi abi/${package}.abi --pkg=${package} --out=${package}/${package}.go 9 | } 10 | 11 | gen oldpolygonzkevmglobalexitroot 12 | gen oldpolygonzkevmbridge 13 | gen oldpolygonzkevm 14 | gen etrogpolygonzkevm 15 | gen polygonzkevm 16 | gen polygonzkevmbridge 17 | gen pol 18 | gen polygonzkevmglobalexitroot 19 | gen polygonrollupmanager 20 | gen mockpolygonrollupmanager 21 | gen mockverifier 22 | gen proxy -------------------------------------------------------------------------------- /etherman/types/finalproofinputs.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "github.com/0xPolygonHermez/zkevm-node/aggregator/prover" 4 | 5 | // FinalProofInputs struct 6 | type FinalProofInputs struct { 7 | FinalProof *prover.FinalProof 8 | NewLocalExitRoot []byte 9 | NewStateRoot []byte 10 | } 11 | -------------------------------------------------------------------------------- /etherman/types/sequence.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // Sequence represents an operation sent to the PoE smart contract to be 10 | // processed. 11 | type Sequence struct { 12 | GlobalExitRoot, StateRoot, LocalExitRoot common.Hash 13 | AccInputHash common.Hash 14 | LastL2BLockTimestamp int64 15 | BatchL2Data []byte 16 | IsSequenceTooBig bool 17 | BatchNumber uint64 18 | ForcedBatchTimestamp int64 19 | PrevBlockHash common.Hash 20 | } 21 | 22 | // IsEmpty checks is sequence struct is empty 23 | func (s Sequence) IsEmpty() bool { 24 | return reflect.DeepEqual(s, Sequence{}) 25 | } 26 | -------------------------------------------------------------------------------- /ethtxmanager/custodialassetshttpauth_xlayer_test.go: -------------------------------------------------------------------------------- 1 | package ethtxmanager 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestClientGenerateSignature(t *testing.T) { 11 | client := &Client{ 12 | cfg: Config{ 13 | CustodialAssets: CustodialAssetsConfig{ 14 | SecretKey: "12doxpwjkengkjna", 15 | }, 16 | }, 17 | } 18 | ctx := context.Background() 19 | treeMap := make(map[string][]string) 20 | treeMap["0"] = []string{"0x07f67d4195bc9940f07eb901ef18f1e9e4af12d7"} 21 | treeMap["1"] = []string{"127"} 22 | treeMap["2"] = []string{"true"} 23 | auth, err := client.generateSignature(ctx, treeMap, "{\"testBOdy\":45251}", algoSha256) 24 | require.NoError(t, err) 25 | require.Equal(t, "si/fTWlDg6+V9OFOM3CictCuqtGfUjKZ3keGLwxM/walrXtQaN8K/PnGTvFvc4q6pb/80HtZIy+hjeugAx8VPLmIXmKpJ5H4mbGEVQe7bk4=", auth) 26 | 27 | auth, err = client.generateSignature(ctx, treeMap, "{\"testBOdy\":45251}", algoMd5) 28 | require.NoError(t, err) 29 | require.Equal(t, "r1HPNFEpExR61IOWf8mP5oOxbz4RnyU0LF67Dv3hlBWuXy6bJA5x467NbVTldTVOdoAB/16w1cc+7/Y5fDEcC7mIXmKpJ5H4mbGEVQe7bk4=", auth) 30 | } 31 | -------------------------------------------------------------------------------- /ethtxmanager/metrics/metrics_xlayer.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/metrics" 5 | "github.com/prometheus/client_golang/prometheus" 6 | ) 7 | 8 | const ( 9 | // Prefix for the metrics of the sequencer package. 10 | Prefix = "ethtxmanager_" 11 | // HaltCountName is the name of the metric that counts the halt count. 12 | HaltCountName = Prefix + "halt_count" 13 | ) 14 | 15 | // Register the metrics for the sequencer package. 16 | func Register() { 17 | var counters = []prometheus.CounterOpts{ 18 | { 19 | Name: HaltCountName, 20 | Help: "[ETHTXMANAGER] total count of halt", 21 | }, 22 | } 23 | 24 | metrics.RegisterCounters(counters...) 25 | } 26 | 27 | // HaltCount increases the counter for the eth-tx-manager halt count. 28 | func HaltCount() { 29 | metrics.CounterAdd(HaltCountName, 1) 30 | } 31 | -------------------------------------------------------------------------------- /ethtxmanager/mock_etherman_xlayer_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v2.39.0. DO NOT EDIT. 2 | 3 | package ethtxmanager 4 | 5 | import ( 6 | common "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // GetZkEvmAddress provides a mock function with given fields: 10 | func (_m *ethermanMock) GetZkEVMAddressAndL1ChainID() (common.Address, common.Address, uint64, error) { 11 | return common.Address{}, common.Address{}, 0, nil 12 | } 13 | -------------------------------------------------------------------------------- /ethtxmanager/monitoredtx_test.go: -------------------------------------------------------------------------------- 1 | package ethtxmanager 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestTx(t *testing.T) { 12 | to := common.HexToAddress("0x2") 13 | nonce := uint64(1) 14 | value := big.NewInt(2) 15 | data := []byte("data") 16 | gas := uint64(3) 17 | gasOffset := uint64(4) 18 | gasPrice := big.NewInt(5) 19 | 20 | mTx := monitoredTx{ 21 | to: &to, 22 | nonce: nonce, 23 | value: value, 24 | data: data, 25 | gas: gas, 26 | gasOffset: gasOffset, 27 | gasPrice: gasPrice, 28 | } 29 | 30 | tx := mTx.Tx() 31 | 32 | assert.Equal(t, &to, tx.To()) 33 | assert.Equal(t, nonce, tx.Nonce()) 34 | assert.Equal(t, value, tx.Value()) 35 | assert.Equal(t, data, tx.Data()) 36 | assert.Equal(t, gas+gasOffset, tx.Gas()) 37 | assert.Equal(t, gasPrice, tx.GasPrice()) 38 | } 39 | -------------------------------------------------------------------------------- /event/config.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "github.com/0xPolygonHermez/zkevm-node/db" 4 | 5 | // Config for event 6 | type Config struct { 7 | // DB is the database configuration 8 | DB db.Config `mapstructure:"DB"` 9 | } 10 | -------------------------------------------------------------------------------- /event/eventlog_test.go: -------------------------------------------------------------------------------- 1 | package event_test 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/event" 8 | "github.com/0xPolygonHermez/zkevm-node/event/pgeventstorage" 9 | "github.com/0xPolygonHermez/zkevm-node/test/dbutils" 10 | "github.com/stretchr/testify/require" 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | func TestStoreEvent(t *testing.T) { 15 | ctx := context.Background() 16 | 17 | eventDBCfg := dbutils.NewEventConfigFromEnv() 18 | eventStorage, err := pgeventstorage.NewPostgresEventStorage(eventDBCfg) 19 | require.NoError(t, err) 20 | 21 | ev := &event.Event{ 22 | ReceivedAt: time.Now(), 23 | IPAddress: "127.0.0.1", 24 | Source: event.Source_Node, 25 | Component: event.Component_Sequencer, 26 | Level: event.Level_Error, 27 | EventID: event.EventID_ExecutorError, 28 | Description: "This is a test event", 29 | Data: []byte("This is a test event"), 30 | Json: eventDBCfg, 31 | } 32 | 33 | eventLog := event.NewEventLog(event.Config{}, eventStorage) 34 | defer eventStorage.Close() //nolint:gosec,errcheck 35 | 36 | err = eventLog.LogEvent(ctx, ev) 37 | require.NoError(t, err) 38 | } 39 | -------------------------------------------------------------------------------- /event/interfaces.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // Storage is the interface for the event storage 8 | type Storage interface { 9 | // LogEvent logs an event 10 | LogEvent(ctx context.Context, event *Event) error 11 | } 12 | -------------------------------------------------------------------------------- /event/nileventstorage/nileventstorage.go: -------------------------------------------------------------------------------- 1 | package nileventstorage 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/event" 7 | "github.com/0xPolygonHermez/zkevm-node/log" 8 | ) 9 | 10 | // NilEventStorage is an implementation of the event storage interface 11 | // that just logs but does not store the data 12 | type NilEventStorage struct { 13 | } 14 | 15 | // NewNilEventStorage creates and initializes an instance of NewNilEventStorage 16 | func NewNilEventStorage() (*NilEventStorage, error) { 17 | return &NilEventStorage{}, nil 18 | } 19 | 20 | // LogEvent logs an event following the defined interface 21 | func (p *NilEventStorage) LogEvent(ctx context.Context, ev *event.Event) error { 22 | LogEvent(ev) 23 | return nil 24 | } 25 | 26 | // LogEvent actually logs the event 27 | func LogEvent(ev *event.Event) { 28 | switch ev.Level { 29 | case event.Level_Emergency, event.Level_Alert, event.Level_Critical, event.Level_Error: 30 | log.Errorf("Event: %+v", ev) 31 | case event.Level_Warning, event.Level_Notice: 32 | log.Warnf("Event: %+v", ev) 33 | case event.Level_Info: 34 | log.Infof("Event: %+v", ev) 35 | case event.Level_Debug: 36 | log.Debugf("Event: %+v", ev) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gasprice/apollo_xlayer.go: -------------------------------------------------------------------------------- 1 | package gasprice 2 | 3 | import "sync" 4 | 5 | // ApolloConfig is the apollo RPC dynamic config 6 | type ApolloConfig struct { 7 | EnableApollo bool 8 | conf Config 9 | sync.RWMutex 10 | } 11 | 12 | var apolloConfig = &ApolloConfig{} 13 | 14 | // getApolloConfig returns the singleton instance 15 | func getApolloConfig() *ApolloConfig { 16 | return apolloConfig 17 | } 18 | 19 | // Enable returns true if apollo is enabled 20 | func (c *ApolloConfig) Enable() bool { 21 | if c == nil || !c.EnableApollo { 22 | return false 23 | } 24 | c.RLock() 25 | defer c.RUnlock() 26 | return c.EnableApollo 27 | } 28 | 29 | // UpdateConfig updates the apollo config 30 | func UpdateConfig(apolloConfig Config) { 31 | getApolloConfig().Lock() 32 | getApolloConfig().EnableApollo = true 33 | getApolloConfig().conf = apolloConfig 34 | getApolloConfig().Unlock() 35 | } 36 | 37 | func (c *ApolloConfig) get() Config { 38 | c.RLock() 39 | defer c.RUnlock() 40 | return c.conf 41 | } 42 | -------------------------------------------------------------------------------- /gasprice/default_test.go: -------------------------------------------------------------------------------- 1 | package gasprice 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | "testing" 7 | 8 | "github.com/0xPolygonHermez/zkevm-node/log" 9 | ) 10 | 11 | func init() { 12 | log.Init(log.Config{ 13 | Level: "debug", 14 | Outputs: []string{"stdout"}, 15 | }) 16 | } 17 | 18 | func TestUpdateGasPriceDefault(t *testing.T) { 19 | ctx := context.Background() 20 | cfg := Config{ 21 | Type: DefaultType, 22 | Factor: 0.5, 23 | DefaultGasPriceWei: 1000000000, 24 | } 25 | factorAsPercentage := int64(cfg.Factor * 100) // nolint:gomnd 26 | factor := big.NewInt(factorAsPercentage) 27 | defaultGasPriceDivByFactor := new(big.Int).Div(new(big.Int).SetUint64(cfg.DefaultGasPriceWei), factor) 28 | l1GasPrice := new(big.Int).Mul(defaultGasPriceDivByFactor, big.NewInt(100)).Uint64() // nolint:gomnd 29 | 30 | poolM := new(poolMock) 31 | poolM.On("SetGasPrices", ctx, cfg.DefaultGasPriceWei, l1GasPrice).Return(nil).Twice() 32 | dge := newDefaultGasPriceSuggester(ctx, cfg, poolM) 33 | dge.UpdateGasPriceAvg() 34 | } 35 | -------------------------------------------------------------------------------- /gasprice/interfaces.go: -------------------------------------------------------------------------------- 1 | package gasprice 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | "time" 7 | 8 | "github.com/0xPolygonHermez/zkevm-node/pool" 9 | "github.com/ethereum/go-ethereum/core/types" 10 | "github.com/jackc/pgx/v4" 11 | ) 12 | 13 | // Consumer interfaces required by the package. 14 | 15 | // poolInterface contains methods to interact with the tx poolInterface. 16 | type poolInterface interface { 17 | SetGasPrices(ctx context.Context, l2GasPrice uint64, l1GasPrice uint64) error 18 | GetGasPrices(ctx context.Context) (pool.GasPrices, error) 19 | DeleteGasPricesHistoryOlderThan(ctx context.Context, date time.Time) error 20 | } 21 | 22 | // stateInterface gathers the methods required to interact with the state. 23 | type stateInterface interface { 24 | GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) 25 | GetTxsByBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) ([]*types.Transaction, error) 26 | } 27 | 28 | // ethermanInterface contains the methods required to interact with ethereum. 29 | type ethermanInterface interface { 30 | GetL1GasPrice(ctx context.Context) *big.Int 31 | } 32 | -------------------------------------------------------------------------------- /gasprice/sorter.go: -------------------------------------------------------------------------------- 1 | package gasprice 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/core/types" 7 | ) 8 | 9 | type txSorter struct { 10 | txs []*types.Transaction 11 | } 12 | 13 | func newSorter(txs []*types.Transaction) *txSorter { 14 | return &txSorter{ 15 | txs: txs, 16 | } 17 | } 18 | 19 | func (s *txSorter) Len() int { return len(s.txs) } 20 | func (s *txSorter) Swap(i, j int) { 21 | s.txs[i], s.txs[j] = s.txs[j], s.txs[i] 22 | } 23 | func (s *txSorter) Less(i, j int) bool { 24 | tip1 := s.txs[i].GasTipCap() 25 | tip2 := s.txs[j].GasTipCap() 26 | return tip1.Cmp(tip2) < 0 27 | } 28 | 29 | type bigIntArray []*big.Int 30 | 31 | func (s bigIntArray) Len() int { return len(s) } 32 | func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 } 33 | func (s bigIntArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 34 | -------------------------------------------------------------------------------- /hex/hex_test.go: -------------------------------------------------------------------------------- 1 | package hex 2 | 3 | import ( 4 | "encoding/hex" 5 | "math" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestEncodeDecodeBig(t *testing.T) { 14 | b := big.NewInt(math.MaxInt64) 15 | e := EncodeBig(b) 16 | d := DecodeBig(e) 17 | assert.Equal(t, b.Uint64(), d.Uint64()) 18 | } 19 | 20 | // Define a struct for test cases 21 | type TestCase struct { 22 | input string 23 | output []byte 24 | err error 25 | } 26 | 27 | // Unit test function 28 | func TestDecodeHex(t *testing.T) { 29 | testCases := []TestCase{ 30 | {"0", []byte{0}, nil}, 31 | {"00", []byte{0}, nil}, 32 | {"0x0", []byte{0}, nil}, 33 | {"0x00", []byte{0}, nil}, 34 | {"1", []byte{1}, nil}, 35 | {"01", []byte{1}, nil}, 36 | {"", []byte{}, hex.ErrLength}, 37 | {"0x", []byte{}, hex.ErrLength}, 38 | {"zz", []byte{}, hex.InvalidByteError('z')}, 39 | } 40 | 41 | for _, tc := range testCases { 42 | t.Run(tc.input, func(t *testing.T) { 43 | output, err := DecodeHex(tc.input) 44 | if tc.err != nil { 45 | require.Error(t, tc.err, err) 46 | } else { 47 | require.NoError(t, err) 48 | } 49 | require.Equal(t, output, tc.output) 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /jsonrpc/client/client_xlayer.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | 9 | "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" 10 | ) 11 | 12 | // JSONRPCRelay executes a 2.0 JSON RPC HTTP Post Request to the provided URL with 13 | // types.Request, which is compatible with the Ethereum 14 | // JSON RPC Server. 15 | func JSONRPCRelay(url string, request types.Request, rerun bool) (types.Response, error) { 16 | httpRes, err := sendJSONRPC_HTTPRequest(url, request) 17 | if err != nil { 18 | return types.Response{}, err 19 | } 20 | 21 | resBody, err := io.ReadAll(httpRes.Body) 22 | if err != nil { 23 | return types.Response{}, err 24 | } 25 | defer httpRes.Body.Close() 26 | 27 | if httpRes.StatusCode != http.StatusOK { 28 | return types.Response{}, fmt.Errorf("http error: %v - %v", httpRes.StatusCode, string(resBody)) 29 | } 30 | 31 | var res types.Response 32 | err = json.Unmarshal(resBody, &res) 33 | if err != nil { 34 | return types.Response{}, err 35 | } 36 | if res.Error != nil && rerun { 37 | return types.Response{}, fmt.Errorf("response error: %v - %v", res.Error.Code, res.Error.Message) 38 | } 39 | return res, nil 40 | } 41 | -------------------------------------------------------------------------------- /jsonrpc/client/zkevm_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/0xPolygonHermez/zkevm-node/log" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestZkevmGetBatch(t *testing.T) { 14 | t.Skip("This test is exploratory") 15 | // Create a new client 16 | client := NewClient("https://zkevm-rpc.com/") 17 | lastTrustedStateBatchNumberSeen, err := client.BatchNumber(context.Background()) 18 | require.NoError(t, err) 19 | log.Info("lastTrustedStateBatchNumberSeen: ", lastTrustedStateBatchNumberSeen) 20 | batch, err := client.BatchByNumber(context.Background(), big.NewInt(int64(lastTrustedStateBatchNumberSeen))) 21 | require.NoError(t, err) 22 | 23 | // Print the batch 24 | fmt.Println(batch) 25 | } 26 | -------------------------------------------------------------------------------- /jsonrpc/config_xlayer.go: -------------------------------------------------------------------------------- 1 | package jsonrpc 2 | 3 | // NacosConfig has parameters to config the nacos client 4 | type NacosConfig struct { 5 | // URLs nacos server urls for discovery service of rest api, url is separated by "," 6 | URLs string `mapstructure:"URLs"` 7 | 8 | // NamespaceId nacos namepace id for discovery service of rest api 9 | NamespaceId string `mapstructure:"NamespaceId"` 10 | 11 | // ApplicationName rest application name in nacos 12 | ApplicationName string `mapstructure:"ApplicationName"` 13 | 14 | // ExternalListenAddr Set the rest-server external ip and port, when it is launched by Docker 15 | ExternalListenAddr string `mapstructure:"ExternalListenAddr"` 16 | } 17 | -------------------------------------------------------------------------------- /jsonrpc/endpoints_net.go: -------------------------------------------------------------------------------- 1 | package jsonrpc 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/encoding" 7 | "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" 8 | ) 9 | 10 | // NetEndpoints contains implementations for the "net" RPC endpoints 11 | type NetEndpoints struct { 12 | cfg Config 13 | chainID uint64 14 | } 15 | 16 | // NewNetEndpoints returns NetEndpoints 17 | func NewNetEndpoints(cfg Config, chainID uint64) *NetEndpoints { 18 | return &NetEndpoints{ 19 | cfg: cfg, 20 | chainID: chainID, 21 | } 22 | } 23 | 24 | // Version returns the current network id 25 | func (n *NetEndpoints) Version() (interface{}, types.Error) { 26 | return strconv.FormatUint(n.chainID, encoding.Base10), nil 27 | } 28 | -------------------------------------------------------------------------------- /jsonrpc/endpoints_web3.go: -------------------------------------------------------------------------------- 1 | package jsonrpc 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node" 7 | "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" 8 | "golang.org/x/crypto/sha3" 9 | ) 10 | 11 | // Web3Endpoints contains implementations for the "web3" RPC endpoints 12 | type Web3Endpoints struct { 13 | } 14 | 15 | // ClientVersion returns the client version. 16 | func (e *Web3Endpoints) ClientVersion() (interface{}, types.Error) { 17 | return zkevm.Version, nil 18 | } 19 | 20 | // Sha3 returns the keccak256 hash of the given data. 21 | func (e *Web3Endpoints) Sha3(data types.ArgBig) (interface{}, types.Error) { 22 | b := (*big.Int)(&data) 23 | hash := sha3.NewLegacyKeccak256() 24 | hash.Write(b.Bytes()) //nolint:errcheck,gosec 25 | keccak256Hash := hash.Sum(nil) 26 | return types.ArgBytes(keccak256Hash), nil 27 | } 28 | -------------------------------------------------------------------------------- /jsonrpc/handler_xlayer.go: -------------------------------------------------------------------------------- 1 | package jsonrpc 2 | 3 | func (h *Handler) setCfg(cfg Config) { 4 | h.cfg = cfg 5 | } 6 | -------------------------------------------------------------------------------- /jsonrpc/interfaces.go: -------------------------------------------------------------------------------- 1 | package jsonrpc 2 | 3 | // storageInterface json rpc internal storage to persist data 4 | type storageInterface interface { 5 | GetAllBlockFiltersWithWSConn() []*Filter 6 | GetAllLogFiltersWithWSConn() []*Filter 7 | GetFilter(filterID string) (*Filter, error) 8 | NewBlockFilter(wsConn *concurrentWsConn) (string, error) 9 | NewLogFilter(wsConn *concurrentWsConn, filter LogFilter) (string, error) 10 | NewPendingTransactionFilter(wsConn *concurrentWsConn) (string, error) 11 | UninstallFilter(filterID string) error 12 | UninstallFilterByWSConn(wsConn *concurrentWsConn) error 13 | UpdateFilterLastPoll(filterID string) error 14 | } 15 | -------------------------------------------------------------------------------- /jsonrpc/types/errors_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestErrorConstants(t *testing.T) { 10 | assert.Equal(t, -32000, DefaultErrorCode) 11 | assert.Equal(t, -32600, InvalidRequestErrorCode) 12 | assert.Equal(t, -32601, NotFoundErrorCode) 13 | assert.Equal(t, -32602, InvalidParamsErrorCode) 14 | assert.Equal(t, -32700, ParserErrorCode) 15 | } 16 | 17 | func TestErrorMethods(t *testing.T) { 18 | const code, msg = 1, "err" 19 | 20 | var err Error = NewRPCError(code, msg) 21 | 22 | assert.Equal(t, code, err.ErrorCode()) 23 | assert.Equal(t, msg, err.Error()) 24 | } 25 | -------------------------------------------------------------------------------- /jsonrpc/types/query.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | ) 6 | 7 | // LogFilterRequest represents a log filter request. 8 | type LogFilterRequest struct { 9 | BlockHash *common.Hash `json:"blockHash,omitempty"` 10 | FromBlock *string `json:"fromBlock,omitempty"` 11 | ToBlock *string `json:"toBlock,omitempty"` 12 | Address interface{} `json:"address,omitempty"` 13 | Topics []interface{} `json:"topics,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /jsonrpc/types/types_xlayer.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // Contains checks if a string is contained in a slice of strings 4 | func Contains(s []string, str string) bool { 5 | for _, v := range s { 6 | if v == str { 7 | return true 8 | } 9 | } 10 | 11 | return false 12 | } 13 | -------------------------------------------------------------------------------- /l1infotree/hash_test.go: -------------------------------------------------------------------------------- 1 | package l1infotree 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestHashLeaf(t *testing.T) { 11 | expectedLeafHash := common.HexToHash("0xf62f487534b899b1c362242616725878188ca891fab60854b792ca0628286de7") 12 | 13 | prevBlockHash := common.HexToHash("0x24a5871d68723340d9eadc674aa8ad75f3e33b61d5a9db7db92af856a19270bb") 14 | var minTimestamp uint64 = 1697231573 15 | ger := common.HexToHash("0x16994edfddddb9480667b64174fc00d3b6da7290d37b8db3a16571b4ddf0789f") 16 | 17 | leaf := HashLeafData(ger, prevBlockHash, minTimestamp) 18 | 19 | assert.Equal(t, expectedLeafHash, common.BytesToHash(leaf[:])) 20 | } 21 | -------------------------------------------------------------------------------- /log/config.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | // Config for log 4 | type Config struct { 5 | // Environment defining the log format ("production" or "development"). 6 | // In development mode enables development mode (which makes DPanicLevel logs panic), uses a console encoder, writes to standard error, and disables sampling. Stacktraces are automatically included on logs of WarnLevel and above. 7 | // Check [here](https://pkg.go.dev/go.uber.org/zap@v1.24.0#NewDevelopmentConfig) 8 | Environment LogEnvironment `mapstructure:"Environment" jsonschema:"enum=production,enum=development"` 9 | // Level of log. As lower value more logs are going to be generated 10 | Level string `mapstructure:"Level" jsonschema:"enum=debug,enum=info,enum=warn,enum=error,enum=dpanic,enum=panic,enum=fatal"` 11 | // Outputs 12 | Outputs []string `mapstructure:"Outputs"` 13 | } 14 | -------------------------------------------------------------------------------- /log/log_test.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLogNotInitialized(t *testing.T) { 8 | Info("Test log.Info", " value is ", 10) 9 | Infof("Test log.Infof %d", 10) 10 | Infow("Test log.Infow", "value", 10) 11 | Debugf("Test log.Debugf %d", 10) 12 | Error("Test log.Error", " value is ", 10) 13 | Errorf("Test log.Errorf %d", 10) 14 | Errorw("Test log.Errorw", "value", 10) 15 | Warnf("Test log.Warnf %d", 10) 16 | Warnw("Test log.Warnw", "value", 10) 17 | } 18 | 19 | func TestLog(t *testing.T) { 20 | cfg := Config{ 21 | Environment: EnvironmentDevelopment, 22 | Level: "debug", 23 | Outputs: []string{"stderr"}, //[]string{"stdout", "test.log"} 24 | } 25 | 26 | Init(cfg) 27 | 28 | Info("Test log.Info", " value is ", 10) 29 | Infof("Test log.Infof %d", 10) 30 | Infow("Test log.Infow", "value", 10) 31 | Debugf("Test log.Debugf %d", 10) 32 | Error("Test log.Error", " value is ", 10) 33 | Errorf("Test log.Errorf %d", 10) 34 | Errorw("Test log.Errorw", "value", 10) 35 | Warnf("Test log.Warnf %d", 10) 36 | Warnw("Test log.Warnw", "value", 10) 37 | } 38 | -------------------------------------------------------------------------------- /merkletree/client.go: -------------------------------------------------------------------------------- 1 | package merkletree 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/log" 8 | "github.com/0xPolygonHermez/zkevm-node/merkletree/hashdb" 9 | "google.golang.org/grpc" 10 | "google.golang.org/grpc/credentials/insecure" 11 | ) 12 | 13 | // NewMTDBServiceClient creates a new MTDB client. 14 | func NewMTDBServiceClient(ctx context.Context, c Config) (hashdb.HashDBServiceClient, *grpc.ClientConn, context.CancelFunc) { 15 | opts := []grpc.DialOption{ 16 | grpc.WithTransportCredentials(insecure.NewCredentials()), 17 | grpc.WithBlock(), 18 | } 19 | const maxWaitSeconds = 120 20 | ctx, cancel := context.WithTimeout(ctx, maxWaitSeconds*time.Second) 21 | 22 | log.Infof("trying to connect to merkletree: %v", c.URI) 23 | mtDBConn, err := grpc.DialContext(ctx, c.URI, opts...) 24 | if err != nil { 25 | log.Fatalf("fail to dial: %v", err) 26 | } 27 | log.Infof("connected to merkletree") 28 | 29 | mtDBClient := hashdb.NewHashDBServiceClient(mtDBConn) 30 | return mtDBClient, mtDBConn, cancel 31 | } 32 | -------------------------------------------------------------------------------- /merkletree/config.go: -------------------------------------------------------------------------------- 1 | package merkletree 2 | 3 | // Config represents the configuration of the merkletree server. 4 | type Config struct { 5 | // URI is the server URI. 6 | URI string `mapstructure:"URI"` 7 | } 8 | -------------------------------------------------------------------------------- /merkletree/leaf.go: -------------------------------------------------------------------------------- 1 | package merkletree 2 | 3 | // leafType specifies type of the leaf 4 | type leafType uint8 5 | 6 | const ( 7 | // LeafTypeBalance specifies that leaf stores Balance 8 | LeafTypeBalance leafType = 0 9 | // LeafTypeNonce specifies that leaf stores Nonce 10 | LeafTypeNonce leafType = 1 11 | // LeafTypeCode specifies that leaf stores Code 12 | LeafTypeCode leafType = 2 13 | // LeafTypeStorage specifies that leaf stores Storage Value 14 | LeafTypeStorage leafType = 3 15 | // LeafTypeSCLength specifies that leaf stores Storage Value 16 | LeafTypeSCLength leafType = 4 17 | ) 18 | -------------------------------------------------------------------------------- /metrics/api.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | const ( 4 | //Endpoint the endpoint for exposing the metrics 5 | Endpoint = "/metrics" 6 | // ProfilingIndexEndpoint the endpoint for exposing the profiling metrics 7 | ProfilingIndexEndpoint = "/debug/pprof/" 8 | // ProfileEndpoint the endpoint for exposing the profile of the profiling metrics 9 | ProfileEndpoint = "/debug/pprof/profile" 10 | // ProfilingCmdEndpoint the endpoint for exposing the command-line of profiling metrics 11 | ProfilingCmdEndpoint = "/debug/pprof/cmdline" 12 | // ProfilingSymbolEndpoint the endpoint for exposing the symbol of profiling metrics 13 | ProfilingSymbolEndpoint = "/debug/pprof/symbol" 14 | // ProfilingTraceEndpoint the endpoint for exposing the trace of profiling metrics 15 | ProfilingTraceEndpoint = "/debug/pprof/trace" 16 | ) 17 | -------------------------------------------------------------------------------- /metrics/config.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | // Config represents the configuration of the metrics 4 | type Config struct { 5 | // Host is the address to bind the metrics server 6 | Host string `mapstructure:"Host"` 7 | // Port is the port to bind the metrics server 8 | Port int `mapstructure:"Port"` 9 | // Enabled is the flag to enable/disable the metrics server 10 | Enabled bool `mapstructure:"Enabled"` 11 | // ProfilingHost is the address to bind the profiling server 12 | ProfilingHost string `mapstructure:"ProfilingHost"` 13 | // ProfilingPort is the port to bind the profiling server 14 | ProfilingPort int `mapstructure:"ProfilingPort"` 15 | // ProfilingEnabled is the flag to enable/disable the profiling server 16 | ProfilingEnabled bool `mapstructure:"ProfilingEnabled"` 17 | } 18 | -------------------------------------------------------------------------------- /pool/trace/trace.go: -------------------------------------------------------------------------------- 1 | package trace 2 | 3 | import "context" 4 | 5 | type contextKey string 6 | 7 | const ( 8 | // ID is the key to store the trace ID in the context 9 | ID contextKey = "traceID" 10 | ) 11 | 12 | // GetID returns the trace ID from the context 13 | func GetID(ctx context.Context) (string, string) { 14 | if ctx == nil || ctx.Value(ID) == nil { 15 | return "", "" 16 | } 17 | return string(ID), ctx.Value(ID).(string) 18 | } 19 | 20 | // String returns the string representation of the context key 21 | func (key contextKey) String() string { 22 | return string(key) 23 | } 24 | -------------------------------------------------------------------------------- /pool/transaction_xlayer.go: -------------------------------------------------------------------------------- 1 | package pool 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/log" 7 | "github.com/ethereum/go-ethereum/common" 8 | ) 9 | 10 | var l2BridgeAddr common.Address 11 | 12 | // SetL2BridgeAddr sets the L2 bridge address 13 | func SetL2BridgeAddr(value common.Address) { 14 | log.Infof("Set L2 bridge address: %s", value.String()) 15 | l2BridgeAddr = value 16 | } 17 | 18 | // IsClaimTx checks, if tx is a claim tx 19 | func (tx *Transaction) IsClaimTx(freeClaimGasLimit uint64, bridgeClaimMethods []string) bool { 20 | if tx.To() == nil { 21 | return false 22 | } 23 | 24 | txGas := tx.Gas() 25 | if txGas > freeClaimGasLimit { 26 | return false 27 | } 28 | 29 | if *tx.To() != l2BridgeAddr { 30 | return false 31 | } 32 | 33 | methods := getClaimMethod(bridgeClaimMethods) 34 | for _, method := range methods { 35 | if strings.HasPrefix("0x"+common.Bytes2Hex(tx.Data()), method) { 36 | log.Infof("Transaction %s is a claim tx", tx.Hash().String()) 37 | return true 38 | } 39 | } 40 | 41 | return false 42 | } 43 | -------------------------------------------------------------------------------- /pool/validation.go: -------------------------------------------------------------------------------- 1 | package pool 2 | 3 | import "net" 4 | 5 | // IsValidIP returns true if the given string is a valid IP address 6 | func IsValidIP(ip string) bool { 7 | return ip != "" && net.ParseIP(ip) != nil 8 | } 9 | -------------------------------------------------------------------------------- /pool/validation_test.go: -------------------------------------------------------------------------------- 1 | package pool 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func Test_IsValidIP(t *testing.T) { 10 | var tests = []struct { 11 | name string 12 | ip string 13 | expected bool 14 | }{ 15 | {"Valid IPv4", "127.0.0.1", true}, 16 | {"Valid IPv6", "2001:db8:0:1:1:1:1:1", true}, 17 | {"Invalid IP", "300.0.0.1", false}, 18 | {"Empty IP", "", false}, 19 | } 20 | 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | result := IsValidIP(tt.ip) 24 | assert.Equal(t, tt.expected, result) 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sequencer/addrqueue_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | func (a *addrQueue) GetTxCount() uint64 { 4 | if a == nil { 5 | return 0 6 | } 7 | var readyTxCount uint64 8 | if a.readyTx != nil { 9 | readyTxCount = 1 10 | } 11 | notReadyTxCount := uint64(len(a.notReadyTxs)) 12 | forcedTxCount := uint64(len(a.forcedTxs)) 13 | pendingTxsToStoreCount := uint64(len(a.pendingTxsToStore)) 14 | 15 | return readyTxCount + notReadyTxCount + forcedTxCount + pendingTxsToStoreCount 16 | } 17 | -------------------------------------------------------------------------------- /sequencer/finalizer_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/0xPolygonHermez/zkevm-node/event" 9 | "github.com/0xPolygonHermez/zkevm-node/log" 10 | seqMetrics "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" 11 | ) 12 | 13 | func (f *finalizer) tryToSleep() { 14 | fullBatchSleepDuration := getFullBatchSleepDuration(f.cfg.FullBatchSleepDuration.Duration) 15 | if fullBatchSleepDuration > 0 { 16 | log.Infof("Slow down sequencer: %v", fullBatchSleepDuration) 17 | time.Sleep(fullBatchSleepDuration) 18 | seqMetrics.GetLogStatistics().CumulativeCounting(seqMetrics.GetTxPauseCounter) 19 | } 20 | } 21 | 22 | // keepHalting keeps the finalizer halted 23 | func (f *finalizer) keepHalting(ctx context.Context, err error) { 24 | f.haltFinalizer.Store(true) 25 | 26 | f.LogEvent(ctx, event.Level_Critical, event.EventID_FinalizerHalt, fmt.Sprintf("finalizer halted due to error: %s", err), nil) 27 | 28 | for { 29 | seqMetrics.HaltCount() 30 | log.Errorf("keep halting finalizer, error: %v", err) 31 | time.Sleep(5 * time.Second) //nolint:gomnd 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sequencer/l2block_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | func (f *finalizer) setWIPL2BlockCloseReason(closeReason BlockClosingReason) { 4 | if f.wipL2Block != nil { 5 | f.wipL2Block.metrics.closeReason = string(closeReason) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /sequencer/metrics_xlayer_test.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func Test_Summary(t *testing.T) { 9 | tests := []struct { 10 | name string 11 | metrics *metrics 12 | }{ 13 | {"1", &metrics{ 14 | closedAt: time.Now(), 15 | processedTxsCount: 10, 16 | l2BlockTxsCount: 10, 17 | idleTime: time.Second, 18 | newL2BlockTimes: processTimes{sequencer: time.Second, executor: time.Second}, 19 | transactionsTimes: processTimes{sequencer: time.Second, executor: time.Second}, 20 | l2BlockTimes: processTimes{sequencer: time.Second, executor: time.Second}, 21 | gas: 10, 22 | estimatedTxsPerSec: 10, 23 | estimatedGasPerSec: 10, 24 | closeReason: "deadline", 25 | }}, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | t.Log(tt.metrics.Summary(1, 3, uint64(time.Now().Unix()))) 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sequencer/mock_pool_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v2.39.0. DO NOT EDIT. 2 | 3 | package sequencer 4 | 5 | import ( 6 | context "context" 7 | ) 8 | 9 | // DeleteFailedTransactionsOlderThan provides a mock function with given fields: ctx, date 10 | func (_m *PoolMock) CountPendingTransactions(ctx context.Context) (uint64, error) { 11 | return 0, nil 12 | } 13 | 14 | func (_m *PoolMock) UpdateReadyTxCount(ctx context.Context, count uint64) error { 15 | return nil 16 | } -------------------------------------------------------------------------------- /sequencer/mock_worker_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | // CountReadyTx provides a mock function with given fields: 4 | func (_m *WorkerMock) CountReadyTx() uint64 { 5 | _m.Called() 6 | ret := _m.Called() 7 | return ret.Get(0).(uint64) 8 | } 9 | -------------------------------------------------------------------------------- /sequencer/pooltx_counter_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | ) 7 | 8 | // PoolReadyTxCounter is the struct that holds the ready tx counter 9 | type PoolReadyTxCounter struct { 10 | // Count is the number of ready transactions 11 | Count uint64 12 | } 13 | 14 | var poolReadyTxCounterInst *PoolReadyTxCounter 15 | var poolReadyTxCounterOnce sync.Once 16 | 17 | func getPoolReadyTxCounter() *PoolReadyTxCounter { 18 | poolReadyTxCounterOnce.Do(func() { 19 | poolReadyTxCounterInst = &PoolReadyTxCounter{} 20 | }) 21 | return poolReadyTxCounterInst 22 | } 23 | 24 | func (ptx *PoolReadyTxCounter) setReadyTxCount(count uint64) { 25 | atomic.StoreUint64(&ptx.Count, count) 26 | } 27 | 28 | // Sum returns the sum of the ready tx counter 29 | func (ptx *PoolReadyTxCounter) getReadyTxCount() uint64 { 30 | return atomic.LoadUint64(&ptx.Count) 31 | } 32 | -------------------------------------------------------------------------------- /sequencer/timeoutCond.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | type timeoutCond struct { 9 | L sync.Locker 10 | ch chan bool 11 | } 12 | 13 | func newTimeoutCond(l sync.Locker) *timeoutCond { 14 | return &timeoutCond{ch: make(chan bool), L: l} 15 | } 16 | 17 | func (t *timeoutCond) Wait() { 18 | t.L.Unlock() 19 | <-t.ch 20 | t.L.Lock() 21 | } 22 | 23 | func (t *timeoutCond) WaitOrTimeout(d time.Duration) bool { 24 | timeout := time.NewTimer(d) 25 | t.L.Unlock() 26 | var r bool 27 | select { 28 | case <-timeout.C: 29 | r = false 30 | case <-t.ch: 31 | r = true 32 | } 33 | if !timeout.Stop() { 34 | select { 35 | case <-timeout.C: 36 | default: 37 | } 38 | } 39 | t.L.Lock() 40 | return r 41 | } 42 | 43 | func (t *timeoutCond) Signal() { 44 | t.signal() 45 | } 46 | 47 | func (t *timeoutCond) Broadcast() { 48 | for { 49 | // Stop when we run out of waiters 50 | if !t.signal() { 51 | return 52 | } 53 | } 54 | } 55 | 56 | func (t *timeoutCond) signal() bool { 57 | select { 58 | case t.ch <- true: 59 | return true 60 | default: 61 | return false 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sequencer/waitgroupcount.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | ) 7 | 8 | // WaitGroupCount implements a sync.WaitGroup that also has a field to get the WaitGroup counter 9 | type WaitGroupCount struct { 10 | sync.WaitGroup 11 | count atomic.Int32 12 | } 13 | 14 | // Add adds delta to the WaitGroup and increase the counter 15 | func (wg *WaitGroupCount) Add(delta int) { 16 | wg.count.Add(int32(delta)) 17 | wg.WaitGroup.Add(delta) 18 | } 19 | 20 | // Done decrements the WaitGroup and counter by one 21 | func (wg *WaitGroupCount) Done() { 22 | wg.count.Add(-1) 23 | wg.WaitGroup.Done() 24 | } 25 | 26 | // Count returns the counter of the WaitGroup 27 | func (wg *WaitGroupCount) Count() int { 28 | return int(wg.count.Load()) 29 | } 30 | -------------------------------------------------------------------------------- /sequencer/worker_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencer 2 | 3 | func (w *Worker) deleteReadyTxCounter(addr string) { 4 | if w == nil || w.readyTxCounter == nil { 5 | return 6 | } 7 | delete(w.readyTxCounter, addr) 8 | } 9 | 10 | func (w *Worker) setReadyTxCounter(addr string, count uint64) { 11 | if w == nil || w.readyTxCounter == nil { 12 | return 13 | } 14 | w.readyTxCounter[addr] = count 15 | } 16 | 17 | // CountReadyTx returns the number of ready transactions 18 | func (w *Worker) CountReadyTx() uint64 { 19 | if w == nil { 20 | return 0 21 | } 22 | w.workerMutex.Lock() 23 | defer w.workerMutex.Unlock() 24 | 25 | var count uint64 26 | for _, c := range w.readyTxCounter { 27 | count += c 28 | } 29 | return count 30 | } 31 | -------------------------------------------------------------------------------- /sequencesender/interfaces_xlayer.go: -------------------------------------------------------------------------------- 1 | package sequencesender 2 | 3 | import ( 4 | "context" 5 | 6 | ethmanTypes "github.com/0xPolygonHermez/zkevm-node/etherman/types" 7 | ) 8 | 9 | type dataAbilitier interface { 10 | PostSequence(ctx context.Context, sequences []ethmanTypes.Sequence) ([]byte, error) 11 | } 12 | -------------------------------------------------------------------------------- /sequencesender/mock_etherman_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v2.39.0. DO NOT EDIT. 2 | 3 | package sequencesender 4 | 5 | import ( 6 | ethmanTypes "github.com/0xPolygonHermez/zkevm-node/etherman/types" 7 | "github.com/ethereum/go-ethereum/common" 8 | types "github.com/ethereum/go-ethereum/core/types" 9 | ) 10 | 11 | func (_m *EthermanMock) BuildSequenceBatchesTxDataXLayer(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64,l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (to *common.Address, data []byte, err error){ 12 | return nil, nil, nil 13 | } 14 | func (_m *EthermanMock) EstimateGasSequenceBatchesXLayer(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64,l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (*types.Transaction, error) { 15 | return nil, nil 16 | } 17 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=xlayer-node 2 | 3 | sonar.sources=. 4 | sonar.exclusions=**/*_test.go 5 | sonar.exclusions=**/mock_*.go 6 | 7 | sonar.tests=. 8 | sonar.test.inclusions=**/*_test.go 9 | sonar.go.coverage.reportPaths=coverage.out 10 | sonar.go.tests.reportPaths=report.json 11 | -------------------------------------------------------------------------------- /state/block.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // Block struct 10 | type Block struct { 11 | BlockNumber uint64 12 | BlockHash common.Hash 13 | ParentHash common.Hash 14 | ReceivedAt time.Time 15 | Checked bool 16 | } 17 | 18 | // NewBlock creates a block with the given data. 19 | func NewBlock(blockNumber uint64) *Block { 20 | return &Block{BlockNumber: blockNumber} 21 | } 22 | -------------------------------------------------------------------------------- /state/crypto.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/ethereum/go-ethereum/core/types" 7 | "github.com/ethereum/go-ethereum/crypto" 8 | ) 9 | 10 | var ( 11 | // ErrInvalidSig indicates the signature of the transaction is not valid 12 | ErrInvalidSig = errors.New("invalid transaction v, r, s values") 13 | ) 14 | 15 | // CheckSignature checks a transaction signature 16 | func CheckSignature(tx types.Transaction) error { 17 | // Check Signature 18 | v, r, s := tx.RawSignatureValues() 19 | plainV := byte(0) 20 | chainID := tx.ChainId().Uint64() 21 | if chainID != 0 { 22 | plainV = byte(v.Uint64() - 35 - 2*(chainID)) 23 | } 24 | if !crypto.ValidateSignatureValues(plainV, r, s, false) { 25 | return ErrInvalidSig 26 | } 27 | 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /state/forcedbatch.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // ForcedBatch represents a ForcedBatch 10 | type ForcedBatch struct { 11 | BlockNumber uint64 12 | ForcedBatchNumber uint64 13 | Sequencer common.Address 14 | GlobalExitRoot common.Hash 15 | RawTxsData []byte 16 | ForcedAt time.Time 17 | } 18 | -------------------------------------------------------------------------------- /state/globalexitroot.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | ) 8 | 9 | // GlobalExitRoot struct 10 | type GlobalExitRoot struct { 11 | BlockNumber uint64 12 | Timestamp time.Time 13 | MainnetExitRoot common.Hash 14 | RollupExitRoot common.Hash 15 | GlobalExitRoot common.Hash 16 | } 17 | -------------------------------------------------------------------------------- /state/infinite.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/log" 7 | ) 8 | 9 | // InfiniteSafeRun executes a function and in case it fails, 10 | // runs the function again infinitely 11 | func InfiniteSafeRun(fn func(), errorMessage string, restartInterval time.Duration) { 12 | for { 13 | SafeRun(fn, errorMessage) 14 | time.Sleep(restartInterval) 15 | } 16 | } 17 | 18 | // SafeRun executes a function with a deferred recover 19 | // to avoid to panic. 20 | func SafeRun(fn func(), errorMessage string) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | log.Errorf(errorMessage, r) 24 | } 25 | }() 26 | fn() 27 | } 28 | -------------------------------------------------------------------------------- /state/l2block_test.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "github.com/ethereum/go-ethereum/core/types" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestL2BlockHash(t *testing.T) { 12 | // create a geth header and block 13 | header := &types.Header{Number: big.NewInt(1)} 14 | ethBlock := types.NewBlockWithHeader(header) 15 | 16 | // create a l2 header and l2 block from geth header 17 | l2Header := NewL2Header(header) 18 | l2Block := NewL2BlockWithHeader(l2Header) 19 | 20 | // compare geth and l2 block hashes, they must match 21 | assert.Equal(t, ethBlock.Hash().String(), l2Block.Hash().String()) 22 | } 23 | -------------------------------------------------------------------------------- /state/mocks/mock_storage_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery. DO NOT EDIT. 2 | 3 | package mocks 4 | 5 | import ( 6 | context "context" 7 | 8 | pgx "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | func (_m *StorageMock) GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error) { 12 | return nil, nil 13 | } 14 | 15 | func (_m *StorageMock) GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) { 16 | return nil, nil 17 | } 18 | 19 | func (_m *StorageMock) GetLastL2BlockTimeByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (uint64, error) { 20 | return 0, nil 21 | } 22 | -------------------------------------------------------------------------------- /state/pgstatestorage/interfaces.go: -------------------------------------------------------------------------------- 1 | package pgstatestorage 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/jackc/pgconn" 7 | "github.com/jackc/pgx/v4" 8 | ) 9 | 10 | type ExecQuerier interface { 11 | Exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) 12 | Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) 13 | QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row 14 | } 15 | -------------------------------------------------------------------------------- /state/pgstatestorage/l2block_xlayer.go: -------------------------------------------------------------------------------- 1 | package pgstatestorage 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/0xPolygonHermez/zkevm-node/state" 9 | "github.com/jackc/pgx/v4" 10 | ) 11 | 12 | // GetLastL2BlockTimeByBatchNumber gets the last l2 block time in a batch by batch number 13 | func (p *PostgresStorage) GetLastL2BlockTimeByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (uint64, error) { 14 | lastClosedBatchNumber, err := p.GetLastBatchNumber(ctx, dbTx) 15 | if err != nil { 16 | return 0, err 17 | } 18 | if batchNumber > lastClosedBatchNumber { 19 | return 0, fmt.Errorf("%w. got %d, last batch should be %d", state.ErrUnexpectedBatch, batchNumber, lastClosedBatchNumber) 20 | } 21 | const query = "SELECT header FROM state.l2block b WHERE batch_num = $1 ORDER BY b.block_num DESC LIMIT 1" 22 | 23 | header := &state.L2Header{} 24 | q := p.getExecQuerier(dbTx) 25 | err = q.QueryRow(ctx, query, batchNumber).Scan(&header) 26 | 27 | if errors.Is(err, pgx.ErrNoRows) { 28 | return 0, state.ErrNotFound 29 | } else if err != nil { 30 | return 0, err 31 | } 32 | 33 | return header.Time, nil 34 | } 35 | -------------------------------------------------------------------------------- /state/pgstatestorage/syncinginfo.go: -------------------------------------------------------------------------------- 1 | package pgstatestorage 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/state" 8 | "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | func (p *PostgresStorage) GetSyncInfoData(ctx context.Context, dbTx pgx.Tx) (state.SyncInfoDataOnStorage, error) { 12 | var info state.SyncInfoDataOnStorage 13 | const getSyncTableSQL = ` 14 | select last_batch_num_seen, last_batch_num_consolidated, init_sync_batch from state.sync_info; 15 | ` 16 | q := p.getExecQuerier(dbTx) 17 | row := q.QueryRow(ctx, getSyncTableSQL) 18 | err := row.Scan(&info.LastBatchNumberSeen, &info.LastBatchNumberConsolidated, &info.InitialSyncingBatch) 19 | if errors.Is(err, pgx.ErrNoRows) { 20 | return state.SyncInfoDataOnStorage{}, state.ErrNotFound 21 | } else if err != nil { 22 | return state.SyncInfoDataOnStorage{}, err 23 | } 24 | return info, nil 25 | } 26 | -------------------------------------------------------------------------------- /state/proof.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import "time" 4 | 5 | // Proof struct 6 | type Proof struct { 7 | BatchNumber uint64 8 | BatchNumberFinal uint64 9 | Proof string 10 | InputProver string 11 | ProofID *string 12 | // Prover name, unique identifier across prover reboots. 13 | Prover *string 14 | // ProverID prover process identifier. 15 | ProverID *string 16 | // GeneratingSince holds the timestamp for the moment in which the 17 | // proof generation has started by a prover. Nil if the proof is not 18 | // currently generating. 19 | GeneratingSince *time.Time 20 | CreatedAt time.Time 21 | UpdatedAt time.Time 22 | } 23 | -------------------------------------------------------------------------------- /state/queue_test.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestQueue(t *testing.T) { 11 | q := NewQueue[int]() 12 | 13 | q.Push(10) 14 | q.Push(20) 15 | q.Push(30) 16 | 17 | top, err := q.Top() 18 | require.NoError(t, err) 19 | assert.Equal(t, 10, top) 20 | assert.Equal(t, 3, q.Len()) 21 | assert.Equal(t, false, q.IsEmpty()) 22 | 23 | pop, err := q.Pop() 24 | require.NoError(t, err) 25 | assert.Equal(t, 10, pop) 26 | assert.Equal(t, 2, q.Len()) 27 | assert.Equal(t, false, q.IsEmpty()) 28 | 29 | top, err = q.Top() 30 | require.NoError(t, err) 31 | assert.Equal(t, 20, top) 32 | assert.Equal(t, 2, q.Len()) 33 | assert.Equal(t, false, q.IsEmpty()) 34 | 35 | pop, err = q.Pop() 36 | require.NoError(t, err) 37 | assert.Equal(t, 20, pop) 38 | assert.Equal(t, 1, q.Len()) 39 | assert.Equal(t, false, q.IsEmpty()) 40 | 41 | pop, err = q.Pop() 42 | require.NoError(t, err) 43 | assert.Equal(t, 30, pop) 44 | assert.Equal(t, 0, q.Len()) 45 | assert.Equal(t, true, q.IsEmpty()) 46 | 47 | _, err = q.Top() 48 | require.Error(t, ErrQueueEmpty, err) 49 | 50 | _, err = q.Pop() 51 | require.Error(t, ErrQueueEmpty, err) 52 | } 53 | -------------------------------------------------------------------------------- /state/reset.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/log" 7 | "github.com/jackc/pgx/v4" 8 | ) 9 | 10 | // Reset resets the state to the given L1 block number 11 | func (s *State) Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error { 12 | // Reset from DB to L1 block number, this will remove in cascade: 13 | // - VirtualBatches 14 | // - VerifiedBatches 15 | // - Entries in exit_root table 16 | err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx) 17 | if err != nil { 18 | log.Error("error resetting L1BlockNumber. Error: ", err) 19 | return err 20 | } 21 | s.ResetL1InfoTree() 22 | return nil 23 | } 24 | 25 | // ResetL1InfoTree resets the L1InfoTree 26 | func (s *State) ResetL1InfoTree() { 27 | // Discard L1InfoTree cache 28 | // We can't rebuild cache, because we are inside a transaction, so we dont known 29 | // is going to be a commit or a rollback. So is going to be rebuild on the next 30 | // request that needs it. 31 | s.l1InfoTree = nil 32 | } 33 | -------------------------------------------------------------------------------- /state/runtime/executor/config.go: -------------------------------------------------------------------------------- 1 | package executor 2 | 3 | import "github.com/0xPolygonHermez/zkevm-node/config/types" 4 | 5 | // Config represents the configuration of the executor server 6 | type Config struct { 7 | URI string `mapstructure:"URI"` 8 | // MaxResourceExhaustedAttempts is the max number of attempts to make a transaction succeed because of resource exhaustion 9 | MaxResourceExhaustedAttempts int `mapstructure:"MaxResourceExhaustedAttempts"` 10 | // WaitOnResourceExhaustion is the time to wait before retrying a transaction because of resource exhaustion 11 | WaitOnResourceExhaustion types.Duration `mapstructure:"WaitOnResourceExhaustion"` 12 | MaxGRPCMessageSize int `mapstructure:"MaxGRPCMessageSize"` 13 | } 14 | -------------------------------------------------------------------------------- /state/runtime/fakevm/account.go: -------------------------------------------------------------------------------- 1 | package fakevm 2 | 3 | import "github.com/ethereum/go-ethereum/common" 4 | 5 | // Account represents a fake EVM account. 6 | type Account struct { 7 | address common.Address 8 | } 9 | 10 | // NewAccount is the Account constructor. 11 | func NewAccount(address common.Address) *Account { 12 | return &Account{address: address} 13 | } 14 | 15 | // Address is the address getter. 16 | func (a *Account) Address() common.Address { return a.address } 17 | -------------------------------------------------------------------------------- /state/runtime/instrumentation/storediff.go: -------------------------------------------------------------------------------- 1 | package instrumentation 2 | 3 | // StoreDiff contains modified storage data 4 | type StoreDiff struct { 5 | Location uint64 `json:"location"` 6 | Value uint64 `json:"value"` 7 | } 8 | -------------------------------------------------------------------------------- /state/runtime/instrumentation/tracers/native/call_flat_xlayer.go: -------------------------------------------------------------------------------- 1 | package native 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/state/runtime/instrumentation/tracers" 5 | ) 6 | 7 | // SetFlatCallTracerLimit set the limit for flatCallFrame. 8 | func SetFlatCallTracerLimit(t tracers.Tracer, l int) tracers.Tracer { 9 | if flatTracer, ok := t.(*flatCallTracer); ok { 10 | flatTracer.limit = l 11 | return flatTracer 12 | } 13 | return t 14 | } 15 | -------------------------------------------------------------------------------- /state/stack.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "errors" 5 | "sync" 6 | ) 7 | 8 | // ErrStackEmpty returned when Pop is called and the stack is empty 9 | var ErrStackEmpty = errors.New("Empty Stack") 10 | 11 | // Stack is a thread safe stack data structure implementation implementing generics 12 | type Stack[T any] struct { 13 | lock sync.Mutex 14 | items []T 15 | } 16 | 17 | // NewStack creates a new stack 18 | func NewStack[T any]() *Stack[T] { 19 | return &Stack[T]{sync.Mutex{}, make([]T, 0)} 20 | } 21 | 22 | // Push adds an item to the stack 23 | func (s *Stack[T]) Push(v T) { 24 | s.lock.Lock() 25 | defer s.lock.Unlock() 26 | 27 | s.items = append(s.items, v) 28 | } 29 | 30 | // Pop removes and returns the last item added to the stack 31 | func (s *Stack[T]) Pop() (T, error) { 32 | s.lock.Lock() 33 | defer s.lock.Unlock() 34 | 35 | size := len(s.items) 36 | if size == 0 { 37 | var r T 38 | return r, ErrStackEmpty 39 | } 40 | 41 | res := s.items[size-1] 42 | s.items = s.items[:size-1] 43 | return res, nil 44 | } 45 | -------------------------------------------------------------------------------- /state/types_xlayer.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | // IsFlatCallTracer returns true when should use flatCallTracer 4 | func (t *TraceConfig) IsFlatCallTracer() bool { 5 | return t.Tracer != nil && *t.Tracer == "flatCallTracer" 6 | } 7 | -------------------------------------------------------------------------------- /synchronizer/actions/actions.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/etherman" 8 | "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | var ( 12 | // ErrInvalidParams is used when the object is not found 13 | ErrInvalidParams = errors.New("invalid params") 14 | ) 15 | 16 | // L1EventProcessor is the interface for a processor of L1 events 17 | // The main function is Process that must execute the event 18 | type L1EventProcessor interface { 19 | // Name of the processor 20 | Name() string 21 | // SupportedForkIds list of forkId that support (you could use WildcardForkId) 22 | SupportedForkIds() []ForkIdType 23 | // SupportedEvents list of events that support (typically one) 24 | SupportedEvents() []etherman.EventOrder 25 | // Process a incomming event 26 | Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error 27 | } 28 | -------------------------------------------------------------------------------- /synchronizer/actions/check_l2block_processor_decorator.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/etherman" 7 | "github.com/jackc/pgx/v4" 8 | ) 9 | 10 | // CheckL2BlockProcessorDecorator This class is just a decorator to call CheckL2Block 11 | type CheckL2BlockProcessorDecorator struct { 12 | L1EventProcessor 13 | l2blockChecker *CheckL2BlockHash 14 | } 15 | 16 | // NewCheckL2BlockDecorator creates a new CheckL2BlockDecorator 17 | func NewCheckL2BlockDecorator(l1EventProcessor L1EventProcessor, l2blockChecker *CheckL2BlockHash) *CheckL2BlockProcessorDecorator { 18 | return &CheckL2BlockProcessorDecorator{ 19 | L1EventProcessor: l1EventProcessor, 20 | l2blockChecker: l2blockChecker, 21 | } 22 | } 23 | 24 | // Process wraps the real Process and after check the L2Blocks 25 | func (p *CheckL2BlockProcessorDecorator) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error { 26 | res := p.L1EventProcessor.Process(ctx, order, l1Block, dbTx) 27 | if res != nil { 28 | return res 29 | } 30 | if p.l2blockChecker == nil { 31 | return nil 32 | } 33 | return p.l2blockChecker.CheckL2Block(ctx, dbTx) 34 | } 35 | -------------------------------------------------------------------------------- /synchronizer/actions/elderberry/processor_l1_sequence_batches_test.go: -------------------------------------------------------------------------------- 1 | package elderberry_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/elderberry" 7 | mock_elderberry "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/elderberry/mocks" 8 | ) 9 | 10 | func TestProcessorL1InfoTreeUpdate_Process(t *testing.T) { 11 | mockState := mock_elderberry.NewStateL1SequenceBatchesElderberry(t) 12 | mockPreviousProcessor := mock_elderberry.NewPreviousProcessor(t) 13 | 14 | _ = elderberry.NewProcessorL1SequenceBatchesElderberry(mockPreviousProcessor, mockState) 15 | } 16 | -------------------------------------------------------------------------------- /synchronizer/actions/incaberry/processor_l1_forced_batches_test.go: -------------------------------------------------------------------------------- 1 | package incaberry 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestProcessorForcedBatchesName(t *testing.T) { 10 | sut := NewProcessL1ForcedBatches(nil) 11 | name := sut.Name() 12 | require.Equal(t, "ProcessL1ForcedBatches", name) 13 | } 14 | -------------------------------------------------------------------------------- /synchronizer/actions/incaberry/processor_l1_sequence_batches_test.go: -------------------------------------------------------------------------------- 1 | package incaberry 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/etherman" 8 | mocks "github.com/0xPolygonHermez/zkevm-node/synchronizer/mocks" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestProcessorL1SequenceBatches_Process(t *testing.T) { 13 | ctx := context.Background() 14 | sut := NewProcessorL1SequenceBatches(nil, nil, nil, nil, nil, nil) 15 | 16 | l1Block := ðerman.Block{ 17 | //SequencedBatches: []Batch{}, // Mock sequenced batches 18 | BlockNumber: 123, // Mock block number 19 | } 20 | 21 | dbTx := mocks.NewDbTxMock(t) 22 | 23 | // Create an instance of ProcessorL1SequenceBatches 24 | 25 | // Test invalid call, no sequenced batches 26 | err := sut.Process(ctx, etherman.Order{Name: sut.SupportedEvents()[0], Pos: 0}, l1Block, dbTx) 27 | require.Error(t, err) 28 | } 29 | -------------------------------------------------------------------------------- /synchronizer/actions/processor_base.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/etherman" 7 | ) 8 | 9 | // ProcessorBase is the base struct for all the processors, if reduces the boilerplate 10 | // implementing the Name, SupportedEvents and SupportedForkIds functions 11 | type ProcessorBase[T any] struct { 12 | SupportedEvent []etherman.EventOrder 13 | SupportedForkdIds *[]ForkIdType 14 | } 15 | 16 | // Name returns the name of the struct T 17 | func (g *ProcessorBase[T]) Name() string { 18 | var value T 19 | a := reflect.TypeOf(value) 20 | b := a.Name() 21 | return b 22 | } 23 | 24 | // SupportedEvents returns the supported events in the struct 25 | func (p *ProcessorBase[T]) SupportedEvents() []etherman.EventOrder { 26 | return p.SupportedEvent 27 | } 28 | 29 | // SupportedForkIds returns the supported forkIds in the struct or the dafault till incaberry forkId 30 | func (p *ProcessorBase[T]) SupportedForkIds() []ForkIdType { 31 | if p.SupportedForkdIds != nil { 32 | return *p.SupportedForkdIds 33 | } 34 | // returns none 35 | return []ForkIdType{} 36 | } 37 | -------------------------------------------------------------------------------- /synchronizer/actions/processor_manager/test/mock_processor.go: -------------------------------------------------------------------------------- 1 | package processor_manager_test 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/etherman" 7 | "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" 8 | "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | type ProcessorStub struct { 12 | name string 13 | supportedEvents []etherman.EventOrder 14 | supportedForkIds []actions.ForkIdType 15 | responseProcess error 16 | } 17 | 18 | func (p *ProcessorStub) Name() string { 19 | return p.name 20 | } 21 | 22 | func (p *ProcessorStub) SupportedEvents() []etherman.EventOrder { 23 | return p.supportedEvents 24 | } 25 | 26 | func (p *ProcessorStub) SupportedForkIds() []actions.ForkIdType { 27 | return p.supportedForkIds 28 | } 29 | 30 | func (p *ProcessorStub) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error { 31 | return p.responseProcess 32 | } 33 | -------------------------------------------------------------------------------- /synchronizer/common/converters.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" 7 | "github.com/0xPolygonHermez/zkevm-node/state" 8 | ) 9 | 10 | // RpcBatchToStateBatch converts a rpc batch to a state batch 11 | func RpcBatchToStateBatch(rpcBatch *types.Batch) *state.Batch { 12 | if rpcBatch == nil { 13 | return nil 14 | } 15 | batch := &state.Batch{ 16 | BatchNumber: uint64(rpcBatch.Number), 17 | Coinbase: rpcBatch.Coinbase, 18 | StateRoot: rpcBatch.StateRoot, 19 | BatchL2Data: rpcBatch.BatchL2Data, 20 | GlobalExitRoot: rpcBatch.GlobalExitRoot, 21 | LocalExitRoot: rpcBatch.LocalExitRoot, 22 | Timestamp: time.Unix(int64(rpcBatch.Timestamp), 0), 23 | WIP: !rpcBatch.Closed, 24 | } 25 | if rpcBatch.ForcedBatchNumber != nil { 26 | batch.ForcedBatchNum = (*uint64)(rpcBatch.ForcedBatchNumber) 27 | } 28 | return batch 29 | } 30 | -------------------------------------------------------------------------------- /synchronizer/common/log_helper_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "testing" 4 | 5 | func TestLogComparedBytes(t *testing.T) { 6 | name1 := "file1.txt" 7 | name2 := "file2.txt" 8 | data1 := []byte{1, 2, 3, 4, 5} 9 | data2 := []byte{1, 2, 6, 4, 5} 10 | numBytesBefore := 2 11 | numBytesAfter := 2 12 | 13 | expected := "file1.txt(5): 0102*0304...(1)\nfile2.txt(5): 0102*0604...(1)" 14 | result := LogComparedBytes(name1, name2, data1, data2, numBytesBefore, numBytesAfter) 15 | if result != expected { 16 | t.Errorf("Unexpected result. Expected: %s, Got: %s", expected, result) 17 | } 18 | } 19 | 20 | func TestLogComparedBytes2(t *testing.T) { 21 | name1 := "file1.txt" 22 | name2 := "file2.txt" 23 | data1 := []byte{10, 20, 30, 1, 2, 3, 4, 5} 24 | data2 := []byte{10, 20, 30, 1, 2, 6, 4, 5} 25 | numBytesBefore := 2 26 | numBytesAfter := 2 27 | 28 | expected := "file1.txt(8): (3)...0102*0304...(1)\nfile2.txt(8): (3)...0102*0604...(1)" 29 | result := LogComparedBytes(name1, name2, data1, data2, numBytesBefore, numBytesAfter) 30 | if result != expected { 31 | t.Errorf("Unexpected result. Expected: %s, Got: %s", expected, result) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /synchronizer/common/mock_time_provider.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "time" 4 | 5 | // MockTimerProvider is a mock implementation of the TimerProvider interface that return the internal variable 6 | type MockTimerProvider struct { 7 | now time.Time 8 | } 9 | 10 | // Now in the implementation of TimeProvider.Now() 11 | func (m *MockTimerProvider) Now() time.Time { 12 | return m.now 13 | } 14 | -------------------------------------------------------------------------------- /synchronizer/common/reorg_error.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "fmt" 4 | 5 | // ReorgError is an error that is raised when a reorg is detected 6 | type ReorgError struct { 7 | // BlockNumber is the block number that caused the reorg 8 | BlockNumber uint64 9 | Err error 10 | } 11 | 12 | // NewReorgError creates a new ReorgError 13 | func NewReorgError(blockNumber uint64, err error) *ReorgError { 14 | return &ReorgError{ 15 | BlockNumber: blockNumber, 16 | Err: err, 17 | } 18 | } 19 | 20 | func (e *ReorgError) Error() string { 21 | return fmt.Sprintf("%s blockNumber: %d", e.Err.Error(), e.BlockNumber) 22 | } 23 | 24 | // IsReorgError checks if an error is a ReorgError 25 | func IsReorgError(err error) bool { 26 | _, ok := err.(*ReorgError) 27 | return ok 28 | } 29 | 30 | // GetReorgErrorBlockNumber returns the block number that caused the reorg 31 | func GetReorgErrorBlockNumber(err error) uint64 { 32 | if reorgErr, ok := err.(*ReorgError); ok { 33 | return reorgErr.BlockNumber 34 | } 35 | return 0 36 | } 37 | 38 | // GetReorgError returns the error that caused the reorg 39 | func GetReorgError(err error) error { 40 | if reorgErr, ok := err.(*ReorgError); ok { 41 | return reorgErr.Err 42 | } 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/critical_error_handler.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import "context" 4 | 5 | // CriticalErrorHandler is an interface for handling critical errors. Before that class this was called Halt() 6 | type CriticalErrorHandler interface { 7 | // CriticalError is called when a critical error occurs. The error is passed in as a parameter. 8 | // this function could be blocking or non-blocking, depending on the implementation. 9 | CriticalError(ctx context.Context, err error) 10 | } 11 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/eth_tx_manager.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/jackc/pgx/v4" 7 | ) 8 | 9 | type EthTxManager interface { 10 | Reorg(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) error 11 | } 12 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/etherman.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/etherman" 8 | "github.com/ethereum/go-ethereum/common" 9 | ethTypes "github.com/ethereum/go-ethereum/core/types" 10 | ) 11 | 12 | // EthermanFullInterface contains the methods required to interact with ethereum. 13 | type EthermanFullInterface interface { 14 | HeaderByNumber(ctx context.Context, number *big.Int) (*ethTypes.Header, error) 15 | GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error) 16 | EthBlockByNumber(ctx context.Context, blockNumber uint64) (*ethTypes.Block, error) 17 | GetTrustedSequencerURL() (string, error) 18 | VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) 19 | GetLatestVerifiedBatchNum() (uint64, error) 20 | 21 | EthermanGetLatestBatchNumber 22 | GetFinalizedBlockNumber(ctx context.Context) (uint64, error) 23 | } 24 | 25 | type EthermanGetLatestBatchNumber interface { 26 | GetLatestBatchNumber() (uint64, error) 27 | } 28 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/evenlog.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/event" 7 | ) 8 | 9 | // EventLogInterface write an event to the event log database 10 | type EventLogInterface interface { 11 | LogEvent(ctx context.Context, event *event.Event) error 12 | } 13 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/mocks/etherman_full_interface_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery. DO NOT EDIT. 2 | 3 | package mock_syncinterfaces 4 | 5 | import ( 6 | "github.com/0xPolygonHermez/zkevm-node/dataavailability/datacommittee" 7 | ) 8 | 9 | func (_m *EthermanFullInterface) GetCurrentDataCommittee() (*datacommittee.DataCommittee, error) { 10 | //TODO implement me 11 | panic("implement me") 12 | } 13 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/mocks/state_full_interface_xlayer.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery. DO NOT EDIT. 2 | 3 | package mock_syncinterfaces 4 | 5 | import ( 6 | context "context" 7 | 8 | "github.com/jackc/pgx/v4" 9 | ) 10 | 11 | func (_m *StateFullInterface) GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error){ 12 | return nil, nil 13 | } -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/pool.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | 6 | ethTypes "github.com/ethereum/go-ethereum/core/types" 7 | ) 8 | 9 | type PoolInterface interface { 10 | DeleteReorgedTransactions(ctx context.Context, txs []*ethTypes.Transaction) error 11 | StoreTx(ctx context.Context, tx ethTypes.Transaction, ip string, isWIP bool) error 12 | } 13 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/sync.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import "github.com/jackc/pgx/v4" 4 | 5 | // SynchronizerFlushIDManager is a interface with the methods to manage the flushID 6 | type SynchronizerFlushIDManager interface { 7 | PendingFlushID(flushID uint64, proverID string) 8 | CheckFlushID(dbTx pgx.Tx) error 9 | } 10 | 11 | type SynchronizerIsTrustedSequencer interface { 12 | IsTrustedSequencer() bool 13 | } 14 | 15 | type SynchronizerCleanTrustedState interface { 16 | CleanTrustedState() 17 | } 18 | 19 | type SynchronizerFullInterface interface { 20 | SynchronizerFlushIDManager 21 | SynchronizerIsTrustedSequencer 22 | SynchronizerCleanTrustedState 23 | } 24 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/zkevm_ethereum_compatible_client.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/ethereum/go-ethereum/core/types" 8 | ) 9 | 10 | // ZKEVMClientEthereumCompatibleInterface contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible 11 | // 12 | // Reason behind: the zkEVMClient have some extensions to ethereum-API that are not compatible with all nodes. So if you need to maximize 13 | // the compatibility the idea is to use a regular ethereum-API compatible client 14 | type ZKEVMClientEthereumCompatibleInterface interface { 15 | ZKEVMClientEthereumCompatibleL2BlockGetter 16 | } 17 | 18 | // ZKEVMClientEthereumCompatibleL2BlockGetter contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible for obtain Block information 19 | type ZKEVMClientEthereumCompatibleL2BlockGetter interface { 20 | BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) 21 | } 22 | -------------------------------------------------------------------------------- /synchronizer/common/syncinterfaces/zkevm_rpc.go: -------------------------------------------------------------------------------- 1 | package syncinterfaces 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" 8 | "github.com/ethereum/go-ethereum/common" 9 | ) 10 | 11 | // ZkEVMClientInterface contains the methods required to interact with zkEVM-RPC 12 | type ZKEVMClientTrustedBatchesGetter interface { 13 | BatchNumber(ctx context.Context) (uint64, error) 14 | BatchByNumber(ctx context.Context, number *big.Int) (*types.Batch, error) 15 | } 16 | 17 | // ZkEVMClientInterface contains the methods required to interact with zkEVM-RPC for obtain GlobalExitRoot information 18 | type ZKEVMClientGlobalExitRootGetter interface { 19 | ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) 20 | } 21 | 22 | type ZKEVMClientGetL2BlockByNumber interface { 23 | BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) 24 | } 25 | 26 | type ZKEVMClientInterface interface { 27 | ZKEVMClientTrustedBatchesGetter 28 | ZKEVMClientGlobalExitRootGetter 29 | ZKEVMClientGetL2BlockByNumber 30 | } 31 | -------------------------------------------------------------------------------- /synchronizer/common/time_provider.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // TimeProvider is a interface for classes that needs time and we want to be able to unittest it 8 | type TimeProvider interface { 9 | // Now returns current time 10 | Now() time.Time 11 | } 12 | 13 | // DefaultTimeProvider is the default implementation of TimeProvider 14 | type DefaultTimeProvider struct{} 15 | 16 | // Now returns current time 17 | func (d DefaultTimeProvider) Now() time.Time { 18 | return time.Now() 19 | } 20 | -------------------------------------------------------------------------------- /synchronizer/interfaces.go: -------------------------------------------------------------------------------- 1 | package synchronizer 2 | 3 | // All interfaces have been moved to the synchronizer/common/syncinterfaces package 4 | -------------------------------------------------------------------------------- /synchronizer/l1_check_block/common.go: -------------------------------------------------------------------------------- 1 | package l1_check_block 2 | 3 | const ( 4 | logPrefix = "checkL1block:" 5 | ) 6 | -------------------------------------------------------------------------------- /synchronizer/l1_parallel_sync/l1_etherman_interface.go: -------------------------------------------------------------------------------- 1 | package l1_parallel_sync 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/etherman" 8 | "github.com/ethereum/go-ethereum/common" 9 | ethTypes "github.com/ethereum/go-ethereum/core/types" 10 | ) 11 | 12 | // L1ParallelEthermanInterface is an interface for the etherman package 13 | type L1ParallelEthermanInterface interface { 14 | HeaderByNumber(ctx context.Context, number *big.Int) (*ethTypes.Header, error) 15 | GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error) 16 | EthBlockByNumber(ctx context.Context, blockNumber uint64) (*ethTypes.Block, error) 17 | GetLatestBatchNumber() (uint64, error) 18 | GetTrustedSequencerURL() (string, error) 19 | VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) 20 | GetLatestVerifiedBatchNum() (uint64, error) 21 | } 22 | -------------------------------------------------------------------------------- /synchronizer/l1_parallel_sync/l1_rollup_info_producer_statistics_test.go: -------------------------------------------------------------------------------- 1 | package l1_parallel_sync 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestProducerStatisticsPercent(t *testing.T) { 11 | sut := newRollupInfoProducerStatistics(100, &common.MockTimerProvider{}) 12 | sut.updateLastBlockNumber(200) 13 | require.Equal(t, float64(0.0), sut.getPercent()) 14 | 15 | sut.onResponseRollupInfo(responseRollupInfoByBlockRange{ 16 | generic: genericResponse{ 17 | err: nil, 18 | duration: 0, 19 | }, 20 | result: &rollupInfoByBlockRangeResult{ 21 | blockRange: blockRange{ 22 | fromBlock: 101, 23 | toBlock: 200, 24 | }, 25 | }, 26 | }) 27 | 28 | require.Equal(t, float64(100.0), sut.getPercent()) 29 | 30 | sut.reset(100) 31 | require.Equal(t, float64(0.0), sut.getPercent()) 32 | } 33 | -------------------------------------------------------------------------------- /synchronizer/l2_sync/config.go: -------------------------------------------------------------------------------- 1 | package l2_sync 2 | 3 | // Config configuration of L2 sync process 4 | type Config struct { 5 | // If enabled then the L2 sync process is permitted (only for permissionless) 6 | Enabled bool `mapstructure:"Enabled"` 7 | // AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches. 8 | // if true, the synchronizer will accept empty batches and process them. 9 | AcceptEmptyClosedBatches bool `mapstructure:"AcceptEmptyClosedBatches"` 10 | 11 | // ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again 12 | ReprocessFullBatchOnClose bool `mapstructure:"ReprocessFullBatchOnClose"` 13 | 14 | // CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash 15 | CheckLastL2BlockHashOnCloseBatch bool `mapstructure:"CheckLastL2BlockHashOnCloseBatch"` 16 | } 17 | -------------------------------------------------------------------------------- /test/aggregator.keystore: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"71b028b6-9b1d-4f4c-9e66-31c94a6eb679","address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"ciphertext":"985d5dc5f7750fc4ad0ad0d370486870016bb97e00ef1f7b146d6ad95d456861","cipherparams":{"iv":"f51b18b9f45872f71c3578513fca6cb0"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6253e2d8a71e4808dd11143329cfea467cabb37ac1e1e55dbc0dd90ff22524a7","n":8192,"r":8,"p":1},"mac":"922f741e84201fc7c17bbf9fae5dba6c04a2a99a7268998b5a0268aa690004be"}} -------------------------------------------------------------------------------- /test/config/grafana/dashboards.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Dockers' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | updateIntervalSeconds: 10 10 | allowUiUpdates: false 11 | options: 12 | path: /etc/grafana/provisioning/dashboards 13 | foldersFromFilesStructure: true 14 | -------------------------------------------------------------------------------- /test/config/grafana/datasources.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Grafana-DB 5 | isDefault: true 6 | type: postgres 7 | url: grafana-db:5432 8 | database: grafana 9 | user: user 10 | secureJsonData: 11 | password: 'password' 12 | jsonData: 13 | sslmode: 'disable' # disable/require/verify-ca/verify-full 14 | maxOpenConns: 0 # Grafana v5.4+ 15 | maxIdleConns: 2 # Grafana v5.4+ 16 | connMaxLifetime: 14400 # Grafana v5.4+ 17 | postgresVersion: 903 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 18 | timescaledb: false 19 | -------------------------------------------------------------------------------- /test/config/signer.config.toml: -------------------------------------------------------------------------------- 1 | Port = 7001 2 | 3 | [L1] 4 | ChainId = 1337 5 | RPC = "http://xlayer-mock-l1-network:8545" 6 | PolygonZkEVMAddress = "0x0D9088C72Cd4F08e9dDe474D8F5394147f64b22C" 7 | GlobalExitRootManagerAddr = "0xEd236da21Ff62bC7B62608AdB818da49E8549fa7" 8 | DataCommitteeAddr = "0x6Ae5b0863dBF3477335c0102DBF432aFf04ceb22" 9 | PolygonMaticAddress = "0xcFE6D77a653b988203BfAc9C6a69eA9D583bdC2b" 10 | SeqPrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} 11 | AggPrivateKey = {Path = "/pk/aggregator.keystore", Password = "testonly"} 12 | 13 | [Log] 14 | Environment = "development" 15 | Level = "debug" 16 | Outputs = ["stdout"] 17 | -------------------------------------------------------------------------------- /test/config/telegraf.conf: -------------------------------------------------------------------------------- 1 | [[inputs.docker]] 2 | endpoint = "unix:///var/run/docker.sock" 3 | gather_services = false 4 | container_names = [] 5 | source_tag = false 6 | perdevice = true 7 | total = true 8 | tag_env = [] 9 | 10 | [[inputs.prometheus]] 11 | ## An array of urls to scrape metrics from. 12 | urls = ["http://xlayer-json-rpc:9091/metrics"] 13 | 14 | [[outputs.postgresql]] 15 | connection = "postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB" 16 | -------------------------------------------------------------------------------- /test/config/test-member.keystore: -------------------------------------------------------------------------------- 1 | {"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} -------------------------------------------------------------------------------- /test/config/test.da.toml: -------------------------------------------------------------------------------- 1 | PrivateKey = {Path = "/pk/test-member.keystore", Password = "testonly"} 2 | 3 | [L1] 4 | WsURL = "ws://xlayer-mock-l1-network:8546" 5 | RpcURL = "http://xlayer-mock-l1-network:8545" 6 | PolygonValidiumAddress = "0xeb173087729c88a47568AF87b17C653039377BA6" 7 | DataCommitteeAddress = "0x3bFa19E4588962D1834B2e4007F150f4447Aa9fe" 8 | Timeout = "3m" 9 | RetryPeriod = "5s" 10 | BlockBatchSize = 32 11 | 12 | [Log] 13 | Environment = "development" # "production" or "development" 14 | Level = "debug" 15 | Outputs = ["stderr"] 16 | 17 | [DB] 18 | User = "committee_user" 19 | Password = "committee_password" 20 | Name = "committee_db" 21 | Host = "xlayer-data-availability-db" 22 | Port = "5432" 23 | EnableLog = false 24 | MaxConns = 200 25 | 26 | [RPC] 27 | Host = "0.0.0.0" 28 | Port = 8444 29 | ReadTimeout = "60s" 30 | WriteTimeout = "60s" 31 | MaxRequestsPerIPAndSecond = 500 32 | -------------------------------------------------------------------------------- /test/constants/effective_percentage.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "github.com/0xPolygonHermez/zkevm-node/state" 4 | 5 | var ( 6 | EffectivePercentage = []uint8{state.MaxEffectivePercentage} 7 | TwoEffectivePercentages = []uint8{state.MaxEffectivePercentage, state.MaxEffectivePercentage} 8 | ) 9 | -------------------------------------------------------------------------------- /test/constants/environment_variables.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | //ENV_ZKPROVER_URI environment variable name for ZKPROVER URI 5 | ENV_ZKPROVER_URI = "ZKPROVER_URI" 6 | //ENV_MERKLETREE_URI environment variable name for MERKLETREE URI 7 | ENV_MERKLETREE_URI = "MERKLETREE_URI" 8 | ) 9 | -------------------------------------------------------------------------------- /test/constants/smart_contracts.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "github.com/ethereum/go-ethereum/crypto" 4 | 5 | var ( 6 | ForcedBatchSignatureHash = crypto.Keccak256Hash([]byte("ForceBatch(uint64,bytes32,address,bytes)")) 7 | ) 8 | -------------------------------------------------------------------------------- /test/contracts/auto/BridgeA.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract BridgeA { 5 | receive() external payable {} 6 | 7 | function exec(address bridgeB, address bridgeC, address bridgeD, address acc) public payable { 8 | bool ok; 9 | (ok,) = bridgeB.delegatecall(abi.encodeWithSignature("exec(address,address,address)", bridgeC, bridgeD, acc)); 10 | require(ok, "failed to perform delegate call to bridge B"); 11 | } 12 | } -------------------------------------------------------------------------------- /test/contracts/auto/BridgeB.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract BridgeB { 5 | receive() external payable {} 6 | 7 | function exec(address bridgeC, address bridgeD, address acc) public payable { 8 | bool ok; 9 | (ok,) = bridgeC.call(abi.encodeWithSignature("exec(address)", bridgeD)); 10 | require(ok, "failed to perform call to bridge C"); 11 | 12 | (ok,) = acc.call{value:msg.value}(""); 13 | require(ok, "failed to perform call to acc"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/contracts/auto/BridgeC.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract BridgeC { 5 | receive() external payable {} 6 | 7 | function exec(address bridgeD) public payable { 8 | bool ok; 9 | (ok,) = bridgeD.delegatecall(abi.encodeWithSignature("exec()")); 10 | require(ok, "failed to perform delegate call to bridge D"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/contracts/auto/BridgeD.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract BridgeD { 5 | receive() external payable {} 6 | 7 | address sender; 8 | uint256 value; 9 | 10 | function exec() public payable { 11 | sender = msg.sender; 12 | value = msg.value; 13 | } 14 | } -------------------------------------------------------------------------------- /test/contracts/auto/Called.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract Called { 5 | uint256 num; 6 | address sender; 7 | uint256 value; 8 | 9 | function setVars(uint256 _num) public payable { 10 | num = _num; 11 | sender = msg.sender; 12 | value = msg.value; 13 | } 14 | 15 | function setVarsViaCall(uint256 _num) public payable { 16 | bool ok; 17 | (ok, ) = address(this).call( 18 | abi.encodeWithSignature("setVars(uint256)", _num) 19 | ); 20 | require(ok, "failed to perform call"); 21 | } 22 | 23 | function getVars() public view returns (uint256, address, uint256) { 24 | return (num, sender, value); 25 | } 26 | 27 | function getVarsAndVariable(uint256 _num) public view returns (uint256, address, uint256, uint256) { 28 | return (num, sender, value, _num); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/contracts/auto/ChainCallLevel4.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract ChainCallLevel4 { 5 | receive() external payable {} 6 | 7 | address sender; 8 | uint256 value; 9 | 10 | function exec() public payable { 11 | sender = msg.sender; 12 | value = msg.value; 13 | } 14 | 15 | function execRevert() public payable { 16 | require(false, "ahoy, this tx will always revert"); 17 | } 18 | 19 | function get() public pure returns (string memory t) { 20 | return "ahoy"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/contracts/auto/ConstructorMap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract ConstructorMap { 6 | mapping(uint => uint) public numbers; 7 | 8 | constructor() { 9 | uint i = 0; 10 | for (i = 0; i < 100; i++) { 11 | numbers[i] = i; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/contracts/auto/Counter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract Counter { 6 | uint public count; 7 | 8 | function increment() external { 9 | count += 1; 10 | } 11 | 12 | function getCount() public view returns (uint) { 13 | return count; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/contracts/auto/CounterAndBlock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract CounterAndBlock { 6 | uint public count; 7 | 8 | function increment() external { 9 | count += 1; 10 | } 11 | 12 | function getCount() public view returns (uint, uint) { 13 | return (count, block.timestamp); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/contracts/auto/DeployCreate0.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract DeployCreate0 { 6 | constructor () { 7 | assembly { 8 | let addr := create(0,0,0) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/contracts/auto/Depth.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract Depth { 5 | uint test = 0; 6 | bytes32 constant auxReturn = 0x6aecbc3300000000000000000000000000000000000000000000000000000000; 7 | 8 | function start(address addr, uint256 gasForwarded) public { 9 | test = this.secondCall{gas: gasForwarded}(addr); 10 | } 11 | 12 | function secondCall(address addr) external returns (uint256) { 13 | uint256 success; 14 | assembly { 15 | mstore(0x80, auxReturn) 16 | success := staticcall(gas(), addr, 0x80, 0x04, 0x80, 0x20) 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /test/contracts/auto/Destruct.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract Destruct { 5 | address payable private owner; 6 | uint256 number; 7 | 8 | constructor() { 9 | owner = payable(msg.sender); 10 | } 11 | 12 | function store(uint256 num) public { 13 | number = num; 14 | } 15 | 16 | function retrieve() public view returns (uint256){ 17 | return number; 18 | } 19 | 20 | function close() public { 21 | selfdestruct(owner); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/contracts/auto/Double.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | contract Double { 4 | function double(int a) public pure returns(int) { 5 | return 2*a; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/contracts/auto/EmitLog.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract EmitLog { 6 | event Log(); 7 | event LogA(uint256 indexed a); 8 | event LogAB(uint256 indexed a, uint256 indexed b); 9 | event LogABC(uint256 indexed a, uint256 indexed b, uint256 indexed c); 10 | event LogABCD(uint256 indexed a, uint256 indexed b, uint256 indexed c, uint256 d); 11 | 12 | function emitLogs() public { 13 | emit Log(); 14 | emit LogA(1); 15 | emit LogAB(1, 2); 16 | emit LogABC(1, 2, 3); 17 | emit LogABCD(1, 2, 3, 4); 18 | emit LogABCD(4, 3, 2, 1); 19 | emit LogABC(3, 2, 1); 20 | emit LogAB(2, 1); 21 | emit LogA(1); 22 | emit Log(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/contracts/auto/EmitLog2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract EmitLog2 { 6 | event Log(); 7 | event LogA(uint256 indexed a); 8 | event LogABCD(uint256 indexed a, uint256 indexed b, uint256 indexed c, uint256 d); 9 | 10 | function emitLogs() public { 11 | assembly { 12 | log0(0, 32) 13 | } 14 | emit Log(); 15 | emit LogA(1); 16 | emit LogABCD(1, 2, 3, 4); 17 | } 18 | } -------------------------------------------------------------------------------- /test/contracts/auto/FFFFFFFF.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract FFFFFFFF { 6 | constructor() { 7 | assembly { 8 | return(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/contracts/auto/FailureTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract FailureTest { 5 | uint256 number; 6 | event numberChanged(uint256 from, uint256 to); 7 | 8 | function store(uint256 num) public { 9 | uint256 oldNum = number; 10 | number = num; 11 | emit numberChanged(oldNum, num); 12 | } 13 | 14 | function storeAndFail(uint256 num) public { 15 | store(num); 16 | require(true == false, "this method always fails"); 17 | } 18 | 19 | function getNumber() public view returns (uint256){ 20 | return number; 21 | } 22 | } -------------------------------------------------------------------------------- /test/contracts/auto/HasOpCode.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | contract HasOpCode { 5 | uint256 gasPrice = 0; 6 | uint256 balance = 0; 7 | 8 | function opGasPrice() public { 9 | uint256 tmp; 10 | assembly { 11 | tmp := gasprice() 12 | } 13 | gasPrice = tmp; 14 | } 15 | 16 | function opBalance() public { 17 | address a = msg.sender; 18 | uint256 tmp; 19 | assembly { 20 | tmp := balance(a) 21 | } 22 | balance = tmp; 23 | } 24 | } -------------------------------------------------------------------------------- /test/contracts/auto/Interaction.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | interface ICounter { 5 | function count() external view returns (uint); 6 | function increment() external; 7 | } 8 | 9 | contract Interaction { 10 | address counterAddr; 11 | 12 | function setCounterAddr(address _counter) public payable { 13 | counterAddr = _counter; 14 | } 15 | 16 | function getCount() external view returns (uint) { 17 | return ICounter(counterAddr).count(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/contracts/auto/Log0.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract Log0 { 5 | // opcode 0xa0 6 | function opLog0() public payable { 7 | assembly { 8 | log0(0, 32) 9 | } 10 | } 11 | 12 | function opLog00() public payable { 13 | assembly { 14 | log0(0, 0) 15 | } 16 | } 17 | 18 | function opLog01() public payable { 19 | assembly { 20 | log0(0, 28) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /test/contracts/auto/Memory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | contract Memory { 5 | bool public resStatic = true; 6 | 7 | function testStaticEcrecover() public { 8 | assembly { 9 | let resultStatic := staticcall(gas(), 0x01, 0x20, 0x80, 0xa0, 0x20) 10 | // staticcall(g, a, in, insize, out, outsize) --> input is mem[in...(in + insize)] 11 | sstore(0, resultStatic) 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /test/contracts/auto/Revert.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity ^0.8.4; 3 | 4 | contract Revert { 5 | constructor () { 6 | revert("Today is not juernes"); 7 | } 8 | } -------------------------------------------------------------------------------- /test/contracts/auto/Revert2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity ^0.8.4; 3 | 4 | contract Revert2 { 5 | function generateError() public { 6 | revert("Today is not juernes"); 7 | } 8 | } -------------------------------------------------------------------------------- /test/contracts/auto/Sha.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity ^0.8.4; 3 | 4 | contract Sha { 5 | function hash() public { 6 | sha256("hello world"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/contracts/auto/Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Storage 7 | * @dev Store & retrieve value in a variable 8 | */ 9 | contract Storage { 10 | 11 | uint256 number; 12 | 13 | /** 14 | * @dev Store value in variable 15 | * @param num value to store 16 | */ 17 | function store(uint256 num) public { 18 | number = num; 19 | } 20 | 21 | /** 22 | * @dev Return value 23 | * @return value of 'number' 24 | */ 25 | function retrieve() public view returns (uint256){ 26 | return number; 27 | } 28 | 29 | function release() public{ 30 | number = 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/contracts/auto/StorageOnDeploy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract StorageOnDeploy { 6 | 7 | uint256 number; 8 | 9 | constructor() { 10 | number = 1234; 11 | } 12 | 13 | function retrieve() public view returns (uint256){ 14 | return number; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/contracts/auto/triggerErrors.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | contract triggerErrors { 6 | uint256 public count = 0; 7 | 8 | // set gasLimit = 50000 & steps = 100 9 | function outOfGas() public { 10 | for (uint256 i = 0; i < 100; i++) { 11 | assembly { 12 | sstore(0x00, i) 13 | } 14 | } 15 | } 16 | 17 | // set gasLimit = 30000000 & steps = 50000 18 | function outOfCountersPoseidon() public { 19 | for (uint256 i = 0; i < 50000; i++) { 20 | assembly { 21 | sstore(0x00, i) 22 | } 23 | } 24 | } 25 | 26 | // bytesKeccak = 1000000 & gasLimit = 50000 27 | function outOfCountersKeccaks() pure public returns (bytes32 test) { 28 | assembly { 29 | test := keccak256(0, 1000000) 30 | } 31 | return test; 32 | } 33 | 34 | // set number and gas limit 35 | // gasLimit = 50000 & iterations = 100000 36 | function outOfCountersSteps() pure public { 37 | for (uint i = 0; i < 100000; i++) { 38 | assembly { 39 | mstore(0x0, 1234) 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IERC20 { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external view returns (string memory); 8 | function symbol() external view returns (string memory); 9 | function decimals() external view returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | } 18 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IUniswapV1Exchange.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV1Exchange { 4 | function balanceOf(address owner) external view returns (uint); 5 | function transferFrom(address from, address to, uint value) external returns (bool); 6 | function removeLiquidity(uint, uint, uint, uint) external returns (uint, uint); 7 | function tokenToEthSwapInput(uint, uint, uint) external returns (uint); 8 | function ethToTokenSwapInput(uint, uint) external payable returns (uint); 9 | } 10 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IUniswapV1Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV1Factory { 4 | function getExchange(address) external view returns (address); 5 | } 6 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IUniswapV2Callee.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Callee { 4 | function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; 5 | } 6 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Factory { 4 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 5 | 6 | function feeTo() external view returns (address); 7 | function feeToSetter() external view returns (address); 8 | 9 | function getPair(address tokenA, address tokenB) external view returns (address pair); 10 | function allPairs(uint) external view returns (address pair); 11 | function allPairsLength() external view returns (uint); 12 | 13 | function createPair(address tokenA, address tokenB) external returns (address pair); 14 | 15 | function setFeeTo(address) external; 16 | function setFeeToSetter(address) external; 17 | } 18 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IUniswapV2Migrator.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Migrator { 4 | function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline) external; 5 | } 6 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/IWETH.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IWETH { 4 | function deposit() external payable; 5 | function transfer(address to, uint value) external returns (bool); 6 | function withdraw(uint) external; 7 | } 8 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/Math.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | // a library for performing various math operations 4 | 5 | library Math { 6 | function min(uint x, uint y) internal pure returns (uint z) { 7 | z = x < y ? x : y; 8 | } 9 | 10 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 11 | function sqrt(uint y) internal pure returns (uint z) { 12 | if (y > 3) { 13 | z = y; 14 | uint x = y / 2 + 1; 15 | while (x < z) { 16 | z = x; 17 | x = (y / x + x) / 2; 18 | } 19 | } else if (y != 0) { 20 | z = 1; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16 || =0.6.6; 2 | 3 | // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) 4 | 5 | library SafeMath { 6 | function add(uint x, uint y) internal pure returns (uint z) { 7 | require((z = x + y) >= x, 'ds-math-add-overflow'); 8 | } 9 | 10 | function sub(uint x, uint y) internal pure returns (uint z) { 11 | require((z = x - y) <= x, 'ds-math-sub-underflow'); 12 | } 13 | 14 | function mul(uint x, uint y) internal pure returns (uint z) { 15 | require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/contracts/uniswap/v2/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 4 | 5 | // range: [0, 2**112 - 1] 6 | // resolution: 1 / 2**112 7 | 8 | library UQ112x112 { 9 | uint224 constant Q112 = 2**112; 10 | 11 | // encode a uint112 as a UQ112x112 12 | function encode(uint112 y) internal pure returns (uint224 z) { 13 | z = uint224(y) * Q112; // never overflows 14 | } 15 | 16 | // divide a UQ112x112 by a uint112, returning a UQ112x112 17 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 18 | z = x / uint224(y); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/e2e/doc.go: -------------------------------------------------------------------------------- 1 | // Package e2e contains e2e test definitions. 2 | package e2e 3 | -------------------------------------------------------------------------------- /test/e2e/forced_batches_vector_group1_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | //TODO: Fix test ETROG 4 | /*func TestForcedBatchesVectorFilesGroup1(t *testing.T) { 5 | if testing.Short() { 6 | t.Skip() 7 | } 8 | LaunchTestForcedBatchesVectorFilesGroup(t, "./../vectors/src/state-transition/forced-tx/group1") 9 | }*/ 10 | -------------------------------------------------------------------------------- /test/e2e/forced_batches_vector_group2_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | //TODO: Fix test 4 | /*func TestForcedBatchesVectorFilesGroup2(t *testing.T) { 5 | if testing.Short() { 6 | t.Skip() 7 | } 8 | LaunchTestForcedBatchesVectorFilesGroup(t, "./../vectors/src/state-transition/forced-tx/group2") 9 | }*/ 10 | -------------------------------------------------------------------------------- /test/e2e/forced_batches_vector_group3_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | //TODO: Fix tests ETROG 4 | /*func TestForcedBatchesVectorFilesGroup3(t *testing.T) { 5 | if testing.Short() { 6 | t.Skip() 7 | } 8 | LaunchTestForcedBatchesVectorFilesGroup(t, "./../vectors/src/state-transition/forced-tx/group3") 9 | }*/ 10 | -------------------------------------------------------------------------------- /test/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /test/scripts/cmd/compilesc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/test/scripts/cmd/compilesc" 5 | "github.com/urfave/cli/v2" 6 | ) 7 | 8 | func compileSC(ctx *cli.Context) error { 9 | manager, err := compilesc.NewManager(ctx.String(flagInput)) 10 | if err != nil { 11 | return err 12 | } 13 | 14 | return manager.Run() 15 | } 16 | -------------------------------------------------------------------------------- /test/scripts/cmd/dependencies.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/test/scripts/cmd/dependencies" 5 | "github.com/urfave/cli/v2" 6 | ) 7 | 8 | func updateDeps(ctx *cli.Context) error { 9 | cfg := &dependencies.Config{ 10 | Images: &dependencies.ImagesConfig{ 11 | Names: []string{"hermeznetwork/geth-zkevm-contracts", "hermeznetwork/zkprover-local"}, 12 | TargetFilePath: "../../../docker-compose.yml", 13 | }, 14 | PB: &dependencies.PBConfig{ 15 | TargetDirPath: "../../../proto/src", 16 | SourceRepo: "https://github.com/0xPolygonHermez/zkevm-comms-protocol.git", 17 | }, 18 | TV: &dependencies.TVConfig{ 19 | TargetDirPath: "../../../test/vectors/src", 20 | SourceRepo: "https://github.com/0xPolygonHermez/zkevm-testvectors.git", 21 | }, 22 | } 23 | 24 | return dependencies.NewManager(cfg).Run() 25 | } 26 | -------------------------------------------------------------------------------- /test/scripts/cmd/dependencies/github_test.go: -------------------------------------------------------------------------------- 1 | package dependencies 2 | 3 | import ( 4 | "path" 5 | "testing" 6 | 7 | "github.com/spf13/afero" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_cloneTargetRepo(t *testing.T) { 12 | var appFs = afero.NewMemMapFs() 13 | 14 | gm := newGithubManager(appFs, "", "") 15 | 16 | tmpdir, err := gm.cloneTargetRepo("https://github.com/git-fixtures/basic.git") 17 | require.NoError(t, err) 18 | 19 | expectedChangelog := "Initial changelog\n" 20 | actualChangelog, err := afero.ReadFile(appFs, path.Join(tmpdir, "CHANGELOG")) 21 | require.NoError(t, err) 22 | 23 | require.Equal(t, expectedChangelog, string(actualChangelog)) 24 | } 25 | -------------------------------------------------------------------------------- /test/scripts/cmd/dependencies/manager.go: -------------------------------------------------------------------------------- 1 | package dependencies 2 | 3 | type dependency interface { 4 | update() error 5 | } 6 | 7 | // Manager is the type with knowledge about how to handle dependencies. 8 | type Manager struct { 9 | cfg *Config 10 | } 11 | 12 | // Config has the configurations options for all the updaters. 13 | type Config struct { 14 | Images *ImagesConfig 15 | PB *PBConfig 16 | TV *TVConfig 17 | } 18 | 19 | // NewManager is the Manager constructor. 20 | func NewManager(cfg *Config) *Manager { 21 | return &Manager{ 22 | cfg: cfg, 23 | } 24 | } 25 | 26 | // Run is the main entry point, it executes all the configured dependency 27 | // updates. 28 | func (m *Manager) Run() error { 29 | iu := newImageUpdater(m.cfg.Images.Names, m.cfg.Images.TargetFilePath) 30 | pb := newPBUpdater(m.cfg.PB.SourceRepo, m.cfg.PB.TargetDirPath) 31 | tv := newTestVectorUpdater(m.cfg.TV.SourceRepo, m.cfg.TV.TargetDirPath) 32 | 33 | for _, dep := range []dependency{iu, pb, tv} { 34 | if err := dep.update(); err != nil { 35 | return err 36 | } 37 | } 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /test/scripts/cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node/log" 7 | "github.com/urfave/cli/v2" 8 | ) 9 | 10 | const ( 11 | flagInput = "input" 12 | ) 13 | 14 | func main() { 15 | app := cli.NewApp() 16 | app.Name = "xlayer-node-scripts" 17 | app.Commands = []*cli.Command{ 18 | { 19 | Name: "updatedeps", 20 | Usage: "Updates external dependencies like images, test vectors or proto files", 21 | Action: updateDeps, 22 | Flags: []cli.Flag{}, 23 | }, 24 | { 25 | Name: "compilesc", 26 | Usage: "Compiles smart contracts required for testing", 27 | Action: compileSC, 28 | Flags: []cli.Flag{ 29 | &cli.StringFlag{ 30 | Name: flagInput, 31 | Aliases: []string{"in"}, 32 | Usage: "Target path where the source solidity files are located. It can be a file or a directory, in which case the command will traverse all the descendants from it.", 33 | Required: true, 34 | }, 35 | }, 36 | }, 37 | } 38 | 39 | err := app.Run(os.Args) 40 | if err != nil { 41 | log.Fatal(err) 42 | os.Exit(1) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/scripts/init_network/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import ( 4 | // "context" 5 | // "log" 6 | // "time" 7 | 8 | // NW "github.com/0xPolygonHermez/zkevm-node/tools/network" 9 | // ) 10 | 11 | // func main() { 12 | // ctx := context.Background() 13 | // if err := NW.InitNetwork(ctx, 14 | // NW.InitNetworkConfig{ 15 | // L1NetworkURL: "http://localhost:8545", 16 | // L2NetworkURL: "http://localhost:8123", 17 | // L1BridgeAddr: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", 18 | // L2BridgeAddr: "0x9d98deabc42dd696deb9e40b4f1cab7ddbf55988", 19 | // L1Deployer: NW.L1Deployer{ 20 | // Address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", 21 | // PrivateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", 22 | // L1ETHAmountToSequencer: "200000000000000000000", 23 | // L1PolAmountToSequencer: "200000000000000000000000", 24 | // }, 25 | // sequencerAddress: "0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D", 26 | // SequencerPrivateKey: "0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", 27 | // TxTimeout: time.Minute, 28 | // }); err != nil { 29 | // log.Fatal(err) 30 | // } 31 | // } 32 | -------------------------------------------------------------------------------- /test/scripts/postgres/prover-user.sql: -------------------------------------------------------------------------------- 1 | create user prover with encrypted password '${PROVER_PASSWORD:-default_prover_password}'; 2 | grant usage on schema state to prover; 3 | grant select on state.merkletree to prover; 4 | -------------------------------------------------------------------------------- /test/scripts/postgres/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | BASEDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | SCRIPT_FILES="${BASEDIR}/*.sql" 7 | DBNAME=test_db 8 | DBUSER=test_user 9 | 10 | main(){ 11 | for origin_script in ${SCRIPT_FILES}; do 12 | echo "Executing ${origin_script}..." 13 | 14 | script_file_path=$(mktemp) 15 | script_file_name=$(basename "${script_file_path}") 16 | script_contents=$(eval "echo \"$(cat ${origin_script})\"") 17 | 18 | echo "${script_contents}" > "${script_file_path}" 19 | 20 | docker cp "${script_file_path}" xlayer-state-db:"${script_file_path}" 21 | docker exec xlayer-state-db bash -c "chmod a+x ${script_file_path} && psql ${DBNAME} ${DBUSER} -v ON_ERROR_STOP=ON --single-transaction -f ${script_file_path}" 22 | 23 | echo "Done" 24 | done 25 | } 26 | 27 | main "${@}" 28 | -------------------------------------------------------------------------------- /test/scripts/sendForcedBatch/README.md: -------------------------------------------------------------------------------- 1 | 2 | Command: 3 | ``` 4 | go run main.go send --url http://localhost:8545 --zkevm 0x8dAF17A20c9DBA35f005b6324F493785D239719d --rollupmanager 0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e 5 | ``` -------------------------------------------------------------------------------- /test/scripts/sequenceForcedBatch/README.md: -------------------------------------------------------------------------------- 1 | 2 | Command: 3 | ``` 4 | go run ./scripts/sequenceForcedBatch/main.go send --url http://localhost:8545 --smc 0x8dAF17A20c9DBA35f005b6324F493785D239719d --ger 0x8A791620dd6260079BF849Dc5567aDC3F2FdC318 -tx 0x -t 1674730229 5 | ``` -------------------------------------------------------------------------------- /test/scripts/txsender/README.md: -------------------------------------------------------------------------------- 1 | # Txsender 2 | 3 | ## Overview 4 | 5 | This script allows to send a specified number of transactions to either L1 or 6 | L2 (or both). Optionally it can wait for the transactions to be verified. 7 | 8 | ## Usage 9 | 10 | The script can be installed running `go install` from this folder. 11 | 12 | ## Examples 13 | 14 | - Send 1 transaction on L2: 15 | 16 | ```sh 17 | $ txsender 18 | ``` 19 | 20 | - Send 1 transaction on L2 and wait for it to be validated: 21 | 22 | ```sh 23 | $ txsender -w send 24 | ``` 25 | 26 | - Send 42 transactions on L1: 27 | 28 | ```sh 29 | $ txsender -n l1 send 42 30 | ``` 31 | 32 | - Send 42 transactions both on L1 and L2 with verbose logs and wait for the validations: 33 | 34 | ```sh 35 | $ txsender -v -w -n l1 -n l2 send 42 36 | ``` 37 | -------------------------------------------------------------------------------- /test/scripts/uniswap/pkg/types.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | import ( 4 | "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" 5 | "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/uniswap/v2/core/UniswapV2Factory" 6 | "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/uniswap/v2/periphery/UniswapV2Router02" 7 | "github.com/ethereum/go-ethereum/common" 8 | ) 9 | 10 | type Deployments struct { 11 | ACoin *ERC20.ERC20 12 | ACoinAddr common.Address 13 | BCoin *ERC20.ERC20 14 | BCoinAddr common.Address 15 | CCoin *ERC20.ERC20 16 | CCoinAddr common.Address 17 | Router *UniswapV2Router02.UniswapV2Router02 18 | Factory *UniswapV2Factory.UniswapV2Factory 19 | } 20 | -------------------------------------------------------------------------------- /test/sequencer.keystore: -------------------------------------------------------------------------------- 1 | {"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} -------------------------------------------------------------------------------- /test/tracers/tracer2.json: -------------------------------------------------------------------------------- 1 | {"tracer":"{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == 'CALL') this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}"} -------------------------------------------------------------------------------- /test/vectors/l1infotree.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | ) 6 | 7 | // L1InfoTree holds the test vector for the merkle tree 8 | type L1InfoTree struct { 9 | PreviousLeafValues []common.Hash `json:"previousLeafValues"` 10 | CurrentRoot common.Hash `json:"currentRoot"` 11 | NewLeafValue common.Hash `json:"newLeafValue"` 12 | NewRoot common.Hash `json:"newRoot"` 13 | } 14 | 15 | // L1InfoTree holds the test vector for the merkle tree 16 | type L1InfoTreeProof struct { 17 | Leaves []common.Hash `json:"leaves"` 18 | Index uint `json:"index"` 19 | Proof []common.Hash `json:"proof"` 20 | Root common.Hash `json:"root"` 21 | } 22 | -------------------------------------------------------------------------------- /test/vectors/smartcontract.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | // LoadTxEventsSendBatchTestCases loads the calldata-test-vector.json 11 | func LoadTxEventsSendBatchTestCases(path string) ([]TxEventsSendBatchTestCase, error) { 12 | var testCases []TxEventsSendBatchTestCase 13 | 14 | jsonFile, err := os.Open(filepath.Clean(path)) 15 | if err != nil { 16 | return testCases, err 17 | } 18 | defer func() { _ = jsonFile.Close() }() 19 | 20 | bytes, err := io.ReadAll(jsonFile) 21 | if err != nil { 22 | return testCases, err 23 | } 24 | 25 | err = json.Unmarshal(bytes, &testCases) 26 | if err != nil { 27 | return testCases, err 28 | } 29 | 30 | return testCases, nil 31 | } 32 | -------------------------------------------------------------------------------- /test/vectors/src/merkle-tree/smt-key-contract-code.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "leafType": 2, 4 | "ethAddr": "0x0000000000000000000000000000000000000000", 5 | "expectedKey": "72618736525103033809705966741823173469010530487114812728907809351129229387686" 6 | }, 7 | { 8 | "leafType": 2, 9 | "ethAddr": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 10 | "expectedKey": "100339618010685329502920959863456851722741867804653471565599858216996781583185" 11 | }, 12 | { 13 | "leafType": 2, 14 | "ethAddr": "0xEEF9f339514298C6A857EfCfC1A762aF84438dEE", 15 | "expectedKey": "37702541001567369137011480863022602456875150323680555331519352316148423991760" 16 | } 17 | ] -------------------------------------------------------------------------------- /test/vectors/src/merkle-tree/smt-key-contract-length.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "leafType": 4, 4 | "ethAddr": "0x0000000000000000000000000000000000000000", 5 | "expectedKey": "41007279171909826356801898715236946089777777871690100429699594563988270638848" 6 | }, 7 | { 8 | "leafType": 4, 9 | "ethAddr": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 10 | "expectedKey": "34646114882128150922895390038184820825657559006046553149154512997547296886401" 11 | }, 12 | { 13 | "leafType": 4, 14 | "ethAddr": "0xEEF9f339514298C6A857EfCfC1A762aF84438dEE", 15 | "expectedKey": "22692912702510785895734212421419794952797782834275353854560810371481244756741" 16 | } 17 | ] -------------------------------------------------------------------------------- /test/vectors/src/tx-hash-ethereum/rlp.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "nonce": "0x02", 4 | "gasPrice": "0x4190AB00", 5 | "gasLimit": "0x5208", 6 | "to": "0x0043d60e87c5dd08C86C3123340705a1556C4719", 7 | "value": "0x470DE4DF820000", 8 | "data": "", 9 | "chainId": "0x599", 10 | "v": "0x0B3F", 11 | "r": "0x3e5cd16f789cc06e40e19243374ae6f7bf6e9023bb8599c9eaa0bf066206bdac", 12 | "s": "0x67afe749b374949fdb1cea34c364c3b125acc2a01b5dc9874e4a125a38fb57b1", 13 | "hash": "0xa05bec4d932f266f68b6804de0a3ab3d1616de1f14252e3b1025f4b55a38036c", 14 | "link": "" 15 | } 16 | ] -------------------------------------------------------------------------------- /test/vectors/statetransition.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | // LoadStateTransitionTestCases loads the state-transition.json into a 11 | // StateTransitionVector instance 12 | func LoadStateTransitionTestCases(path string) ([]StateTransitionTestCase, error) { 13 | var testCases []StateTransitionTestCase 14 | 15 | jsonFile, err := os.Open(filepath.Clean(path)) 16 | if err != nil { 17 | return testCases, err 18 | } 19 | defer func() { _ = jsonFile.Close() }() 20 | 21 | bytes, err := io.ReadAll(jsonFile) 22 | if err != nil { 23 | return testCases, err 24 | } 25 | 26 | err = json.Unmarshal(bytes, &testCases) 27 | if err != nil { 28 | return testCases, err 29 | } 30 | 31 | return testCases, nil 32 | } 33 | -------------------------------------------------------------------------------- /test/vectors/statetransition_etrog.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | // LoadStateTransitionTestCasesEtrog loads the state-transition tests cases 11 | func LoadStateTransitionTestCasesEtrog(path string) ([]StateTransitionTestCaseEtrog, error) { 12 | var testCases []StateTransitionTestCaseEtrog 13 | 14 | jsonFile, err := os.Open(filepath.Clean(path)) 15 | if err != nil { 16 | return testCases, err 17 | } 18 | defer func() { _ = jsonFile.Close() }() 19 | 20 | bytes, err := io.ReadAll(jsonFile) 21 | if err != nil { 22 | return testCases, err 23 | } 24 | 25 | err = json.Unmarshal(bytes, &testCases) 26 | if err != nil { 27 | return testCases, err 28 | } 29 | 30 | return testCases, nil 31 | } 32 | -------------------------------------------------------------------------------- /test/vectors/statetransition_v2.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | // LoadStateTransitionTestCaseV2 loads the state-transition JSON file into a 12 | // StateTransitionTestCaseV2 instance 13 | func LoadStateTransitionTestCaseV2(path string) (StateTransitionTestCaseV2, error) { 14 | var testCase StateTransitionTestCaseV2 15 | 16 | jsonFile, err := os.Open(filepath.Clean(path)) 17 | if err != nil { 18 | return testCase, err 19 | } 20 | defer func() { _ = jsonFile.Close() }() 21 | 22 | bytes, err := io.ReadAll(jsonFile) 23 | if err != nil { 24 | return testCase, err 25 | } 26 | 27 | err = json.Unmarshal(bytes, &testCase) 28 | if err != nil { 29 | return testCase, err 30 | } 31 | if testCase.Description == "" { 32 | testCase.Description = strings.Replace(filepath.Base(path), ".json", "", 1) 33 | } 34 | 35 | return testCase, nil 36 | } 37 | -------------------------------------------------------------------------------- /test/vectors/types.go: -------------------------------------------------------------------------------- 1 | package vectors 2 | 3 | import ( 4 | "math/big" 5 | "strings" 6 | 7 | "github.com/0xPolygonHermez/zkevm-node/encoding" 8 | "github.com/0xPolygonHermez/zkevm-node/hex" 9 | ) 10 | 11 | type argBigInt struct { 12 | big.Int 13 | } 14 | 15 | func (a argBigInt) MarshalJSON() ([]byte, error) { 16 | return []byte(a.Text(hex.Base)), nil 17 | } 18 | 19 | func (a *argBigInt) UnmarshalJSON(input []byte) error { 20 | str := strings.Trim(string(input), "\"") 21 | if strings.ToLower(strings.TrimSpace(str)) == "null" { 22 | return nil 23 | } 24 | 25 | bi, err := encoding.DecodeUint256orHex(&str) 26 | if err != nil { 27 | return err 28 | } 29 | 30 | a.Int = *bi 31 | 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /tools/datastreamer/config/default.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | // DefaultValues is the default configuration 4 | const DefaultValues = ` 5 | [Online] 6 | URI = "zkevm-sequencer:6900" 7 | StreamType = 1 8 | 9 | [Offline] 10 | Port = 6901 11 | Filename = "datastreamer.bin" 12 | Version = 4 13 | ChainID = 1440 14 | UpgradeEtrogBatchNumber = 0 15 | 16 | [StateDB] 17 | User = "state_user" 18 | Password = "state_password" 19 | Name = "state_db" 20 | Host = "localhost" 21 | Port = "5432" 22 | EnableLog = false 23 | MaxConns = 200 24 | 25 | [Executor] 26 | URI = "zkevm-prover:50071" 27 | MaxGRPCMessageSize = 100000000 28 | 29 | [MerkleTree] 30 | URI = "zkevm-prover:50061" 31 | MaxThreads = 20 32 | CacheFile = "" 33 | 34 | [Log] 35 | Environment = "development" # "production" or "development" 36 | Level = "info" 37 | Outputs = ["stderr"] 38 | ` 39 | -------------------------------------------------------------------------------- /tools/datastreamer/config/tool.config.toml: -------------------------------------------------------------------------------- 1 | [Online] 2 | URI = "localhost:6900" 3 | StreamType = 1 4 | 5 | [Offline] 6 | Port = 6901 7 | Filename = "datastream.bin" 8 | Version = 4 9 | ChainID = 1440 10 | WriteTimeout = "5s" 11 | InactivityTimeout = "120s" 12 | InactivityCheckInterval = "5s" 13 | UpgradeEtrogBatchNumber = 0 14 | 15 | [StateDB] 16 | User = "state_user" 17 | Password = "state_password" 18 | Name = "state_db" 19 | Host = "localhost" 20 | Port = "5432" 21 | EnableLog = false 22 | MaxConns = 200 23 | 24 | [MerkleTree] 25 | URI = "localhost:50061" 26 | MaxThreads = 20 27 | CacheFile = "merkle_tree_cache.json" 28 | 29 | [Log] 30 | Environment = "development" 31 | Level = "error" 32 | Outputs = ["stdout"] 33 | -------------------------------------------------------------------------------- /tools/egp/cfg/egp0.config.toml: -------------------------------------------------------------------------------- 1 | # gas cost of 1 byte 2 | ByteGasCost = 16 3 | 4 | # gas cost of 1 byte zero 5 | ZeroGasCost = 4 6 | 7 | # L2 network profit factor 8 | NetProfitFactor = 1.0 9 | 10 | # L1 gas price factor 11 | L1GasPriceFactor = 0.25 12 | 13 | # L2 gas price suggester factor 14 | L2GasPriceSugFactor = 0.5 15 | 16 | # Max final deviation percentage 17 | FinalDeviationPct = 10 18 | 19 | # Min gas price allowed 20 | MinGasPriceAllowed = 1000000000 21 | 22 | # L2 gas price suggester factor pre EGP 23 | L2GasPriceSugFactorPreEGP = 0.1 24 | -------------------------------------------------------------------------------- /tools/egp/cfg/egp1.config.toml: -------------------------------------------------------------------------------- 1 | # gas cost of 1 byte 2 | ByteGasCost = 16 3 | 4 | # gas cost of 1 byte zero 5 | ZeroGasCost = 4 6 | 7 | # L2 network profit factor 8 | NetProfitFactor = 1.5 9 | 10 | # L1 gas price factor 11 | L1GasPriceFactor = 0.01 12 | 13 | # L2 gas price suggester factor 14 | L2GasPriceSugFactor = 0.25 15 | 16 | # Max final deviation percentage 17 | FinalDeviationPct = 10 18 | 19 | # Min gas price allowed 20 | MinGasPriceAllowed = 1000000000 21 | 22 | # L2 gas price suggester factor pre EGP 23 | L2GasPriceSugFactorPreEGP = 0.1 24 | -------------------------------------------------------------------------------- /tools/egp/cfg/egp2.config.toml: -------------------------------------------------------------------------------- 1 | # gas cost of 1 byte 2 | ByteGasCost = 16 3 | 4 | # gas cost of 1 byte zero 5 | ZeroGasCost = 4 6 | 7 | # L2 network profit factor 8 | NetProfitFactor = 1.2 9 | 10 | # L1 gas price factor 11 | L1GasPriceFactor = 0.04 12 | 13 | # L2 gas price suggester factor 14 | L2GasPriceSugFactor = 0.30 15 | 16 | # Max final deviation percentage 17 | FinalDeviationPct = 10 18 | 19 | # Min gas price allowed 20 | MinGasPriceAllowed = 1000000000 21 | 22 | # L2 gas price suggester factor pre EGP 23 | L2GasPriceSugFactorPreEGP = 0.1 24 | -------------------------------------------------------------------------------- /tools/executor/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | networks: 3 | default: 4 | name: executor-tool 5 | 6 | services: 7 | executor-tool-db: 8 | container_name: executor-tool-db 9 | image: postgres:15 10 | ports: 11 | - 5432:5432 12 | volumes: 13 | - ../../db/scripts/init_prover_db.sql:/docker-entrypoint-initdb.d/init.sql 14 | environment: 15 | # In order to update this values, you may need to run: docker rm -f -v postgres 16 | - POSTGRES_USER=test_user 17 | - POSTGRES_PASSWORD=test_password 18 | - POSTGRES_DB=test_db 19 | command: ["postgres", "-N", "500"] 20 | 21 | executor-tool-prover: 22 | container_name: executor-tool-prover 23 | image: hermeznetwork/zkprover-local@sha256:f3eb2a1c0728c51c182e778c33d10eefbf4703f0e96a6e15e88ad155078a5e9e 24 | ports: 25 | - 50061:50061 # MT 26 | - 50071:50071 # Executor 27 | volumes: 28 | - ./prover.config.json:/usr/src/app/config.json 29 | command: > 30 | zkProver -c /usr/src/app/config.json 31 | -------------------------------------------------------------------------------- /tools/signer/Dockerfile: -------------------------------------------------------------------------------- 1 | # CONTAINER FOR BUILDING BINARY 2 | FROM golang:1.21 AS build 3 | 4 | # INSTALL DEPENDENCIES 5 | RUN go install github.com/gobuffalo/packr/v2/packr2@v2.8.3 6 | COPY go.mod go.sum /src/ 7 | RUN cd /src && go mod download 8 | 9 | # BUILD BINARY 10 | COPY . /src 11 | RUN cd /src/db && packr2 12 | RUN cd /src/tools/signer && make build 13 | 14 | # CONTAINER FOR RUNNING BINARY 15 | FROM alpine:3.18.0 16 | COPY --from=build /src/tools/signer/dist/xlayer-signer /app/xlayer-signer 17 | COPY --from=build /src/tools/signer/config/signer.config.toml /app/example.config.toml 18 | RUN apk update && apk add postgresql15-client 19 | EXPOSE 7001 20 | CMD ["/bin/sh", "-c", "/app/xlayer-signer"] 21 | -------------------------------------------------------------------------------- /tools/signer/config/default.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | // DefaultValues is the default configuration 4 | const DefaultValues = ` 5 | Port = 8080 6 | 7 | [L1] 8 | ChainId = 11155111 9 | RPC = "https://rpc.ankr.com/eth_sepolia/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 10 | PolygonZkEVMAddress = "0x812cB73e48841a6736bB94c65c56341817cE6304" 11 | GlobalExitRootManagerAddr = "0x0e9Bb928351a50227ebFEC9782Db005Ba9b6C052" 12 | DataCommitteeAddr = "0x246EcFCae4423631c9eE3A86DE37F77BCF27FAaE" 13 | PolygonMaticAddress = "0xe223519d64C0A49e7C08303c2220251be6b70e1d" 14 | SeqPrivateKey = {Path = "../../test/sequencer.keystore", Password = "testonly"} 15 | AggPrivateKey = {Path = "../../test/aggregator.keystore", Password = "testonly"} 16 | 17 | [Log] 18 | Environment = "development" 19 | Level = "debug" 20 | Outputs = ["stdout"] 21 | ` 22 | -------------------------------------------------------------------------------- /tools/signer/config/signer.config.toml: -------------------------------------------------------------------------------- 1 | Port = 7001 2 | 3 | [L1] 4 | ChainId = 11155111 5 | RPC = "https://sepolia.infura.io/v3/xxxxxxxx" 6 | PolygonZkEVMAddress = "0x812cB73e48841a6736bB94c65c56341817cE6304" 7 | GlobalExitRootManagerAddr = "0x0e9Bb928351a50227ebFEC9782Db005Ba9b6C052" 8 | DataCommitteeAddr = "0x246EcFCae4423631c9eE3A86DE37F77BCF27FAaE" 9 | PolygonMaticAddress = "0xe223519d64C0A49e7C08303c2220251be6b70e1d" 10 | SeqPrivateKey = {Path = "../../test/sequencer.keystore", Password = "testonly"} 11 | AggPrivateKey = {Path = "../../test/aggregator.keystore", Password = "testonly"} 12 | 13 | [Log] 14 | Environment = "development" 15 | Level = "debug" 16 | Outputs = ["stdout"] 17 | -------------------------------------------------------------------------------- /tools/state/estimated_time.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "time" 4 | 5 | const conversionFactorPercentage = 100 6 | 7 | type estimatedTimeOfArrival struct { 8 | totalItems int 9 | processedItems int 10 | startTime time.Time 11 | previousStepTime time.Time 12 | } 13 | 14 | func (e *estimatedTimeOfArrival) start(totalItems int) { 15 | e.totalItems = totalItems 16 | e.processedItems = 0 17 | e.startTime = time.Now() 18 | e.previousStepTime = e.startTime 19 | } 20 | 21 | // return eta time.Duration, percent float64, itemsPerSecond float64 22 | func (e *estimatedTimeOfArrival) step(itemsProcessedInthisStep int) (time.Duration, float64, float64) { 23 | e.processedItems += itemsProcessedInthisStep 24 | 25 | curentTime := time.Now() 26 | elapsedTime := curentTime.Sub(e.startTime) 27 | eta := time.Duration(float64(elapsedTime) / float64(e.processedItems) * float64(e.totalItems-e.processedItems)) 28 | percent := float64(e.processedItems) / float64(e.totalItems) * conversionFactorPercentage 29 | itemsPerSecond := float64(e.processedItems) / elapsedTime.Seconds() 30 | e.previousStepTime = curentTime 31 | return eta, percent, itemsPerSecond 32 | } 33 | -------------------------------------------------------------------------------- /tools/state/output_interface.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/ethereum/go-ethereum/common" 4 | 5 | type reprocessingOutputer interface { 6 | start(fromBatchNumber uint64, toBatchNumber uint64, l2ChainId uint64) 7 | startProcessingBatch(current_batch_number uint64) 8 | numOfTransactionsInBatch(numOfTrs int) 9 | addTransactionError(trxIndex int, err error) 10 | isWrittenOnHashDB(isWritten bool, flushid uint64) 11 | finishProcessingBatch(stateRoot common.Hash, err error) 12 | end(err error) 13 | } 14 | -------------------------------------------------------------------------------- /tools/state/version.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/0xPolygonHermez/zkevm-node" 7 | "github.com/urfave/cli/v2" 8 | ) 9 | 10 | func versionCmd(*cli.Context) error { 11 | zkevm.PrintVersion(os.Stdout) 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | package zkevm 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | // Populated during build, don't touch! 10 | var ( 11 | Version = "v0.1.0" 12 | GitRev = "undefined" 13 | GitBranch = "undefined" 14 | BuildDate = "Fri, 17 Jun 1988 01:58:00 +0200" 15 | ) 16 | 17 | // PrintVersion prints version info into the provided io.Writer. 18 | func PrintVersion(w io.Writer) { 19 | fmt.Fprintf(w, "Version: %s\n", Version) 20 | fmt.Fprintf(w, "Git revision: %s\n", GitRev) 21 | fmt.Fprintf(w, "Git branch: %s\n", GitBranch) 22 | fmt.Fprintf(w, "Go version: %s\n", runtime.Version()) 23 | fmt.Fprintf(w, "Built: %s\n", BuildDate) 24 | fmt.Fprintf(w, "OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH) 25 | } 26 | -------------------------------------------------------------------------------- /version.mk: -------------------------------------------------------------------------------- 1 | VERSION := $(shell git describe --tags --always) 2 | GITREV := $(shell git rev-parse --short HEAD) 3 | GITBRANCH := $(shell git rev-parse --abbrev-ref HEAD) 4 | DATE := $(shell LANG=US date +"%a, %d %b %Y %X %z") 5 | --------------------------------------------------------------------------------