diff --git a/Cargo.lock b/Cargo.lock index 74d62ad1..97c16531 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12787,7 +12787,10 @@ dependencies = [ "alloy-rpc-types-eth", "eyre", "getrandom 0.2.16", + "reth-tracing", "scroll-alloy-network", + "serde", + "serde_json", "tokio", "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index 8da9ef4f..60b97a1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,7 +123,7 @@ alloy-consensus = { version = "1.0.13", default-features = false } alloy-eips = { version = "1.0.13", default-features = false } alloy-json-rpc = { version = "1.0.13", default-features = false } alloy-network = { version = "1.0.13", default-features = false } -alloy-primitives = { version = "1.2.0", default-features = false } +alloy-primitives = { version = "1.3.1", default-features = false } alloy-provider = { version = "1.0.13", default-features = false } alloy-rpc-client = { version = "1.0.13", default-features = false } alloy-rpc-types-engine = { version = "1.0.13", default-features = false } @@ -185,7 +185,7 @@ scroll-wire = { path = "crates/scroll-wire" } scroll-migration = { path = "crates/database/migration" } # misc -arbitrary = { version = "1.4", default-features = false } +arbitrary = { version = "1.4", default-features = false, features = ["derive"] } async-trait = "0.1" auto_impl = "1.2" bitvec = { version = "1.0", default-features = false } diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 00000000..40fa48e2 --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,51 @@ +FROM rust:1.88.0 AS chef + +ARG CARGO_FEATURES="" + +# Install basic packages +RUN apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config +RUN cargo install cargo-chef --locked --version 0.1.71 + +FROM chef AS planner +WORKDIR /app + +COPY . . +# Hacky: Replace tests with dummy stub to avoid workspace member issues of top-level Cargo.toml. +# This is needed because within the Docker integration tests we don't need the tests crate +# and want to avoid rebuilding it on every change. +RUN mkdir -p tests/src && \ + echo '[package]' > tests/Cargo.toml && \ + echo 'name = "tests"' >> tests/Cargo.toml && \ + echo 'version = "0.0.1"' >> tests/Cargo.toml && \ + echo 'edition = "2021"' >> tests/Cargo.toml && \ + echo '' >> tests/Cargo.toml && \ + echo '[lib]' >> tests/Cargo.toml && \ + echo 'name = "tests"' >> tests/Cargo.toml && \ + echo 'path = "src/lib.rs"' >> tests/Cargo.toml && \ + echo 'pub fn dummy() {}' > tests/src/lib.rs +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + cargo chef prepare --recipe-path /recipe.json + +FROM chef AS builder +WORKDIR /app +COPY --from=planner /recipe.json recipe.json +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + cargo chef cook --release --recipe-path recipe.json + +COPY . . +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + cargo build ${CARGO_FEATURES:+--features $CARGO_FEATURES} --release --target-dir=/app-target + +# Release +FROM debian:bookworm-slim + +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl sqlite3 && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /app-target/release/rollup-node /bin/ + +EXPOSE 30303 30303/udp 9001 8545 8546 + +ENTRYPOINT ["rollup-node"] diff --git a/Dockerfile.test.dockerignore b/Dockerfile.test.dockerignore new file mode 100644 index 00000000..c152cc23 --- /dev/null +++ b/Dockerfile.test.dockerignore @@ -0,0 +1,14 @@ +# exclude everything +* + +# include source files +!/bin +!/crates +!/testing +!book.toml +!Cargo.lock +!Cargo.toml +!Cross.toml +!deny.toml +!Makefile + diff --git a/crates/node/src/args.rs b/crates/node/src/args.rs index 99dee50b..01a1d3dd 100644 --- a/crates/node/src/args.rs +++ b/crates/node/src/args.rs @@ -211,6 +211,8 @@ impl ScrollRollupNodeConfig { db.insert_genesis_block(genesis_hash) .await .expect("failed to insert genesis block (custom chain)"); + + tracing::info!(target: "scroll::node::args", ?genesis_hash, "Overwriting genesis hash for custom chain"); } // Wrap the database in an Arc diff --git a/crates/node/tests/e2e.rs b/crates/node/tests/e2e.rs index fb03792e..63986d7c 100644 --- a/crates/node/tests/e2e.rs +++ b/crates/node/tests/e2e.rs @@ -1322,9 +1322,10 @@ async fn test_custom_genesis_block_production_and_propagation() -> eyre::Result< "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", "l1MessageQueueV2Address": "0x000000000000000000000000000000000003dead", "scrollChainAddress": "0x000000000000000000000000000000000003dead", - "l2SystemConfigAddress": "0x000000000000000000000000000000000003dead", + "l2SystemConfigAddress": "0x0000000000000000000000000000000dddd3dead", + "systemContractAddress": "0x110000000000000000000000000000000003dead", "numL1MessagesPerBlock": 10, - "l1MessageQueueV2DeploymentBlock": 12345 + "startL1Block": 12345 } } }, diff --git a/crates/primitives/src/node/config.rs b/crates/primitives/src/node/config.rs index 489307c3..69dfab40 100644 --- a/crates/primitives/src/node/config.rs +++ b/crates/primitives/src/node/config.rs @@ -96,27 +96,59 @@ impl NodeConfig { return Ok(Self::from_named_chain(named_chain)); } + // Note: It is important to make sure the chain id is not a named chain accidentally. + // For example, a custom `chain id=1337` will be treated as a named chain as it + // matches the dev chain. https://github.com/scroll-tech/rollup-node/issues/303 // If not a named chain, extract the configuration from the chain spec let config = chain_spec.chain_config(); let genesis = chain_spec.genesis(); - let l1_message_queue_v2_deployment_block = genesis + + // let l1_message_queue_v2_deployment_block = genesis + // .config + // .extra_fields + // .get("scroll") + // .and_then(|scroll| scroll.get("l1Config")) + // .and_then(|l1_config| l1_config.get("l1MessageQueueV2DeploymentBlock")) + // .and_then(|v| v.as_u64()) + // .ok_or_else(|| eyre::eyre!("Invalid or missing 'l1MessageQueueV2DeploymentBlock'"))?; + + let start_l1_block = genesis .config .extra_fields .get("scroll") .and_then(|scroll| scroll.get("l1Config")) - .and_then(|l1_config| l1_config.get("l1MessageQueueV2DeploymentBlock")) + .and_then(|l1_config| l1_config.get("startL1Block")) .and_then(|v| v.as_u64()) - .ok_or_else(|| eyre::eyre!("Invalid or missing 'l1MessageQueueV2DeploymentBlock'"))?; + .ok_or_else(|| eyre::eyre!("Invalid or missing 'startL1Block'"))?; + + let system_contract_address = genesis + .config + .extra_fields + .get("scroll") + .and_then(|scroll| scroll.get("l1Config")) + .and_then(|l1_config| l1_config.get("systemContractAddress")) + .and_then(|v| v.as_str()) + .and_then(|s| s.parse().ok()) + .ok_or_else(|| eyre::eyre!("Invalid or missing 'systemContractAddress'"))?; + + // TODO: + // - config.l1_config.l2_system_config_address is not used here. + // - start_l1_block is not present currently in the config. + // - system_contract_address is not extracted from the config in https://github.com/scroll-tech/reth/blob/scroll/crates/scroll/chainspec/src/genesis.rs#L20 + // - do we need: l1_message_queue_v2_deployment_block? maybe instead we could use + // v2_message_queue_starting_index + // - ultimately we want to make sure all relevant config is extracted from `ScrollChainInfo` + // and not partially here. see https://github.com/scroll-tech/rollup-node/issues/303 Ok(Self { address_book: ScrollAddressBook { rollup_node_contract_address: config.l1_config.scroll_chain_address, v1_message_queue_address: config.l1_config.l1_message_queue_address, v2_message_queue_address: config.l1_config.l1_message_queue_v2_address, - system_contract_address: config.l1_config.l2_system_config_address, + system_contract_address, }, - start_l1_block: l1_message_queue_v2_deployment_block, + start_l1_block, }) } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 41693cf8..2c8b9aba 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -17,3 +17,6 @@ tokio = { workspace = true, features = ["rt", "time"] } eyre = { workspace = true } getrandom = { workspace = true } tracing = { workspace = true } +reth-tracing = { workspace = true } +serde = { workspace = true } +serde_json = "1.0" diff --git a/tests/discovery-secret b/tests/discovery-secret deleted file mode 100644 index cb3c2aa5..00000000 --- a/tests/discovery-secret +++ /dev/null @@ -1 +0,0 @@ -6381271558bd1ae75c7b092553e3ecc04b104c38f34e126399ce4da4fd5e8730 \ No newline at end of file diff --git a/tests/docker-compose.test.yml b/tests/docker-compose.test.yml index 2212d3ec..e840d9dd 100644 --- a/tests/docker-compose.test.yml +++ b/tests/docker-compose.test.yml @@ -1,51 +1,91 @@ -version: '3.8' - services: + l1-node: + image: ghcr.io/foundry-rs/foundry:latest + container_name: l1-node + entrypoint: [ "bash", "/launch_l1.bash" ] + ports: + - "8544:8545" + volumes: + - ./launch_l1.bash:/launch_l1.bash:ro + healthcheck: + test: ["CMD", "bash", "-c", "[ \"$(cast storage 0x55B150d210356452e4E79cCb6B778b4e1B167091 0x67 --rpc-url http://localhost:8545)\" = \"0x000000000000000000000000b674ff99cca262c99d3eab5b32796a99188543da\" ]"] + interval: 3s + timeout: 10s + retries: 30 + start_period: 0s + rollup-node-sequencer: build: context: ../ - dockerfile: Dockerfile + dockerfile: Dockerfile.test container_name: rollup-node-sequencer entrypoint: ["bash", "/launch_rollup_node_sequencer.bash"] environment: - - ENV=dev - RUST_LOG=info ports: - "8545:8545" # JSON-RPC - - "8546:8546" # WebSocket - "6060:6060" # Metrics volumes: - ./launch_rollup_node_sequencer.bash:/launch_rollup_node_sequencer.bash:ro - - ./discovery-secret:/l2reth/discovery-secret:ro + - ./l2reth-genesis-e2e.json:/l2reth/l2reth-genesis-e2e.json:ro - l2reth-sequencer:/l2reth - networks: - - test-scroll-network + depends_on: + l1-node: + condition: service_healthy rollup-node-follower: build: context: ../ - dockerfile: Dockerfile + dockerfile: Dockerfile.test container_name: rollup-node-follower entrypoint: ["bash", "/launch_rollup_node_follower.bash"] environment: - - ENV=dev - RUST_LOG=info ports: - - "8547:8545" # JSON-RPC - - "8548:8546" # WebSocket + - "8546:8545" # JSON-RPC - "6061:6060" # Metrics volumes: - ./launch_rollup_node_follower.bash:/launch_rollup_node_follower.bash:ro + - ./l2reth-genesis-e2e.json:/l2reth/l2reth-genesis-e2e.json:ro - l2reth-follower:/l2reth - networks: - - test-scroll-network depends_on: - - rollup-node-sequencer + l1-node: + condition: service_healthy -networks: - test-scroll-network: - driver: bridge + l2geth-sequencer: + image: scrolltech/l2geth:scroll-v5.9.4 + platform: linux/amd64 + container_name: l2geth-sequencer + entrypoint: ["bash", "/launch_l2geth.bash"] + ports: + - "8547:8545" # JSON-RPC + - "6062:6060" # Metrics + volumes: + - ./l2geth-genesis-e2e.json:/l2geth-genesis-e2e.json:ro + - ./launch_l2geth_sequencer.bash:/launch_l2geth.bash:ro + - l2geth-sequencer:/l2geth + depends_on: + l1-node: + condition: service_healthy + + l2geth-follower: + image: scrolltech/l2geth:scroll-v5.9.4 + platform: linux/amd64 + container_name: l2geth-follower + entrypoint: ["bash", "/launch_l2geth.bash"] + ports: + - "8548:8545" # JSON-RPC + - "6063:6060" # Metrics + volumes: + - ./l2geth-genesis-e2e.json:/l2geth-genesis-e2e.json:ro + - ./launch_l2geth_follower.bash:/launch_l2geth.bash:ro + - l2geth-follower:/l2geth + depends_on: + l1-node: + condition: service_healthy volumes: l2reth-sequencer: l2reth-follower: + l2geth-sequencer: + l2geth-follower: diff --git a/tests/l2geth-genesis-e2e.json b/tests/l2geth-genesis-e2e.json new file mode 100644 index 00000000..a63be7b0 --- /dev/null +++ b/tests/l2geth-genesis-e2e.json @@ -0,0 +1,114 @@ +{ + "config": { + "chainId": 938471, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "archimedesBlock": 0, + "shanghaiBlock": 0, + "bernoulliBlock": 0, + "curieBlock": 0, + "darwinTime": 0, + "darwinV2Time": 0, + "euclidTime": 0, + "euclidV2Time": 0, + "feynmanTime": 0, + "systemContract": { + "period": 1, + "system_contract_address": "0x55B150d210356452e4E79cCb6B778b4e1B167091", + "system_contract_slot": "0x0000000000000000000000000000000000000000000000000000000000000067" + }, + "scroll": { + "useZktrie": false, + "maxTxPerBlock": 100, + "maxTxPayloadBytesPerBlock": 122880, + "feeVaultAddress": "0x5300000000000000000000000000000000000005", + "l1Config": { + "l1ChainId": "22222222", + "l1MessageQueueAddress": "0x0000000000000000000000000000000000000001", + "l1MessageQueueV2Address": "0x160dd98613ba6C6E0a14086a87cf36244558422E", + "l1MessageQueueV2DeploymentBlock": 0, + "scrollChainAddress": "0x84044d3a645843bAF0752eA591E1EAB643beD904", + "l2SystemConfigAddress": "0x2E48aC0df81f1fa57722e115e807C9dB1819bA13", + "numL1MessagesPerBlock": "10" + } + } + }, + "nonce": "0x0", + "timestamp": "0x00000000000000000000000000000000000000000000000000000000689b3f30", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "30000000", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0x1", + "alloc": { + "0x4e59b44847b379578588920ca78fbf26c0b4956c": { + "balance": "0x0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + "nonce": "0x1", + "storage": {} + }, + "0x5300000000000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c806383cc76601161006357806383cc7660146100f85780638da5cb5b1461010b578063c4d66de81461011e578063d4b9f4fa14610131578063f2fde38b14610139575f80fd5b806326aad7b7146100945780633cb747bf146100b0578063600a2e77146100db578063715018a6146100ee575b5f80fd5b61009d60015481565b6040519081526020015b60405180910390f35b6053546100c3906001600160a01b031681565b6040516001600160a01b0390911681526020016100a7565b61009d6100e9366004610539565b61014c565b6100f66101ef565b005b61009d610106366004610539565b610224565b6052546100c3906001600160a01b031681565b6100f661012c366004610550565b61023a565b61009d5f5481565b6100f6610147366004610550565b6102d2565b6053545f906001600160a01b0316331461019e5760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b5f806101a98461035e565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102195760405162461bcd60e51b81526004016101959061057d565b6102225f610477565b565b602a8160288110610233575f80fd5b0154905081565b6052546001600160a01b031633146102645760405162461bcd60e51b81526004016101959061057d565b600154156102a85760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b6044820152606401610195565b6102b06104c8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146102fc5760405162461bcd60e51b81526004016101959061057d565b6001600160a01b0381166103525760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f20616464726573730000006044820152606401610195565b61035b81610477565b50565b6003545f9081906103b15760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e0000000000006044820152606401610195565b600154835f5b8215610448576103c86002846105c8565b5f036104125781602a82602881106103e2576103e26105b4565b015561040b82600283602881106103fb576103fb6105b4565b01545f9182526020526040902090565b915061043c565b610439602a8260288110610428576104286105b4565b0154835f9182526020526040902090565b91505b600192831c92016103b7565b81602a826028811061045c5761045c6105b4565b0155505f819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f5b60286104d78260016105fb565b101561035b57610508600282602881106104f3576104f36105b4565b0154600283602881106103fb576103fb6105b4565b60026105158360016105fb565b60288110610525576105256105b4565b01558061053181610614565b9150506104ca565b5f60208284031215610549575f80fd5b5035919050565b5f60208284031215610560575f80fd5b81356001600160a01b0381168114610576575f80fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b5f826105e257634e487b7160e01b5f52601260045260245ffd5b500690565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060e5761060e6105e7565b92915050565b5f60018201610625576106256105e7565b506001019056fea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000052": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0x5300000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106101a1575f3560e01c806384189161116100f3578063c63b9e2d11610093578063e88a60ad1161006e578063e88a60ad1461032e578063f2fde38b14610341578063f45e65d814610354578063fe5b04151461035d575f80fd5b8063c63b9e2d146102ff578063c91e514914610312578063de26c4a11461031b575f80fd5b8063944b247f116100ce578063944b247f146102be578063a911d77f146102d1578063aa5e9334146102d9578063bede39b5146102ec575f80fd5b806384189161146102785780638da5cb5b1461028157806393e59dc1146102ab575f80fd5b80633d0f963e1161015e5780636112d6db116101395780636112d6db1461024b5780636a5e67e514610254578063704655971461025d578063715018a614610270575f80fd5b80633d0f963e1461021c57806349948e0e1461022f578063519b4bd314610242575f80fd5b80630c18c162146101a557806313dad5be146101c157806323e524ac146101de5780633577afc5146101e757806339455d3a146101fc5780633b7656bb1461020f575b5f80fd5b6101ae60025481565b6040519081526020015b60405180910390f35b6008546101ce9060ff1681565b60405190151581526020016101b8565b6101ae60065481565b6101fa6101f5366004610c73565b610365565b005b6101fa61020a366004610c8a565b6103f7565b600b546101ce9060ff1681565b6101fa61022a366004610caa565b6104f4565b6101ae61023d366004610ceb565b610577565b6101ae60015481565b6101ae600a5481565b6101ae60075481565b6101fa61026b366004610c73565b6105b0565b6101fa61063e565b6101ae60055481565b5f54610293906001600160a01b031681565b6040516001600160a01b0390911681526020016101b8565b600454610293906001600160a01b031681565b6101fa6102cc366004610c73565b610672565b6101fa6106fe565b6101fa6102e7366004610c73565b61075a565b6101fa6102fa366004610c73565b6107f4565b6101fa61030d366004610c73565b6108b1565b6101ae60095481565b6101ae610329366004610ceb565b61094a565b6101fa61033c366004610c73565b610974565b6101fa61034f366004610caa565b610a00565b6101ae60035481565b6101fa610a8b565b5f546001600160a01b031633146103975760405162461bcd60e51b815260040161038e90610d96565b60405180910390fd5b621c9c388111156103bb57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561043e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104629190610dcd565b61047f576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b0316331461051d5760405162461bcd60e51b815260040161038e90610d96565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f791016104e8565b600b545f9060ff16156105935761058d82610ae7565b92915050565b60085460ff16156105a75761058d82610b45565b61058d82610b81565b5f546001600160a01b031633146105d95760405162461bcd60e51b815260040161038e90610d96565b6105e9633b9aca006103e8610e00565b81111561060957604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a906020016103ec565b5f546001600160a01b031633146106675760405162461bcd60e51b815260040161038e90610d96565b6106705f610bc4565b565b5f546001600160a01b0316331461069b5760405162461bcd60e51b815260040161038e90610d96565b6106a9633b9aca0080610e00565b8111156106c95760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a108906020016103ec565b5f546001600160a01b031633146107275760405162461bcd60e51b815260040161038e90610d96565b60085460ff161561074b576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b5f546001600160a01b031633146107835760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806107a1575061079e633b9aca0080610e00565b81115b156107bf5760405163d9b5dcdf60e01b815260040160405180910390fd5b60098190556040518181527fd50d3079c77df569cd58d55d4e5614bfe7066449009425d22bde8e75242f50bb906020016103ec565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561083b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085f9190610dcd565b61087c576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44906020016103ec565b5f546001600160a01b031633146108da5760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806108f857506108f5633b9aca0080610e00565b81115b156109155760405162ae184360e01b815260040160405180910390fd5b600a8190556040518181527f8647cebb7e57360673a28415c0bed2f68c42a86c5035f1c9b2eda2b09509288a906020016103ec565b600b545f9060ff168061095f575060085460ff165b1561096b57505f919050565b61058d82610c13565b5f546001600160a01b0316331461099d5760405162461bcd60e51b815260040161038e90610d96565b6109ab633b9aca0080610e00565b8111156109cb5760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa906020016103ec565b5f546001600160a01b03163314610a295760405162461bcd60e51b815260040161038e90610d96565b6001600160a01b038116610a7f5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161038e565b610a8881610bc4565b50565b5f546001600160a01b03163314610ab45760405162461bcd60e51b815260040161038e90610d96565b600b5460ff1615610ad857604051631a7c228b60e21b815260040160405180910390fd5b600b805460ff19166001179055565b5f633b9aca0080600a548451600554600754610b039190610e00565b600154600654610b139190610e00565b610b1d9190610e17565b610b279190610e00565b610b319190610e00565b610b3b9190610e2a565b61058d9190610e2a565b5f633b9aca006005548351600754610b5d9190610e00565b610b679190610e00565b600154600654610b779190610e00565b610b3b9190610e17565b5f80610b8c83610c13565b90505f60015482610b9d9190610e00565b9050633b9aca0060035482610bb29190610e00565b610bbc9190610e2a565b949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b81811015610c6457848181518110610c3557610c35610e49565b01602001516001600160f81b0319165f03610c5557600483019250610c5c565b6010830192505b600101610c1b565b50506002540160400192915050565b5f60208284031215610c83575f80fd5b5035919050565b5f8060408385031215610c9b575f80fd5b50508035926020909101359150565b5f60208284031215610cba575f80fd5b81356001600160a01b0381168114610cd0575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610cfb575f80fd5b813567ffffffffffffffff80821115610d12575f80fd5b818401915084601f830112610d25575f80fd5b813581811115610d3757610d37610cd7565b604051601f8201601f19908116603f01168101908382118183101715610d5f57610d5f610cd7565b81604052828152876020848701011115610d77575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610ddd575f80fd5b81518015158114610cd0575f80fd5b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761058d5761058d610dec565b8082018082111561058d5761058d610dec565b5f82610e4457634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000009": "0x000000000000000000000000000000000000000000000000000000003b9aca00", + "0x000000000000000000000000000000000000000000000000000000000000000a": "0x000000000000000000000000000000000000000000000000000000003b9aca00", + "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + }, + "0x5300000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610055575f3560e01c8063715018a61461005957806379586dd7146100635780638da5cb5b14610076578063efc78401146100a5578063f2fde38b146100e0575b5f80fd5b6100616100f3565b005b61006161007136600461033a565b610130565b5f54610088906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d06100b336600461040c565b6001600160a01b03165f9081526001602052604090205460ff1690565b604051901515815260200161009c565b6100616100ee36600461040c565b610222565b5f546001600160a01b031633146101255760405162461bcd60e51b815260040161011c9061042c565b60405180910390fd5b61012e5f6102ad565b565b5f546001600160a01b031633146101595760405162461bcd60e51b815260040161011c9061042c565b5f5b825181101561021d578160015f85848151811061017a5761017a610463565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff0219169083151502179055508281815181106101c9576101c9610463565b60200260200101516001600160a01b03167f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d8360405161020d911515815260200190565b60405180910390a260010161015b565b505050565b5f546001600160a01b0316331461024b5760405162461bcd60e51b815260040161011c9061042c565b6001600160a01b0381166102a15760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161011c565b6102aa816102ad565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b5f52604160045260245ffd5b80356001600160a01b0381168114610326575f80fd5b919050565b80358015158114610326575f80fd5b5f806040838503121561034b575f80fd5b823567ffffffffffffffff80821115610362575f80fd5b818501915085601f830112610375575f80fd5b8135602082821115610389576103896102fc565b8160051b604051601f19603f830116810181811086821117156103ae576103ae6102fc565b6040529283528183019350848101820192898411156103cb575f80fd5b948201945b838610156103f0576103e186610310565b855294820194938201936103d0565b96506103ff905087820161032b565b9450505050509250929050565b5f6020828403121561041c575f80fd5b61042582610310565b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0x5300000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x6080604052600436106100a8575f3560e01c806384411d651161006257806384411d651461017a5780638da5cb5b1461018f5780639e7adc79146101ad578063f2fde38b146101cc578063feec756c146101eb578063ff4f35461461020a575f80fd5b80632e1a7d4d146100b35780633cb747bf146100d45780633ccfd60b14610110578063457e1a491461012457806366d003ac14610147578063715018a614610166575f80fd5b366100af57005b5f80fd5b3480156100be575f80fd5b506100d26100cd366004610663565b610229565b005b3480156100df575f80fd5b506002546100f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561011b575f80fd5b506100d26103e9565b34801561012f575f80fd5b5061013960015481565b604051908152602001610107565b348015610152575f80fd5b506003546100f3906001600160a01b031681565b348015610171575f80fd5b506100d26103f6565b348015610185575f80fd5b5061013960045481565b34801561019a575f80fd5b505f546100f3906001600160a01b031681565b3480156101b8575f80fd5b506100d26101c736600461067a565b61042a565b3480156101d7575f80fd5b506100d26101e636600461067a565b6104a4565b3480156101f6575f80fd5b506100d261020536600461067a565b61052c565b348015610215575f80fd5b506100d2610224366004610663565b6105a6565b6001548110156102b95760405162461bcd60e51b815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d20776974686472616064820152691dd85b08185b5bdd5b9d60b21b608482015260a4015b60405180910390fd5b478082111561031d5760405162461bcd60e51b815260206004820152602a60248201527f4665655661756c743a20696e73756666696369656e742062616c616e636520746044820152696f20776974686472617760b01b60648201526084016102b0565b6004805483019055600354604080518481526001600160a01b0390921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1600254600354604080516020810182525f808252915163b2267a7b60e01b81526001600160a01b039485169463b2267a7b9488946103b79491909216928592906004016106a7565b5f604051808303818588803b1580156103ce575f80fd5b505af11580156103e0573d5f803e3d5ffd5b50505050505050565b476103f381610229565b50565b5f546001600160a01b0316331461041f5760405162461bcd60e51b81526004016102b090610711565b6104285f610614565b565b5f546001600160a01b031633146104535760405162461bcd60e51b81526004016102b090610711565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f1c928c417a10a21c3cddad148c5dba5d710e4b1442d6d8a36de345935ad84612905f90a35050565b5f546001600160a01b031633146104cd5760405162461bcd60e51b81526004016102b090610711565b6001600160a01b0381166105235760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016102b0565b6103f381610614565b5f546001600160a01b031633146105555760405162461bcd60e51b81526004016102b090610711565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f7e1e96961a397c8aa26162fe259cc837afc95e33aad4945ddc61c18dabb7a6ad905f90a35050565b5f546001600160a01b031633146105cf5760405162461bcd60e51b81526004016102b090610711565b600180549082905560408051828152602081018490527f0d3c80219fe57713b9f9c83d1e51426792d0c14d8e330e65b102571816140965910160405180910390a15050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610673575f80fd5b5035919050565b5f6020828403121561068a575f80fd5b81356001600160a01b03811681146106a0575f80fd5b9392505050565b60018060a01b03851681525f60208560208401526080604084015284518060808501525f5b818110156106e85786810183015185820160a0015282016106cc565b505f60a0828601015260a0601f19601f8301168501019250505082606083015295945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060408201526060019056fea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000df45f4790e20509959fccc0d09245b216abdaa37", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0xdf45f4790e20509959fccc0d09245b216abdaa37": { + "balance": "0x7ffffffffffffffffffffffffffffffffffffffffffffff21f494c589c0000", + "code": "0x", + "nonce": "0x0", + "storage": { + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0xde0b6b3a7640000", + "code": "0x", + "nonce": "0x1", + "storage": {} + } + } +} diff --git a/tests/l2reth-genesis-e2e.json b/tests/l2reth-genesis-e2e.json new file mode 100644 index 00000000..2d8e461e --- /dev/null +++ b/tests/l2reth-genesis-e2e.json @@ -0,0 +1,108 @@ +{ + "config": { + "chainId": 938471, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "archimedesBlock": 0, + "shanghaiBlock": 0, + "bernoulliBlock": 0, + "curieBlock": 0, + "darwinTime": 0, + "darwinV2Time": 0, + "euclidTime": 0, + "euclidV2Time": 0, + "feynmanTime": 0, + "scroll": { + "maxTxPayloadBytesPerBlock": 122880, + "feeVaultAddress": "0x5300000000000000000000000000000000000005", + "l1Config": { + "l1ChainId": 22222222, + "l1MessageQueueAddress": "0x0000000000000000000000000000000000000001", + "l1MessageQueueV2Address": "0x160dd98613ba6C6E0a14086a87cf36244558422E", + "scrollChainAddress": "0x84044d3a645843bAF0752eA591E1EAB643beD904", + "systemContractAddress": "0x55B150d210356452e4E79cCb6B778b4e1B167091", + "l2SystemConfigAddress": "0x2E48aC0df81f1fa57722e115e807C9dB1819bA13", + "numL1MessagesPerBlock": 10, + "startL1Block": 0 + } + } + }, + "nonce": "0x0", + "timestamp": "0x00000000000000000000000000000000000000000000000000000000689b3f30", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "30000000", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0x1", + "alloc": { + "0x4e59b44847b379578588920ca78fbf26c0b4956c": { + "balance": "0x0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + "nonce": "0x1", + "storage": {} + }, + "0x5300000000000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c806383cc76601161006357806383cc7660146100f85780638da5cb5b1461010b578063c4d66de81461011e578063d4b9f4fa14610131578063f2fde38b14610139575f80fd5b806326aad7b7146100945780633cb747bf146100b0578063600a2e77146100db578063715018a6146100ee575b5f80fd5b61009d60015481565b6040519081526020015b60405180910390f35b6053546100c3906001600160a01b031681565b6040516001600160a01b0390911681526020016100a7565b61009d6100e9366004610539565b61014c565b6100f66101ef565b005b61009d610106366004610539565b610224565b6052546100c3906001600160a01b031681565b6100f661012c366004610550565b61023a565b61009d5f5481565b6100f6610147366004610550565b6102d2565b6053545f906001600160a01b0316331461019e5760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b5f806101a98461035e565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102195760405162461bcd60e51b81526004016101959061057d565b6102225f610477565b565b602a8160288110610233575f80fd5b0154905081565b6052546001600160a01b031633146102645760405162461bcd60e51b81526004016101959061057d565b600154156102a85760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b6044820152606401610195565b6102b06104c8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146102fc5760405162461bcd60e51b81526004016101959061057d565b6001600160a01b0381166103525760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f20616464726573730000006044820152606401610195565b61035b81610477565b50565b6003545f9081906103b15760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e0000000000006044820152606401610195565b600154835f5b8215610448576103c86002846105c8565b5f036104125781602a82602881106103e2576103e26105b4565b015561040b82600283602881106103fb576103fb6105b4565b01545f9182526020526040902090565b915061043c565b610439602a8260288110610428576104286105b4565b0154835f9182526020526040902090565b91505b600192831c92016103b7565b81602a826028811061045c5761045c6105b4565b0155505f819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f5b60286104d78260016105fb565b101561035b57610508600282602881106104f3576104f36105b4565b0154600283602881106103fb576103fb6105b4565b60026105158360016105fb565b60288110610525576105256105b4565b01558061053181610614565b9150506104ca565b5f60208284031215610549575f80fd5b5035919050565b5f60208284031215610560575f80fd5b81356001600160a01b0381168114610576575f80fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b5f826105e257634e487b7160e01b5f52601260045260245ffd5b500690565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060e5761060e6105e7565b92915050565b5f60018201610625576106256105e7565b506001019056fea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000052": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0x5300000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106101a1575f3560e01c806384189161116100f3578063c63b9e2d11610093578063e88a60ad1161006e578063e88a60ad1461032e578063f2fde38b14610341578063f45e65d814610354578063fe5b04151461035d575f80fd5b8063c63b9e2d146102ff578063c91e514914610312578063de26c4a11461031b575f80fd5b8063944b247f116100ce578063944b247f146102be578063a911d77f146102d1578063aa5e9334146102d9578063bede39b5146102ec575f80fd5b806384189161146102785780638da5cb5b1461028157806393e59dc1146102ab575f80fd5b80633d0f963e1161015e5780636112d6db116101395780636112d6db1461024b5780636a5e67e514610254578063704655971461025d578063715018a614610270575f80fd5b80633d0f963e1461021c57806349948e0e1461022f578063519b4bd314610242575f80fd5b80630c18c162146101a557806313dad5be146101c157806323e524ac146101de5780633577afc5146101e757806339455d3a146101fc5780633b7656bb1461020f575b5f80fd5b6101ae60025481565b6040519081526020015b60405180910390f35b6008546101ce9060ff1681565b60405190151581526020016101b8565b6101ae60065481565b6101fa6101f5366004610c73565b610365565b005b6101fa61020a366004610c8a565b6103f7565b600b546101ce9060ff1681565b6101fa61022a366004610caa565b6104f4565b6101ae61023d366004610ceb565b610577565b6101ae60015481565b6101ae600a5481565b6101ae60075481565b6101fa61026b366004610c73565b6105b0565b6101fa61063e565b6101ae60055481565b5f54610293906001600160a01b031681565b6040516001600160a01b0390911681526020016101b8565b600454610293906001600160a01b031681565b6101fa6102cc366004610c73565b610672565b6101fa6106fe565b6101fa6102e7366004610c73565b61075a565b6101fa6102fa366004610c73565b6107f4565b6101fa61030d366004610c73565b6108b1565b6101ae60095481565b6101ae610329366004610ceb565b61094a565b6101fa61033c366004610c73565b610974565b6101fa61034f366004610caa565b610a00565b6101ae60035481565b6101fa610a8b565b5f546001600160a01b031633146103975760405162461bcd60e51b815260040161038e90610d96565b60405180910390fd5b621c9c388111156103bb57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561043e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104629190610dcd565b61047f576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b0316331461051d5760405162461bcd60e51b815260040161038e90610d96565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f791016104e8565b600b545f9060ff16156105935761058d82610ae7565b92915050565b60085460ff16156105a75761058d82610b45565b61058d82610b81565b5f546001600160a01b031633146105d95760405162461bcd60e51b815260040161038e90610d96565b6105e9633b9aca006103e8610e00565b81111561060957604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a906020016103ec565b5f546001600160a01b031633146106675760405162461bcd60e51b815260040161038e90610d96565b6106705f610bc4565b565b5f546001600160a01b0316331461069b5760405162461bcd60e51b815260040161038e90610d96565b6106a9633b9aca0080610e00565b8111156106c95760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a108906020016103ec565b5f546001600160a01b031633146107275760405162461bcd60e51b815260040161038e90610d96565b60085460ff161561074b576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b5f546001600160a01b031633146107835760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806107a1575061079e633b9aca0080610e00565b81115b156107bf5760405163d9b5dcdf60e01b815260040160405180910390fd5b60098190556040518181527fd50d3079c77df569cd58d55d4e5614bfe7066449009425d22bde8e75242f50bb906020016103ec565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561083b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085f9190610dcd565b61087c576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44906020016103ec565b5f546001600160a01b031633146108da5760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806108f857506108f5633b9aca0080610e00565b81115b156109155760405162ae184360e01b815260040160405180910390fd5b600a8190556040518181527f8647cebb7e57360673a28415c0bed2f68c42a86c5035f1c9b2eda2b09509288a906020016103ec565b600b545f9060ff168061095f575060085460ff165b1561096b57505f919050565b61058d82610c13565b5f546001600160a01b0316331461099d5760405162461bcd60e51b815260040161038e90610d96565b6109ab633b9aca0080610e00565b8111156109cb5760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa906020016103ec565b5f546001600160a01b03163314610a295760405162461bcd60e51b815260040161038e90610d96565b6001600160a01b038116610a7f5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161038e565b610a8881610bc4565b50565b5f546001600160a01b03163314610ab45760405162461bcd60e51b815260040161038e90610d96565b600b5460ff1615610ad857604051631a7c228b60e21b815260040160405180910390fd5b600b805460ff19166001179055565b5f633b9aca0080600a548451600554600754610b039190610e00565b600154600654610b139190610e00565b610b1d9190610e17565b610b279190610e00565b610b319190610e00565b610b3b9190610e2a565b61058d9190610e2a565b5f633b9aca006005548351600754610b5d9190610e00565b610b679190610e00565b600154600654610b779190610e00565b610b3b9190610e17565b5f80610b8c83610c13565b90505f60015482610b9d9190610e00565b9050633b9aca0060035482610bb29190610e00565b610bbc9190610e2a565b949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b81811015610c6457848181518110610c3557610c35610e49565b01602001516001600160f81b0319165f03610c5557600483019250610c5c565b6010830192505b600101610c1b565b50506002540160400192915050565b5f60208284031215610c83575f80fd5b5035919050565b5f8060408385031215610c9b575f80fd5b50508035926020909101359150565b5f60208284031215610cba575f80fd5b81356001600160a01b0381168114610cd0575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610cfb575f80fd5b813567ffffffffffffffff80821115610d12575f80fd5b818401915084601f830112610d25575f80fd5b813581811115610d3757610d37610cd7565b604051601f8201601f19908116603f01168101908382118183101715610d5f57610d5f610cd7565b81604052828152876020848701011115610d77575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610ddd575f80fd5b81518015158114610cd0575f80fd5b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761058d5761058d610dec565b8082018082111561058d5761058d610dec565b5f82610e4457634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000009": "0x000000000000000000000000000000000000000000000000000000003b9aca00", + "0x000000000000000000000000000000000000000000000000000000000000000a": "0x000000000000000000000000000000000000000000000000000000003b9aca00", + "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + }, + "0x5300000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610055575f3560e01c8063715018a61461005957806379586dd7146100635780638da5cb5b14610076578063efc78401146100a5578063f2fde38b146100e0575b5f80fd5b6100616100f3565b005b61006161007136600461033a565b610130565b5f54610088906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d06100b336600461040c565b6001600160a01b03165f9081526001602052604090205460ff1690565b604051901515815260200161009c565b6100616100ee36600461040c565b610222565b5f546001600160a01b031633146101255760405162461bcd60e51b815260040161011c9061042c565b60405180910390fd5b61012e5f6102ad565b565b5f546001600160a01b031633146101595760405162461bcd60e51b815260040161011c9061042c565b5f5b825181101561021d578160015f85848151811061017a5761017a610463565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff0219169083151502179055508281815181106101c9576101c9610463565b60200260200101516001600160a01b03167f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d8360405161020d911515815260200190565b60405180910390a260010161015b565b505050565b5f546001600160a01b0316331461024b5760405162461bcd60e51b815260040161011c9061042c565b6001600160a01b0381166102a15760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161011c565b6102aa816102ad565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b5f52604160045260245ffd5b80356001600160a01b0381168114610326575f80fd5b919050565b80358015158114610326575f80fd5b5f806040838503121561034b575f80fd5b823567ffffffffffffffff80821115610362575f80fd5b818501915085601f830112610375575f80fd5b8135602082821115610389576103896102fc565b8160051b604051601f19603f830116810181811086821117156103ae576103ae6102fc565b6040529283528183019350848101820192898411156103cb575f80fd5b948201945b838610156103f0576103e186610310565b855294820194938201936103d0565b96506103ff905087820161032b565b9450505050509250929050565b5f6020828403121561041c575f80fd5b61042582610310565b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0x5300000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x6080604052600436106100a8575f3560e01c806384411d651161006257806384411d651461017a5780638da5cb5b1461018f5780639e7adc79146101ad578063f2fde38b146101cc578063feec756c146101eb578063ff4f35461461020a575f80fd5b80632e1a7d4d146100b35780633cb747bf146100d45780633ccfd60b14610110578063457e1a491461012457806366d003ac14610147578063715018a614610166575f80fd5b366100af57005b5f80fd5b3480156100be575f80fd5b506100d26100cd366004610663565b610229565b005b3480156100df575f80fd5b506002546100f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561011b575f80fd5b506100d26103e9565b34801561012f575f80fd5b5061013960015481565b604051908152602001610107565b348015610152575f80fd5b506003546100f3906001600160a01b031681565b348015610171575f80fd5b506100d26103f6565b348015610185575f80fd5b5061013960045481565b34801561019a575f80fd5b505f546100f3906001600160a01b031681565b3480156101b8575f80fd5b506100d26101c736600461067a565b61042a565b3480156101d7575f80fd5b506100d26101e636600461067a565b6104a4565b3480156101f6575f80fd5b506100d261020536600461067a565b61052c565b348015610215575f80fd5b506100d2610224366004610663565b6105a6565b6001548110156102b95760405162461bcd60e51b815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d20776974686472616064820152691dd85b08185b5bdd5b9d60b21b608482015260a4015b60405180910390fd5b478082111561031d5760405162461bcd60e51b815260206004820152602a60248201527f4665655661756c743a20696e73756666696369656e742062616c616e636520746044820152696f20776974686472617760b01b60648201526084016102b0565b6004805483019055600354604080518481526001600160a01b0390921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1600254600354604080516020810182525f808252915163b2267a7b60e01b81526001600160a01b039485169463b2267a7b9488946103b79491909216928592906004016106a7565b5f604051808303818588803b1580156103ce575f80fd5b505af11580156103e0573d5f803e3d5ffd5b50505050505050565b476103f381610229565b50565b5f546001600160a01b0316331461041f5760405162461bcd60e51b81526004016102b090610711565b6104285f610614565b565b5f546001600160a01b031633146104535760405162461bcd60e51b81526004016102b090610711565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f1c928c417a10a21c3cddad148c5dba5d710e4b1442d6d8a36de345935ad84612905f90a35050565b5f546001600160a01b031633146104cd5760405162461bcd60e51b81526004016102b090610711565b6001600160a01b0381166105235760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016102b0565b6103f381610614565b5f546001600160a01b031633146105555760405162461bcd60e51b81526004016102b090610711565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f7e1e96961a397c8aa26162fe259cc837afc95e33aad4945ddc61c18dabb7a6ad905f90a35050565b5f546001600160a01b031633146105cf5760405162461bcd60e51b81526004016102b090610711565b600180549082905560408051828152602081018490527f0d3c80219fe57713b9f9c83d1e51426792d0c14d8e330e65b102571816140965910160405180910390a15050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610673575f80fd5b5035919050565b5f6020828403121561068a575f80fd5b81356001600160a01b03811681146106a0575f80fd5b9392505050565b60018060a01b03851681525f60208560208401526080604084015284518060808501525f5b818110156106e85786810183015185820160a0015282016106cc565b505f60a0828601015260a0601f19601f8301168501019250505082606083015295945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060408201526060019056fea164736f6c6343000818000a", + "nonce": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000df45f4790e20509959fccc0d09245b216abdaa37", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + "0xdf45f4790e20509959fccc0d09245b216abdaa37": { + "balance": "0x7ffffffffffffffffffffffffffffffffffffffffffffff21f494c589c0000", + "code": "0x", + "nonce": "0x0", + "storage": { + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0xde0b6b3a7640000", + "code": "0x", + "nonce": "0x1", + "storage": {} + } + } +} diff --git a/tests/launch_l1.bash b/tests/launch_l1.bash new file mode 100644 index 00000000..c64f011d --- /dev/null +++ b/tests/launch_l1.bash @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -e + +# Start anvil in background +anvil --host 0.0.0.0 --port 8545 --chain-id 22222222 --accounts 10 --balance 10000 --code-size-limit 100000000 & +ANVIL_PID=$! + +# Wait for anvil to start (with retry) +echo "Waiting for anvil to start..." +for i in {1..10}; do + if cast rpc eth_blockNumber --rpc-url http://localhost:8545 > /dev/null 2>&1; then + echo "anvil is ready" + break + fi + sleep 1 + echo "Waiting ($i/10)..." +done + +# Check if anvil is running +if ! cast rpc eth_blockNumber --rpc-url http://localhost:8545 > /dev/null 2>&1; then + echo "Error: anvil failed to start" + exit 1 +fi + +# Set L1 system contract consensus address +echo "Setting system contract consensus address..." +cast rpc anvil_setStorageAt \ + 0x55B150d210356452e4E79cCb6B778b4e1B167091 \ + 0x0000000000000000000000000000000000000000000000000000000000000067 \ + 0x000000000000000000000000b674Ff99cca262c99D3eAb5B32796a99188543dA \ + --rpc-url http://localhost:8545 + +# Verify that storage was set correctly +echo "Verifying storage..." +storage_value=$(cast storage 0x55B150d210356452e4E79cCb6B778b4e1B167091 0x67 --rpc-url http://localhost:8545) +expected_value="0x000000000000000000000000b674ff99cca262c99d3eab5b32796a99188543da" + +if [ "$storage_value" != "$expected_value" ]; then + echo "Error: Storage verify failed" + echo "Expected: $expected_value" + echo "Actual: $storage_value" + exit 1 +fi + +echo "anvil started and configured, PID: $ANVIL_PID" + +# Keep container running +wait $ANVIL_PID diff --git a/tests/launch_l2geth_follower.bash b/tests/launch_l2geth_follower.bash new file mode 100644 index 00000000..0e4b06d3 --- /dev/null +++ b/tests/launch_l2geth_follower.bash @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +geth init --datadir=/l2geth /l2geth-genesis-e2e.json + +# Create config.toml with static nodes instead of bootnodes +echo '[Node.P2P]' > /l2geth/config.toml +echo 'StaticNodes = ["enode://8fc4f6dfd0a2ebf56560d0b0ef5e60ad7bcb01e13f929eae53a4c77086d9c1e74eb8b8c8945035d25c6287afdd871f0d41b3fd7e189697decd0f13538d1ac620@l2geth-sequencer:30303","enode://e7f7e271f62bd2b697add14e6987419758c97e83b0478bd948f5f2d271495728e7edef5bd78ad65258ac910f28e86928ead0c42ee51f2a0168d8ca23ba939766@rollup-node-sequencer:30303"]' >> /l2geth/config.toml + +echo "Starting l2geth as follower..." +exec geth --datadir=/l2geth \ + --config /l2geth/config.toml \ + --port 30303 --syncmode full --networkid 938471 --nodiscover \ + --http --http.addr 0.0.0.0 --http.port 8545 --http.vhosts "*" --http.corsdomain "*" --http.api "eth,scroll,net,web3,debug" \ + --ws --ws.addr 0.0.0.0 --ws.port 8546 --ws.api "eth,scroll,net,web3,debug" \ + --pprof --pprof.addr 0.0.0.0 --pprof.port 6060 --metrics --verbosity 5 --log.debug \ + --l1.endpoint "http://l1-node:8545" --l1.confirmations finalized --l1.sync.startblock 0 \ + --gcmode archive --cache.noprefetch --cache.snapshot=0 --snapshot=false \ + --nat extip:0.0.0.0 diff --git a/tests/launch_l2geth_sequencer.bash b/tests/launch_l2geth_sequencer.bash new file mode 100644 index 00000000..bb6572da --- /dev/null +++ b/tests/launch_l2geth_sequencer.bash @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -e + +geth init --datadir=/l2geth /l2geth-genesis-e2e.json + +# Prepare node key for the sequencer node to have a predictable enode URL +echo "054ad0005a8d36f2eff836902010ca75c306c6051ef22eaa82dc4a8800beb287" > /l2geth/nodekey +# -> enode://8fc4f6dfd0a2ebf56560d0b0ef5e60ad7bcb01e13f929eae53a4c77086d9c1e74eb8b8c8945035d25c6287afdd871f0d41b3fd7e189697decd0f13538d1ac620@l2geth-sequencer:30303 + +# Prepare keystore and password file for the sequencer signer key: generated via `geth account import sequencer-key.txt` +L2GETH_KEYSTORE_STRING='{"address":"b674ff99cca262c99d3eab5b32796a99188543da","crypto":{"cipher":"aes-128-ctr","ciphertext":"e9e92784d60f3434fe7059ca7ec297da40b458429bb3d711eb40615fe39a0253","cipherparams":{"iv":"6d992a9d54ce4c48c16dd02ec6e40f45"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"74526cd2b28edbc3131da62e05e5778ba81086a3b9b07d0a31d31b1320f7e5b2"},"mac":"9947fc130580750dded6a3454addebf7a5b59c7b9fd0da287e43d97c2e47cc79"},"id":"b6f7cacd-2fcb-4142-92bb-4a4dd26a71a3","version":3}' +echo "$L2GETH_KEYSTORE_STRING" > /l2geth/keystore/keystore.json +echo "test" > /l2geth/keystore/password.txt + +# --config /l2geth/config.toml \ +echo "Starting l2geth as sequencer..." +exec geth --datadir=/l2geth \ + --port 30303 --syncmode full --networkid 938471 --nodiscover \ + --http --http.addr 0.0.0.0 --http.port 8545 --http.vhosts "*" --http.corsdomain "*" --http.api "eth,scroll,net,web3,debug,miner" \ + --ws --ws.addr 0.0.0.0 --ws.port 8546 --ws.api "eth,scroll,net,web3,debug,miner" \ + --pprof --pprof.addr 0.0.0.0 --pprof.port 6060 --metrics --verbosity 5 --log.debug \ + --l1.endpoint "http://l1-node:8545" --l1.confirmations finalized --l1.sync.startblock 0 \ + --gcmode archive --cache.noprefetch --cache.snapshot=0 --snapshot=false \ + --nat extip:0.0.0.0 \ + --unlock "0xb674ff99cca262c99d3eab5b32796a99188543da" --password "/l2geth/keystore/password.txt" --allow-insecure-unlock \ + --miner.allowempty diff --git a/tests/launch_rollup_node_follower.bash b/tests/launch_rollup_node_follower.bash index 117608f7..eb3bca81 100644 --- a/tests/launch_rollup_node_follower.bash +++ b/tests/launch_rollup_node_follower.bash @@ -1,13 +1,15 @@ #!/usr/bin/env bash set -e -exec rollup-node node --chain dev --datadir=/l2reth --metrics=0.0.0.0:6060 --network.scroll-wire --network.bridge \ +export RUST_LOG=sqlx=off,scroll=trace,reth=trace,rollup=trace,info + +exec rollup-node node --chain /l2reth/l2reth-genesis-e2e.json --datadir=/l2reth --metrics=0.0.0.0:6060 --network.scroll-wire --network.bridge \ --http --http.addr=0.0.0.0 --http.port=8545 --http.corsdomain "*" --http.api admin,debug,eth,net,trace,txpool,web3,rpc,reth,ots,flashbots,miner,mev \ --ws --ws.addr=0.0.0.0 --ws.port=8546 --ws.api admin,debug,eth,net,trace,txpool,web3,rpc,reth,ots,flashbots,miner,mev \ --log.stdout.format log-fmt -vvv \ - --test \ --txpool.pending-max-count=1000 \ - --builder.gaslimit=20000000 \ + --builder.gaslimit=30000000 \ --rpc.max-connections=5000 \ - --trusted-peers enode://3983278a7cab48862d9ab3187278edf376a0736a7deb55472a5650592f6922ce626a1ea7d74b77b9a679694b343f5e93ea97d5d60a9db4e4b51bb0c23a36d01b@rollup-node-sequencer:30303 \ - --consensus.algorithm=noop + --trusted-peers enode://8fc4f6dfd0a2ebf56560d0b0ef5e60ad7bcb01e13f929eae53a4c77086d9c1e74eb8b8c8945035d25c6287afdd871f0d41b3fd7e189697decd0f13538d1ac620@l2geth-sequencer:30303,enode://e7f7e271f62bd2b697add14e6987419758c97e83b0478bd948f5f2d271495728e7edef5bd78ad65258ac910f28e86928ead0c42ee51f2a0168d8ca23ba939766@rollup-node-sequencer:30303 \ + --engine.sync-at-startup false \ + --l1.url http://l1-node:8545 diff --git a/tests/launch_rollup_node_sequencer.bash b/tests/launch_rollup_node_sequencer.bash index 685ab9ff..5e9d021b 100644 --- a/tests/launch_rollup_node_sequencer.bash +++ b/tests/launch_rollup_node_sequencer.bash @@ -1,17 +1,29 @@ #!/usr/bin/env bash set -e -exec rollup-node node --chain dev --datadir=/l2reth --metrics=0.0.0.0:6060 --network.scroll-wire --network.bridge \ +# Prepare signer key +echo -n "0xd510c4b7c61a604f800c4f06803b1ee14b9a63de345e53426ae50425f2dbb058" > /l2reth/sequencer-key + +# Prepare node key for the sequencer node to have a predictable enode URL +echo -n "01c0d9156e199d89814d4b18e9eb64e25de3927f3f6d27b778177f3ff6b610ad" > /l2reth/nodekey +# -> enode://e7f7e271f62bd2b697add14e6987419758c97e83b0478bd948f5f2d271495728e7edef5bd78ad65258ac910f28e86928ead0c42ee51f2a0168d8ca23ba939766@rollup-node-sequencer:30303 + +export RUST_LOG=sqlx=off,scroll=trace,reth=trace,rollup=trace,info + +exec rollup-node node --chain /l2reth/l2reth-genesis-e2e.json --datadir=/l2reth --metrics=0.0.0.0:6060 --network.scroll-wire --network.bridge \ --http --http.addr=0.0.0.0 --http.port=8545 --http.corsdomain "*" --http.api admin,debug,eth,net,trace,txpool,web3,rpc,reth,ots,flashbots,miner,mev \ --ws --ws.addr=0.0.0.0 --ws.port=8546 --ws.api admin,debug,eth,net,trace,txpool,web3,rpc,reth,ots,flashbots,miner,mev \ --log.stdout.format log-fmt -vvv \ - --test \ --sequencer.enabled \ - --sequencer.auto-start \ - --sequencer.block-time 250 \ - --sequencer.payload-building-duration 230 \ --sequencer.allow-empty-blocks \ + --signer.key-file /l2reth/sequencer-key \ + --sequencer.block-time 1000 \ + --sequencer.payload-building-duration 800 \ --txpool.pending-max-count=1000 \ - --builder.gaslimit=20000000 \ + --builder.gaslimit=30000000 \ --rpc.max-connections=5000 \ - --consensus.algorithm=noop + --p2p-secret-key /l2reth/nodekey \ + --trusted-peers enode://8fc4f6dfd0a2ebf56560d0b0ef5e60ad7bcb01e13f929eae53a4c77086d9c1e74eb8b8c8945035d25c6287afdd871f0d41b3fd7e189697decd0f13538d1ac620@l2geth-sequencer:30303 \ + --engine.sync-at-startup false \ + --l1.url http://l1-node:8545 + diff --git a/tests/src/docker_compose.rs b/tests/src/docker_compose.rs index 06c29a73..f5775b3b 100644 --- a/tests/src/docker_compose.rs +++ b/tests/src/docker_compose.rs @@ -6,18 +6,35 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; +/// A wrapper that combines a provider with its human-readable name for testing +pub struct NamedProvider { + pub provider: Box>, + pub name: &'static str, +} + +impl NamedProvider { + pub fn new(provider: Box>, name: &'static str) -> Self { + Self { provider, name } + } +} + +/// The sequencer node RPC URL for the Docker Compose environment. +const RN_SEQUENCER_RPC_URL: &str = "http://localhost:8545"; + +/// The follower node RPC URL for the Docker Compose environment. +const RN_FOLLOWER_RPC_URL: &str = "http://localhost:8546"; + +/// The l2geth node RPC URL for the Docker Compose environment. +const L2GETH_SEQUENCER_RPC_URL: &str = "http://localhost:8547"; + +const L2GETH_FOLLOWER_RPC_URL: &str = "http://localhost:8548"; + pub struct DockerComposeEnv { project_name: String, compose_file: String, } impl DockerComposeEnv { - /// The sequencer node RPC URL for the Docker Compose environment. - const SEQUENCER_RPC_URL: &str = "http://localhost:8545"; - - /// The follower node RPC URL for the Docker Compose environment. - const FOLLOWER_RPC_URL: &str = "http://localhost:8547"; - // ===== CONSTRUCTOR AND LIFECYCLE ===== /// Create a new DockerComposeEnv and wait for all services to be ready @@ -38,8 +55,10 @@ impl DockerComposeEnv { // Wait for all services to be ready tracing::info!("⏳ Waiting for services to be ready..."); - env.wait_for_sequencer_ready().await?; - env.wait_for_follower_ready().await?; + Self::wait_for_l2_node_ready(RN_SEQUENCER_RPC_URL, 30).await?; + Self::wait_for_l2_node_ready(RN_FOLLOWER_RPC_URL, 30).await?; + Self::wait_for_l2_node_ready(L2GETH_SEQUENCER_RPC_URL, 30).await?; + Self::wait_for_l2_node_ready(L2GETH_FOLLOWER_RPC_URL, 30).await?; tracing::info!("✅ All services are ready!"); Ok(env) @@ -57,8 +76,8 @@ impl DockerComposeEnv { project_name, "up", "-d", - "--force-recreate", - "--build", + // "--force-recreate", + // "--build", ]) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -102,25 +121,61 @@ impl DockerComposeEnv { "--volumes", "--remove-orphans", "--timeout", - "30", + "3", ]) .output(); + let _result = Command::new("docker") + .args(["compose", "-f", compose_file, "rm", "--force", "--volumes", "--stop"]) + .output(); + tracing::info!("✅ Cleanup completed"); } - // ===== READINESS CHECKS ===== + // ===== PROVIDER FACTORIES ===== - /// Wait for sequencer to be ready - async fn wait_for_sequencer_ready(&self) -> Result<()> { - Self::wait_for_l2_node_ready(Self::SEQUENCER_RPC_URL, 30).await + /// Get a configured sequencer provider + pub async fn get_rn_sequencer_provider(&self) -> Result { + let provider = ProviderBuilder::<_, _, Scroll>::default() + .with_recommended_fillers() + .connect(RN_SEQUENCER_RPC_URL) + .await + .map_err(|e| eyre::eyre!("Failed to connect to RN sequencer: {}", e))?; + Ok(NamedProvider::new(Box::new(provider), "RN Sequencer")) } - /// Wait for follower to be ready - async fn wait_for_follower_ready(&self) -> Result<()> { - Self::wait_for_l2_node_ready(Self::FOLLOWER_RPC_URL, 30).await + /// Get a configured follower provider + pub async fn get_rn_follower_provider(&self) -> Result { + let provider = ProviderBuilder::<_, _, Scroll>::default() + .with_recommended_fillers() + .connect(RN_FOLLOWER_RPC_URL) + .await + .map_err(|e| eyre::eyre!("Failed to connect to RN follower: {}", e))?; + Ok(NamedProvider::new(Box::new(provider), "RN Follower")) } + /// Get a configured l2geth sequencer provider + pub async fn get_l2geth_sequencer_provider(&self) -> Result { + let provider = ProviderBuilder::<_, _, Scroll>::default() + .with_recommended_fillers() + .connect(L2GETH_SEQUENCER_RPC_URL) + .await + .map_err(|e| eyre::eyre!("Failed to connect to l2geth sequencer: {}", e))?; + Ok(NamedProvider::new(Box::new(provider), "L2Geth Sequencer")) + } + + /// Get a configured l2geth follower provider + pub async fn get_l2geth_follower_provider(&self) -> Result { + let provider = ProviderBuilder::<_, _, Scroll>::default() + .with_recommended_fillers() + .connect(L2GETH_FOLLOWER_RPC_URL) + .await + .map_err(|e| eyre::eyre!("Failed to connect to l2geth follower: {}", e))?; + Ok(NamedProvider::new(Box::new(provider), "L2Geth Follower")) + } + + // ===== UTILITIES ===== + /// Wait for L2 node to be ready async fn wait_for_l2_node_ready(provider_url: &str, max_retries: u32) -> Result<()> { for i in 0..max_retries { @@ -153,28 +208,6 @@ impl DockerComposeEnv { ); } - // ===== PROVIDER FACTORIES ===== - - /// Get a configured sequencer provider - pub async fn get_sequencer_provider(&self) -> Result> { - ProviderBuilder::<_, _, Scroll>::default() - .with_recommended_fillers() - .connect(Self::SEQUENCER_RPC_URL) - .await - .map_err(|e| eyre::eyre!("Failed to connect to sequencer: {}", e)) - } - - /// Get a configured follower provider - pub async fn get_follower_provider(&self) -> Result> { - ProviderBuilder::<_, _, Scroll>::default() - .with_recommended_fillers() - .connect(Self::FOLLOWER_RPC_URL) - .await - .map_err(|e| eyre::eyre!("Failed to connect to follower: {}", e)) - } - - // ===== UTILITIES ===== - /// Show logs for all containers fn show_all_container_logs(compose_file: &str, project_name: &str) { tracing::info!("🔍 Getting all container logs..."); diff --git a/tests/src/lib.rs b/tests/src/lib.rs index a752d9a3..70beba2f 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,2 +1,3 @@ pub mod docker_compose; -pub use docker_compose::DockerComposeEnv; +pub mod utils; +pub use docker_compose::{DockerComposeEnv, NamedProvider}; diff --git a/tests/src/utils.rs b/tests/src/utils.rs new file mode 100644 index 00000000..5e2a5b10 --- /dev/null +++ b/tests/src/utils.rs @@ -0,0 +1,160 @@ +use alloy_rpc_types_eth::BlockNumberOrTag; +use eyre::Result; +use std::time::Duration; + +use crate::docker_compose::NamedProvider; + +/// Enable automatic sequencing on a rollup node +pub async fn enable_automatic_sequencing(provider: &NamedProvider) -> Result { + provider + .provider + .client() + .request("rollupNode_enableAutomaticSequencing", ()) + .await + .map_err(|e| eyre::eyre!("Failed to enable automatic sequencing: {}", e)) +} + +/// Disable automatic sequencing on a rollup node +pub async fn disable_automatic_sequencing(provider: &NamedProvider) -> Result { + provider + .provider + .client() + .request("rollupNode_disableAutomaticSequencing", ()) + .await + .map_err(|e| eyre::eyre!("Failed to disable automatic sequencing: {}", e)) +} + +pub async fn miner_start(provider: &NamedProvider) -> Result<()> { + provider + .provider + .client() + .request("miner_start", ()) + .await + .map_err(|e| eyre::eyre!("Failed to start miner: {}", e)) +} + +pub async fn miner_stop(provider: &NamedProvider) -> Result<()> { + provider + .provider + .client() + .request("miner_stop", ()) + .await + .map_err(|e| eyre::eyre!("Failed to stop miner: {}", e)) +} + +/// Waits for all provided nodes to reach the target block number. +/// +/// # Arguments +/// * `nodes` - Slice of NamedProvider structs containing provider and name +/// * `target_block` - The block number to wait for all nodes to reach +/// +/// # Returns +/// * `Ok(())` if all nodes reach the target block within the timeout +/// * `Err` if timeout is reached or any provider call fails +pub async fn wait_for_block(nodes: &[&NamedProvider], target_block: u64) -> Result<()> { + let timeout_duration = Duration::from_secs(60); + let timeout_secs = timeout_duration.as_secs(); + + tracing::info!( + "⏳ Waiting for {} nodes to reach block {}... (timeout: {}s)", + nodes.len(), + target_block, + timeout_secs + ); + + for i in 0..timeout_secs { + let mut all_synced = true; + let mut node_statuses = Vec::new(); + + for node in nodes { + let current_block = node.provider.get_block_number().await?; + node_statuses.push((node.name, current_block)); + + if current_block < target_block { + all_synced = false; + } + } + + if all_synced { + tracing::info!("✅ All nodes reached target block {}", target_block); + for (name, block) in node_statuses { + tracing::info!(" - {}: block {}", name, block); + } + return Ok(()); + } + + // Log progress every 5 seconds + if i % 5 == 0 { + tracing::info!("Progress check ({}s elapsed):", i); + for (name, block) in node_statuses { + tracing::info!( + " - {}: block {} / {} {}", + name, + block, + target_block, + if block >= target_block { "✅" } else { "⏳" } + ); + } + } + + tokio::time::sleep(Duration::from_secs(1)).await; + } + + eyre::bail!( + "Timeout after {}s waiting for all nodes to reach block {}", + timeout_secs, + target_block + ) +} + +/// Verifies that all provided nodes have the same block hash for a given block number. +/// +/// # Arguments +/// * `nodes` - Slice of NamedProvider structs containing provider and name +/// * `block_number` - The block number to verify across all nodes +/// +/// # Returns +/// * `Ok(())` if all nodes have the same block hash +/// * `Err` if any blocks are missing or hashes don't match +pub async fn assert_blocks_match(nodes: &[&NamedProvider], block_number: u64) -> Result<()> { + if nodes.is_empty() { + return Ok(()); + } + + let mut blocks = Vec::new(); + + // Fetch blocks from all nodes + for node in nodes { + let block_opt = + node.provider.get_block_by_number(BlockNumberOrTag::Number(block_number)).await?; + + let block = block_opt + .ok_or_else(|| eyre::eyre!("{} block {} not found", node.name, block_number))?; + + blocks.push((node.name, block)); + } + + // Get the reference hash from the first node + let (ref_node_name, ref_block) = &blocks[0]; + let ref_hash = ref_block.header.hash; + + // Compare all other blocks to the reference + for (node_name, block) in &blocks[1..] { + let block_hash = block.header.hash; + + assert_eq!( + block_hash, ref_hash, + "Block {} hashes differ: {} has {:?}, {} has {:?}", + block_number, ref_node_name, ref_hash, node_name, block_hash + ); + } + + tracing::info!( + "✅ Block {} matches across all {} nodes: hash={:?}", + block_number, + nodes.len(), + ref_hash + ); + + Ok(()) +} diff --git a/tests/tests/block_production.rs b/tests/tests/block_production.rs deleted file mode 100644 index 1746c9db..00000000 --- a/tests/tests/block_production.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Tests for basic block production. - -use alloy_provider::Provider; -use eyre::Result; -use scroll_alloy_network::Scroll; -use std::time::Duration; -use tests::DockerComposeEnv; - -#[tokio::test] -async fn test_docker_block_production() -> Result<()> { - tracing::info!("=== STARTING test_docker_block_production ==="); - let env = DockerComposeEnv::new("block-production").await?; - - let sequencer = env.get_sequencer_provider().await?; - tracing::info!("✅ Sequencer provider created"); - - let initial_block = sequencer.get_block_number().await?; - tracing::info!("Initial block number: {initial_block}"); - - let final_block = wait_for_sequencer_blocks(&sequencer, 20).await?; - tracing::info!("Final block number: {final_block}"); - - assert!( - final_block >= initial_block + 5, - "Sequencer should have produced at least 5 new blocks." - ); - - tracing::info!("✅ Block production test completed successfully!"); - Ok(()) -} - -/// Waits for the sequencer to produce a specific number of new blocks. -async fn wait_for_sequencer_blocks( - sequencer: &impl Provider, - num_blocks: u64, -) -> Result { - let start_block = sequencer.get_block_number().await?; - let target_block = start_block + num_blocks; - tracing::info!( - "⏳ Waiting for sequencer to produce {num_blocks} blocks (target: {target_block})..." - ); - - for _ in 0..10 { - // 10 second timeout - let current_block = sequencer.get_block_number().await?; - if current_block >= target_block { - tracing::info!("✅ Sequencer reached block {current_block}"); - return Ok(current_block); - } - tokio::time::sleep(Duration::from_secs(1)).await; - } - eyre::bail!("Timeout waiting for sequencer to produce blocks") -} diff --git a/tests/tests/block_propagation.rs b/tests/tests/block_propagation.rs deleted file mode 100644 index 13132d1c..00000000 --- a/tests/tests/block_propagation.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Tests for basic block propagation. - -use alloy_provider::Provider; -use alloy_rpc_types_eth::BlockNumberOrTag; -use eyre::Result; -use scroll_alloy_network::Scroll; -use std::time::Duration; -use tests::DockerComposeEnv; - -#[tokio::test] -async fn test_docker_block_propagation() -> Result<()> { - tracing::info!("=== STARTING test_docker_block_propagation ==="); - let env = DockerComposeEnv::new("basic-block-propagation").await?; - - let sequencer = env.get_sequencer_provider().await?; - tracing::info!("✅ Sequencer provider created"); - - let follower = env.get_follower_provider().await?; - tracing::info!("✅ Follower provider created"); - - let s_chain_id = sequencer.get_chain_id().await?; - let f_chain_id = follower.get_chain_id().await?; - tracing::info!( - "✅ Sequencer (Chain ID: {s_chain_id}) & Follower (Chain ID: {f_chain_id}) connected." - ); - assert_eq!(s_chain_id, f_chain_id, "Chain IDs must match"); - - let target_block = wait_for_sequencer_blocks(&sequencer, 20).await?; - tracing::info!("Sequencer produced {target_block} blocks, now waiting for follower sync..."); - - wait_for_follower_sync(&follower, target_block).await?; - tracing::info!("Follower synced to block {target_block}"); - - for block_num in 1..=target_block { - verify_blocks_match(&sequencer, &follower, block_num).await?; - } - tracing::info!("✅ Block hashes match for all blocks up to {target_block}, Basic block propagation test completed successfully!"); - - Ok(()) -} - -/// Waits for the sequencer to produce a specific number of new blocks. -async fn wait_for_sequencer_blocks( - sequencer: &impl Provider, - num_blocks: u64, -) -> Result { - let start_block = sequencer.get_block_number().await?; - let target_block = start_block + num_blocks; - tracing::info!( - "⏳ Waiting for sequencer to produce {num_blocks} blocks (target: {target_block})..." - ); - - for _ in 0..10 { - // 10 second timeout - let current_block = sequencer.get_block_number().await?; - if current_block >= target_block { - tracing::info!("✅ Sequencer reached block {current_block}"); - return Ok(current_block); - } - tokio::time::sleep(Duration::from_secs(1)).await; - } - eyre::bail!("Timeout waiting for sequencer to produce blocks") -} - -/// Waits for the follower to sync up to the target block. -async fn wait_for_follower_sync(follower: &impl Provider, target_block: u64) -> Result<()> { - tracing::info!("⏳ Waiting for follower to sync to block {target_block}..."); - - for _ in 0..10 { - // 10 second timeout - let follower_block = follower.get_block_number().await?; - if follower_block >= target_block { - tracing::info!("✅ Follower synced to block {follower_block}"); - return Ok(()); - } - tokio::time::sleep(Duration::from_secs(1)).await; - } - eyre::bail!("Timeout waiting for follower to sync") -} - -/// Verifies that block hashes match between two nodes for a given block number. -async fn verify_blocks_match( - sequencer: &impl Provider, - follower: &impl Provider, - block_number: u64, -) -> Result<()> { - let seq_block_opt = - sequencer.get_block_by_number(BlockNumberOrTag::Number(block_number)).await?; - let fol_block_opt = - follower.get_block_by_number(BlockNumberOrTag::Number(block_number)).await?; - - let seq_block = - seq_block_opt.ok_or_else(|| eyre::eyre!("Sequencer block {} not found", block_number))?; - let fol_block = - fol_block_opt.ok_or_else(|| eyre::eyre!("Follower block {} not found", block_number))?; - - // Compare block hashes. - let seq_hash = seq_block.header.hash; - let fol_hash = fol_block.header.hash; - - if seq_hash != fol_hash { - eyre::bail!( - "Block {} hashes differ: sequencer={:?}, follower={:?}", - block_number, - seq_hash, - fol_hash - ); - } - - tracing::debug!("✅ Block {block_number} matches: hash={seq_hash:?}"); - Ok(()) -} diff --git a/tests/tests/block_propagation_multi_clients.rs b/tests/tests/block_propagation_multi_clients.rs new file mode 100644 index 00000000..c6f41f60 --- /dev/null +++ b/tests/tests/block_propagation_multi_clients.rs @@ -0,0 +1,30 @@ +//! Tests for block propagation to both geth and reth follower nodes. + +use eyre::Result; +use tests::*; + +#[tokio::test] +async fn test_docker_block_propagation_to_both_clients() -> Result<()> { + reth_tracing::init_test_tracing(); + + tracing::info!("=== STARTING test_docker_block_propagation_to_both_clients ==="); + let env = DockerComposeEnv::new("multi-client-propagation").await?; + + let rn_sequencer = env.get_rn_sequencer_provider().await?; + let rn_follower = env.get_rn_follower_provider().await?; + let l2geth_sequencer = env.get_l2geth_sequencer_provider().await?; + let l2geth_follower = env.get_l2geth_follower_provider().await?; + + let nodes = [&rn_sequencer, &rn_follower, &l2geth_sequencer, &l2geth_follower]; + + // Enable block production on l2geth sequencer + utils::miner_start(&l2geth_sequencer).await?; + + // Wait for all nodes to be at block 10 + let target_block = 10; + utils::wait_for_block(&nodes, target_block).await?; + // Verify blocks match across all clients + utils::assert_blocks_match(&nodes, target_block).await?; + + Ok(()) +}