├── .clabot ├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── buildspec.yml ├── codeql │ └── codeql-config.yml ├── manifest-buildspec.yml └── workflows │ ├── arbitrator-ci.yml │ ├── arbitrator-skip-ci.yml │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── docker.yml │ ├── gotestsum.sh │ ├── merge-checks.yml │ ├── nightly-ci.yml │ ├── release-ci.yml │ ├── shellcheck-ci.yml │ ├── submodule-pin-check.yml │ └── waitForNitro.sh ├── .gitignore ├── .gitmodules ├── .golangci.yml ├── .nitro-tag.txt ├── .nvmrc ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE.md ├── Makefile ├── README.md ├── arbcompress ├── compress_common.go ├── compress_test.go ├── native.go └── wasm.go ├── arbitrator ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── arbutil │ ├── Cargo.toml │ └── src │ │ ├── benchmark.rs │ │ ├── color.rs │ │ ├── crypto.rs │ │ ├── evm │ │ ├── api.rs │ │ ├── mod.rs │ │ ├── req.rs │ │ ├── storage.rs │ │ └── user.rs │ │ ├── format.rs │ │ ├── lib.rs │ │ ├── math.rs │ │ ├── operator.rs │ │ ├── pricing.rs │ │ └── types.rs ├── bench │ ├── Cargo.toml │ └── src │ │ └── bin.rs ├── brotli │ ├── Cargo.toml │ ├── build.rs │ ├── fuzz │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ ├── README │ │ └── fuzz_targets │ │ │ ├── compress.rs │ │ │ ├── decompress.rs │ │ │ └── round_trip.rs │ └── src │ │ ├── cgo.rs │ │ ├── dicts │ │ ├── mod.rs │ │ └── stylus-program-11.lz │ │ ├── lib.rs │ │ ├── types.rs │ │ └── wasmer_traits.rs ├── caller-env │ ├── Cargo.toml │ └── src │ │ ├── brotli │ │ └── mod.rs │ │ ├── guest_ptr.rs │ │ ├── lib.rs │ │ ├── static_caller.rs │ │ ├── wasip1_stub.rs │ │ └── wasmer_traits.rs ├── jit │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── programs │ │ ├── print │ │ │ └── main.go │ │ ├── pure │ │ │ └── main.wat │ │ └── time │ │ │ └── main.go │ └── src │ │ ├── arbcompress.rs │ │ ├── caller_env.rs │ │ ├── lib.rs │ │ ├── machine.rs │ │ ├── main.rs │ │ ├── prepare.rs │ │ ├── program.rs │ │ ├── socket.rs │ │ ├── stylus_backend.rs │ │ ├── test.rs │ │ ├── wasip1_stub.rs │ │ └── wavmio.rs ├── prover │ ├── Cargo.toml │ ├── benches │ │ └── merkle_bench.rs │ ├── fuzz │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── fuzz_targets │ │ │ └── osp.rs │ ├── src │ │ ├── binary.rs │ │ ├── bulk_memory.wat │ │ ├── host.rs │ │ ├── kzg-trusted-setup.json │ │ ├── kzg.rs │ │ ├── lib.rs │ │ ├── machine.rs │ │ ├── main.rs │ │ ├── memory.rs │ │ ├── merkle.rs │ │ ├── merkle │ │ │ └── zerohashes.rs │ │ ├── parse_input.rs │ │ ├── prepare.rs │ │ ├── print.rs │ │ ├── programs │ │ │ ├── config.rs │ │ │ ├── counter.rs │ │ │ ├── depth.rs │ │ │ ├── dynamic.rs │ │ │ ├── heap.rs │ │ │ ├── memory.rs │ │ │ ├── meter.rs │ │ │ ├── mod.rs │ │ │ ├── prelude.rs │ │ │ └── start.rs │ │ ├── reinterpret.rs │ │ ├── test.rs │ │ ├── utils.rs │ │ ├── value.rs │ │ └── wavm.rs │ └── test-cases │ │ ├── block.wat │ │ ├── bulk-memory.wat │ │ ├── call-indirect.wat │ │ ├── call.wat │ │ ├── const.wat │ │ ├── div-overflow.wat │ │ ├── dynamic.wat │ │ ├── float32.wat │ │ ├── float64.wat │ │ ├── forward-test.wat │ │ ├── forward │ │ ├── forward.wat │ │ └── target.wat │ │ ├── global-state-wavm.wat │ │ ├── global-state-wrapper.wat │ │ ├── global-state.wat │ │ ├── globals.wat │ │ ├── go │ │ └── main.go │ │ ├── if-else.wat │ │ ├── iops.wat │ │ ├── link.txt │ │ ├── link.wat │ │ ├── locals.wat │ │ ├── loop.wat │ │ ├── math.wat │ │ ├── memory-grow.wat │ │ ├── memory.wat │ │ ├── no-stack-pollution.wat │ │ ├── read-inboxmsg-10.wat │ │ ├── return.wat │ │ ├── rust │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── data │ │ │ ├── msg0.bin │ │ │ └── msg1.bin │ │ └── src │ │ │ ├── bin │ │ │ ├── basics.rs │ │ │ ├── globalstate.rs │ │ │ ├── host-io.rs │ │ │ ├── keccak256.rs │ │ │ ├── pi.rs │ │ │ └── stdlib.rs │ │ │ └── lib.rs │ │ └── user.wat ├── stylus │ ├── Cargo.toml │ ├── cbindgen.toml │ ├── src │ │ ├── benchmarks.rs │ │ ├── cache.rs │ │ ├── env.rs │ │ ├── evm_api.rs │ │ ├── host.rs │ │ ├── lib.rs │ │ ├── native.rs │ │ ├── run.rs │ │ ├── target_cache.rs │ │ ├── test │ │ │ ├── api.rs │ │ │ ├── misc.rs │ │ │ ├── mod.rs │ │ │ ├── native.rs │ │ │ ├── sdk.rs │ │ │ ├── timings.rs │ │ │ └── wavm.rs │ │ └── util.rs │ └── tests │ │ ├── .cargo │ │ └── config.toml │ │ ├── add.wat │ │ ├── bad-mods │ │ ├── bad-export.wat │ │ ├── bad-export2.wat │ │ ├── bad-export3.wat │ │ ├── bad-export4.wat │ │ └── bad-import.wat │ │ ├── bf │ │ ├── .gitignore │ │ └── cat.b │ │ ├── bulk-memory-oob.wat │ │ ├── clz.wat │ │ ├── console.wat │ │ ├── create │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── depth.wat │ │ ├── erc20 │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── erc20.rs │ │ │ └── main.rs │ │ ├── evm-data │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── exit-early │ │ ├── exit-early.wat │ │ └── panic-after-write.wat │ │ ├── fallible │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── grow │ │ ├── fixed.wat │ │ ├── grow-120.wat │ │ ├── grow-and-call.wat │ │ └── mem-write.wat │ │ ├── hostio-test │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── keccak-100 │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── keccak │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── log │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── math │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── memory.wat │ │ ├── memory2.wat │ │ ├── module-mod.wat │ │ ├── multicall │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── read-return-data │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── return-size.wat │ │ ├── sdk-storage │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── start.wat │ │ ├── storage │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ ├── test.wat │ │ ├── timings │ │ ├── Cargo.lock │ │ ├── block_basefee.wat │ │ ├── block_coinbase.wat │ │ ├── block_gas_limit.wat │ │ ├── block_number.wat │ │ ├── block_timestamp.wat │ │ ├── chainid.wat │ │ ├── contract_address.wat │ │ ├── evm_gas_left.wat │ │ ├── evm_ink_left.wat │ │ ├── keccak.wat │ │ ├── msg_sender.wat │ │ ├── msg_value.wat │ │ ├── null_host.wat │ │ ├── read_args.wat │ │ ├── return_data_size.wat │ │ ├── tx_gas_price.wat │ │ ├── tx_ink_price.wat │ │ ├── tx_origin.wat │ │ └── write_result.wat │ │ └── write-result-len.wat ├── tools │ ├── module_roots │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── stylus_benchmark │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ ├── benchmark.rs │ │ ├── main.rs │ │ ├── scenario.rs │ │ └── scenarios │ │ ├── br.rs │ │ ├── br_if.rs │ │ ├── br_table.rs │ │ ├── call.rs │ │ ├── call_indirect.rs │ │ ├── convert.rs │ │ ├── data_type.rs │ │ ├── global_get.rs │ │ ├── global_set.rs │ │ ├── if_op.rs │ │ ├── instruction_with_1_arg_1_return.rs │ │ ├── instruction_with_2_args_1_return.rs │ │ ├── load.rs │ │ ├── local_get.rs │ │ ├── local_set.rs │ │ ├── local_tee.rs │ │ ├── mod.rs │ │ ├── select.rs │ │ └── store.rs ├── wasm-libraries │ ├── .cargo │ │ └── config.toml │ ├── Cargo.lock │ ├── Cargo.toml │ ├── arbcompress │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ └── lib.rs │ ├── forward │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── host-io │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── program-exec │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── soft-float │ │ ├── bindings32.c │ │ └── bindings64.c │ ├── user-host-trait │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── user-host │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── host.rs │ │ │ ├── ink.rs │ │ │ ├── lib.rs │ │ │ ├── link.rs │ │ │ └── program.rs │ ├── user-test │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── host.rs │ │ │ ├── ink.rs │ │ │ ├── lib.rs │ │ │ └── program.rs │ └── wasi-stub │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs └── wasm-testsuite │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── check.sh │ └── src │ └── main.rs ├── arbnode ├── api.go ├── batch_poster.go ├── blockmetadata.go ├── consensus_execution_syncer.go ├── dataposter │ ├── data_poster.go │ ├── dataposter_test.go │ ├── dbstorage │ │ └── storage.go │ ├── externalsignertest │ │ └── externalsignertest.go │ ├── noop │ │ └── storage.go │ ├── redis │ │ └── redisstorage.go │ ├── slice │ │ └── slicestorage.go │ ├── storage │ │ ├── rlp_test.go │ │ ├── storage.go │ │ └── time.go │ ├── storage_test.go │ └── testdata │ │ ├── client.cnf │ │ ├── client.crt │ │ ├── client.key │ │ ├── localhost.cnf │ │ ├── localhost.crt │ │ ├── localhost.key │ │ └── regenerate-certs.sh ├── delay_buffer.go ├── delayed.go ├── delayed_seq_reorg_test.go ├── delayed_sequencer.go ├── inbox_reader.go ├── inbox_test.go ├── inbox_tracker.go ├── inbox_tracker_test.go ├── maintenance.go ├── maintenance_test.go ├── message-extraction │ ├── extraction-function │ │ └── message_extraction_function.go │ ├── fsm.go │ ├── mel.go │ ├── mel_test.go │ └── types │ │ └── state.go ├── message_pruner.go ├── message_pruner_test.go ├── node.go ├── parent │ └── parent.go ├── redislock │ └── redis.go ├── resourcemanager │ ├── resource_management.go │ └── resource_management_test.go ├── schema.go ├── seq_coordinator.go ├── seq_coordinator_test.go ├── sequencer_inbox.go ├── simple_redis_lock_test.go ├── sync_monitor.go ├── transaction_streamer.go └── tx_streamer_test.go ├── arbos ├── activate_test.go ├── addressSet │ ├── addressSet.go │ └── addressSet_test.go ├── addressTable │ ├── addressTable.go │ └── addressTable_test.go ├── arbosState │ ├── arbosstate.go │ ├── arbosstate_test.go │ ├── common_test.go │ ├── initialization_test.go │ └── initialize.go ├── arbostypes │ ├── incomingmessage.go │ └── messagewithmeta.go ├── block_processor.go ├── blockhash │ ├── blockhash.go │ └── blockhash_test.go ├── burn │ └── burn.go ├── common_test.go ├── engine.go ├── extra_transaction_checks.go ├── features │ └── features.go ├── incomingmessage_test.go ├── internal_tx.go ├── l1pricing │ ├── batchPoster.go │ ├── batchPoster_test.go │ ├── common_test.go │ ├── l1PricingOldVersions.go │ ├── l1pricing.go │ └── l1pricing_test.go ├── l1pricing_test.go ├── l2pricing │ ├── l2pricing.go │ ├── l2pricing_test.go │ └── model.go ├── merkleAccumulator │ └── merkleAccumulator.go ├── parse_l2.go ├── programs │ ├── api.go │ ├── cgo_test.go │ ├── data_pricer.go │ ├── memory.go │ ├── memory_test.go │ ├── native.go │ ├── native_api.go │ ├── params.go │ ├── programs.go │ ├── testcompile.go │ ├── testconstants.go │ ├── wasm.go │ ├── wasm_api.go │ └── wasmstorehelper.go ├── queue_test.go ├── retryable_test.go ├── retryables │ └── retryable.go ├── storage │ ├── queue.go │ ├── storage.go │ └── storage_test.go ├── tx_processor.go └── util │ ├── retryable_encoding_test.go │ ├── storage_cache.go │ ├── storage_cache_test.go │ ├── tracing.go │ ├── transfer.go │ └── util.go ├── arbstate ├── inbox.go └── inbox_fuzz_test.go ├── arbutil ├── block_message_relation.go ├── correspondingl1blocknumber.go ├── finality_data.go ├── format.go ├── hash.go ├── hash_test.go ├── preimage_type.go ├── transaction_data.go ├── unsafe.go └── wait_for_l1.go ├── blocks_reexecutor └── blocks_reexecutor.go ├── blsSignatures ├── blsSignatures.go └── blsSignatures_test.go ├── broadcastclient ├── broadcastclient.go └── broadcastclient_test.go ├── broadcastclients ├── broadcastclients.go └── broadcastclients_test.go ├── broadcaster ├── backlog │ ├── backlog.go │ ├── backlog_test.go │ └── config.go ├── broadcaster.go ├── broadcaster_test.go └── message │ ├── message.go │ ├── message_blockmetadata_test.go │ ├── message_serialization_test.go │ └── message_test_utils.go ├── cmd ├── autonomous-auctioneer │ ├── config.go │ └── main.go ├── bidder-client │ └── main.go ├── chaininfo │ ├── arbitrum_chain_info.json │ ├── chain_defaults.go │ ├── chain_defaults_test.go │ └── chain_info.go ├── conf │ ├── chain.go │ ├── database.go │ └── init.go ├── daprovider │ └── daprovider.go ├── daserver │ └── daserver.go ├── dataavailability │ ├── data_availability_check │ └── data_availability_check.go ├── datool │ └── datool.go ├── dbconv │ ├── dbconv │ │ ├── config.go │ │ ├── dbconv.go │ │ ├── dbconv_test.go │ │ └── stats.go │ └── main.go ├── deploy │ └── deploy.go ├── genericconf │ ├── config.go │ ├── filehandler_test.go │ ├── getversion17.go │ ├── getversion18.go │ ├── jwt.go │ ├── liveconfig.go │ ├── logging.go │ ├── loglevel.go │ ├── pprof.go │ ├── server.go │ └── wallet.go ├── mockexternalsigner │ └── mockexternalsigner.go ├── nitro-val │ ├── config.go │ └── nitro_val.go ├── nitro │ ├── config_test.go │ ├── init.go │ ├── init_test.go │ └── nitro.go ├── pruning │ └── pruning.go ├── relay │ ├── config_test.go │ └── relay.go ├── replay │ ├── db.go │ └── main.go ├── seq-coordinator-invalidate │ └── seq-coordinator-invalidate.go ├── seq-coordinator-manager │ ├── rediscoordinator │ │ └── redis_coordinator.go │ └── seq-coordinator-manager.go ├── staterecovery │ └── staterecovery.go └── util │ ├── confighelpers │ └── configuration.go │ ├── keystore.go │ ├── keystore_test.go │ └── util.go ├── codecov.yml ├── daprovider ├── daclient │ └── daclient.go ├── das │ ├── aggregator.go │ ├── aggregator_test.go │ ├── cache_storage_service.go │ ├── cache_storage_service_test.go │ ├── chain_fetch_das.go │ ├── das.go │ ├── dasRpcClient.go │ ├── dasRpcServer.go │ ├── das_test.go │ ├── dasserver │ │ └── dasserver.go │ ├── dastree │ │ ├── dastree.go │ │ └── dastree_test.go │ ├── dasutil │ │ └── dasutil.go │ ├── db_storage_service.go │ ├── extra_signature_checker_test.go │ ├── factory.go │ ├── fallback_storage_service.go │ ├── fallback_storage_service_test.go │ ├── google_cloud_storage_service.go │ ├── google_cloud_storage_service_test.go │ ├── key_utils.go │ ├── lifecycle.go │ ├── local_file_storage_service.go │ ├── local_file_storage_service_test.go │ ├── memory_backed_storage_service.go │ ├── panic_wrapper.go │ ├── read_limited.go │ ├── reader_aggregator_strategies.go │ ├── reader_aggregator_strategies_test.go │ ├── redis_storage_service.go │ ├── redis_storage_service_test.go │ ├── redundant_storage_service.go │ ├── redundant_storage_test.go │ ├── rest_server_list.go │ ├── restful_client.go │ ├── restful_server.go │ ├── restful_server_list_test.go │ ├── restful_server_test.go │ ├── rpc_aggregator.go │ ├── rpc_test.go │ ├── s3_storage_service.go │ ├── s3_storage_service_test.go │ ├── sign_after_store_das_writer.go │ ├── signature_verifier.go │ ├── simple_das_reader_aggregator.go │ ├── simple_das_reader_aggregator_test.go │ ├── storage_service.go │ ├── store_signing.go │ ├── store_signing_test.go │ ├── syncing_fallback_storage.go │ ├── timeout_wrapper.go │ └── util.go ├── reader.go ├── util.go └── writer.go ├── deploy └── deploy.go ├── docs ├── Nitro-whitepaper.pdf ├── decisions │ ├── 0000-use-markdown-architectural-decision-records.md │ ├── 0001-avoid-primitive-constraint-types.md │ ├── README.md │ ├── adr-template-bare-minimal.md │ ├── adr-template-bare.md │ ├── adr-template-minimal.md │ └── adr-template.md └── notice.md ├── execution ├── gethexec │ ├── api.go │ ├── arb_interface.go │ ├── block_recorder.go │ ├── blockchain.go │ ├── blockchain_test.go │ ├── blockmetadata.go │ ├── classicMessage.go │ ├── contract_adapter.go │ ├── executionengine.go │ ├── express_lane_service.go │ ├── express_lane_service_test.go │ ├── express_lane_tracker.go │ ├── forwarder.go │ ├── node.go │ ├── sequencer.go │ ├── stylus_tracer.go │ ├── sync_monitor.go │ ├── tx_pre_checker.go │ └── wasmstorerebuilder.go ├── interface.go └── nodeInterface │ ├── NodeInterface.go │ ├── NodeInterfaceDebug.go │ └── virtual-contracts.go ├── gethhook ├── geth-hook.go └── geth_test.go ├── go.mod ├── go.sum ├── linters ├── koanf │ ├── handlers.go │ ├── koanf.go │ └── koanf_test.go ├── linters.go ├── pointercheck │ ├── pointercheck.go │ └── pointercheck_test.go ├── rightshift │ ├── rightshift.go │ └── rightshift_test.go ├── structinit │ ├── structinit.go │ └── structinit_test.go └── testdata │ └── src │ ├── koanf │ ├── a │ │ └── a.go │ └── b │ │ └── b.go │ ├── pointercheck │ └── pointercheck.go │ ├── rightshift │ └── rightshift.go │ └── structinit │ └── a │ └── a.go ├── precompiles ├── ArbAddressTable.go ├── ArbAddressTable_test.go ├── ArbAggregator.go ├── ArbAggregator_test.go ├── ArbBLS.go ├── ArbDebug.go ├── ArbFunctionTable.go ├── ArbGasInfo.go ├── ArbGasInfo_test.go ├── ArbInfo.go ├── ArbNativeTokenManager.go ├── ArbOwner.go ├── ArbOwnerPublic.go ├── ArbOwner_test.go ├── ArbRetryableTx.go ├── ArbRetryableTx_test.go ├── ArbStatistics.go ├── ArbSys.go ├── ArbWasm.go ├── ArbWasmCache.go ├── ArbosActs.go ├── ArbosTest.go ├── context.go ├── precompile.go ├── precompile_test.go └── wrapper.go ├── pubsub ├── common.go ├── consumer.go ├── producer.go └── pubsub_test.go ├── relay ├── relay.go └── relay_stress_test.go ├── scripts ├── build-brotli.sh ├── check-build.sh ├── convert-databases.bash ├── create-test-preimages.py ├── download-machine.sh ├── fuzz.bash ├── remove_reference_types.sh ├── split-val-entry.sh ├── startup-testnode.bash └── validate-wasm-module-root.sh ├── solgen └── gen.go ├── staker ├── block_validator.go ├── block_validator_schema.go ├── bold │ ├── bold_staker.go │ ├── bold_state_provider.go │ └── data_poster_transactor.go ├── challenge-cache │ ├── cache.go │ └── cache_test.go ├── execution_challenge_bakend.go ├── legacy │ ├── assertion.go │ ├── block_challenge_backend.go │ ├── challenge_manager.go │ ├── challenge_test.go │ ├── common_test.go │ ├── fast_confirm.go │ ├── l1_validator.go │ ├── mock_machine_test.go │ ├── rollup_watcher.go │ └── staker.go ├── multi_protocol │ └── multi_protocol_staker.go ├── stateless_block_validator.go ├── txbuilder │ └── builder.go └── validatorwallet │ ├── contract.go │ ├── eoa.go │ └── noop.go ├── statetransfer ├── data.go ├── interface.go ├── jsondatareader.go └── memdatareader.go ├── system_tests ├── aliasing_test.go ├── arbos_upgrade_test.go ├── arbtrace_test.go ├── archive_redirect_test.go ├── batch_poster_test.go ├── benchmarks_test.go ├── block_hash_test.go ├── block_validator_bench_test.go ├── block_validator_test.go ├── blocks_reexecutor_test.go ├── bloom_test.go ├── bold_challenge_protocol_test.go ├── bold_l3_support_test.go ├── bold_new_challenge_test.go ├── bold_state_provider_test.go ├── classic_redirect_test.go ├── client_wrapper.go ├── common_test.go ├── conditionaltx_test.go ├── contract_tx_test.go ├── das_test.go ├── db_conversion_test.go ├── debug_trace_test.go ├── debugapi_test.go ├── delayedinbox_test.go ├── delayedinboxlong_test.go ├── deployment_test.go ├── estimation_test.go ├── eth_sync_test.go ├── execution_client_only_test.go ├── express_lane_timeboost_test.go ├── fast_confirm_test.go ├── fees_test.go ├── finality_data_test.go ├── forwarder_test.go ├── full_challenge_impl_test.go ├── full_challenge_mock_test.go ├── full_challenge_test.go ├── historical_block_hash_test.go ├── infra_fee_test.go ├── initialization_test.go ├── l3_test.go ├── log_subscription_test.go ├── maintenance_test.go ├── meaningless_reorg_test.go ├── mock_machine_test.go ├── nodeinterface_test.go ├── outbox_test.go ├── overflow_assertions_test.go ├── pendingblock_test.go ├── precompile_doesnt_revert_test.go ├── precompile_fuzz_test.go ├── precompile_test.go ├── program_gas_test.go ├── program_norace_test.go ├── program_race_test.go ├── program_recursive_test.go ├── program_test.go ├── pruning_test.go ├── recreatestate_rpc_test.go ├── reorg_resequencing_test.go ├── retryable_test.go ├── revalidation_test.go ├── rpc_test.go ├── self_destruct_test.go ├── seq_coordinator_test.go ├── seq_filter_test.go ├── seq_nonce_test.go ├── seq_pause_test.go ├── seq_reject_test.go ├── seq_whitelist_test.go ├── seqcompensation_test.go ├── seqfeed_test.go ├── seqinbox_test.go ├── snap_sync_test.go ├── staker_challenge_test.go ├── staker_test.go ├── state_fuzz_test.go ├── staterecovery_test.go ├── storage_trie_test.go ├── stylus_test.go ├── stylus_trace_test.go ├── stylus_tracer_test.go ├── test_info.go ├── timeboost_test.go ├── transfer_test.go ├── triedb_race_test.go ├── twonodes_test.go ├── twonodeslong_test.go ├── unsupported_txtypes_test.go ├── validation_mock_test.go ├── validator_reorg_test.go └── wrap_transaction_test.go ├── timeboost ├── auctioneer.go ├── auctioneer_bid_consumption_test.go ├── auctioneer_failover_test.go ├── auctioneer_test.go ├── bid_cache.go ├── bid_cache_test.go ├── bid_validator.go ├── bid_validator_test.go ├── bidder_client.go ├── bindings │ └── mockerc20.go ├── db.go ├── db_test.go ├── errors.go ├── redis_coordinator.go ├── redis_coordinator_test.go ├── roundtiminginfo.go ├── s3_storage.go ├── s3_storage_test.go ├── schema.go ├── sequencer_endpoint_manager.go ├── setup_test.go ├── ticker.go ├── ticker_test.go └── types.go ├── util ├── arbmath │ ├── bips.go │ ├── bits.go │ ├── math.go │ ├── math_fuzz_test.go │ ├── math_test.go │ ├── moving_average.go │ ├── moving_average_test.go │ ├── time.go │ └── uint24.go ├── blobs │ ├── blobs.go │ └── blobs_test.go ├── colors │ └── colors.go ├── common.go ├── containers │ ├── lru.go │ ├── promise.go │ ├── promise_test.go │ ├── queue.go │ ├── queue_test.go │ ├── stack.go │ └── syncmap.go ├── contracts │ └── address_verifier.go ├── dbutil │ ├── dbutil.go │ └── dbutil_test.go ├── gzip │ ├── gzip_compression.go │ └── gzip_compression_test.go ├── headerreader │ ├── blob_client.go │ ├── blob_client_test.go │ ├── execution_reverted_test.go │ └── header_reader.go ├── iostat │ └── iostat.go ├── jsonapi │ ├── preimages.go │ ├── preimages_test.go │ └── uint64_string.go ├── log.go ├── log_test.go ├── merkletree │ ├── common_test.go │ ├── merkleAccumulator_test.go │ ├── merkleEventProof.go │ ├── merkleEventProof_test.go │ └── merkleTree.go ├── metricsutil │ └── metricsutil.go ├── normalizeGas.go ├── pretty │ └── pretty_printing.go ├── redisutil │ ├── redis_coordinator.go │ ├── redisutil.go │ └── test_redis.go ├── rpcclient │ ├── rpcclient.go │ ├── rpcclient_test.go │ └── rpcclient_toxiproxy_test.go ├── runtime.go ├── s3client │ └── s3client.go ├── sharedmetrics │ └── sharedmetrics.go ├── signature │ ├── datasigner.go │ ├── sign_verify.go │ ├── sign_verify_test.go │ ├── simple_hmac.go │ ├── verifier.go │ └── verifier_test.go ├── stopwaiter │ ├── stopwaiter.go │ ├── stopwaiter_promise_test.go │ └── stopwaiter_test.go └── testhelpers │ ├── env │ └── env.go │ ├── flag │ └── flag.go │ ├── github │ ├── releases.go │ └── releases_test.go │ ├── port.go │ ├── port_test.go │ ├── pseudorandom.go │ ├── stackconfig.go │ └── testhelpers.go ├── validator ├── client │ ├── redis │ │ └── producer.go │ └── validation_client.go ├── execution_state.go ├── inputs │ ├── writer.go │ └── writer_test.go ├── interface.go ├── retry_wrapper │ └── retry_wrapper.go ├── server_api │ └── json.go ├── server_arb │ ├── bold_machine.go │ ├── execution_run.go │ ├── execution_run_test.go │ ├── machine.go │ ├── machine_cache.go │ ├── machine_loader.go │ ├── machine_test.go │ ├── nitro_machine.go │ ├── preimage_resolver.go │ ├── prover_interface.go │ └── validator_spawner.go ├── server_common │ ├── machine_loader.go │ ├── machine_locator.go │ ├── machine_locator_test.go │ ├── testdata │ │ ├── 0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4 │ │ │ └── module-root.txt │ │ ├── 0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4 │ │ │ └── module-root.txt │ │ ├── 0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a │ │ │ └── module-root.txt │ │ └── latest │ └── valrun.go ├── server_jit │ ├── jit_machine.go │ ├── machine_loader.go │ └── spawner.go ├── utils.go ├── validation_entry.go └── valnode │ ├── redis │ ├── consumer.go │ └── consumer_test.go │ ├── validation_api.go │ └── valnode.go ├── wavmio ├── higher.go ├── raw.go └── stub.go ├── wsbroadcastserver ├── clientconnection.go ├── clientmanager.go ├── connectionlimiter.go ├── connectionlimiter_test.go ├── dictionary.go ├── utils.go └── wsbroadcastserver.go └── zeroheavy ├── common_test.go ├── zeroheavy.go └── zeroheavy_test.go /.clabot: -------------------------------------------------------------------------------- 1 | { 2 | "contributors": "https://api.github.com/repos/OffchainLabs/clabot-config/contents/nitro-contributors.json", 3 | "message": "We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign the linked documents below to get yourself added. https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=b15c81cc-b5ea-42a6-9107-3992526f2898&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2", 4 | "label": "s" 5 | } 6 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.github 2 | .make 3 | **/.dockerignore 4 | **/Dockerfile 5 | **/.gitignore 6 | **/.git 7 | **/.gitmodules 8 | go-ethereum/tests 9 | **/*.yml 10 | contracts/build 11 | contracts/cache/ 12 | safe-smart-account/build/ 13 | solgen/go 14 | **/node_modules 15 | 16 | target/**/* 17 | !target/machines 18 | !target/machines/* 19 | !target/machines/**/* 20 | brotli/buildfiles/**/* 21 | 22 | # these are used by environment outside the docker: 23 | nitro-testnode/**/* 24 | 25 | # Arbitrator ignores 26 | arbitrator/tools/module_roots 27 | arbitrator/tools/pricer 28 | 29 | # Rust outputs 30 | arbitrator/target/**/* 31 | arbitrator/target 32 | arbitrator/stylus/tests/*/target/ 33 | arbitrator/wasm-testsuite/target/ 34 | arbitrator/wasm-libraries/target/ 35 | arbitrator/tools/wasmer/target/ 36 | arbitrator/tools/wasm-tools/ 37 | arbitrator/tools/pricers/ 38 | arbitrator/tools/module_roots/ 39 | arbitrator/tools/stylus_benchmark 40 | arbitrator/langs/rust/target/ 41 | arbitrator/langs/bf/target/ 42 | 43 | # Compiled files 44 | **/*.o 45 | **/*.a 46 | *.wasm 47 | 48 | # Autogenerated test files 49 | arbitrator/prover/test-cases/**/* 50 | arbitrator/prover/test-cases 51 | 52 | # external tools and IDEs 53 | .vscode 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/codeql/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: "Nitro CodeQL config" 2 | 3 | -------------------------------------------------------------------------------- /.github/workflows/arbitrator-skip-ci.yml: -------------------------------------------------------------------------------- 1 | name: Arbitrator skip CI 2 | run-name: Arbitrator skip CI triggered from @${{ github.actor }} of ${{ github.head_ref }} 3 | 4 | on: 5 | merge_group: 6 | pull_request: 7 | paths-ignore: 8 | - 'arbitrator/**' 9 | - 'contracts/src/osp/**' 10 | - 'contracts/src/mock/**' 11 | - 'contracts/test/**' 12 | - 'contracts/hardhat.config.ts' 13 | - 'Makefile' 14 | 15 | jobs: 16 | arbitrator: 17 | name: Run Arbitrator tests 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Do nothing 21 | run: echo "doing nothing" 22 | -------------------------------------------------------------------------------- /.github/workflows/release-ci.yml: -------------------------------------------------------------------------------- 1 | name: Release CI 2 | run-name: Release CI triggered from @${{ github.actor }} of ${{ github.head_ref }} 3 | 4 | on: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build_and_run: 9 | runs-on: ubuntu-8 10 | 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | with: 15 | submodules: recursive 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v3 19 | with: 20 | driver-opts: network=host 21 | 22 | - name: Cache Docker layers 23 | uses: actions/cache@v3 24 | with: 25 | path: /tmp/.buildx-cache 26 | key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }} 27 | restore-keys: ${{ runner.os }}-buildx- 28 | 29 | - name: Startup Nitro testnode 30 | run: ./scripts/startup-testnode.bash 31 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck-ci.yml: -------------------------------------------------------------------------------- 1 | name: ShellCheck CI 2 | run-name: ShellCheck CI triggered from @${{ github.actor }} of ${{ github.head_ref }} 3 | 4 | on: 5 | workflow_dispatch: 6 | merge_group: 7 | pull_request: 8 | push: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | shellcheck: 14 | name: Run ShellCheck 15 | runs-on: ubuntu-8 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | 20 | - name: Run ShellCheck 21 | uses: ludeeus/action-shellcheck@master 22 | with: 23 | ignore_paths: >- 24 | ./fastcache/** 25 | ./contracts/** 26 | ./safe-smart-account/** 27 | ./go-ethereum/** 28 | ./nitro-testnode/** 29 | ./brotli/** 30 | ./arbitrator/** 31 | -------------------------------------------------------------------------------- /.github/workflows/waitForNitro.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # poll the nitro endpoint until we get a 0 return code or 30mins have passed, in that case exit 1 3 | timeout_time=$(($(date +%s) + 1800)) 4 | 5 | while (( $(date +%s) <= timeout_time )); do 6 | if curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":45678,"method":"eth_chainId","params":[]}' 'http://localhost:8547'; then 7 | exit 0 8 | else 9 | sleep 20 10 | fi 11 | done 12 | 13 | exit 1 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /record 2 | /cmd/record/record 3 | /replay 4 | /cmd/replay/replay 5 | /*.bin 6 | /*.test 7 | /system_tests/*_fuzz/* 8 | !/system_tests/*_fuzz/*_fuzz.go 9 | node_modules 10 | .DS_Store 11 | .idea 12 | .vscode 13 | cmd/node/data 14 | cmd/node/node 15 | solgen/go/ 16 | .make/ 17 | /cmd/statetransfer/statetransfer 18 | /reproducible-wasm/*.wasm 19 | target/ 20 | yarn-error.log 21 | local/ 22 | system_tests/test-data/* 23 | .configs/ 24 | system_tests/testdata/* 25 | arbos/testdata/* 26 | -------------------------------------------------------------------------------- /.nitro-tag.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/.nitro-tag.txt -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /arbcompress/compress_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbcompress 5 | 6 | type Dictionary uint32 7 | 8 | const ( 9 | EmptyDictionary Dictionary = iota 10 | StylusProgramDictionary 11 | ) 12 | 13 | const LEVEL_WELL = 11 14 | const WINDOW_SIZE = 22 // BROTLI_DEFAULT_WINDOW 15 | 16 | func compressedBufferSizeFor(length int) int { 17 | return length + (length>>10)*8 + 64 // actual limit is: length + (length >> 14) * 4 + 6 18 | } 19 | 20 | func CompressLevel(input []byte, level uint64) ([]byte, error) { 21 | // level is trusted and shouldn't be anything crazy 22 | // #nosec G115 23 | return Compress(input, uint32(level), EmptyDictionary) 24 | } 25 | -------------------------------------------------------------------------------- /arbitrator/.gitignore: -------------------------------------------------------------------------------- 1 | # Rust files 2 | target 3 | 4 | # Node/yarn files 5 | node_modules 6 | yarn-error.log 7 | .env 8 | 9 | # Hardhat files 10 | cache 11 | build/contracts 12 | build/types 13 | deployments 14 | !deployments/* 15 | deployments/localhost 16 | 17 | # SoftFloat files 18 | wasm-libraries/soft-float/**/*.o 19 | wasm-libraries/soft-float/**/*.a 20 | wasm-libraries/soft-float/**/*.wasm 21 | 22 | # Autogenerated test files 23 | prover/test-cases/**/*.wasm 24 | prover/test-cases/go/main 25 | 26 | # external tools and IDEs 27 | .vscode 28 | -------------------------------------------------------------------------------- /arbitrator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "arbutil", 4 | "bench", 5 | "brotli", 6 | "brotli/fuzz", 7 | "caller-env", 8 | "prover", 9 | "stylus", 10 | "jit", 11 | ] 12 | exclude = [ 13 | "stylus/tests/", 14 | "tools/wasmer/", 15 | "tools/stylus_benchmark", 16 | ] 17 | resolver = "2" 18 | 19 | [workspace.package] 20 | authors = ["Offchain Labs"] 21 | edition = "2021" 22 | homepage = "https://arbitrum.io" 23 | license = "BSL" 24 | repository = "https://github.com/OffchainLabs/nitro.git" 25 | rust-version = "1.67" 26 | 27 | [workspace.dependencies] 28 | lazy_static = "1.4.0" 29 | num_enum = { version = "0.7.2", default-features = false } 30 | ruint2 = "1.9.0" 31 | wasmparser = "0.121" 32 | wee_alloc = "0.4.2" 33 | 34 | [profile.release] 35 | debug = true 36 | -------------------------------------------------------------------------------- /arbitrator/arbutil/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arbutil" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | digest = "0.10.7" 8 | eyre = "0.6.5" 9 | fnv = "1.0.7" 10 | hex = "0.4.3" 11 | num-traits = "0.2.17" 12 | siphasher = "0.3.10" 13 | tiny-keccak = { version = "2.0.2", features = ["keccak"] } 14 | ruint2.workspace = true 15 | wasmparser.workspace = true 16 | serde = { version = "1.0.130", features = ["derive", "rc"] } 17 | num_enum = "0.7.1" 18 | sha2 = "0.10.7" 19 | sha3 = "0.10.8" 20 | -------------------------------------------------------------------------------- /arbitrator/arbutil/src/benchmark.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::evm::api::Ink; 5 | use std::time::{Duration, Instant}; 6 | 7 | // Benchmark is used to track the performance of blocks of code in stylus 8 | #[derive(Clone, Copy, Debug, Default)] 9 | pub struct Benchmark { 10 | pub timer: Option, 11 | pub elapsed_total: Duration, 12 | pub ink_start: Option, 13 | pub ink_total: Ink, 14 | } 15 | -------------------------------------------------------------------------------- /arbitrator/arbutil/src/crypto.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use siphasher::sip::SipHasher24; 5 | use std::mem::MaybeUninit; 6 | use tiny_keccak::{Hasher, Keccak}; 7 | 8 | pub fn keccak>(preimage: T) -> [u8; 32] { 9 | let mut output = MaybeUninit::<[u8; 32]>::uninit(); 10 | let mut hasher = Keccak::v256(); 11 | hasher.update(preimage.as_ref()); 12 | 13 | // SAFETY: finalize() writes 32 bytes 14 | unsafe { 15 | hasher.finalize(&mut *output.as_mut_ptr()); 16 | output.assume_init() 17 | } 18 | } 19 | 20 | pub fn siphash(preimage: &[u8], key: &[u8; 16]) -> u64 { 21 | use std::hash::Hasher; 22 | let mut hasher = SipHasher24::new_with_key(key); 23 | hasher.write(preimage); 24 | hasher.finish() 25 | } 26 | -------------------------------------------------------------------------------- /arbitrator/arbutil/src/math.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use num_traits::{ops::saturating::SaturatingAdd, Zero}; 5 | use std::ops::{BitAnd, Sub}; 6 | 7 | /// Checks if a number is a power of 2. 8 | pub fn is_power_of_2(value: T) -> bool 9 | where 10 | T: Sub + BitAnd + PartialOrd + From + Copy, 11 | { 12 | if value <= 0.into() { 13 | return false; 14 | } 15 | value & (value - 1.into()) == 0.into() 16 | } 17 | 18 | /// Calculates a sum, saturating in cases of overflow. 19 | pub trait SaturatingSum { 20 | type Number; 21 | 22 | fn saturating_sum(self) -> Self::Number; 23 | } 24 | 25 | impl SaturatingSum for I 26 | where 27 | I: Iterator, 28 | T: SaturatingAdd + Zero, 29 | { 30 | type Number = T; 31 | 32 | fn saturating_sum(self) -> Self::Number { 33 | self.fold(T::zero(), |acc, x| acc.saturating_add(&x)) 34 | } 35 | } 36 | 37 | /// Returns `num` divided by `N`, rounded up. 38 | pub fn div_ceil(num: usize) -> usize { 39 | match num % N { 40 | 0 => num / N, 41 | _ => num / N + 1, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /arbitrator/arbutil/src/pricing.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::evm::api::Ink; 5 | 6 | /// For hostios that may return something. 7 | pub const HOSTIO_INK: Ink = Ink(8400); 8 | 9 | /// For hostios that include pointers. 10 | pub const PTR_INK: Ink = Ink(13440).sub(HOSTIO_INK); 11 | 12 | /// For hostios that involve an API cost. 13 | pub const EVM_API_INK: Ink = Ink(59673); 14 | 15 | /// For hostios that involve a div or mod. 16 | pub const DIV_INK: Ink = Ink(20000); 17 | 18 | /// For hostios that involve a mulmod. 19 | pub const MUL_MOD_INK: Ink = Ink(24100); 20 | 21 | /// For hostios that involve an addmod. 22 | pub const ADD_MOD_INK: Ink = Ink(21000); 23 | -------------------------------------------------------------------------------- /arbitrator/bench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [[bin]] 7 | name = "benchbin" 8 | path = "src/bin.rs" 9 | 10 | [dependencies] 11 | hex = { version = "0.4.3", features = ["serde"] } 12 | eyre = "0.6.5" 13 | prover = { path = "../prover" } 14 | arbutil = { path = "../arbutil" } 15 | clap = { version = "4.4.8", features = ["derive"] } 16 | gperftools = { version = "0.2.0", optional = true } 17 | serde = { version = "1.0.130", features = ["derive", "rc"] } 18 | serde_json = "1.0.67" 19 | 20 | [features] 21 | counters = [] 22 | cpuprof = ["gperftools"] 23 | heapprof = ["gperftools", "gperftools/heap"] 24 | -------------------------------------------------------------------------------- /arbitrator/brotli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "brotli" 3 | version = "0.1.0" 4 | authors.workspace = true 5 | edition.workspace = true 6 | homepage.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | rust-version.workspace = true 10 | 11 | [dependencies] 12 | lazy_static.workspace = true 13 | num_enum.workspace = true 14 | wasmer = { path = "../tools/wasmer/lib/api", optional = true } 15 | wee_alloc.workspace = true 16 | 17 | [lib] 18 | crate-type = ["lib"] 19 | 20 | [features] 21 | wasmer_traits = ["dep:wasmer"] 22 | -------------------------------------------------------------------------------- /arbitrator/brotli/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::env; 5 | 6 | fn main() { 7 | let target_arch = env::var("TARGET").unwrap(); 8 | 9 | if target_arch.contains("wasm32") { 10 | println!("cargo:rustc-link-search=../../target/lib-wasm/"); 11 | } else { 12 | println!("cargo:rustc-link-search=../target/lib/"); 13 | println!("cargo:rustc-link-search=../../target/lib/"); 14 | } 15 | println!("cargo:rustc-link-lib=static=brotlienc-static"); 16 | println!("cargo:rustc-link-lib=static=brotlidec-static"); 17 | println!("cargo:rustc-link-lib=static=brotlicommon-static"); 18 | } 19 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | corpus 3 | artifacts 4 | coverage 5 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "brotli-fuzz" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2021" 6 | 7 | [package.metadata] 8 | cargo-fuzz = true 9 | 10 | [dependencies] 11 | libfuzzer-sys = "0.4" 12 | hex = "0.4.3" 13 | 14 | [dependencies.brotli] 15 | path = ".." 16 | 17 | [[bin]] 18 | name = "compress" 19 | path = "fuzz_targets/compress.rs" 20 | test = false 21 | doc = false 22 | bench = false 23 | 24 | [[bin]] 25 | name = "decompress" 26 | path = "fuzz_targets/decompress.rs" 27 | test = false 28 | doc = false 29 | bench = false 30 | 31 | [[bin]] 32 | name = "round-trip" 33 | path = "fuzz_targets/round_trip.rs" 34 | test = false 35 | doc = false 36 | bench = false 37 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/README: -------------------------------------------------------------------------------- 1 | 2 | Fuzzing for brotli. You'll need `cargo-fuzz`. Install it with `cargo install 3 | cargo-fuzz`. You'll also need to use the Rust nightly compiler - `rustup 4 | default nightly`. 5 | 6 | Then you can fuzz with 7 | ```bash 8 | cargo +nightly fuzz run compress -- -max_len=262144 9 | ``` 10 | or 11 | ```bash 12 | cargo +nightly fuzz run decompress -- -max_len=262144 13 | ``` 14 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/fuzz_targets/compress.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use libfuzzer_sys::fuzz_target; 7 | 8 | fuzz_target!(|arg: (&[u8], u32, u32)| { 9 | let data = arg.0; 10 | let quality = arg.1; 11 | let window = arg.2; 12 | let _ = brotli::compress( 13 | data, 14 | 1 + quality % 12, 15 | 10 + window % 15, 16 | brotli::Dictionary::StylusProgram, 17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/fuzz_targets/decompress.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use brotli::Dictionary; 7 | use libfuzzer_sys::fuzz_target; 8 | 9 | fuzz_target!(|data: &[u8]| { 10 | let mut data = data; 11 | let dict = Dictionary::StylusProgram; 12 | 13 | let mut space = 0_u32; 14 | if data.len() >= 4 { 15 | space = u32::from_le_bytes(data[..4].try_into().unwrap()); 16 | data = &data[4..]; 17 | } 18 | 19 | let mut array = Vec::with_capacity(space as usize % 65536); 20 | let array = &mut array.spare_capacity_mut(); 21 | 22 | let plain = brotli::decompress(data, dict); 23 | let fixed = brotli::decompress_fixed(data, array, dict); 24 | 25 | if let Ok(fixed) = fixed { 26 | assert_eq!(fixed.len(), plain.unwrap().len()); // fixed succeeding implies both do 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /arbitrator/brotli/fuzz/fuzz_targets/round_trip.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use brotli::Dictionary; 7 | use libfuzzer_sys::fuzz_target; 8 | 9 | fuzz_target!(|data: &[u8]| { 10 | let dict = Dictionary::Empty; 11 | let split = data 12 | .first() 13 | .map(|x| *x as usize) 14 | .unwrap_or_default() 15 | .min(data.len()); 16 | 17 | let (header, data) = data.split_at(split); 18 | let image = brotli::compress_into(data, header.to_owned(), 0, 22, dict).unwrap(); 19 | let prior = brotli::decompress(&image[split..], dict).unwrap(); 20 | 21 | assert_eq!(&image[..split], header); 22 | assert_eq!(prior, data); 23 | }); 24 | -------------------------------------------------------------------------------- /arbitrator/brotli/src/dicts/stylus-program-11.lz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/arbitrator/brotli/src/dicts/stylus-program-11.lz -------------------------------------------------------------------------------- /arbitrator/brotli/src/wasmer_traits.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::{dicts::Dictionary, types::BrotliStatus}; 5 | use wasmer::FromToNativeWasmType; 6 | 7 | unsafe impl FromToNativeWasmType for BrotliStatus { 8 | type Native = i32; 9 | 10 | fn from_native(native: i32) -> Self { 11 | Self::try_from(u32::from_native(native)).expect("unknown brotli status") 12 | } 13 | 14 | fn to_native(self) -> i32 { 15 | (self as u32).to_native() 16 | } 17 | } 18 | 19 | unsafe impl FromToNativeWasmType for Dictionary { 20 | type Native = i32; 21 | 22 | fn from_native(native: i32) -> Self { 23 | Self::try_from(u32::from_native(native)).expect("unknown brotli dictionary") 24 | } 25 | 26 | fn to_native(self) -> i32 { 27 | (self as u32).to_native() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /arbitrator/caller-env/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "caller-env" 3 | version = "0.1.0" 4 | edition.workspace = true 5 | 6 | [dependencies] 7 | brotli = { path = "../brotli/", optional = true } 8 | num_enum.workspace = true 9 | rand_pcg = { version = "0.3.1", default-features = false } 10 | rand = { version = "0.8.4", default-features = false } 11 | wasmer = { path = "../tools/wasmer/lib/api", optional = true } 12 | 13 | [features] 14 | default = ["brotli"] 15 | brotli = ["dep:brotli"] 16 | static_caller = [] 17 | wasmer_traits = ["dep:wasmer", "brotli?/wasmer_traits"] 18 | -------------------------------------------------------------------------------- /arbitrator/caller-env/src/guest_ptr.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use core::ops::{Add, AddAssign, Deref}; 5 | 6 | /// Represents a pointer to a Guest WASM's memory. 7 | #[derive(Clone, Copy, Eq, PartialEq)] 8 | #[repr(transparent)] 9 | pub struct GuestPtr(pub u32); 10 | 11 | impl Add for GuestPtr { 12 | type Output = Self; 13 | 14 | fn add(self, rhs: u32) -> Self::Output { 15 | Self(self.0 + rhs) 16 | } 17 | } 18 | 19 | impl AddAssign for GuestPtr { 20 | fn add_assign(&mut self, rhs: u32) { 21 | *self = *self + rhs; 22 | } 23 | } 24 | 25 | impl From for u32 { 26 | fn from(value: GuestPtr) -> Self { 27 | value.0 28 | } 29 | } 30 | 31 | impl From for u64 { 32 | fn from(value: GuestPtr) -> Self { 33 | value.0.into() 34 | } 35 | } 36 | 37 | impl Deref for GuestPtr { 38 | type Target = u32; 39 | 40 | fn deref(&self) -> &Self::Target { 41 | &self.0 42 | } 43 | } 44 | 45 | impl GuestPtr { 46 | pub fn to_u64(self) -> u64 { 47 | self.into() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /arbitrator/caller-env/src/wasmer_traits.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::{Errno, GuestPtr}; 5 | use wasmer::{FromToNativeWasmType, WasmPtr}; 6 | 7 | unsafe impl FromToNativeWasmType for GuestPtr { 8 | type Native = i32; 9 | 10 | fn from_native(native: i32) -> Self { 11 | Self(u32::from_native(native)) 12 | } 13 | 14 | fn to_native(self) -> i32 { 15 | self.0.to_native() 16 | } 17 | } 18 | 19 | unsafe impl FromToNativeWasmType for Errno { 20 | type Native = i32; 21 | 22 | fn from_native(native: i32) -> Self { 23 | Self(u16::from_native(native)) 24 | } 25 | 26 | fn to_native(self) -> i32 { 27 | self.0.to_native() 28 | } 29 | } 30 | 31 | impl From for WasmPtr { 32 | fn from(value: GuestPtr) -> Self { 33 | WasmPtr::new(value.0) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /arbitrator/jit/.gitignore: -------------------------------------------------------------------------------- 1 | **.wasm 2 | -------------------------------------------------------------------------------- /arbitrator/jit/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "runtime-validator" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /arbitrator/jit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jit" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | arbutil = { path = "../arbutil/" } 8 | brotli = { path = "../brotli/", features = ["wasmer_traits"] } 9 | caller-env = { path = "../caller-env/", features = ["wasmer_traits"] } 10 | prover = { path = "../prover/", default-features = false, features = ["native"] } 11 | stylus = { path = "../stylus/", default-features = false } 12 | wasmer = { path = "../tools/wasmer/lib/api/" } 13 | wasmer-compiler-llvm = { path = "../tools/wasmer/lib/compiler-llvm/", optional = true } 14 | wasmer-compiler-cranelift = { path = "../tools/wasmer/lib/compiler-cranelift/" } 15 | eyre = "0.6.5" 16 | parking_lot = "0.12.1" 17 | rand = { version = "0.8.4", default-features = false } 18 | rand_pcg = { version = "0.3.1", default-features = false } 19 | thiserror = "1.0.33" 20 | hex = "0.4.3" 21 | structopt = "0.3.26" 22 | sha3 = "0.9.1" 23 | libc = "0.2.132" 24 | sha2 = "0.9.9" 25 | 26 | [features] 27 | llvm = ["dep:wasmer-compiler-llvm"] 28 | -------------------------------------------------------------------------------- /arbitrator/jit/programs/print/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package main 5 | 6 | func main() { 7 | // what follows is a heartfelt poem about spiders, compilers, 8 | // and the language that brings them together 9 | 10 | println("itsy bitsy spider /\\oo/\\ made 407614 lines 🎵") 11 | println("that's because it's golang and there's a huge runtime 🎵") 12 | println("there's more than just 4 printlns since we might reflect 🎵") 13 | println("that's the state of golang, what would you expect? 🎵") 14 | } 15 | -------------------------------------------------------------------------------- /arbitrator/jit/programs/pure/main.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type $t0 (func (param i32) (result i32))) 3 | (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) 4 | get_local $p0 5 | i32.const 1 6 | i32.add)) 7 | -------------------------------------------------------------------------------- /arbitrator/jit/programs/time/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package main 5 | 6 | import "time" 7 | 8 | func main() { 9 | println("What time is it??") 10 | println(time.Now().Nanosecond()) 11 | println(time.Now().Nanosecond()) 12 | println(time.Now().Nanosecond()) 13 | } 14 | -------------------------------------------------------------------------------- /arbitrator/jit/src/test.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![cfg(test)] 5 | 6 | use eyre::Result; 7 | use wasmer::{imports, Instance, Module, Store, Value}; 8 | 9 | #[test] 10 | fn test_crate() -> Result<()> { 11 | // Adapted from https://docs.rs/wasmer/3.1.0/wasmer/index.html 12 | 13 | let source = std::fs::read("programs/pure/main.wat")?; 14 | 15 | let mut store = Store::default(); 16 | let module = Module::new(&store, source)?; 17 | let imports = imports! {}; 18 | let instance = Instance::new(&mut store, &module, &imports)?; 19 | 20 | let add_one = instance.exports.get_function("add_one")?; 21 | let result = add_one.call(&mut store, &[Value::I32(42)])?; 22 | assert_eq!(result[0], Value::I32(43)); 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /arbitrator/prover/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | corpus 3 | artifacts 4 | fuzz*.log 5 | -------------------------------------------------------------------------------- /arbitrator/prover/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prover-fuzz" 3 | version = "0.0.0" 4 | authors = ["Automatically generated"] 5 | publish = false 6 | edition = "2018" 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | lazy_static = "1.4.0" 13 | libfuzzer-sys = "0.4" 14 | eyre = "0.6.8" 15 | tokio = { version = "1.18.5", features = ["rt", "rt-multi-thread"] } 16 | serde = { version = "1.0.137", features = ["derive"] } 17 | hex = "0.4.3" 18 | evm = "0.41.1" 19 | serde_json = "1.0.81" 20 | primitive-types = "0.11.1" 21 | rayon = "1.5.1" 22 | 23 | [dependencies.prover] 24 | path = ".." 25 | 26 | # Prevent this from interfering with workspaces 27 | [workspace] 28 | members = ["."] 29 | 30 | [[bin]] 31 | name = "osp" 32 | path = "fuzz_targets/osp.rs" 33 | test = false 34 | doc = false 35 | -------------------------------------------------------------------------------- /arbitrator/prover/src/programs/prelude.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | pub use super::{ 5 | config::{CompileConfig, StylusConfig}, 6 | counter::CountingMachine, 7 | depth::DepthCheckedMachine, 8 | meter::{GasMeteredMachine, MachineMeter, MeteredMachine}, 9 | }; 10 | 11 | #[cfg(feature = "native")] 12 | pub use super::start::StartlessMachine; 13 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/block.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (i32.const 1) 3 | (block 4 | (block 5 | (br 1) 6 | (unreachable) 7 | ) 8 | (unreachable) 9 | ) 10 | (block (param i32) 11 | (br_if 0) 12 | (unreachable) 13 | ) 14 | (block 15 | (block 16 | (i32.const 2) 17 | (br_table 0 0 1 0 0) 18 | (unreachable) 19 | ) 20 | (unreachable) 21 | ) 22 | (block 23 | (block 24 | (i32.const 8) 25 | (br_table 0 0 0 0 1) 26 | (unreachable) 27 | ) 28 | (unreachable) 29 | ) 30 | 31 | (i32.const 1) 32 | (block 33 | (i64.const -64) 34 | (i64.const -64) 35 | (br 0) 36 | (unreachable) 37 | ) 38 | (block 39 | (i64.const -64) 40 | (i32.const 1) 41 | (br_if 0) 42 | (unreachable) 43 | ) 44 | (block (param i32) 45 | (br_if 0) 46 | (unreachable) 47 | ) 48 | (block (result i32) 49 | (i64.const 0) 50 | (i32.const 1) 51 | (i32.const 1) 52 | (br_if 0) 53 | (unreachable) 54 | ) 55 | (block (param i32) 56 | (br_if 0) 57 | (unreachable) 58 | ) 59 | (i32.const 1) 60 | (block 61 | (i32.const 1) 62 | (i64.const -64) 63 | (br 0) 64 | (unreachable) 65 | ) 66 | (br_if 0) 67 | ) 68 | 69 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 70 | (i32.const 0) 71 | ) 72 | 73 | (start 0) 74 | (memory (export "memory") 0 0) 75 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/call-indirect.wat: -------------------------------------------------------------------------------- 1 | (table 4 funcref) 2 | (elem (i32.const 1) 1 2) 3 | 4 | (type (func (param i32) (result i32))) 5 | (type (func (param i32))) 6 | 7 | (func 8 | (i32.const 4) 9 | (i32.const 1) 10 | (call_indirect (type 0)) 11 | (i32.const 2) 12 | (call_indirect (type 0)) 13 | (i32.const 1) 14 | (call_indirect (type 1)) 15 | ) 16 | 17 | (func (param i32) (result i32) 18 | (local.get 0) 19 | (i32.const 1) 20 | (i32.add) 21 | ) 22 | 23 | (func (param i32) (result i32) 24 | (local.get 0) 25 | (i32.const 2) 26 | (i32.mul) 27 | ) 28 | 29 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 30 | (i32.const 0) 31 | ) 32 | 33 | (start 0) 34 | (memory (export "memory") 0 0) 35 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/call.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (i32.const 1) 3 | (call 1) 4 | ) 5 | 6 | (func (param i32) 7 | (local.get 0) 8 | (if 9 | (then (call 2)) 10 | (else (unreachable)) 11 | ) 12 | ) 13 | 14 | (func 15 | (i32.const 0) 16 | (call 1) 17 | ) 18 | 19 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 20 | (i32.const 0) 21 | ) 22 | 23 | (start 0) 24 | (memory (export "memory") 0 0) 25 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/const.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (nop) 3 | (i32.const 0) 4 | (i32.const 1) 5 | (i32.const 2) 6 | (drop) 7 | (drop) 8 | (drop) 9 | ) 10 | 11 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 12 | (i32.const 0) 13 | ) 14 | 15 | (start 0) 16 | (memory (export "memory") 0 0) 17 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/div-overflow.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (i32.const -0x80000000) 3 | (i32.const -1) 4 | (i32.div_s) 5 | (drop) 6 | (i64.const -0x8000000000000000) 7 | (i64.const -1) 8 | (i64.div_s) 9 | (drop) 10 | ) 11 | 12 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 13 | (i32.const 0) 14 | ) 15 | 16 | (start 0) 17 | (memory (export "memory") 0 0) 18 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/forward-test.wat: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (import "forward" "add" (func $add (param i32 i32) (result i32))) 4 | (import "forward" "sub" (func $sub (param i32 i32) (result i32))) 5 | (import "forward" "mul" (func $mul (param i32 i32) (result i32))) 6 | (func $start 7 | ;; this address will update each time a forwarded call is made 8 | i32.const 0xa4b 9 | i32.const 805 10 | i32.store 11 | 12 | i32.const 11 13 | i32.const 5 14 | call $sub 15 | 16 | i32.const 3 17 | i32.const -2 18 | call $mul 19 | 20 | call $add 21 | (if 22 | (then (unreachable))) 23 | 24 | ;; check that the address has changed 25 | i32.const 0xa4b 26 | i32.load 27 | i32.const 808 28 | i32.ne 29 | (if 30 | (then (unreachable)))) 31 | (start $start) 32 | (memory 1)) 33 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/forward/forward.wat: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (import "target" "arbitrator_forward__add" (func $add (param i32 i32) (result i32))) 4 | (import "target" "arbitrator_forward__sub" (func $sub (param i32 i32) (result i32))) 5 | (import "target" "arbitrator_forward__mul" (func $mul (param i32 i32) (result i32))) 6 | (export "forward__add" (func $add)) 7 | (export "forward__sub" (func $sub)) 8 | (export "forward__mul" (func $mul))) 9 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/forward/target.wat: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (import "env" "wavm_caller_load8" (func $load (param i32) (result i32))) 4 | (import "env" "wavm_caller_store8" (func $store (param i32 i32))) 5 | (func (export "target__add") (param i32 i32) (result i32) 6 | call $write_caller 7 | local.get 0 8 | local.get 1 9 | i32.add) 10 | (func (export "target__sub") (param i32 i32) (result i32) 11 | call $write_caller 12 | local.get 0 13 | local.get 1 14 | i32.sub) 15 | (func (export "target__mul") (param i32 i32) (result i32) 16 | call $write_caller 17 | local.get 0 18 | local.get 1 19 | i32.mul) 20 | (func $write_caller (export "write_caller") 21 | ;; increment the value at address 0xa4b in the caller 22 | i32.const 0xa4b 23 | i32.const 0xa4b 24 | call $load 25 | i32.const 1 26 | i32.add 27 | call $store)) 28 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/global-state-wavm.wat: -------------------------------------------------------------------------------- 1 | (import "env" "wavm_set_globalstate_u64" (func $set (param i32) (param i64))) 2 | (import "env" "wavm_get_globalstate_u64" (func $get (param i32) (result i64))) 3 | (import "env" "wavm_halt_and_set_finished" (func $halt)) 4 | 5 | (func $entry 6 | (i32.const 0) 7 | (i64.const 10) 8 | (call $set) 9 | (loop 10 | (i32.const 0) 11 | (i32.const 0) 12 | (call $get) 13 | (i64.sub (i64.const 1)) 14 | (call $set) 15 | (i32.const 0) 16 | (call $get) 17 | (i32.wrap_i64) 18 | (br_if 0) 19 | ) 20 | (call $halt) 21 | ) 22 | 23 | (start $entry) 24 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/global-state-wrapper.wat: -------------------------------------------------------------------------------- 1 | ;; By default, arbitrator doesn't allow host IO use directly from the main module. 2 | ;; This fixes that by wrapping the host IO in this library, which then reexports it with the same name. 3 | 4 | (import "env" "wavm_set_globalstate_u64" (func $set (param i32) (param i64))) 5 | (import "env" "wavm_get_globalstate_u64" (func $get (param i32) (result i64))) 6 | (import "env" "wavm_read_inbox_message" (func $readinbox (param i64) (param i32) (param i32) (result i32))) 7 | (import "env" "wavm_halt_and_set_finished" (func $halt)) 8 | 9 | (export "wrapper__set_globalstate_u64" (func $set)) 10 | (export "wrapper__get_globalstate_u64" (func $get)) 11 | (export "wrapper__read_inbox_message" (func $readinbox)) 12 | (export "wrapper__halt_and_set_finished" (func $halt)) 13 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/global-state.wat: -------------------------------------------------------------------------------- 1 | (import "wrapper" "set_globalstate_u64" (func $set (param i32) (param i64))) 2 | (import "wrapper" "get_globalstate_u64" (func $get (param i32) (result i64))) 3 | (import "wrapper" "halt_and_set_finished" (func $halt)) 4 | 5 | (func $entry 6 | (i32.const 0) 7 | (i64.const 10) 8 | (call $set) 9 | (loop 10 | (i32.const 0) 11 | (i32.const 0) 12 | (call $get) 13 | (i64.sub (i64.const 1)) 14 | (call $set) 15 | (i32.const 0) 16 | (call $get) 17 | (i32.wrap_i64) 18 | (br_if 0) 19 | ) 20 | (call $halt) 21 | ) 22 | 23 | (start $entry) 24 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/globals.wat: -------------------------------------------------------------------------------- 1 | (global (mut i32) (i32.const 1)) 2 | (global (mut i32) (i32.const 2)) 3 | 4 | (func 5 | (global.get 0) 6 | (i32.const 1) 7 | (i32.add) 8 | (global.set 0) 9 | (global.get 0) 10 | (global.set 1) 11 | (global.get 0) 12 | (i32.const 1) 13 | (i32.add) 14 | (global.set 1) 15 | (global.get 0) 16 | (global.get 1) 17 | (i32.add) 18 | (drop) 19 | ) 20 | 21 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 22 | (i32.const 0) 23 | ) 24 | 25 | (start 0) 26 | (memory (export "memory") 0 0) 27 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/if-else.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (i32.const 1) 3 | (if (result i32) 4 | (then 5 | (i32.const 2) 6 | ) 7 | (else (unreachable)) 8 | ) 9 | (drop) 10 | (i32.const 0) 11 | (if (result i32) 12 | (then (unreachable)) 13 | (else 14 | (i32.const 3) 15 | (br 0) 16 | ) 17 | ) 18 | (drop) 19 | ) 20 | 21 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 22 | (i32.const 0) 23 | ) 24 | 25 | (start 0) 26 | (memory (export "memory") 0 0) 27 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/link.txt: -------------------------------------------------------------------------------- 1 | block 2 | call 3 | call-indirect 4 | const 5 | div-overflow 6 | globals 7 | if-else 8 | locals 9 | loop 10 | math 11 | iops 12 | user 13 | return 14 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/locals.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (local i32 i32) 3 | (local.get 0) 4 | (i32.const 1) 5 | (i32.add) 6 | (local.set 0) 7 | (local.get 0) 8 | (local.set 1) 9 | (local.get 0) 10 | (i32.const 1) 11 | (i32.add) 12 | (local.set 1) 13 | (local.get 0) 14 | (local.get 1) 15 | (i32.add) 16 | (drop) 17 | ) 18 | 19 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 20 | (i32.const 0) 21 | ) 22 | 23 | (start 0) 24 | (memory (export "memory") 0 0) 25 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/loop.wat: -------------------------------------------------------------------------------- 1 | (func (local i32) 2 | (i32.const 0) 3 | (loop 4 | (i64.const 123) 5 | (local.get 0) 6 | (i32.add (i32.const 1)) 7 | (local.tee 0) 8 | (i32.ne (i32.const 10)) 9 | (br_if 0) 10 | (drop) 11 | ) 12 | (br_if 0) 13 | 14 | (block 15 | (i32.const 0) 16 | (loop (param i32) 17 | (br_if 1) 18 | (i64.const 123) 19 | (i32.const 1) 20 | (br 0) 21 | ) 22 | ) 23 | 24 | (i32.const 1) 25 | (loop 26 | (br 0) 27 | (unreachable) 28 | ) 29 | (unreachable) 30 | ) 31 | 32 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 33 | (i32.const 0) 34 | ) 35 | 36 | (start 0) 37 | (memory (export "memory") 0 0) 38 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/memory-grow.wat: -------------------------------------------------------------------------------- 1 | (memory 1) 2 | 3 | (data (i32.const 1) "\01\02") 4 | 5 | (func 6 | (i32.const 0) 7 | (i64.load) 8 | (drop) 9 | (i32.const 0) 10 | (i64.const 123) 11 | (i64.store) 12 | (i32.const 0) 13 | (i64.load) 14 | (drop) 15 | (memory.size) 16 | (drop) 17 | (i32.const 1) 18 | (memory.grow) 19 | (drop) 20 | (i32.const 1073741824) 21 | (memory.grow) 22 | (drop) 23 | (memory.size) 24 | (drop) 25 | (i32.const 100000) 26 | (i64.load) 27 | (drop) 28 | (i32.const 100000) 29 | (i64.const 0) 30 | (i64.store) 31 | ) 32 | 33 | (start 0) 34 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/no-stack-pollution.wat: -------------------------------------------------------------------------------- 1 | (import "env" "wavm_halt_and_set_finished" (func $wavm_halt_and_set_finished)) 2 | 3 | (func 4 | (i32.const 1) 5 | (block 6 | (block 7 | (i32.const 2) 8 | (br_table 0 0 1 0 0) 9 | (unreachable) 10 | ) 11 | (unreachable) 12 | ) 13 | (if (i32.eq (i32.const 1)) 14 | (then (call $wavm_halt_and_set_finished)) 15 | (else (unreachable)) 16 | ) 17 | ) 18 | 19 | (start 1) 20 | 21 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/read-inboxmsg-10.wat: -------------------------------------------------------------------------------- 1 | (import "wrapper" "set_globalstate_u64" (func $set (param i32) (param i64))) 2 | (import "wrapper" "get_globalstate_u64" (func $get (param i32) (result i64))) 3 | (import "wrapper" "read_inbox_message" (func $readinbox (param i64) (param i32) (param i32) (result i32))) 4 | (import "wrapper" "halt_and_set_finished" (func $halt)) 5 | 6 | (memory 1) 7 | 8 | (func $entry 9 | (i64.const 10) 10 | (i32.const 0) 11 | (i32.const 0) 12 | (call $readinbox) 13 | (drop) 14 | ;; halt 15 | (call $halt) 16 | ) 17 | 18 | (start $entry) -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/return.wat: -------------------------------------------------------------------------------- 1 | (func 2 | (i32.const 1) 3 | (call 1) 4 | (drop) 5 | ) 6 | 7 | (func (param i32) (result i32) 8 | (i32.const 5) 9 | (local.get 0) 10 | (if (param i32) (result i32) 11 | (then 12 | (i32.const 0) 13 | (call 1) 14 | (i32.add) 15 | ) 16 | (else 17 | (i32.const 10) 18 | (return) 19 | ) 20 | ) 21 | ) 22 | 23 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 24 | (i32.const 0) 25 | ) 26 | 27 | (start 0) 28 | (memory (export "memory") 0 0) 29 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-wasi" 3 | 4 | [target.wasm32-wasi] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | 9 | [unstable] 10 | build-std = ["core", "panic_abort", "alloc", "std"] 11 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test-cases" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [dependencies] 8 | digest = { version = "0.9.0", default-features = false } 9 | hex-literal = "0.3.4" 10 | num-bigint = { version = "0.4.4", default-features = false } 11 | sha2 = { version = "0.9.9", default-features = false } 12 | sha3 = { version = "0.9.1", default-features = false } 13 | 14 | [workspace] 15 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/data/msg0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/arbitrator/prover/test-cases/rust/data/msg0.bin -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/data/msg1.bin: -------------------------------------------------------------------------------- 1 |  2 |  -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/src/bin/basics.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut x: i32 = 100; 3 | if std::env::vars().count() == 0 { 4 | x = x.wrapping_add(1); 5 | } 6 | std::process::exit(x ^ 101) 7 | } 8 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/src/bin/keccak256.rs: -------------------------------------------------------------------------------- 1 | use sha3::Keccak256; 2 | use digest::Digest; 3 | 4 | fn main() { 5 | let mut hasher = Keccak256::new(); 6 | for i in 0..5 { 7 | hasher.update(&[i]); 8 | } 9 | let output: [u8; 32] = hasher.finalize().into(); 10 | std::process::exit(i32::from(output[0]) ^ 183); 11 | } 12 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/src/bin/pi.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // Compute π with Ramanujan's approximation 3 | 4 | macro_rules! compute { 5 | ($t:ty) => { 6 | let mut estimate = 0.; 7 | let multiplier = 2. * (2 as $t).sqrt() / 9801.; 8 | let mut fact = 1.; 9 | let mut quad_fact = 1.; 10 | let mut k = 0. as $t; 11 | while k <= 10. { 12 | let quad = k * 4.; 13 | if k > 0. { 14 | fact *= k; 15 | quad_fact *= quad - 3.; 16 | quad_fact *= quad - 2.; 17 | quad_fact *= quad - 1.; 18 | quad_fact *= quad; 19 | } 20 | let fact_square = fact * fact; 21 | estimate += multiplier * quad_fact * (1103. + 26390. * k) / (fact_square * fact_square * (396 as $t).powf(quad)); 22 | let pi = 1./estimate; 23 | println!("Estimation with {} after iteration {}: {}", stringify!($t), k, pi); 24 | assert!(pi.is_nan() || (pi > 3.13 && pi < 3.15)); 25 | k += 1.; 26 | } 27 | } 28 | } 29 | 30 | compute!(f32); 31 | compute!(f64); 32 | } 33 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/src/bin/stdlib.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut x = Vec::new(); 3 | for i in 1..10 { 4 | x.push(i); 5 | } 6 | let sum: usize = x.iter().cloned().sum(); 7 | let product = x.into_iter().fold(1, |p, x| p * x); 8 | println!("Sum: {}", sum); 9 | eprintln!("Product: {}", product); 10 | assert_eq!(sum, 45); 11 | assert_eq!(product, 362880); 12 | } 13 | -------------------------------------------------------------------------------- /arbitrator/prover/test-cases/rust/src/lib.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/arbitrator/prover/test-cases/rust/src/lib.rs -------------------------------------------------------------------------------- /arbitrator/stylus/cbindgen.toml: -------------------------------------------------------------------------------- 1 | language = "C" 2 | include_guard = "arbitrator_bindings" 3 | 4 | [parse] 5 | parse_deps = true 6 | include = ["arbutil", "prover", "brotli"] 7 | extra_bindings = ["arbutil", "prover", "brotli"] 8 | 9 | [enum] 10 | prefix_with_name = true 11 | 12 | [export] 13 | include = ["EvmApiMethod", "EvmApiStatus"] 14 | -------------------------------------------------------------------------------- /arbitrator/stylus/src/util.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use arbutil::crypto; 5 | use eyre::Report; 6 | 7 | /// This function panics while saving an offending wasm to disk. 8 | pub fn panic_with_wasm(wasm: &[u8], error: Report) -> ! { 9 | // save at a deterministic path 10 | let hash = hex::encode(crypto::keccak(wasm)); 11 | let mut path = std::env::temp_dir(); 12 | path.push(format!("stylus-panic-{hash}.wasm")); 13 | 14 | // try to save to disk, otherwise dump to the console 15 | if let Err(io_error) = std::fs::write(&path, wasm) { 16 | let wasm = hex::encode(wasm); 17 | panic!("failed to write fatal wasm {error:?}: {io_error:?}\nwasm: {wasm}"); 18 | } 19 | panic!("encountered fatal wasm: {error:?}"); 20 | } 21 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | "-C", "link-arg=-zstack-size=8192", 8 | "-C", "target-feature=-reference-types", 9 | # "-C", "link-arg=--export=__heap_base", 10 | # "-C", "link-arg=--export=__data_end", 11 | ] 12 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/add.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (memory 0 0) 6 | (export "memory" (memory 0)) 7 | (type $t0 (func (param i32) (result i32))) 8 | (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) 9 | get_local $p0 10 | i32.const 1 11 | i32.add) 12 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 13 | (i32.const 0) 14 | )) 15 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bad-mods/bad-export.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022-2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (global $status (export "stylus_ink_left") (mut i64) (i64.const -1))) 6 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bad-mods/bad-export2.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022-2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (func (export "stylus_global_with_random_name"))) 6 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bad-mods/bad-export3.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (func (export "memory"))) 6 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bad-mods/bad-export4.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (global (export "user_entrypoint") i32 (i32.const 0)) 6 | (memory (export "memory") 0 0) 7 | ) 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bad-mods/bad-import.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022-2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "env" "stylus_global_with_random_name" (func))) 6 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bf/.gitignore: -------------------------------------------------------------------------------- 1 | **.wat 2 | **.wasm 3 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bf/cat.b: -------------------------------------------------------------------------------- 1 | ,[.,] 2 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/bulk-memory-oob.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (func (export "fill") 6 | (memory.fill (i32.const 0xffff) (i32.const 0) (i32.const 2))) 7 | (func (export "copy_left") 8 | (memory.copy (i32.const 0xffff) (i32.const 0xfffe) (i32.const 2))) 9 | (func (export "copy_right") 10 | (memory.copy (i32.const 0xfffe) (i32.const 0xffff) (i32.const 2))) 11 | (func (export "copy_same") 12 | (memory.copy (i32.const 0xffff) (i32.const 0xffff) (i32.const 2))) 13 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 14 | (i32.const 0) 15 | ) 16 | (data (i32.const 0xfffe) "\01\02") ;; last two bytes shouldn't change 17 | (memory (export "memory") 1 1)) 18 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/clz.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022-2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (global $global (mut i64) (i64.const 32)) 6 | (func $start 7 | global.get $global 8 | i64.clz 9 | drop 10 | ) 11 | (start $start)) 12 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/create/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/create/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "create" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 8 | hex = "0.4.3" 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/create/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use stylus_sdk::{alloy_primitives::{B256, U256}, deploy::RawDeploy, evm, prelude::*}; 7 | 8 | #[entrypoint] 9 | fn user_main(input: Vec) -> Result, Vec> { 10 | let kind = input[0]; 11 | let mut input = &input[1..]; 12 | 13 | let endowment = U256::from_be_bytes::<32>(input[..32].try_into().unwrap()); 14 | input = &input[32..]; 15 | 16 | let mut salt = None; 17 | if kind == 2 { 18 | salt = Some(B256::try_from(&input[..32]).unwrap()); 19 | input = &input[32..]; 20 | } 21 | 22 | let code = input; 23 | let contract = unsafe { RawDeploy::new().salt_option(salt).deploy(code, endowment)? }; 24 | evm::raw_log(&[contract.into_word()], &[]).unwrap(); 25 | Ok(contract.to_vec()) 26 | } 27 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/depth.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "test" "noop" (func)) 6 | (memory 0 0) 7 | (export "memory" (memory 0)) 8 | (global $depth (export "depth") (mut i32) (i32.const 0)) 9 | (func $recurse (export "recurse") (param $ignored i64) (local f32 f64) 10 | local.get $ignored ;; push 1 -- 1 on stack 11 | global.get $depth ;; push 1 -- 2 on stack 12 | i32.const 1 ;; push 1 -- 3 on stack <- 3 words max 13 | i32.add ;; pop 2, push 1 -- 2 on stack 14 | global.set $depth ;; pop 1 -- 1 on stack 15 | call $recurse) 16 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 17 | (i32.const 0) 18 | )) 19 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/erc20/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "erc20" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk", features = ["reentrant"] } 10 | hex = "0.4.3" 11 | wee_alloc = "0.4.5" 12 | 13 | [features] 14 | export-abi = ["stylus-sdk/export-abi"] 15 | 16 | [profile.release] 17 | codegen-units = 1 18 | strip = true 19 | lto = true 20 | panic = "abort" 21 | opt-level = "s" 22 | 23 | [workspace] 24 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/evm-data/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/evm-data/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "evm-data" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk", features = ["debug"] } 8 | hex = "0.4.3" 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/exit-early/exit-early.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "exit_early" (func $exit (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 10 | ;; write args to offset 0 11 | (call $read_args (i32.const 0)) 12 | 13 | ;; set the args as the result 14 | (call $write_result (i32.const 0) (local.get $args_len)) 15 | 16 | ;; exit with the status code given by the first byte 17 | i32.const 0 18 | i32.load8_u 19 | call $exit 20 | 21 | ;; unreachable 22 | (i32.const 0xff) 23 | ) 24 | ) 25 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/exit-early/panic-after-write.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "exit_early" (func $exit (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 10 | ;; write args to offset 0 11 | (call $read_args (i32.const 0)) 12 | 13 | ;; set the args as the result 14 | (call $write_result (i32.const 0) (local.get $args_len)) 15 | 16 | ;; perform a hard revert (results should be discarded) 17 | unreachable 18 | ) 19 | ) 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/fallible/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/fallible/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fallible" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 8 | 9 | [profile.release] 10 | codegen-units = 1 11 | strip = true 12 | lto = true 13 | panic = "abort" 14 | 15 | # uncomment to optimize for size 16 | # opt-level = "z" 17 | 18 | [workspace] 19 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/fallible/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use stylus_sdk::stylus_proc::entrypoint; 7 | 8 | /// A program that will fail on certain inputs 9 | #[entrypoint] 10 | fn user_main(input: Vec) -> Result, Vec> { 11 | if input[0] == 0 { 12 | core::arch::wasm32::unreachable() 13 | } else { 14 | Ok(input) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/grow/fixed.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023-2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "console" "tee_i32" (func $tee_i32 (param i32) (result i32))) 6 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 7 | ;; fail to grow the memory a non-zero number of pages 8 | i32.const -65537 9 | call $tee_i32 10 | memory.grow 11 | call $tee_i32 12 | i32.const -1 13 | i32.eq 14 | i32.eqz 15 | (if (then unreachable)) 16 | 17 | ;; succeed growing 0 pages 18 | i32.const 0 19 | memory.grow 20 | call $tee_i32 21 | i32.eqz 22 | i32.eqz 23 | ) 24 | (memory (export "memory") 0 0) 25 | ) 26 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/grow/grow-120.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 6 | i32.const 0 7 | ) 8 | (memory (export "memory") 120 120) 9 | ) 10 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/hostio-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hostio-test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk", features = ["debug", "hostio"] } 8 | mini-alloc.path = "../../../langs/rust/mini-alloc" 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | opt-level = "s" 16 | 17 | [workspace] 18 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/keccak-100/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "keccak-100" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | sha3 = "0.10.5" 8 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/keccak-100/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use sha3::{Digest, Keccak256}; 7 | use stylus_sdk::stylus_proc::entrypoint; 8 | 9 | #[entrypoint] 10 | fn user_main(_: Vec) -> Result, Vec> { 11 | let mut data = [0; 32]; 12 | for _ in 0..100 { 13 | data = keccak(&data); 14 | } 15 | assert_ne!(data, [0; 32]); 16 | Ok(data.as_ref().into()) 17 | } 18 | 19 | fn keccak(preimage: &[u8]) -> [u8; 32] { 20 | let mut hasher = Keccak256::new(); 21 | hasher.update(preimage); 22 | hasher.finalize().into() 23 | } 24 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/keccak/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "keccak" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | sha3 = "0.10.5" 8 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/keccak/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use sha3::{Digest, Keccak256}; 7 | use stylus_sdk::{alloy_primitives, crypto, prelude::*}; 8 | 9 | #[entrypoint] 10 | fn user_main(input: Vec) -> Result, Vec> { 11 | let mut data = keccak(&input[1..]); 12 | let rounds = input[0]; 13 | for _ in 1..rounds { 14 | let hash = keccak(&data); 15 | assert_eq!(hash, crypto::keccak(data)); 16 | assert_eq!(hash, alloy_primitives::keccak256(data)); 17 | data = hash; 18 | } 19 | Ok(data.as_ref().into()) 20 | } 21 | 22 | fn keccak(preimage: &[u8]) -> [u8; 32] { 23 | let mut hasher = Keccak256::new(); 24 | hasher.update(preimage); 25 | hasher.finalize().into() 26 | } 27 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/log/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/log/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "log" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 8 | hex = "0.4.3" 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/log/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | #![no_main] 5 | 6 | use stylus_sdk::{alloy_primitives::B256, evm, prelude::*}; 7 | 8 | #[entrypoint] 9 | fn user_main(input: Vec) -> Result, Vec> { 10 | let num_topics = input[0]; 11 | let mut input = &input[1..]; 12 | 13 | let mut topics = vec![]; 14 | for _ in 0..num_topics { 15 | topics.push(B256::try_from(&input[..32]).unwrap()); 16 | input = &input[32..]; 17 | } 18 | evm::raw_log(&topics, input).unwrap(); 19 | Ok(vec![]) 20 | } 21 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/math/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "math" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk", features = ["debug"] } 8 | 9 | [profile.release] 10 | codegen-units = 1 11 | strip = true 12 | lto = true 13 | panic = "abort" 14 | 15 | # uncomment to optimize for size 16 | # opt-level = "z" 17 | 18 | [workspace] 19 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/memory2.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "pay_for_memory_grow" (func $pay_for_memory_grow (param i32))) 6 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 7 | (call $pay_for_memory_grow (i32.const 0)) 8 | (call $pay_for_memory_grow (i32.sub (i32.const 0) (i32.const 1))) 9 | i32.const 0 10 | ) 11 | (memory (export "memory") 0) 12 | ) 13 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/module-mod.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "test" "noop" (func)) 6 | (memory (export "memory") 0 0) 7 | (func (export "void")) 8 | (func (export "more") (param i32 i64) (result f32) 9 | unreachable)) 10 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/multicall/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/multicall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multicall" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | mini-alloc = "0.4.2" 10 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk", features = ["reentrant"] } 11 | hex = "0.4.3" 12 | wee_alloc = "0.4.5" 13 | 14 | [profile.release] 15 | codegen-units = 1 16 | strip = true 17 | lto = true 18 | panic = "abort" 19 | 20 | # uncomment to optimize for size 21 | # opt-level = "z" 22 | 23 | [workspace] 24 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/read-return-data/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/read-return-data/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "read-return-data" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 8 | hex = "0.4.3" 9 | 10 | [profile.release] 11 | codegen-units = 1 12 | strip = true 13 | lto = true 14 | panic = "abort" 15 | 16 | # uncomment to optimize for size 17 | # opt-level = "z" 18 | 19 | [workspace] 20 | 21 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/sdk-storage/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/sdk-storage/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sdk-storage" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk.path = "../../../langs/rust/stylus-sdk" 8 | mini-alloc.path = "../../../langs/rust/mini-alloc" 9 | hex = "0.4.3" 10 | wee_alloc = "0.4.5" 11 | 12 | [profile.release] 13 | codegen-units = 1 14 | strip = true 15 | lto = true 16 | panic = "abort" 17 | opt-level = "s" 18 | 19 | [workspace] 20 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/start.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (global $status (export "status") (mut i32) (i32.const 10)) 6 | (memory 0 0) 7 | (export "memory" (memory 0)) 8 | (type $void (func (param) (result))) 9 | (func $start (export "move_me") (type $void) 10 | get_global $status 11 | i32.const 1 12 | i32.add 13 | set_global $status ;; increment the global 14 | ) 15 | (func (export "user_entrypoint") (param $args_len i32) (result i32) 16 | (i32.const 0) 17 | ) 18 | (start $start)) 19 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/storage/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.wasm32-unknown-unknown] 5 | rustflags = [ 6 | "-C", "target-cpu=mvp", 7 | ] 8 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/storage/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "storage" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | stylus-sdk = { path = "../../../langs/rust/stylus-sdk" } 8 | 9 | [profile.release] 10 | codegen-units = 1 11 | strip = true 12 | lto = true 13 | panic = "abort" 14 | 15 | [workspace] 16 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/test.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2022, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (func (export "test__noop"))) 6 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/block_basefee.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "block_basefee" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/block_coinbase.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "block_coinbase" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/block_gas_limit.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "block_gas_limit" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/block_number.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "block_number" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/block_timestamp.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "block_timestamp" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/chainid.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "chainid" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/contract_address.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "contract_address" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/evm_gas_left.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "evm_gas_left" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/evm_ink_left.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "evm_ink_left" (func $test (result i64))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/keccak.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "native_keccak256" (func $test (param i32 i32 i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | (call $test (i32.const 0) (local.get $args_len) (i32.const 0)) 23 | 24 | ;; decrement and loop 25 | (i32.sub (local.get $i) (i32.const 1)) 26 | local.tee $i 27 | i32.const 0 28 | i32.ne 29 | br_if 0 30 | ) 31 | 32 | ;; return success 33 | i32.const 0 34 | ) 35 | ) 36 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/msg_sender.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "msg_sender" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/msg_value.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "msg_value" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/null_host.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "debug" "null_host" (func $test)) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | 24 | ;; decrement and loop 25 | (i32.sub (local.get $i) (i32.const 1)) 26 | local.tee $i 27 | i32.const 0 28 | i32.ne 29 | br_if 0 30 | ) 31 | 32 | ;; return success 33 | i32.const 0 34 | ) 35 | ) 36 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/read_args.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (memory (export "memory") 1 1) 8 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 9 | (local $i i32) 10 | 11 | ;; write args to 0x0 12 | i32.const 0 13 | call $read_args 14 | 15 | ;; treat first 4 bytes as # of iterations 16 | (i32.load (i32.const 0)) 17 | local.set $i 18 | 19 | (loop 20 | ;; call the test function 21 | (call $read_args (i32.const 0)) 22 | 23 | ;; decrement and loop 24 | (i32.sub (local.get $i) (i32.const 1)) 25 | local.tee $i 26 | i32.const 1 ;; skip the first 27 | i32.ne 28 | br_if 0 29 | ) 30 | 31 | ;; return success 32 | i32.const 0 33 | ) 34 | ) 35 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/return_data_size.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "return_data_size" (func $test (result i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/tx_gas_price.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "tx_gas_price" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/tx_ink_price.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "tx_ink_price" (func $test (result i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | call $test 23 | drop 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/tx_origin.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (import "vm_hooks" "tx_origin" (func $test (param i32))) 8 | (memory (export "memory") 1 1) 9 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 10 | (local $i i32) 11 | 12 | ;; write args to 0x0 13 | i32.const 0 14 | call $read_args 15 | 16 | ;; treat first 4 bytes as # of iterations 17 | (i32.load (i32.const 0)) 18 | local.set $i 19 | 20 | (loop 21 | ;; call the test function 22 | i32.const 0 23 | call $test 24 | 25 | ;; decrement and loop 26 | (i32.sub (local.get $i) (i32.const 1)) 27 | local.tee $i 28 | i32.const 0 29 | i32.ne 30 | br_if 0 31 | ) 32 | 33 | ;; return success 34 | i32.const 0 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/timings/write_result.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2023, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (memory (export "memory") 1 1) 8 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 9 | (local $i i32) 10 | 11 | ;; write args to 0x0 12 | i32.const 0 13 | call $read_args 14 | 15 | ;; treat first 4 bytes as # of iterations 16 | (i32.load (i32.const 0)) 17 | local.set $i 18 | 19 | (loop 20 | ;; call the test function 21 | (call $write_result (i32.const 0) (local.get $args_len)) 22 | 23 | ;; decrement and loop 24 | (i32.sub (local.get $i) (i32.const 1)) 25 | local.tee $i 26 | i32.const 1 ;; skip the last 27 | i32.ne 28 | br_if 0 29 | ) 30 | 31 | ;; return success 32 | i32.const 0 33 | ) 34 | ) 35 | -------------------------------------------------------------------------------- /arbitrator/stylus/tests/write-result-len.wat: -------------------------------------------------------------------------------- 1 | ;; Copyright 2024, Offchain Labs, Inc. 2 | ;; For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | (module 5 | (import "vm_hooks" "read_args" (func $read_args (param i32))) 6 | (import "vm_hooks" "write_result" (func $write_result (param i32 i32))) 7 | (memory (export "memory") 2 2) 8 | (func $main (export "user_entrypoint") (param $args_len i32) (result i32) 9 | (local $len i32) 10 | 11 | ;; write args to 0x0 12 | (call $read_args (i32.const 0)) 13 | 14 | ;; treat first 4 bytes as size to write 15 | (i32.load (i32.const 0)) 16 | local.set $len 17 | 18 | ;; call write 19 | (call $write_result (i32.const 0) (local.get $len)) 20 | 21 | ;; return success 22 | i32.const 0 23 | ) 24 | ) 25 | -------------------------------------------------------------------------------- /arbitrator/tools/module_roots/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "module_roots" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | arbutil = { path = "../../arbutil/" } 8 | prover = { path = "../../prover/" } 9 | eyre = "0.6.5" 10 | structopt = "0.3.23" 11 | 12 | [workspace] 13 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stylus_benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | eyre = "0.6.12" 8 | jit = { path = "../../jit/" } 9 | wasmer = { path = "../wasmer/lib/api/" } 10 | wasmer-compiler-cranelift = { path = "../wasmer/lib/compiler-cranelift/" } 11 | arbutil = { path = "../../arbutil/" } 12 | prover = { path = "../../prover/", default-features = false, features = ["native"] } 13 | stylus = { path = "../../stylus/", default-features = false } 14 | clap = { version = "4.4.8", features = ["derive"] } 15 | strum = "0.26" 16 | strum_macros = "0.26" 17 | rand = "0.8.5" 18 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/br.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_wat_ops(wat: &mut Vec, number_of_ops_per_loop_iteration: usize) { 7 | for _ in 0..number_of_ops_per_loop_iteration { 8 | wat.write_all(b" (block\n").unwrap(); 9 | wat.write_all(b" (block \n").unwrap(); 10 | wat.write_all(b" (block \n").unwrap(); 11 | wat.write_all(b" br 2\n").unwrap(); // it will jump to the end of the first block 12 | wat.write_all(b" )\n").unwrap(); 13 | wat.write_all(b" )\n").unwrap(); 14 | wat.write_all(b" )\n").unwrap(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/br_if.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_wat_ops(wat: &mut Vec, number_of_ops_per_loop_iteration: usize) { 7 | for _ in 0..number_of_ops_per_loop_iteration { 8 | wat.write_all(b" (block\n").unwrap(); 9 | wat.write_all(b" (block \n").unwrap(); 10 | wat.write_all(b" (block \n").unwrap(); 11 | wat.write_all(b" i32.const 1\n") 12 | .unwrap(); 13 | wat.write_all(b" br_if 2\n").unwrap(); // it will jump to the end of the first block 14 | wat.write_all(b" )\n").unwrap(); 15 | wat.write_all(b" )\n").unwrap(); 16 | wat.write_all(b" )\n").unwrap(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/call.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_wat_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (func $nop nop)\n").unwrap(); 8 | } 9 | 10 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 11 | for _ in 0..number_of_loop_iterations { 12 | wat.write_all(b" call $nop\n").unwrap(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/call_indirect.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_wat_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (type $nop_func_type (func))\n") 8 | .unwrap(); 9 | wat.write_all(b" (func $nop nop)\n").unwrap(); 10 | wat.write_all(b" (table 1 funcref)\n").unwrap(); 11 | wat.write_all(b" (elem (i32.const 0) $nop)\n") 12 | .unwrap(); 13 | } 14 | 15 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 16 | for _ in 0..number_of_loop_iterations { 17 | wat.write_all(b" i32.const 0\n").unwrap(); 18 | wat.write_all(b" call_indirect (type $nop_func_type)\n") 19 | .unwrap(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/convert.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops( 8 | wat: &mut Vec, 9 | number_of_ops_per_loop_iteration: usize, 10 | source_data_type: DataType, 11 | dest_data_type: DataType, 12 | instruction: &str, 13 | ) { 14 | for _ in 0..number_of_ops_per_loop_iteration { 15 | wat.write_all( 16 | format!( 17 | " {}.const {}\n", 18 | source_data_type, 19 | DataType::I32.gen() 20 | ) 21 | .as_bytes(), 22 | ) 23 | .unwrap(); 24 | wat.write_all(format!(" {}.{}\n", dest_data_type, instruction).as_bytes()) 25 | .unwrap(); 26 | wat.write_all(b" drop\n").unwrap(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/data_type.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use rand::Rng; 5 | use strum_macros::{Display, EnumString}; 6 | 7 | #[derive(Debug, Display, EnumString)] 8 | #[strum(serialize_all = "lowercase")] 9 | pub enum DataType { 10 | I32, 11 | I64, 12 | } 13 | 14 | pub trait Rand { 15 | fn gen(&self) -> usize; 16 | } 17 | 18 | impl Rand for DataType { 19 | fn gen(&self) -> usize { 20 | let mut rng = rand::thread_rng(); 21 | match self { 22 | DataType::I32 => rng.gen_range(0..i32::MAX).try_into().unwrap(), 23 | DataType::I64 => rng.gen_range(0..i64::MAX).try_into().unwrap(), 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/global_get.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_wat_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (global $var i32 (i32.const 10))\n") 8 | .unwrap(); 9 | } 10 | 11 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 12 | for _ in 0..number_of_loop_iterations { 13 | wat.write_all(b" global.get $var\n").unwrap(); 14 | wat.write_all(b" drop\n").unwrap(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/global_set.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_wat_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (global $var (mut i32) (i32.const 0))\n") 8 | .unwrap(); 9 | } 10 | 11 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 12 | for _ in 0..number_of_loop_iterations { 13 | wat.write_all(b" i32.const 10\n").unwrap(); 14 | wat.write_all(b" global.set $var\n").unwrap(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/if_op.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_wat_ops(wat: &mut Vec, number_of_ops_per_loop_iteration: usize) { 7 | for _ in 0..number_of_ops_per_loop_iteration { 8 | wat.write_all(b" i32.const 0\n").unwrap(); 9 | wat.write_all(b" (if\n").unwrap(); 10 | wat.write_all(b" (then\n").unwrap(); 11 | wat.write_all(b" nop\n").unwrap(); 12 | wat.write_all(b" )\n").unwrap(); 13 | wat.write_all(b" )\n").unwrap(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/instruction_with_1_arg_1_return.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops( 8 | wat: &mut Vec, 9 | number_of_ops_per_loop_iteration: usize, 10 | data_type: DataType, 11 | instruction: &str, 12 | ) { 13 | for _ in 0..number_of_ops_per_loop_iteration { 14 | wat.write_all(format!(" {}.const {}\n", data_type, data_type.gen()).as_bytes()) 15 | .unwrap(); 16 | wat.write_all(format!(" {}.{}\n", data_type, instruction).as_bytes()) 17 | .unwrap(); 18 | wat.write_all(b" drop\n").unwrap(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/instruction_with_2_args_1_return.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops( 8 | wat: &mut Vec, 9 | number_of_ops_per_loop_iteration: usize, 10 | data_type: DataType, 11 | instruction: &str, 12 | ) { 13 | for _ in 0..number_of_ops_per_loop_iteration { 14 | wat.write_all(format!(" {}.const {}\n", data_type, data_type.gen()).as_bytes()) 15 | .unwrap(); 16 | wat.write_all(format!(" {}.const {}\n", data_type, data_type.gen()).as_bytes()) 17 | .unwrap(); 18 | wat.write_all(format!(" {}.{}\n", data_type, instruction).as_bytes()) 19 | .unwrap(); 20 | wat.write_all(b" drop\n").unwrap(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/load.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::DataType; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops( 8 | wat: &mut Vec, 9 | number_of_ops_per_loop_iteration: usize, 10 | data_type: DataType, 11 | ) { 12 | for _ in 0..number_of_ops_per_loop_iteration { 13 | wat.write_all(format!(" i32.const 0\n").as_bytes()) 14 | .unwrap(); 15 | wat.write_all(format!(" {}.load\n", data_type).as_bytes()) 16 | .unwrap(); 17 | wat.write_all(b" drop\n").unwrap(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/local_get.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_exported_func_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (local $var i32)\n").unwrap(); 8 | wat.write_all(b" (local.set $var (i32.const 10))\n") 9 | .unwrap(); 10 | } 11 | 12 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 13 | for _ in 0..number_of_loop_iterations { 14 | wat.write_all(b" local.get $var\n").unwrap(); 15 | wat.write_all(b" drop\n").unwrap(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/local_set.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_specific_exported_func_beginning(wat: &mut Vec) { 8 | wat.write_all(b" (local $var i32)\n").unwrap(); 9 | } 10 | 11 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 12 | for _ in 0..number_of_loop_iterations { 13 | wat.write_all( 14 | format!( 15 | " (local.set $var (i32.const {}))\n", 16 | DataType::I32.gen() 17 | ) 18 | .as_bytes(), 19 | ) 20 | .unwrap(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/local_tee.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use std::io::Write; 5 | 6 | pub fn write_specific_exported_func_beginning(wat: &mut Vec) { 7 | wat.write_all(b" (local $var i32)\n").unwrap(); 8 | } 9 | 10 | pub fn write_wat_ops(wat: &mut Vec, number_of_loop_iterations: usize) { 11 | wat.write_all(b" (i32.const 1073741823)\n") 12 | .unwrap(); 13 | for _ in 0..number_of_loop_iterations { 14 | wat.write_all(b" local.tee $var\n").unwrap(); 15 | } 16 | wat.write_all(b" drop\n").unwrap(); 17 | } 18 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | pub mod br; 5 | pub mod br_if; 6 | pub mod br_table; 7 | pub mod call; 8 | pub mod call_indirect; 9 | pub mod convert; 10 | pub mod data_type; 11 | pub mod global_get; 12 | pub mod global_set; 13 | pub mod if_op; 14 | pub mod instruction_with_1_arg_1_return; 15 | pub mod instruction_with_2_args_1_return; 16 | pub mod load; 17 | pub mod local_get; 18 | pub mod local_set; 19 | pub mod local_tee; 20 | pub mod select; 21 | pub mod store; 22 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/select.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops(wat: &mut Vec, number_of_ops_per_loop_iteration: usize) { 8 | for _ in 0..number_of_ops_per_loop_iteration { 9 | wat.write_all(format!(" i32.const {}\n", DataType::I32.gen()).as_bytes()) 10 | .unwrap(); 11 | wat.write_all(format!(" i32.const {}\n", DataType::I32.gen()).as_bytes()) 12 | .unwrap(); 13 | wat.write_all(b" i32.const 0\n").unwrap(); 14 | wat.write_all(b" select\n").unwrap(); 15 | wat.write_all(b" drop\n").unwrap(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /arbitrator/tools/stylus_benchmark/src/scenarios/store.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::scenarios::data_type::{DataType, Rand}; 5 | use std::io::Write; 6 | 7 | pub fn write_wat_ops( 8 | wat: &mut Vec, 9 | number_of_ops_per_loop_iteration: usize, 10 | data_type: DataType, 11 | ) { 12 | for _ in 0..number_of_ops_per_loop_iteration { 13 | wat.write_all(format!(" i32.const 0\n").as_bytes()) 14 | .unwrap(); 15 | wat.write_all(format!(" {}.const {}\n", data_type, data_type.gen()).as_bytes()) 16 | .unwrap(); 17 | wat.write_all(format!(" {}.store\n", data_type).as_bytes()) 18 | .unwrap(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.wasm32-unknown-unknown] 2 | rustflags = [ 3 | "-C", "target-cpu=mvp", 4 | ] 5 | 6 | [target.wasm32-wasi] 7 | rustflags = [ 8 | "-C", "target-cpu=mvp", 9 | ] 10 | 11 | [unstable] 12 | build-std = ["core", "panic_abort", "alloc", "std"] 13 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "arbcompress", 4 | "wasi-stub", 5 | "host-io", 6 | "user-host", 7 | "user-host-trait", 8 | "user-test", 9 | "program-exec", 10 | "forward", 11 | ] 12 | resolver = "2" 13 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/arbcompress/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arbcompress" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | brotli.path = "../../brotli" 12 | caller-env = { path = "../../caller-env/", features = ["static_caller"] } 13 | paste = "1.0.14" 14 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/arbcompress/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | fn main() { 5 | // Tell Cargo that if the given file changes, to rerun this build script. 6 | println!("cargo:rustc-link-search=../../target/lib-wasm/"); 7 | println!("cargo:rustc-link-search=../target/lib/"); 8 | println!("cargo:rustc-link-lib=static=brotlienc-static"); 9 | println!("cargo:rustc-link-lib=static=brotlidec-static"); 10 | println!("cargo:rustc-link-lib=static=brotlicommon-static"); 11 | } 12 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/forward/.gitignore: -------------------------------------------------------------------------------- 1 | **.wat 2 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/forward/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forward" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | eyre = "0.6.5" 8 | structopt = "0.3.26" 9 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/host-io/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "host-io" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | arbutil = { path = "../../arbutil/" } 12 | caller-env = { path = "../../caller-env/", default-features = false, features = ["static_caller"] } 13 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/program-exec/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "program-exec" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-host-trait/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "user-host-trait" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | arbutil = { path = "../../arbutil/" } 8 | caller-env = { path = "../../caller-env/" } 9 | prover = { path = "../../prover/", default-features = false } 10 | eyre = "0.6.5" 11 | ruint2 = "1.9.0" 12 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-host/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "user-host" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | arbutil = { path = "../../arbutil/" } 11 | caller-env = { path = "../../caller-env/", features = ["static_caller"] } 12 | prover = { path = "../../prover/", default-features = false } 13 | user-host-trait = { path = "../user-host-trait" } 14 | wasmer-types = { path = "../../tools/wasmer/lib/types" } 15 | eyre = "0.6.5" 16 | fnv = "1.0.7" 17 | hex = "0.4.3" 18 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-host/src/ink.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::program::Program; 5 | use arbutil::evm::api::Ink; 6 | use prover::programs::{ 7 | config::PricingParams, 8 | prelude::{GasMeteredMachine, MachineMeter, MeteredMachine}, 9 | }; 10 | 11 | #[link(wasm_import_module = "hostio")] 12 | extern "C" { 13 | fn user_ink_left() -> u64; 14 | fn user_ink_status() -> u32; 15 | fn user_set_ink(ink: u64, status: u32); 16 | } 17 | 18 | impl MeteredMachine for Program { 19 | fn ink_left(&self) -> MachineMeter { 20 | unsafe { 21 | match user_ink_status() { 22 | 0 => MachineMeter::Ready(Ink(user_ink_left())), 23 | _ => MachineMeter::Exhausted, 24 | } 25 | } 26 | } 27 | 28 | fn set_meter(&mut self, meter: MachineMeter) { 29 | unsafe { 30 | user_set_ink(meter.ink().0, meter.status()); 31 | } 32 | } 33 | } 34 | 35 | impl GasMeteredMachine for Program { 36 | fn pricing(&self) -> PricingParams { 37 | self.config.pricing 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-host/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | mod host; 5 | mod ink; 6 | mod link; 7 | mod program; 8 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "user-test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | arbutil = { path = "../../arbutil/" } 11 | caller-env = { path = "../../caller-env/", features = ["static_caller"] } 12 | prover = { path = "../../prover/", default-features = false } 13 | user-host-trait = { path = "../user-host-trait" } 14 | eyre = "0.6.5" 15 | fnv = "1.0.7" 16 | hex = "0.4.3" 17 | lazy_static = "1.4.0" 18 | parking_lot = "0.12.1" 19 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/user-test/src/ink.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | use crate::{program::Program, CONFIG}; 5 | use arbutil::evm::api::Ink; 6 | use prover::programs::{ 7 | config::PricingParams, 8 | prelude::{GasMeteredMachine, MachineMeter, MeteredMachine}, 9 | }; 10 | 11 | #[link(wasm_import_module = "hostio")] 12 | extern "C" { 13 | fn user_ink_left() -> u64; 14 | fn user_ink_status() -> u32; 15 | fn user_set_ink(ink: u64, status: u32); 16 | } 17 | 18 | impl MeteredMachine for Program { 19 | fn ink_left(&self) -> MachineMeter { 20 | unsafe { 21 | match user_ink_status() { 22 | 0 => MachineMeter::Ready(Ink(user_ink_left())), 23 | _ => MachineMeter::Exhausted, 24 | } 25 | } 26 | } 27 | 28 | fn set_meter(&mut self, meter: MachineMeter) { 29 | unsafe { 30 | user_set_ink(meter.ink().0, meter.status()); 31 | } 32 | } 33 | } 34 | 35 | impl GasMeteredMachine for Program { 36 | fn pricing(&self) -> PricingParams { 37 | unsafe { CONFIG.unwrap().pricing } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /arbitrator/wasm-libraries/wasi-stub/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasi-stub" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | paste = { version = "1.0.14" } 12 | caller-env = { path = "../../caller-env/", default-features = false, features = ["static_caller"] } 13 | wee_alloc = "0.4.2" 14 | -------------------------------------------------------------------------------- /arbitrator/wasm-testsuite/.gitignore: -------------------------------------------------------------------------------- 1 | tests/* 2 | -------------------------------------------------------------------------------- /arbitrator/wasm-testsuite/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm-testsuite" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | arbutil = { path = "../arbutil" } 10 | prover = { path = "../prover" } 11 | structopt = "0.3.23" 12 | serde = { version = "1.0.130", features = ["derive", "rc"] } 13 | serde_json = "1.0.67" 14 | eyre = "0.6.5" 15 | hex = "0.4.3" 16 | 17 | [workspace] 18 | members = [] 19 | -------------------------------------------------------------------------------- /arbitrator/wasm-testsuite/check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | # Copyright 2022, Offchain Labs, Inc. 4 | # For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 5 | 6 | rm -rf tests ../../contracts/test/prover/spec-proofs 7 | mkdir -p tests/ 8 | mkdir -p ../../contracts/test/prover/spec-proofs/ 9 | 10 | for file in testsuite/*wast; do 11 | wast="${file##testsuite/}" 12 | json="tests/${wast%.wast}.json" 13 | wast2json $file -o $json 2>/dev/null 14 | done 15 | 16 | cargo build --release 17 | 18 | for file in tests/*.json; do 19 | base="${file#tests/}" 20 | name="${base%.wasm}" 21 | nice target/release/wasm-testsuite $name & 22 | done 23 | 24 | wait 25 | -------------------------------------------------------------------------------- /arbnode/dataposter/noop/storage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | package noop 4 | 5 | import ( 6 | "context" 7 | 8 | "github.com/offchainlabs/nitro/arbnode/dataposter/storage" 9 | ) 10 | 11 | // Storage implements noop storage for dataposter. This is for clients that want 12 | // to have option to directly post to geth without keeping state. 13 | type Storage struct{} 14 | 15 | func (s *Storage) FetchContents(_ context.Context, _, _ uint64) ([]*storage.QueuedTransaction, error) { 16 | return nil, nil 17 | } 18 | 19 | func (s *Storage) Get(_ context.Context, _ uint64) (*storage.QueuedTransaction, error) { 20 | return nil, nil 21 | } 22 | 23 | func (s *Storage) FetchLast(ctx context.Context) (*storage.QueuedTransaction, error) { 24 | return nil, nil 25 | } 26 | 27 | func (s *Storage) Prune(_ context.Context, _ uint64) error { 28 | return nil 29 | } 30 | 31 | func (s *Storage) Put(_ context.Context, _ uint64, _, _ *storage.QueuedTransaction) error { 32 | return nil 33 | } 34 | 35 | func (s *Storage) Length(context.Context) (int, error) { 36 | return 0, nil 37 | } 38 | 39 | func (s *Storage) IsPersistent() bool { 40 | return false 41 | } 42 | -------------------------------------------------------------------------------- /arbnode/dataposter/testdata/regenerate-certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | cd "$(dirname "$0")" 4 | for name in localhost client; do 5 | openssl genrsa -out "$name.key" 2048 6 | csr="$(openssl req -new -key "$name.key" -config "$name.cnf" -batch)" 7 | openssl x509 -req -signkey "$name.key" -out "$name.crt" -days 36500 -extensions req_ext -extfile "$name.cnf" <<< "$csr" 8 | done 9 | -------------------------------------------------------------------------------- /arbos/arbosState/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbosState 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | -------------------------------------------------------------------------------- /arbos/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbos 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | -------------------------------------------------------------------------------- /arbos/l1pricing/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package l1pricing 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | -------------------------------------------------------------------------------- /arbos/l1pricing/l1pricing_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package l1pricing 5 | 6 | import ( 7 | "math/big" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/params" 12 | 13 | "github.com/offchainlabs/nitro/arbos/burn" 14 | "github.com/offchainlabs/nitro/arbos/storage" 15 | ) 16 | 17 | func TestL1PriceUpdate(t *testing.T) { 18 | sto := storage.NewMemoryBacked(burn.NewSystemBurner(nil, false)) 19 | initialPriceEstimate := big.NewInt(123 * params.GWei) 20 | err := InitializeL1PricingState(sto, common.Address{}, initialPriceEstimate) 21 | Require(t, err) 22 | ps := OpenL1PricingState(sto) 23 | 24 | tyme, err := ps.LastUpdateTime() 25 | Require(t, err) 26 | if tyme != 0 { 27 | Fail(t) 28 | } 29 | 30 | priceEstimate, err := ps.PricePerUnit() 31 | Require(t, err) 32 | if priceEstimate.Cmp(initialPriceEstimate) != 0 { 33 | Fail(t) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /arbutil/block_message_relation.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | // messages are 0-indexed 7 | type MessageIndex uint64 8 | 9 | func BlockNumberToMessageCount(blockNumber uint64, genesisBlockNumber uint64) MessageIndex { 10 | return MessageIndex(blockNumber + 1 - genesisBlockNumber) 11 | } 12 | 13 | func MessageCountToBlockNumber(messageCount MessageIndex, genesisBlockNumber uint64) int64 { 14 | // #nosec G115 15 | return int64(uint64(messageCount)+genesisBlockNumber) - 1 16 | } 17 | -------------------------------------------------------------------------------- /arbutil/correspondingl1blocknumber.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "math/big" 10 | 11 | "github.com/ethereum/go-ethereum/core/types" 12 | ) 13 | 14 | func ParentHeaderToL1BlockNumber(header *types.Header) uint64 { 15 | headerInfo := types.DeserializeHeaderExtraInformation(header) 16 | if headerInfo.ArbOSFormatVersion > 0 { 17 | return headerInfo.L1BlockNumber 18 | } 19 | return header.Number.Uint64() 20 | } 21 | 22 | type ParentHeaderFetcher interface { 23 | HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) 24 | } 25 | 26 | func CorrespondingL1BlockNumber(ctx context.Context, client ParentHeaderFetcher, parentBlockNumber uint64) (uint64, error) { 27 | // #nosec G115 28 | header, err := client.HeaderByNumber(ctx, big.NewInt(int64(parentBlockNumber))) 29 | if err != nil { 30 | return 0, fmt.Errorf("error getting L1 block number %d header : %w", parentBlockNumber, err) 31 | } 32 | return ParentHeaderToL1BlockNumber(header), nil 33 | } 34 | -------------------------------------------------------------------------------- /arbutil/finality_data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2025, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | import "github.com/ethereum/go-ethereum/common" 7 | 8 | type FinalityData struct { 9 | MsgIdx MessageIndex 10 | BlockHash common.Hash 11 | } 12 | -------------------------------------------------------------------------------- /arbutil/format.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | import ( 7 | "encoding/hex" 8 | "unicode/utf8" 9 | ) 10 | 11 | func ToStringOrHex(input []byte) string { 12 | if input == nil { 13 | return "" 14 | } 15 | if utf8.Valid(input) { 16 | return string(input) 17 | } 18 | return hex.EncodeToString(input) 19 | } 20 | -------------------------------------------------------------------------------- /arbutil/hash.go: -------------------------------------------------------------------------------- 1 | package arbutil 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/crypto" 8 | ) 9 | 10 | // PaddedKeccak256 pads each argument to 32 bytes, concatenates and returns 11 | // keccak256 hash of the result. 12 | func PaddedKeccak256(args ...[]byte) []byte { 13 | var data []byte 14 | for _, arg := range args { 15 | data = append(data, common.BytesToHash(arg).Bytes()...) 16 | } 17 | return crypto.Keccak256(data) 18 | } 19 | 20 | // SumBytes sums two byte slices and returns the result. 21 | // If the sum of bytes are over 32 bytes, it return last 32. 22 | func SumBytes(a, b []byte) []byte { 23 | A := big.NewInt(0).SetBytes(a) 24 | B := big.NewInt(0).SetBytes(b) 25 | return common.BytesToHash((A.Add(A, B)).Bytes()).Bytes() 26 | } 27 | -------------------------------------------------------------------------------- /arbutil/preimage_type.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | type PreimageType uint8 7 | 8 | // These values must be kept in sync with `arbitrator/arbutil/src/types.rs`, 9 | // and the if statement in `contracts/src/osp/OneStepProverHostIo.sol` (search for "UNKNOWN_PREIMAGE_TYPE"). 10 | const ( 11 | Keccak256PreimageType PreimageType = iota 12 | Sha2_256PreimageType 13 | EthVersionedHashPreimageType 14 | ) 15 | -------------------------------------------------------------------------------- /arbutil/transaction_data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | "github.com/ethereum/go-ethereum/core/types" 11 | "github.com/ethereum/go-ethereum/ethclient" 12 | ) 13 | 14 | func GetLogTransaction(ctx context.Context, client *ethclient.Client, log types.Log) (*types.Transaction, error) { 15 | tx, err := client.TransactionInBlock(ctx, log.BlockHash, log.TxIndex) 16 | if err != nil { 17 | return nil, err 18 | } 19 | if tx.Hash() != log.TxHash { 20 | return nil, fmt.Errorf("L1 client returned unexpected transaction hash %v when looking up block %v transaction %v with expected hash %v", tx.Hash(), log.BlockHash, log.TxIndex, log.TxHash) 21 | } 22 | return tx, nil 23 | } 24 | 25 | // GetLogEmitterTxData requires that the tx's data is at least 4 bytes long 26 | func GetLogEmitterTxData(ctx context.Context, client *ethclient.Client, log types.Log) ([]byte, error) { 27 | tx, err := GetLogTransaction(ctx, client, log) 28 | if err != nil { 29 | return nil, err 30 | } 31 | if len(tx.Data()) < 4 { 32 | return nil, fmt.Errorf("log emitting transaction %v unexpectedly does not have enough data", tx.Hash()) 33 | } 34 | return tx.Data(), nil 35 | } 36 | -------------------------------------------------------------------------------- /arbutil/unsafe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbutil 5 | 6 | import "unsafe" 7 | 8 | func SliceToPointer[T any](slice []T) *T { 9 | if len(slice) == 0 { 10 | return nil 11 | } 12 | return &slice[0] 13 | } 14 | 15 | func SliceToUnsafePointer[T any](slice []T) unsafe.Pointer { 16 | return unsafe.Pointer(SliceToPointer(slice)) 17 | } 18 | 19 | // does a defensive copy due to Go's lake of immutable types 20 | func PointerToSlice[T any](pointer *T, length int) []T { 21 | return CopySlice(unsafe.Slice(pointer, length)) 22 | } 23 | 24 | func CopySlice[T any](slice []T) []T { 25 | output := make([]T, len(slice)) 26 | copy(output, slice) 27 | return output 28 | } 29 | -------------------------------------------------------------------------------- /broadcaster/backlog/config.go: -------------------------------------------------------------------------------- 1 | package backlog 2 | 3 | import ( 4 | flag "github.com/spf13/pflag" 5 | ) 6 | 7 | type ConfigFetcher func() *Config 8 | 9 | type Config struct { 10 | SegmentLimit int `koanf:"segment-limit" reload:"hot"` 11 | } 12 | 13 | func AddOptions(prefix string, f *flag.FlagSet) { 14 | f.Int(prefix+".segment-limit", DefaultConfig.SegmentLimit, "the maximum number of messages each segment within the backlog can contain") 15 | } 16 | 17 | var ( 18 | DefaultConfig = Config{ 19 | SegmentLimit: 240, 20 | } 21 | DefaultTestConfig = Config{ 22 | SegmentLimit: 3, 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /broadcaster/message/message_test_utils.go: -------------------------------------------------------------------------------- 1 | package message 2 | 3 | import ( 4 | "github.com/offchainlabs/nitro/arbos/arbostypes" 5 | "github.com/offchainlabs/nitro/arbutil" 6 | ) 7 | 8 | func CreateDummyBroadcastMessage(seqNums []arbutil.MessageIndex) *BroadcastMessage { 9 | return &BroadcastMessage{ 10 | Messages: CreateDummyBroadcastMessages(seqNums), 11 | } 12 | } 13 | 14 | func CreateDummyBroadcastMessages(seqNums []arbutil.MessageIndex) []*BroadcastFeedMessage { 15 | return CreateDummyBroadcastMessagesImpl(seqNums, len(seqNums)) 16 | } 17 | 18 | func CreateDummyBroadcastMessagesImpl(seqNums []arbutil.MessageIndex, length int) []*BroadcastFeedMessage { 19 | broadcastMessages := make([]*BroadcastFeedMessage, 0, length) 20 | for _, seqNum := range seqNums { 21 | broadcastMessage := &BroadcastFeedMessage{ 22 | SequenceNumber: seqNum, 23 | Message: arbostypes.EmptyTestMessageWithMetadata, 24 | } 25 | broadcastMessages = append(broadcastMessages, broadcastMessage) 26 | } 27 | 28 | return broadcastMessages 29 | } 30 | -------------------------------------------------------------------------------- /cmd/chaininfo/chain_defaults_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package chaininfo 5 | 6 | import ( 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | func TestDefaultChainConfigsCopyCorrectly(t *testing.T) { 12 | for _, chainName := range []string{"arb1", "nova", "goerli-rollup", "arb-dev-test", "anytrust-dev-test"} { 13 | if !reflect.DeepEqual(DefaultChainConfigs[chainName], fetchChainConfig(chainName)) { 14 | t.Fatalf("copy of %s default chain config mismatch", chainName) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /cmd/dataavailability/data_availability_check: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/cmd/dataavailability/data_availability_check -------------------------------------------------------------------------------- /cmd/genericconf/getversion17.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | //go:build !go1.18 5 | 6 | package genericconf 7 | 8 | func GetVersion() (string, string) { 9 | return "development", "development" 10 | } 11 | -------------------------------------------------------------------------------- /cmd/genericconf/jwt.go: -------------------------------------------------------------------------------- 1 | package genericconf 2 | 3 | import ( 4 | "crypto/rand" 5 | "errors" 6 | "fmt" 7 | "io/fs" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/ethereum/go-ethereum/common" 12 | "github.com/ethereum/go-ethereum/log" 13 | ) 14 | 15 | func TryCreatingJWTSecret(filename string) error { 16 | err := os.MkdirAll(filepath.Dir(filename), 0755) 17 | if err != nil { 18 | return fmt.Errorf("couldn't create directory for jwt secret: %w", err) 19 | } 20 | f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_EXCL, fs.FileMode(0600)) 21 | if errors.Is(err, fs.ErrExist) { 22 | log.Info("using existing jwt file", "filename", filename) 23 | return nil 24 | } 25 | if err != nil { 26 | return fmt.Errorf("couldn't create file: %w", err) 27 | } 28 | defer func() { 29 | if err := f.Close(); err != nil { 30 | log.Error("failed to close file", "err", err) 31 | } 32 | }() 33 | secret := common.Hash{} 34 | _, err = rand.Read(secret[:]) 35 | if err != nil { 36 | return fmt.Errorf("couldn't generate secret: %w", err) 37 | } 38 | _, err = f.Write([]byte(secret.Hex())) 39 | if err != nil { 40 | return fmt.Errorf("couldn't writeto file: %w", err) 41 | } 42 | log.Info("created jwt file", "filename", filename) 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /cmd/genericconf/loglevel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package genericconf 5 | 6 | import ( 7 | "errors" 8 | "log/slog" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/ethereum/go-ethereum/log" 13 | ) 14 | 15 | func ToSlogLevel(str string) (slog.Level, error) { 16 | switch strings.ToLower(str) { 17 | case "trace": 18 | return log.LevelTrace, nil 19 | case "debug": 20 | return log.LevelDebug, nil 21 | case "info": 22 | return log.LevelInfo, nil 23 | case "warn": 24 | return log.LevelWarn, nil 25 | case "error": 26 | return log.LevelError, nil 27 | case "crit": 28 | return log.LevelCrit, nil 29 | default: 30 | legacyLevel, err := strconv.Atoi(str) 31 | if err != nil { 32 | // Leave legacy geth numeric log levels undocumented, but if anyone happens 33 | // to be using them, it will work. 34 | return log.LevelTrace, errors.New("invalid log-level") 35 | } 36 | return log.FromLegacyLevel(legacyLevel), nil 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /cmd/genericconf/pprof.go: -------------------------------------------------------------------------------- 1 | package genericconf 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | // Blank import pprof registers its HTTP handlers. 7 | _ "net/http/pprof" // #nosec G108 8 | 9 | "github.com/ethereum/go-ethereum/log" 10 | "github.com/ethereum/go-ethereum/metrics" 11 | "github.com/ethereum/go-ethereum/metrics/exp" 12 | ) 13 | 14 | func StartPprof(address string) { 15 | exp.Exp(metrics.DefaultRegistry) 16 | log.Info("Starting metrics server with pprof", "addr", fmt.Sprintf("http://%s/debug/metrics", address)) 17 | log.Info("Pprof endpoint", "addr", fmt.Sprintf("http://%s/debug/pprof", address)) 18 | go func() { 19 | if err := http.ListenAndServe(address, http.DefaultServeMux); /* #nosec G114 */ err != nil { 20 | log.Error("Failure in running pprof server", "err", err) 21 | } 22 | }() 23 | } 24 | -------------------------------------------------------------------------------- /cmd/relay/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "strings" 9 | "testing" 10 | 11 | "github.com/offchainlabs/nitro/relay" 12 | "github.com/offchainlabs/nitro/util/testhelpers" 13 | ) 14 | 15 | func TestRelayConfig(t *testing.T) { 16 | args := strings.Split("--node.feed.output.port 9652 --node.feed.input.url ws://sequencer:9642/feed", " ") 17 | _, err := relay.ParseRelay(context.Background(), args) 18 | testhelpers.RequireImpl(t, err) 19 | } 20 | -------------------------------------------------------------------------------- /cmd/seq-coordinator-invalidate/seq-coordinator-invalidate.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2021-2022, Offchain Labs, Inc. All rights reserved. 3 | // 4 | 5 | package main 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "os" 11 | "strconv" 12 | 13 | "github.com/offchainlabs/nitro/arbnode" 14 | "github.com/offchainlabs/nitro/arbutil" 15 | "github.com/offchainlabs/nitro/util/redisutil" 16 | ) 17 | 18 | func main() { 19 | if len(os.Args) != 4 { 20 | fmt.Fprintf(os.Stderr, "Usage: seq-coordinator-invalidate [redis url] [signing key] [msg index]\n") 21 | os.Exit(1) 22 | } 23 | redisUrl := os.Args[1] 24 | signingKey := os.Args[2] 25 | msgIndex, err := strconv.ParseUint(os.Args[3], 10, 64) 26 | if err != nil { 27 | panic("Failed to parse msg index: " + err.Error()) 28 | } 29 | redisClient, err := redisutil.RedisClientFromURL(redisUrl) 30 | if err != nil { 31 | panic(err) 32 | } 33 | if redisClient == nil { 34 | panic("redis url not defined") 35 | } 36 | err = arbnode.StandaloneSeqCoordinatorInvalidateMsgIndex(context.Background(), redisClient, signingKey, arbutil.MessageIndex(msgIndex)) 37 | if err != nil { 38 | panic(err) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cmd/seq-coordinator-manager/rediscoordinator/redis_coordinator.go: -------------------------------------------------------------------------------- 1 | package rediscoordinator 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "strings" 7 | 8 | "github.com/redis/go-redis/v9" 9 | 10 | "github.com/offchainlabs/nitro/util/redisutil" 11 | ) 12 | 13 | // RedisCoordinator builds upon RedisCoordinator of redisutil with additional functionality 14 | type RedisCoordinator struct { 15 | *redisutil.RedisCoordinator 16 | } 17 | 18 | // UpdatePriorities updates the priority list of sequencers 19 | func (rc *RedisCoordinator) UpdatePriorities(ctx context.Context, priorities []string) error { 20 | if len(priorities) == 0 { 21 | return rc.Client.Del(ctx, redisutil.PRIORITIES_KEY).Err() 22 | } 23 | prioritiesString := strings.Join(priorities, ",") 24 | err := rc.Client.Set(ctx, redisutil.PRIORITIES_KEY, prioritiesString, 0).Err() 25 | if err != nil { 26 | if errors.Is(err, redis.Nil) { 27 | err = errors.New("sequencer priorities unset") 28 | } 29 | return err 30 | } 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: false 5 | patch: false 6 | github_checks: 7 | annotations: false 8 | comment: 9 | layout: "diff" 10 | behavior: once 11 | after_n_builds: 2 12 | -------------------------------------------------------------------------------- /daprovider/das/lifecycle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "time" 10 | 11 | "github.com/ethereum/go-ethereum/log" 12 | ) 13 | 14 | type Closer interface { 15 | Close(ctx context.Context) error 16 | fmt.Stringer 17 | } 18 | 19 | type LifecycleManager struct { 20 | toClose []Closer 21 | } 22 | 23 | func (m *LifecycleManager) Register(c Closer) { 24 | m.toClose = append(m.toClose, c) 25 | } 26 | 27 | func (m *LifecycleManager) StopAndWaitUntil(t time.Duration) { 28 | if m != nil && m.toClose != nil { 29 | ctx, cancel := context.WithTimeout(context.Background(), t) 30 | defer cancel() 31 | for _, c := range m.toClose { 32 | err := c.Close(ctx) 33 | if err != nil { 34 | log.Warn("Failed to Close DAS component", "err", err) 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /daprovider/das/storage_service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "fmt" 10 | "strings" 11 | "time" 12 | 13 | "github.com/ethereum/go-ethereum/common" 14 | "github.com/ethereum/go-ethereum/common/hexutil" 15 | 16 | "github.com/offchainlabs/nitro/daprovider/das/dasutil" 17 | ) 18 | 19 | var ErrNotFound = errors.New("not found") 20 | 21 | type StorageService interface { 22 | dasutil.DASReader 23 | Put(ctx context.Context, data []byte, expirationTime uint64) error 24 | Sync(ctx context.Context) error 25 | Closer 26 | fmt.Stringer 27 | HealthCheck(ctx context.Context) error 28 | } 29 | 30 | const defaultStorageRetention = time.Hour * 24 * 21 // 6 days longer than the batch poster default 31 | 32 | func EncodeStorageServiceKey(key common.Hash) string { 33 | return key.Hex()[2:] 34 | } 35 | 36 | func DecodeStorageServiceKey(input string) (common.Hash, error) { 37 | if !strings.HasPrefix(input, "0x") { 38 | input = "0x" + input 39 | } 40 | key, err := hexutil.Decode(input) 41 | if err != nil { 42 | return common.Hash{}, err 43 | } 44 | return common.BytesToHash(key), nil 45 | } 46 | -------------------------------------------------------------------------------- /daprovider/das/store_signing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "encoding/binary" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/crypto" 11 | 12 | "github.com/offchainlabs/nitro/daprovider/das/dastree" 13 | "github.com/offchainlabs/nitro/util/signature" 14 | ) 15 | 16 | var uniquifyingPrefix = []byte("Arbitrum Nitro DAS API Store:") 17 | 18 | func applyDasSigner(signer signature.DataSignerFunc, data []byte, extraFields ...uint64) ([]byte, error) { 19 | return signer(dasStoreHash(data, extraFields...)) 20 | } 21 | 22 | func DasRecoverSigner(data []byte, sig []byte, extraFields ...uint64) (common.Address, error) { 23 | pk, err := crypto.SigToPub(dasStoreHash(data, extraFields...), sig) 24 | if err != nil { 25 | return common.Address{}, err 26 | } 27 | return crypto.PubkeyToAddress(*pk), nil 28 | } 29 | 30 | func dasStoreHash(data []byte, extraFields ...uint64) []byte { 31 | var buf []byte 32 | 33 | for _, field := range extraFields { 34 | buf = binary.BigEndian.AppendUint64(buf, field) 35 | } 36 | 37 | return dastree.HashBytes(uniquifyingPrefix, buf, data) 38 | } 39 | -------------------------------------------------------------------------------- /daprovider/das/store_signing_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | 10 | "github.com/ethereum/go-ethereum/crypto" 11 | 12 | "github.com/offchainlabs/nitro/util/signature" 13 | ) 14 | 15 | func TestStoreSigning(t *testing.T) { 16 | privateKey, err := crypto.GenerateKey() 17 | Require(t, err) 18 | 19 | addr := crypto.PubkeyToAddress(privateKey.PublicKey) 20 | 21 | weirdMessage := []byte("The quick brown fox jumped over the lazy dog.") 22 | // #nosec G115 23 | timeout := uint64(time.Now().Unix()) 24 | 25 | signer := signature.DataSignerFromPrivateKey(privateKey) 26 | sig, err := applyDasSigner(signer, weirdMessage, timeout) 27 | Require(t, err) 28 | 29 | recoveredAddr, err := DasRecoverSigner(weirdMessage, sig, timeout) 30 | Require(t, err) 31 | 32 | if recoveredAddr != addr { 33 | t.Fatal() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /daprovider/das/timeout_wrapper.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "time" 10 | 11 | "github.com/ethereum/go-ethereum/common" 12 | ) 13 | 14 | type ReaderTimeoutWrapper struct { 15 | t time.Duration 16 | DataAvailabilityServiceReader 17 | } 18 | 19 | type TimeoutWrapper struct { 20 | ReaderTimeoutWrapper 21 | } 22 | 23 | func NewReaderTimeoutWrapper(dataAvailabilityServiceReader DataAvailabilityServiceReader, t time.Duration) DataAvailabilityServiceReader { 24 | return &ReaderTimeoutWrapper{ 25 | t: t, 26 | DataAvailabilityServiceReader: dataAvailabilityServiceReader, 27 | } 28 | } 29 | 30 | func (w *ReaderTimeoutWrapper) GetByHash(ctx context.Context, hash common.Hash) ([]byte, error) { 31 | deadlineCtx, cancel := context.WithDeadline(ctx, time.Now().Add(w.t)) 32 | // For GetByHash we want fast cancellation of all goroutines started by 33 | // the aggregator as soon as one returns. 34 | defer cancel() 35 | return w.DataAvailabilityServiceReader.GetByHash(deadlineCtx, hash) 36 | } 37 | 38 | func (w *ReaderTimeoutWrapper) String() string { 39 | return fmt.Sprintf("ReaderTimeoutWrapper{%v}", w.DataAvailabilityServiceReader) 40 | } 41 | -------------------------------------------------------------------------------- /daprovider/das/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package das 5 | 6 | import ( 7 | "time" 8 | 9 | "github.com/ethereum/go-ethereum/log" 10 | 11 | "github.com/offchainlabs/nitro/daprovider/das/dasutil" 12 | "github.com/offchainlabs/nitro/util/pretty" 13 | ) 14 | 15 | func logPut(store string, data []byte, timeout uint64, reader dasutil.DASReader, more ...interface{}) { 16 | if len(more) == 0 { 17 | // #nosec G115 18 | log.Trace( 19 | store, "message", pretty.FirstFewBytes(data), "timeout", time.Unix(int64(timeout), 0), 20 | "this", reader, 21 | ) 22 | } else { 23 | // #nosec G115 24 | log.Trace( 25 | store, "message", pretty.FirstFewBytes(data), "timeout", time.Unix(int64(timeout), 0), 26 | "this", reader, more, 27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /daprovider/writer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/nitro/blob/master/LICENSE 3 | 4 | package daprovider 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | type Writer interface { 11 | // Store posts the batch data to the invoking DA provider 12 | // And returns sequencerMsg which is later used to retrieve the batch data 13 | Store( 14 | ctx context.Context, 15 | message []byte, 16 | timeout uint64, 17 | disableFallbackStoreDataOnChain bool, 18 | ) ([]byte, error) 19 | } 20 | -------------------------------------------------------------------------------- /docs/Nitro-whitepaper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OffchainLabs/nitro/6e3aba7190261da2a98c63eff8676e8011d00ff9/docs/Nitro-whitepaper.pdf -------------------------------------------------------------------------------- /docs/decisions/README.md: -------------------------------------------------------------------------------- 1 | # Decisions 2 | 3 | For new Architectural Decision Records (ADRs), please use one of the following templates as a starting point: 4 | 5 | * [adr-template.md](adr-template.md) has all sections, with explanations about them. 6 | * [adr-template-minmal.md](adr-template-minimal.md) only contains mandatory sections, with explanations about them. 7 | * [adr-template-bare.md](adr-template-bare.md) has all sections, wich are empty (no explanations). 8 | * [adr-template-bare-minimal.md](adr-template-bare-minimal.md) has the mandatory sections, without explanations. 9 | 10 | The MADR documentation is available at while general information about ADRs is available at . 11 | -------------------------------------------------------------------------------- /docs/decisions/adr-template-bare-minimal.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 | ## Context and Problem Statement 4 | 5 | 6 | 7 | ## Considered Options 8 | 9 | 10 | 11 | ## Decision Outcome 12 | 13 | 14 | 15 | ### Consequences 16 | 17 | -------------------------------------------------------------------------------- /docs/decisions/adr-template-bare.md: -------------------------------------------------------------------------------- 1 | --- 2 | status: 3 | date: 4 | decision-makers: 5 | consulted: 6 | informed: 7 | --- 8 | 9 | # 10 | 11 | ## Context and Problem Statement 12 | 13 | 14 | 15 | ## Decision Drivers 16 | 17 | * 18 | 19 | ## Considered Options 20 | 21 | * 22 | 23 | ## Decision Outcome 24 | 25 | Chosen option: "", because 26 | 27 | ### Consequences 28 | 29 | * Good, because 30 | * Bad, because 31 | 32 | ### Confirmation 33 | 34 | 35 | 36 | ## Pros and Cons of the Options 37 | 38 | ### 39 | 40 | * Good, because 41 | * Neutral, because 42 | * Bad, because 43 | 44 | ## More Information 45 | -------------------------------------------------------------------------------- /docs/decisions/adr-template-minimal.md: -------------------------------------------------------------------------------- 1 | # {short title, representative of solved problem and found solution} 2 | 3 | ## Context and Problem Statement 4 | 5 | {Describe the context and problem statement, e.g., in free form using two to three sentences or in the form of an illustrative story. You may want to articulate the problem in form of a question and add links to collaboration boards or issue management systems.} 6 | 7 | ## Considered Options 8 | 9 | * {title of option 1} 10 | * {title of option 2} 11 | * {title of option 3} 12 | * … 13 | 14 | ## Decision Outcome 15 | 16 | Chosen option: "{title of option 1}", because {justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force {force} | … | comes out best (see below)}. 17 | 18 | 19 | ### Consequences 20 | 21 | * Good, because {positive consequence, e.g., improvement of one or more desired qualities, …} 22 | * Bad, because {negative consequence, e.g., compromising one or more desired qualities, …} 23 | * … 24 | -------------------------------------------------------------------------------- /docs/notice.md: -------------------------------------------------------------------------------- 1 | **Note**: Docs now live at https://github.com/OffchainLabs/nitro-docs -------------------------------------------------------------------------------- /execution/gethexec/blockchain_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package gethexec 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestGetStateHistory(t *testing.T) { 12 | maxBlockSpeed := time.Millisecond * 250 13 | expectedStateHistory := uint64(345600) 14 | actualStateHistory := getStateHistory(maxBlockSpeed) 15 | if actualStateHistory != expectedStateHistory { 16 | t.Errorf("Expected state history to be %d, but got %d", expectedStateHistory, actualStateHistory) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /linters/linters.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "golang.org/x/tools/go/analysis/multichecker" 5 | 6 | "github.com/offchainlabs/nitro/linters/koanf" 7 | "github.com/offchainlabs/nitro/linters/pointercheck" 8 | "github.com/offchainlabs/nitro/linters/rightshift" 9 | "github.com/offchainlabs/nitro/linters/structinit" 10 | ) 11 | 12 | func main() { 13 | multichecker.Main( 14 | koanf.Analyzer, 15 | pointercheck.Analyzer, 16 | rightshift.Analyzer, 17 | structinit.Analyzer, 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /linters/pointercheck/pointercheck_test.go: -------------------------------------------------------------------------------- 1 | package pointercheck 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "golang.org/x/tools/go/analysis/analysistest" 9 | ) 10 | 11 | func TestAll(t *testing.T) { 12 | wd, err := os.Getwd() 13 | if err != nil { 14 | t.Fatalf("Failed to get working directory: %v", err) 15 | } 16 | testdata := filepath.Join(filepath.Dir(wd), "testdata") 17 | res := analysistest.Run(t, testdata, analyzerForTests, "pointercheck") 18 | if cnt := countErrors(res); cnt != 6 { 19 | t.Errorf("analysistest.Run() got %v errors, expected 6", cnt) 20 | } 21 | } 22 | 23 | func countErrors(errs []*analysistest.Result) int { 24 | cnt := 0 25 | for _, e := range errs { 26 | if r, ok := e.Result.(Result); ok { 27 | cnt += len(r.Errors) 28 | } 29 | } 30 | return cnt 31 | } 32 | -------------------------------------------------------------------------------- /linters/rightshift/rightshift_test.go: -------------------------------------------------------------------------------- 1 | package rightshift 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/google/go-cmp/cmp" 9 | "golang.org/x/tools/go/analysis/analysistest" 10 | ) 11 | 12 | func TestAll(t *testing.T) { 13 | wd, err := os.Getwd() 14 | if err != nil { 15 | t.Fatalf("Failed to get working directory: %v", err) 16 | } 17 | testdata := filepath.Join(filepath.Dir(wd), "testdata") 18 | res := analysistest.Run(t, testdata, analyzerForTests, "rightshift") 19 | want := []int{6, 11, 12} 20 | got := erroLines(res) 21 | if diff := cmp.Diff(want, got); diff != "" { 22 | t.Errorf("analysistest.Ru() unexpected diff in error lines:\n%s\n", diff) 23 | } 24 | } 25 | 26 | func erroLines(errs []*analysistest.Result) []int { 27 | var ret []int 28 | for _, e := range errs { 29 | if r, ok := e.Result.(Result); ok { 30 | for _, err := range r.Errors { 31 | ret = append(ret, err.Pos.Line) 32 | } 33 | } 34 | } 35 | return ret 36 | } 37 | -------------------------------------------------------------------------------- /linters/structinit/structinit_test.go: -------------------------------------------------------------------------------- 1 | package structinit 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "golang.org/x/tools/go/analysis/analysistest" 9 | ) 10 | 11 | func testData(t *testing.T) string { 12 | t.Helper() 13 | wd, err := os.Getwd() 14 | if err != nil { 15 | t.Fatalf("Failed to get working directory: %v", err) 16 | } 17 | return filepath.Join(filepath.Dir(wd), "testdata") 18 | } 19 | 20 | func TestLinter(t *testing.T) { 21 | testdata := testData(t) 22 | got := errCount(analysistest.Run(t, testdata, analyzerForTests, "structinit/a")) 23 | if got != 2 { 24 | t.Errorf("analysistest.Run() got %d errors, expected 2", got) 25 | } 26 | } 27 | 28 | func errCount(res []*analysistest.Result) int { 29 | cnt := 0 30 | for _, r := range res { 31 | if rs, ok := r.Result.(Result); ok { 32 | cnt += len(rs.Errors) 33 | } 34 | } 35 | return cnt 36 | } 37 | -------------------------------------------------------------------------------- /linters/testdata/src/koanf/b/b.go: -------------------------------------------------------------------------------- 1 | package b 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | ) 7 | 8 | type ParCfg struct { 9 | child ChildCfg `koanf:"child"` 10 | grandChild GrandChildCfg `koanf:grandchild` 11 | } 12 | 13 | var defaultCfg = ParCfg{} 14 | 15 | type ChildCfg struct { 16 | A bool `koanf:"A"` 17 | B bool `koanf:"B"` 18 | C bool `koanf:"C"` 19 | D bool `koanf:"D"` // Error: not used outside flag definition. 20 | } 21 | 22 | var defaultChildCfg = ChildCfg{} 23 | 24 | func childConfigAddOptions(prefix string, f *flag.FlagSet) { 25 | f.Bool(prefix+".a", defaultChildCfg.A, "") 26 | f.Bool("b", defaultChildCfg.B, "") 27 | f.Bool("c", defaultChildCfg.C, "") 28 | f.Bool("d", defaultChildCfg.D, "") 29 | } 30 | 31 | type GrandChildCfg struct { 32 | A int `koanf:"A"` // Error: unused. 33 | } 34 | 35 | func (c *GrandChildCfg) Do() { 36 | } 37 | 38 | func configPtr() *ChildCfg { 39 | return nil 40 | } 41 | func config() ChildCfg { 42 | return ChildCfg{} 43 | } 44 | 45 | func init() { 46 | fmt.Printf("%v %v", config().A, configPtr().B) 47 | // This covers usage of both `ParCfg.Child` and `ChildCfg.C`. 48 | _ = defaultCfg.child.C 49 | // Covers usage of grandChild. 50 | defaultCfg.grandChild.Do() 51 | 52 | } 53 | -------------------------------------------------------------------------------- /linters/testdata/src/pointercheck/pointercheck.go: -------------------------------------------------------------------------------- 1 | package pointercheck 2 | 3 | import "fmt" 4 | 5 | type A struct { 6 | x, y int 7 | } 8 | 9 | // pointerCmp compares pointers, sometimes inside 10 | func pointerCmp() { 11 | a, b := &A{}, &A{} 12 | // Simple comparions. 13 | if a != b { 14 | fmt.Println("Not Equal") 15 | } 16 | if a == b { 17 | fmt.Println("Equals") 18 | } 19 | // Nested binary expressions. 20 | if (2 > 1) && (a != b) { 21 | fmt.Println("Still not equal") 22 | } 23 | if (174%15 > 3) && (2 > 1 && (1+2 > 2 || a != b)) { 24 | fmt.Println("Who knows at this point") 25 | } 26 | // Nested and inside unary operator. 27 | if 10 > 5 && !(2 > 1 || a == b) { 28 | fmt.Println("Not equal") 29 | } 30 | c, d := 1, 2 31 | if &c != &d { 32 | fmt.Println("Not equal") 33 | } 34 | } 35 | 36 | func legitCmps() { 37 | a, b := &A{}, &A{} 38 | if a.x == b.x { 39 | fmt.Println("Allowed") 40 | } 41 | } 42 | 43 | type cache struct { 44 | dirty *A 45 | } 46 | 47 | // matches does pointer comparison. 48 | func (c *cache) matches(a *A) bool { 49 | return c.dirty == a 50 | } 51 | -------------------------------------------------------------------------------- /linters/testdata/src/rightshift/rightshift.go: -------------------------------------------------------------------------------- 1 | package rightshift 2 | 3 | import "fmt" 4 | 5 | func doThing(v int) int { 6 | return 1 >> v // Error: Ln: 6 7 | } 8 | 9 | func calc() { 10 | val := 10 11 | fmt.Printf("%v", 1>>val) // Error: Ln 11 12 | _ = doThing(1 >> val) // Error: Ln 12 13 | fmt.Printf("%v", 1<") 29 | sys.exit(1) 30 | 31 | filename = sys.argv[1] 32 | 33 | preimages = [ 34 | (0, b'hello world'), 35 | (1, b'hello world'), 36 | (2, kzg_test_data()), 37 | ] 38 | 39 | write_data_to_file(filename, preimages) 40 | -------------------------------------------------------------------------------- /scripts/download-machine.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | mkdir "$2" 5 | ln -sfT "$2" latest 6 | cd "$2" 7 | echo "$2" > module-root.txt 8 | url_base="https://github.com/OffchainLabs/nitro/releases/download/$1" 9 | wget "$url_base/machine.wavm.br" 10 | 11 | status_code="$(curl -LI "$url_base/replay.wasm" -so /dev/null -w '%{http_code}')" 12 | if [ "$status_code" -ne 404 ]; then 13 | wget "$url_base/replay.wasm" 14 | fi 15 | -------------------------------------------------------------------------------- /scripts/remove_reference_types.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script removes reference types from a wasm file 4 | 5 | wasm2wat "$1" > "$1.wat" 6 | wat2wasm "$1.wat" -o "$1" 7 | -------------------------------------------------------------------------------- /scripts/startup-testnode.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # The script starts up the test node (with timeout 1 minute), to make sure the 3 | # nitro-testnode script isn't out of sync with flags with nitro. 4 | # This is used in CI, basically as smoke test. 5 | 6 | timeout 60 ./nitro-testnode/test-node.bash --init --dev || exit_status=$? 7 | 8 | if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ] && [ "$exit_status" -ne 124 ]; then 9 | echo "Startup failed." 10 | exit "$exit_status" 11 | fi 12 | 13 | echo "Startup succeeded." 14 | -------------------------------------------------------------------------------- /scripts/validate-wasm-module-root.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | MACHINES_DIR=$1 5 | PROVER=$2 6 | 7 | for machine in "$MACHINES_DIR"/*/ ; do 8 | if [ -d "$machine" ]; then 9 | expectedWasmModuleRoot=$(cat "$machine/module-root.txt") 10 | actualWasmModuleRoot=$(cd "$machine" && "$PROVER" machine.wavm.br --print-wasmmoduleroot) 11 | if [ "$expectedWasmModuleRoot" != "$actualWasmModuleRoot" ]; then 12 | echo "Error: Expected module root $expectedWasmModuleRoot but found $actualWasmModuleRoot in $machine" 13 | exit 1 14 | fi 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /staker/block_validator_schema.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package staker 5 | 6 | import ( 7 | "github.com/ethereum/go-ethereum/common" 8 | 9 | "github.com/offchainlabs/nitro/validator" 10 | ) 11 | 12 | type legacyLastBlockValidatedDbInfo struct { 13 | BlockNumber uint64 14 | BlockHash common.Hash 15 | AfterPosition GlobalStatePosition 16 | } 17 | 18 | type GlobalStateValidatedInfo struct { 19 | GlobalState validator.GoGlobalState 20 | WasmRoots []common.Hash 21 | } 22 | 23 | var ( 24 | lastGlobalStateValidatedInfoKey = []byte("_lastGlobalStateValidatedInfo") // contains a rlp encoded lastBlockValidatedDbInfo 25 | legacyLastBlockValidatedInfoKey = []byte("_lastBlockValidatedInfo") // LEGACY - contains a rlp encoded lastBlockValidatedDbInfo 26 | ) 27 | -------------------------------------------------------------------------------- /staker/legacy/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package legacystaker 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | -------------------------------------------------------------------------------- /statetransfer/interface.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package statetransfer 5 | 6 | import ( 7 | "errors" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | ) 11 | 12 | var errNoMore = errors.New("no more elements") 13 | 14 | type InitDataReader interface { 15 | Close() error 16 | GetAddressTableReader() (AddressReader, error) 17 | GetNextBlockNumber() (uint64, error) 18 | GetRetryableDataReader() (RetryableDataReader, error) 19 | GetAccountDataReader() (AccountDataReader, error) 20 | GetChainOwner() (common.Address, error) 21 | } 22 | 23 | type ListReader interface { 24 | More() bool 25 | Close() error 26 | } 27 | 28 | type AddressReader interface { 29 | ListReader 30 | GetNext() (*common.Address, error) 31 | } 32 | 33 | type RetryableDataReader interface { 34 | ListReader 35 | GetNext() (*InitializationDataForRetryable, error) 36 | } 37 | 38 | type AccountDataReader interface { 39 | ListReader 40 | GetNext() (*AccountInitializationInfo, error) 41 | } 42 | -------------------------------------------------------------------------------- /system_tests/block_hash_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbtest 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 11 | 12 | "github.com/offchainlabs/nitro/solgen/go/mocksgen" 13 | ) 14 | 15 | func TestBlockHash(t *testing.T) { 16 | ctx, cancel := context.WithCancel(context.Background()) 17 | defer cancel() 18 | 19 | // Even though we don't use the L1, we need to create this node on L1 to get accurate L1 block numbers 20 | builder := NewNodeBuilder(ctx).DefaultConfig(t, true) 21 | cleanup := builder.Build(t) 22 | defer cleanup() 23 | 24 | auth := builder.L2Info.GetDefaultTransactOpts("Faucet", ctx) 25 | 26 | _, _, simple, err := mocksgen.DeploySimple(&auth, builder.L2.Client) 27 | Require(t, err) 28 | 29 | _, err = simple.CheckBlockHashes(&bind.CallOpts{Context: ctx}) 30 | Require(t, err) 31 | } 32 | -------------------------------------------------------------------------------- /system_tests/block_validator_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | // race detection makes things slow and miss timeouts 5 | //go:build block_validator_bench 6 | // +build block_validator_bench 7 | 8 | package arbtest 9 | 10 | import ( 11 | "testing" 12 | ) 13 | 14 | func TestBlockValidatorBenchmark(t *testing.T) { 15 | testBlockValidatorSimple(t, "onchain", 1, depleteGas, true) 16 | } 17 | -------------------------------------------------------------------------------- /system_tests/express_lane_timeboost_test.go: -------------------------------------------------------------------------------- 1 | package arbtest 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/offchainlabs/nitro/util/redisutil" 8 | ) 9 | 10 | func TestBidValidatorAuctioneerRedisStream(t *testing.T) { 11 | ctx, cancel := context.WithCancel(context.Background()) 12 | defer cancel() 13 | redisURL := redisutil.CreateTestRedis(ctx, t) 14 | _ = redisURL 15 | } 16 | -------------------------------------------------------------------------------- /system_tests/full_challenge_mock_test.go: -------------------------------------------------------------------------------- 1 | // race detection makes things slow and miss timeouts 2 | //go:build !race 3 | // +build !race 4 | 5 | package arbtest 6 | 7 | import "testing" 8 | 9 | func TestMockChallengeManagerAsserterIncorrect(t *testing.T) { 10 | defaultWasmRootDir := "" 11 | for i := int64(1); i <= makeBatch_MsgsPerBatch*3; i++ { 12 | RunChallengeTest(t, false, true, i, defaultWasmRootDir) 13 | } 14 | } 15 | 16 | func TestMockChallengeManagerAsserterCorrect(t *testing.T) { 17 | defaultWasmRootDir := "" 18 | for i := int64(1); i <= makeBatch_MsgsPerBatch*3; i++ { 19 | RunChallengeTest(t, true, true, i, defaultWasmRootDir) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /system_tests/program_race_test.go: -------------------------------------------------------------------------------- 1 | //go:build race 2 | // +build race 3 | 4 | // when running with race detection - skip block validation 5 | 6 | package arbtest 7 | 8 | import ( 9 | "testing" 10 | ) 11 | 12 | // used in program test 13 | func validateBlocks( 14 | t *testing.T, start uint64, jit bool, builder *NodeBuilder, 15 | ) { 16 | } 17 | 18 | // used in program test 19 | func validateBlockRange( 20 | t *testing.T, blocks []uint64, jit bool, 21 | builder *NodeBuilder, 22 | ) { 23 | } 24 | -------------------------------------------------------------------------------- /system_tests/rpc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbtest 5 | 6 | import ( 7 | "context" 8 | "path/filepath" 9 | "testing" 10 | 11 | "github.com/ethereum/go-ethereum/ethclient" 12 | ) 13 | 14 | func TestIpcRpc(t *testing.T) { 15 | ipcPath := filepath.Join(t.TempDir(), "test.ipc") 16 | 17 | ctx, cancel := context.WithCancel(context.Background()) 18 | defer cancel() 19 | 20 | builder := NewNodeBuilder(ctx).DefaultConfig(t, true) 21 | builder.l2StackConfig.IPCPath = ipcPath 22 | cleanup := builder.Build(t) 23 | defer cleanup() 24 | 25 | _, err := ethclient.Dial(ipcPath) 26 | Require(t, err) 27 | } 28 | -------------------------------------------------------------------------------- /system_tests/staker_challenge_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | // race detection makes things slow and miss timeouts 5 | //go:build challengetest 6 | // +build challengetest 7 | 8 | package arbtest 9 | 10 | import "testing" 11 | 12 | func TestChallengeStakersFaultyHonestActive(t *testing.T) { 13 | stakerTestImpl(t, true, false) 14 | } 15 | 16 | func TestChallengeStakersFaultyHonestInactive(t *testing.T) { 17 | stakerTestImpl(t, true, true) 18 | } 19 | -------------------------------------------------------------------------------- /system_tests/validator_reorg_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | //go:build validatorreorgtest 5 | // +build validatorreorgtest 6 | 7 | package arbtest 8 | 9 | import "testing" 10 | 11 | func TestBlockValidatorReorg(t *testing.T) { 12 | testSequencerInboxReaderImpl(t, true) 13 | } 14 | -------------------------------------------------------------------------------- /timeboost/errors.go: -------------------------------------------------------------------------------- 1 | package timeboost 2 | 3 | import "github.com/pkg/errors" 4 | 5 | var ( 6 | ErrMalformedData = errors.New("MALFORMED_DATA") 7 | ErrNotDepositor = errors.New("NOT_DEPOSITOR") 8 | ErrWrongChainId = errors.New("WRONG_CHAIN_ID") 9 | ErrWrongSignature = errors.New("WRONG_SIGNATURE") 10 | ErrBadRoundNumber = errors.New("BAD_ROUND_NUMBER") 11 | ErrInsufficientBalance = errors.New("INSUFFICIENT_BALANCE") 12 | ErrReservePriceNotMet = errors.New("RESERVE_PRICE_NOT_MET") 13 | ErrNoOnchainController = errors.New("NO_ONCHAIN_CONTROLLER") 14 | ErrWrongAuctionContract = errors.New("WRONG_AUCTION_CONTRACT") 15 | ErrNotExpressLaneController = errors.New("NOT_EXPRESS_LANE_CONTROLLER") 16 | ErrDuplicateSequenceNumber = errors.New("SEQUENCE_NUMBER_ALREADY_SEEN") 17 | ErrSequenceNumberTooLow = errors.New("SEQUENCE_NUMBER_TOO_LOW") 18 | ErrTooManyBids = errors.New("PER_ROUND_BID_LIMIT_REACHED") 19 | ) 20 | -------------------------------------------------------------------------------- /timeboost/schema.go: -------------------------------------------------------------------------------- 1 | package timeboost 2 | 3 | var ( 4 | flagSetup = ` 5 | CREATE TABLE IF NOT EXISTS Flags ( 6 | FlagName TEXT NOT NULL PRIMARY KEY, 7 | FlagValue INTEGER NOT NULL 8 | ); 9 | INSERT INTO Flags (FlagName, FlagValue) VALUES ('CurrentVersion', 0); 10 | ` 11 | version1 = ` 12 | CREATE TABLE IF NOT EXISTS Bids ( 13 | Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 14 | ChainId TEXT NOT NULL, 15 | Bidder TEXT NOT NULL, 16 | ExpressLaneController TEXT NOT NULL, 17 | AuctionContractAddress TEXT NOT NULL, 18 | Round INTEGER NOT NULL, 19 | Amount TEXT NOT NULL, 20 | Signature TEXT NOT NULL 21 | ); 22 | CREATE INDEX idx_bids_round ON Bids(Round); 23 | ` 24 | schemaList = []string{version1} 25 | ) 26 | -------------------------------------------------------------------------------- /timeboost/ticker.go: -------------------------------------------------------------------------------- 1 | package timeboost 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type roundTicker struct { 8 | c chan time.Time 9 | done chan bool 10 | roundTimingInfo RoundTimingInfo 11 | } 12 | 13 | func newRoundTicker(roundTimingInfo RoundTimingInfo) *roundTicker { 14 | return &roundTicker{ 15 | c: make(chan time.Time, 1), 16 | done: make(chan bool), 17 | roundTimingInfo: roundTimingInfo, 18 | } 19 | } 20 | 21 | func (t *roundTicker) tickAtAuctionClose() { 22 | t.start(t.roundTimingInfo.AuctionClosing) 23 | } 24 | 25 | func (t *roundTicker) tickAtReserveSubmissionDeadline() { 26 | t.start(t.roundTimingInfo.AuctionClosing + t.roundTimingInfo.ReserveSubmission) 27 | } 28 | 29 | func (t *roundTicker) start(timeBeforeRoundStart time.Duration) { 30 | for { 31 | nextTick := t.roundTimingInfo.TimeTilNextRound() - timeBeforeRoundStart 32 | if nextTick < 0 { 33 | nextTick += t.roundTimingInfo.Round 34 | } 35 | 36 | select { 37 | case <-time.After(nextTick): 38 | t.c <- time.Now() 39 | case <-t.done: 40 | close(t.c) 41 | return 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /util/arbmath/moving_average.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbmath 5 | 6 | import "fmt" 7 | 8 | // A simple moving average of a generic number type. 9 | type MovingAverage[T Number] struct { 10 | buffer []T 11 | bufferPosition int 12 | sum T 13 | } 14 | 15 | func NewMovingAverage[T Number](period int) (*MovingAverage[T], error) { 16 | if period <= 0 { 17 | return nil, fmt.Errorf("MovingAverage period specified as %v but it must be positive", period) 18 | } 19 | return &MovingAverage[T]{ 20 | buffer: make([]T, 0, period), 21 | }, nil 22 | } 23 | 24 | func (a *MovingAverage[T]) Update(value T) { 25 | period := cap(a.buffer) 26 | if period == 0 { 27 | return 28 | } 29 | if len(a.buffer) < period { 30 | a.buffer = append(a.buffer, value) 31 | a.sum += value 32 | } else { 33 | a.sum += value 34 | a.sum -= a.buffer[a.bufferPosition] 35 | a.buffer[a.bufferPosition] = value 36 | a.bufferPosition = (a.bufferPosition + 1) % period 37 | } 38 | } 39 | 40 | // Average returns the current moving average, or zero if no values have been added. 41 | func (a *MovingAverage[T]) Average() T { 42 | if len(a.buffer) == 0 { 43 | return 0 44 | } 45 | return a.sum / T(len(a.buffer)) 46 | } 47 | -------------------------------------------------------------------------------- /util/arbmath/moving_average_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbmath 5 | 6 | import "testing" 7 | 8 | func TestMovingAverage(t *testing.T) { 9 | _, err := NewMovingAverage[int](0) 10 | if err == nil { 11 | t.Error("Expected error when creating moving average of period 0") 12 | } 13 | _, err = NewMovingAverage[int](-1) 14 | if err == nil { 15 | t.Error("Expected error when creating moving average of period -1") 16 | } 17 | 18 | ma, err := NewMovingAverage[int](5) 19 | if err != nil { 20 | t.Fatalf("Error creating moving average of period 5: %v", err) 21 | } 22 | if ma.Average() != 0 { 23 | t.Errorf("Average() = %v, want 0", ma.Average()) 24 | } 25 | ma.Update(2) 26 | if ma.Average() != 2 { 27 | t.Errorf("Average() = %v, want 2", ma.Average()) 28 | } 29 | ma.Update(4) 30 | if ma.Average() != 3 { 31 | t.Errorf("Average() = %v, want 3", ma.Average()) 32 | } 33 | 34 | for i := 0; i < 5; i++ { 35 | ma.Update(10) 36 | } 37 | if ma.Average() != 10 { 38 | t.Errorf("Average() = %v, want 10", ma.Average()) 39 | } 40 | 41 | for i := 0; i < 5; i++ { 42 | ma.Update(0) 43 | } 44 | if ma.Average() != 0 { 45 | t.Errorf("Average() = %v, want 0", ma.Average()) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /util/arbmath/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package arbmath 5 | 6 | func DaysToSeconds[T Unsigned](days T) uint64 { 7 | return uint64(days) * 24 * 60 * 60 8 | } 9 | -------------------------------------------------------------------------------- /util/common.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | func ArrayToSet[T comparable](arr []T) map[T]struct{} { 4 | ret := make(map[T]struct{}) 5 | for _, elem := range arr { 6 | ret[elem] = struct{}{} 7 | } 8 | return ret 9 | } 10 | -------------------------------------------------------------------------------- /util/containers/queue.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package containers 5 | 6 | // Queue of an arbitrary type backed by a slice which is shrunk when it grows too large 7 | type Queue[T any] struct { 8 | slice []T 9 | } 10 | 11 | func (q *Queue[T]) Push(item T) { 12 | q.slice = append(q.slice, item) 13 | } 14 | 15 | // If cap(slice) >= len(slice)*shrinkRatio && cap(slice) >= shrinkMinimum, 16 | // shrink the slice capacity back down to twice its length by re-allocating it. 17 | const shrinkRatio = 16 18 | const shrinkMinimum = 512 19 | 20 | func (q *Queue[T]) shrink() { 21 | if cap(q.slice) >= len(q.slice)*shrinkRatio && cap(q.slice) >= shrinkMinimum { 22 | oldSlice := q.slice 23 | q.slice = make([]T, len(oldSlice), len(oldSlice)*2) 24 | copy(q.slice, oldSlice) 25 | } 26 | } 27 | 28 | func (q *Queue[T]) Pop() T { 29 | var empty T 30 | if len(q.slice) == 0 { 31 | return empty 32 | } 33 | item := q.slice[0] 34 | q.slice[0] = empty 35 | q.slice = q.slice[1:] 36 | q.shrink() 37 | return item 38 | } 39 | 40 | func (q *Queue[T]) Len() int { 41 | return len(q.slice) 42 | } 43 | -------------------------------------------------------------------------------- /util/containers/stack.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package containers 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/ethereum/go-ethereum/log" 10 | ) 11 | 12 | type Stack[T any] []T 13 | 14 | func NewStack[T any]() *Stack[T] { 15 | return &Stack[T]{} 16 | } 17 | 18 | func (s *Stack[T]) Push(v T) { 19 | if s == nil { 20 | log.Warn("trying to push nil stack") 21 | return 22 | } 23 | *s = append(*s, v) 24 | } 25 | 26 | func (s *Stack[T]) Pop() (T, error) { 27 | if s == nil { 28 | var zeroVal T 29 | return zeroVal, fmt.Errorf("trying to pop nil stack") 30 | } 31 | if s.Empty() { 32 | var zeroVal T 33 | return zeroVal, fmt.Errorf("trying to pop empty stack") 34 | } 35 | i := len(*s) - 1 36 | val := (*s)[i] 37 | *s = (*s)[:i] 38 | return val, nil 39 | } 40 | 41 | func (s *Stack[T]) Empty() bool { 42 | return s == nil || len(*s) == 0 43 | } 44 | 45 | func (s *Stack[T]) Len() int { 46 | if s == nil { 47 | return 0 48 | } 49 | return len(*s) 50 | } 51 | -------------------------------------------------------------------------------- /util/containers/syncmap.go: -------------------------------------------------------------------------------- 1 | package containers 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | type SyncMap[K any, V any] struct { 9 | internal sync.Map 10 | } 11 | 12 | func (m *SyncMap[K, V]) Load(key K) (V, bool) { 13 | val, found := m.internal.Load(key) 14 | if !found { 15 | var empty V 16 | return empty, false 17 | } 18 | vVal, ok := val.(V) 19 | if !ok { 20 | panic(fmt.Sprintf("type assertion failed on %s", val)) 21 | } 22 | return vVal, true 23 | } 24 | 25 | func (m *SyncMap[K, V]) Store(key K, val V) { 26 | m.internal.Store(key, val) 27 | } 28 | 29 | func (m *SyncMap[K, V]) Delete(key K) { 30 | m.internal.Delete(key) 31 | } 32 | 33 | // Only used for testing 34 | func (m *SyncMap[K, V]) Keys() []K { 35 | s := make([]K, 0) 36 | m.internal.Range(func(k, v interface{}) bool { 37 | kKey, ok := k.(K) 38 | if !ok { 39 | panic(fmt.Sprintf("type assertion failed on %s", k)) 40 | } 41 | s = append(s, kKey) 42 | return true 43 | }) 44 | return s 45 | } 46 | -------------------------------------------------------------------------------- /util/gzip/gzip_compression.go: -------------------------------------------------------------------------------- 1 | package gzip 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | func CompressGzip(data []byte) ([]byte, error) { 11 | var buffer bytes.Buffer 12 | gzipWriter := gzip.NewWriter(&buffer) 13 | if _, err := gzipWriter.Write(data); err != nil { 14 | return nil, fmt.Errorf("failed to write to gzip writer: %w", err) 15 | } 16 | if err := gzipWriter.Close(); err != nil { 17 | return nil, fmt.Errorf("failed to close gzip writer: %w", err) 18 | } 19 | return buffer.Bytes(), nil 20 | } 21 | 22 | func DecompressGzip(data []byte) ([]byte, error) { 23 | buffer := bytes.NewReader(data) 24 | gzipReader, err := gzip.NewReader(buffer) 25 | if err != nil { 26 | return nil, fmt.Errorf("failed to create gzip reader: %w", err) 27 | } 28 | defer gzipReader.Close() 29 | decompressData, err := io.ReadAll(gzipReader) 30 | if err != nil { 31 | return nil, fmt.Errorf("failed to read decompressed data: %w", err) 32 | } 33 | return decompressData, nil 34 | } 35 | -------------------------------------------------------------------------------- /util/gzip/gzip_compression_test.go: -------------------------------------------------------------------------------- 1 | package gzip 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | func TestCompressDecompress(t *testing.T) { 9 | sampleData := []byte{1, 2, 3, 4} 10 | compressedData, err := CompressGzip(sampleData) 11 | if err != nil { 12 | t.Fatalf("got error gzip-compressing data: %v", err) 13 | } 14 | gotData, err := DecompressGzip(compressedData) 15 | if err != nil { 16 | t.Fatalf("got error gzip-decompressing data: %v", err) 17 | } 18 | if !bytes.Equal(sampleData, gotData) { 19 | t.Fatal("original data and decompression of its compression don't match") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /util/jsonapi/uint64_string.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package jsonapi 5 | 6 | import ( 7 | "encoding/json" 8 | "fmt" 9 | "strconv" 10 | ) 11 | 12 | // Uint64String is a uint64 that JSON marshals and unmarshals as string in decimal 13 | type Uint64String uint64 14 | 15 | func (u *Uint64String) UnmarshalJSON(b []byte) error { 16 | jsonString := string(b) 17 | if jsonString == "null" { 18 | return nil 19 | } 20 | 21 | var s string 22 | err := json.Unmarshal(b, &s) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | value, err := strconv.ParseUint(s, 10, 64) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | *u = Uint64String(value) 33 | return nil 34 | } 35 | 36 | func (u Uint64String) MarshalJSON() ([]byte, error) { 37 | return []byte(fmt.Sprintf("\"%d\"", uint64(u))), nil 38 | } 39 | -------------------------------------------------------------------------------- /util/merkletree/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package merkletree 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | -------------------------------------------------------------------------------- /util/metricsutil/metricsutil.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package metricsutil 5 | 6 | import ( 7 | "regexp" 8 | ) 9 | 10 | // Prometheus metric names must contain only chars [a-zA-Z0-9:_] 11 | func CanonicalizeMetricName(metric string) string { 12 | invalidPromCharRegex := regexp.MustCompile(`[^a-zA-Z0-9:_]+`) 13 | return invalidPromCharRegex.ReplaceAllString(metric, "_") 14 | 15 | } 16 | -------------------------------------------------------------------------------- /util/normalizeGas.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package util 5 | 6 | import ( 7 | "github.com/offchainlabs/nitro/arbos/l2pricing" 8 | ) 9 | 10 | // NormalizeL2GasForL1GasInitial is for testing, adjusts an L2 gas amount that represents L1 gas spending, to compensate for 11 | // the difference between the assumed L2 base fee and the actual initial L2 base fee. 12 | func NormalizeL2GasForL1GasInitial(l2gas uint64, assumedL2Basefee uint64) uint64 { 13 | return l2gas * assumedL2Basefee / l2pricing.InitialBaseFeeWei 14 | } 15 | -------------------------------------------------------------------------------- /util/pretty/pretty_printing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package pretty 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | ) 11 | 12 | func FirstFewBytes(b []byte) string { 13 | if len(b) < 9 { 14 | return fmt.Sprintf("[% x]", b) 15 | } else { 16 | return fmt.Sprintf("[% x ... ]", b[:8]) 17 | } 18 | } 19 | 20 | func PrettyBytes(b []byte) string { 21 | hex := common.Bytes2Hex(b) 22 | if len(hex) > 24 { 23 | return fmt.Sprintf("%v...", hex[:24]) 24 | } 25 | return hex 26 | } 27 | 28 | func PrettyHash(hash common.Hash) string { 29 | return FirstFewBytes(hash.Bytes()) 30 | } 31 | 32 | func FirstFewChars(s string) string { 33 | if len(s) < 9 { 34 | return fmt.Sprintf("\"%s\"", s) 35 | } else { 36 | return fmt.Sprintf("\"%s...\"", s[:8]) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /util/redisutil/test_redis.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package redisutil 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "testing" 10 | 11 | "github.com/alicebob/miniredis/v2" 12 | 13 | "github.com/offchainlabs/nitro/util/testhelpers" 14 | testflag "github.com/offchainlabs/nitro/util/testhelpers/flag" 15 | ) 16 | 17 | // CreateTestRedis Provides external redis url, this is only done with --test_redis flag, 18 | // else creates a new miniredis and returns its url. 19 | func CreateTestRedis(ctx context.Context, t testing.TB) string { 20 | if *testflag.RedisFlag != "" { 21 | return *testflag.RedisFlag 22 | } 23 | redisServer, err := miniredis.Run() 24 | testhelpers.RequireImpl(t, err) 25 | go func() { 26 | <-ctx.Done() 27 | redisServer.Close() 28 | }() 29 | 30 | return fmt.Sprintf("redis://%s/0", redisServer.Addr()) 31 | } 32 | -------------------------------------------------------------------------------- /util/runtime.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "runtime" 5 | 6 | _ "go.uber.org/automaxprocs" 7 | ) 8 | 9 | // Automaxprocs automatically set GOMAXPROCS to match Linux container CPU quota. 10 | // So we are wrapping it here to make sure we do not call it anywhere else without importing automaxprocs. 11 | func GoMaxProcs() int { 12 | return runtime.GOMAXPROCS(-1) 13 | } 14 | -------------------------------------------------------------------------------- /util/sharedmetrics/sharedmetrics.go: -------------------------------------------------------------------------------- 1 | package sharedmetrics 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/metrics" 5 | 6 | "github.com/offchainlabs/nitro/arbutil" 7 | ) 8 | 9 | var ( 10 | latestSequenceNumberGauge = metrics.NewRegisteredGauge("arb/sequencenumber/latest", nil) 11 | sequenceNumberInBlockGauge = metrics.NewRegisteredGauge("arb/sequencenumber/inblock", nil) 12 | ) 13 | 14 | func UpdateSequenceNumberGauge(sequenceNumber arbutil.MessageIndex) { 15 | // #nosec G115 16 | latestSequenceNumberGauge.Update(int64(sequenceNumber)) 17 | } 18 | func UpdateSequenceNumberInBlockGauge(sequenceNumber arbutil.MessageIndex) { 19 | // #nosec G115 20 | sequenceNumberInBlockGauge.Update(int64(sequenceNumber)) 21 | } 22 | -------------------------------------------------------------------------------- /util/signature/datasigner.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package signature 5 | 6 | import ( 7 | "crypto/ecdsa" 8 | 9 | "github.com/ethereum/go-ethereum/crypto" 10 | ) 11 | 12 | type DataSignerFunc func([]byte) ([]byte, error) 13 | 14 | func DataSignerFromPrivateKey(privateKey *ecdsa.PrivateKey) DataSignerFunc { 15 | return func(data []byte) ([]byte, error) { 16 | return crypto.Sign(data, privateKey) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /util/testhelpers/env/env.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package env 5 | 6 | import ( 7 | "github.com/ethereum/go-ethereum/core/rawdb" 8 | "github.com/ethereum/go-ethereum/log" 9 | 10 | testflag "github.com/offchainlabs/nitro/util/testhelpers/flag" 11 | ) 12 | 13 | // There are two CI steps, one to run tests using the path state scheme, and one to run tests using the hash state scheme. 14 | // An environment variable controls that behavior. 15 | func GetTestStateScheme() string { 16 | stateScheme := rawdb.HashScheme 17 | if *testflag.StateSchemeFlag == rawdb.PathScheme || *testflag.StateSchemeFlag == rawdb.HashScheme { 18 | stateScheme = *testflag.StateSchemeFlag 19 | } 20 | log.Debug("test state scheme", "testStateScheme", stateScheme) 21 | return stateScheme 22 | } 23 | -------------------------------------------------------------------------------- /util/testhelpers/github/releases_test.go: -------------------------------------------------------------------------------- 1 | package github 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | ) 7 | 8 | func TestReleases(t *testing.T) { 9 | rels, err := NitroReleases(context.Background()) 10 | if err != nil { 11 | t.Error(err) 12 | } 13 | if len(rels) == 0 { 14 | t.Error("No releases found") 15 | } 16 | if len(rels) != 50 { 17 | t.Errorf("Expected 50 releases, got %d", len(rels)) 18 | } 19 | } 20 | 21 | func TestLatestConsensusRelease(t *testing.T) { 22 | rel, err := LatestConsensusRelease(context.Background()) 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | if rel == nil { 27 | t.Fatal("No consensus release found") 28 | } 29 | if rel.WavmModuleRoot == "" { 30 | t.Error("Unexpected empty WAVM module root.") 31 | } 32 | if rel.MachineWavmURL.String() == "" { 33 | t.Error("Unexpected empty machine WAVM URL.") 34 | } 35 | if rel.ReplayWasmURL.String() == "" { 36 | t.Error("Unexpected empty replay WASM URL.") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /util/testhelpers/port.go: -------------------------------------------------------------------------------- 1 | package testhelpers 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | ) 7 | 8 | // FreeTCPPortListener returns a listener listening on an unused local port. 9 | // 10 | // This is useful for tests that need to bind to a port without risking a conflict. 11 | func FreeTCPPortListener() (net.Listener, error) { 12 | // This works because the kernel will assign an unused port when ":0" is opened. 13 | l, err := net.Listen("tcp", "127.0.0.1:0") 14 | if err != nil { 15 | return nil, err 16 | } 17 | return l, nil 18 | } 19 | 20 | // Func AddrTCPPort returns the port of a net.Addr. 21 | func AddrTCPPort(n net.Addr, t *testing.T) int { 22 | t.Helper() 23 | tcpAddr, ok := n.(*net.TCPAddr) 24 | if !ok { 25 | t.Fatal("Could not get TCP address net.Addr") 26 | } 27 | return tcpAddr.Port 28 | } 29 | -------------------------------------------------------------------------------- /util/testhelpers/port_test.go: -------------------------------------------------------------------------------- 1 | package testhelpers 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | ) 7 | 8 | func TestFreeTCPPortListener(t *testing.T) { 9 | aListener, err := FreeTCPPortListener() 10 | if err != nil { 11 | t.Fatal(err) 12 | } 13 | bListener, err := FreeTCPPortListener() 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | aTCPAddr, ok := aListener.Addr().(*net.TCPAddr) 18 | if !ok { 19 | t.Fatalf("aListener.Addr() is not a *net.TCPAddr: %v", aListener.Addr()) 20 | } 21 | bTCPAddr, ok := bListener.Addr().(*net.TCPAddr) 22 | if !ok { 23 | t.Fatalf("bListener.Addr() is not a *net.TCPAddr: %v", aListener.Addr()) 24 | } 25 | if aTCPAddr.Port == bTCPAddr.Port { 26 | t.Errorf("FreeTCPPortListener() got same port: %v, %v", aListener, bListener) 27 | } 28 | if aTCPAddr.Port == 0 || bTCPAddr.Port == 0 { 29 | t.Errorf("FreeTCPPortListener() got port 0") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /util/testhelpers/pseudorandom.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package testhelpers 5 | 6 | import ( 7 | "math/rand" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | ) 12 | 13 | type PseudoRandomDataSource struct { 14 | rand *rand.Rand 15 | } 16 | 17 | // NewPseudoRandomDataSource is the pseudorandom source that repeats on different executions 18 | // T param is to make sure it's only used in testing 19 | func NewPseudoRandomDataSource(_ *testing.T, seed int64) *PseudoRandomDataSource { 20 | return &PseudoRandomDataSource{ 21 | rand: rand.New(rand.NewSource(seed)), 22 | } 23 | } 24 | 25 | func (r *PseudoRandomDataSource) GetHash() common.Hash { 26 | var outHash common.Hash 27 | r.rand.Read(outHash[:]) 28 | return outHash 29 | } 30 | 31 | func (r *PseudoRandomDataSource) GetAddress() common.Address { 32 | return common.BytesToAddress(r.GetHash().Bytes()[:20]) 33 | } 34 | 35 | func (r *PseudoRandomDataSource) GetUint64() uint64 { 36 | return r.rand.Uint64() 37 | } 38 | 39 | func (r *PseudoRandomDataSource) GetData(size int) []byte { 40 | outArray := make([]byte, size) 41 | r.rand.Read(outArray) 42 | return outArray 43 | } 44 | -------------------------------------------------------------------------------- /util/testhelpers/stackconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package testhelpers 5 | 6 | import "github.com/ethereum/go-ethereum/node" 7 | 8 | func CreateStackConfigForTest(dataDir string) *node.Config { 9 | stackConf := node.DefaultConfig 10 | stackConf.DataDir = dataDir 11 | stackConf.UseLightweightKDF = true 12 | stackConf.WSPort = 0 13 | stackConf.WSModules = append(stackConf.WSModules, "eth", "debug") 14 | stackConf.HTTPPort = 0 15 | stackConf.HTTPHost = "" 16 | stackConf.HTTPModules = append(stackConf.HTTPModules, "eth", "debug") 17 | stackConf.AuthPort = 0 18 | stackConf.P2P.NoDiscovery = true 19 | stackConf.P2P.NoDial = true 20 | stackConf.P2P.ListenAddr = "" 21 | stackConf.P2P.NAT = nil 22 | stackConf.DBEngine = "leveldb" 23 | return &stackConf 24 | } 25 | -------------------------------------------------------------------------------- /validator/server_arb/preimage_resolver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package server_arb 5 | 6 | /* 7 | #cgo CFLAGS: -g -I../../target/include/ 8 | #include "arbitrator.h" 9 | 10 | extern ResolvedPreimage preimageResolver(size_t context, uint8_t preimageType, const uint8_t* hash); 11 | 12 | ResolvedPreimage preimageResolverC(size_t context, uint8_t preimageType, const uint8_t* hash) { 13 | return preimageResolver(context, preimageType, hash); 14 | } 15 | */ 16 | import "C" 17 | -------------------------------------------------------------------------------- /validator/server_common/machine_locator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package server_common 5 | 6 | import ( 7 | "sort" 8 | "testing" 9 | 10 | "github.com/google/go-cmp/cmp" 11 | ) 12 | 13 | var ( 14 | wantLatestModuleRoot = "0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a" 15 | wantModuleRoots = []string{ 16 | "0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4", 17 | "0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4", 18 | "0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a", 19 | } 20 | ) 21 | 22 | func TestNewMachineLocator(t *testing.T) { 23 | ml, err := NewMachineLocator("testdata") 24 | if err != nil { 25 | t.Fatalf("Error creating new machine locator: %v", err) 26 | } 27 | if ml.latest.Hex() != wantLatestModuleRoot { 28 | t.Errorf("NewMachineLocator() got latestModuleRoot: %v, want: %v", ml.latest, wantLatestModuleRoot) 29 | } 30 | var got []string 31 | for _, s := range ml.ModuleRoots() { 32 | got = append(got, s.Hex()) 33 | } 34 | sort.Strings(got) 35 | sort.Strings(wantModuleRoots) 36 | if diff := cmp.Diff(got, wantModuleRoots); diff != "" { 37 | t.Errorf("NewMachineLocator() unexpected diff (-want +got):\n%s", diff) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /validator/server_common/testdata/0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4/module-root.txt: -------------------------------------------------------------------------------- 1 | 0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4 2 | -------------------------------------------------------------------------------- /validator/server_common/testdata/0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4/module-root.txt: -------------------------------------------------------------------------------- 1 | 0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4 2 | -------------------------------------------------------------------------------- /validator/server_common/testdata/0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a/module-root.txt: -------------------------------------------------------------------------------- 1 | 0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a 2 | -------------------------------------------------------------------------------- /validator/server_common/testdata/latest: -------------------------------------------------------------------------------- 1 | 0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a -------------------------------------------------------------------------------- /validator/server_common/valrun.go: -------------------------------------------------------------------------------- 1 | package server_common 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | 6 | "github.com/offchainlabs/nitro/util/containers" 7 | "github.com/offchainlabs/nitro/validator" 8 | ) 9 | 10 | type ValRun struct { 11 | containers.PromiseInterface[validator.GoGlobalState] 12 | root common.Hash 13 | } 14 | 15 | func (r *ValRun) WasmModuleRoot() common.Hash { 16 | return r.root 17 | } 18 | 19 | func NewValRun(promise containers.PromiseInterface[validator.GoGlobalState], root common.Hash) *ValRun { 20 | return &ValRun{ 21 | PromiseInterface: promise, 22 | root: root, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /validator/utils.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | "github.com/ethereum/go-ethereum/log" 6 | ) 7 | 8 | func SpawnerSupportsModule(spawner ValidationSpawner, requested common.Hash) bool { 9 | supported, err := spawner.WasmModuleRoots() 10 | if err != nil { 11 | log.Warn("WasmModuleRoots returned error", "err", err) 12 | return false 13 | } 14 | for _, root := range supported { 15 | if root == requested { 16 | return true 17 | } 18 | } 19 | return false 20 | } 21 | -------------------------------------------------------------------------------- /validator/validation_entry.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | "github.com/ethereum/go-ethereum/ethdb" 6 | 7 | "github.com/offchainlabs/nitro/daprovider" 8 | ) 9 | 10 | type BatchInfo struct { 11 | Number uint64 12 | Data []byte 13 | } 14 | 15 | type ValidationInput struct { 16 | Id uint64 17 | HasDelayedMsg bool 18 | DelayedMsgNr uint64 19 | Preimages daprovider.PreimagesMap 20 | UserWasms map[ethdb.WasmTarget]map[common.Hash][]byte 21 | BatchInfo []BatchInfo 22 | DelayedMsg []byte 23 | StartState GoGlobalState 24 | DebugChain bool 25 | } 26 | -------------------------------------------------------------------------------- /validator/valnode/redis/consumer_test.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | "time" 7 | 8 | "github.com/ethereum/go-ethereum/log" 9 | 10 | "github.com/offchainlabs/nitro/util/redisutil" 11 | "github.com/offchainlabs/nitro/util/testhelpers" 12 | ) 13 | 14 | func TestTimeout(t *testing.T) { 15 | handler := testhelpers.InitTestLog(t, log.LevelInfo) 16 | ctx, cancel := context.WithCancel(context.Background()) 17 | redisURL := redisutil.CreateTestRedis(ctx, t) 18 | TestValidationServerConfig.RedisURL = redisURL 19 | TestValidationServerConfig.ModuleRoots = []string{"0x123"} 20 | TestValidationServerConfig.StreamTimeout = 100 * time.Millisecond 21 | vs, err := NewValidationServer(&TestValidationServerConfig, nil) 22 | if err != nil { 23 | t.Fatalf("NewValidationSever() unexpected error: %v", err) 24 | } 25 | vs.Start(ctx) 26 | time.Sleep(time.Second) 27 | if !handler.WasLogged("Waiting for redis streams timed out") { 28 | t.Error("Expected message about stream time-outs was not logged") 29 | } 30 | cancel() 31 | } 32 | -------------------------------------------------------------------------------- /wavmio/raw.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2024, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | //go:build wasm 5 | // +build wasm 6 | 7 | package wavmio 8 | 9 | import "unsafe" 10 | 11 | //go:wasmimport wavmio getGlobalStateBytes32 12 | func getGlobalStateBytes32(idx uint32, output unsafe.Pointer) 13 | 14 | //go:wasmimport wavmio setGlobalStateBytes32 15 | func setGlobalStateBytes32(idx uint32, val unsafe.Pointer) 16 | 17 | //go:wasmimport wavmio getGlobalStateU64 18 | func getGlobalStateU64(idx uint32) uint64 19 | 20 | //go:wasmimport wavmio setGlobalStateU64 21 | func setGlobalStateU64(idx uint32, val uint64) 22 | 23 | //go:wasmimport wavmio readInboxMessage 24 | func readInboxMessage(msgNum uint64, offset uint32, output unsafe.Pointer) uint32 25 | 26 | //go:wasmimport wavmio readDelayedInboxMessage 27 | func readDelayedInboxMessage(seqNum uint64, offset uint32, output unsafe.Pointer) uint32 28 | 29 | //go:wasmimport wavmio resolveTypedPreimage 30 | func resolveTypedPreimage(ty uint32, hash unsafe.Pointer, offset uint32, output unsafe.Pointer) uint32 31 | -------------------------------------------------------------------------------- /zeroheavy/common_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022, Offchain Labs, Inc. 2 | // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md 3 | 4 | package zeroheavy 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/offchainlabs/nitro/util/testhelpers" 10 | ) 11 | 12 | func Require(t *testing.T, err error, printables ...interface{}) { 13 | t.Helper() 14 | testhelpers.RequireImpl(t, err, printables...) 15 | } 16 | 17 | func Fail(t *testing.T, printables ...interface{}) { 18 | t.Helper() 19 | testhelpers.FailImpl(t, printables...) 20 | } 21 | 22 | func ShowError(t *testing.T, err error) { 23 | t.Helper() 24 | if err != nil { 25 | t.Error(err) 26 | } 27 | } 28 | --------------------------------------------------------------------------------