fix/beryl b20 logs#14
Closed
sduchesneau wants to merge 348 commits into
Closed
Conversation
…for invalid IDs (base#2844) * feat(precompiles): soften policy_exists and is_authorized error handling for malformed and missing policies policy_exists now returns Ok(false) for malformed policyIds (type byte > 1) instead of reverting. is_authorized similarly returns Ok(false) for malformed IDs, drops the existence check (so unwritten slots are treated with default type semantics: ALLOWLIST=not authorized, BLOCKLIST=authorized), and never returns PolicyNotFound. Fast-paths for ALWAYS_ALLOW_ID and ALWAYS_BLOCK_ID are preserved. Signed-off-by: Eric Liu <ericliu@base.org> Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * fix(policy): replace dead wildcard arm with unreachable, document is_authorized/policy_exists divergence Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> --------- Signed-off-by: Eric Liu <ericliu@base.org> Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
base#2857) * refactor(policy): align IPolicyRegistry errors with base-std interface Remove `InvalidPolicyType` and `MalformedPolicyId` from the Rust ABI definition; neither appears in `base/base-std`'s `IPolicyRegistry.sol`, so Solidity callers have no way to decode reverts carrying those selectors. Behavioral consequences: - Write ops with a malformed policy ID (type byte > 1) now reach `PolicyNotFound` via the zero-slot read in `require_custom`, which is the correct error: a malformed ID was never created. - `policy_exists` with a malformed ID now returns `false` (zero slot, `exists()` bit unset) and never reverts, matching the base-std `Never reverts` contract. - `InvalidPolicyType` in `create_policy` was dead code: `PolicyType` is decoded from ABI before the function body runs, so out-of-range values are rejected by the ABI decoder. The guard is dropped; the `_` arm in `create_policy_with_accounts` becomes `unreachable!()`. - The `_ =>` fallback in `is_authorized`'s match becomes `unreachable!()` for the same reason: `packed.exists()` is the gatekeeper and no stored policy can carry a type byte > 1. Add unit tests covering the new behavior: - `policy_exists_malformed_id_returns_false` - `write_op_with_malformed_id_returns_policy_not_found` Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * fix(policy): update PolicyAdminStaged callers to use currentAdmin/pendingAdmin field names Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> --------- Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
Unifies all step-security/harden-runner pins to v2.15.0 (a90bcbc6539c36a85cdfeb73f7e2f433735f215b) across all workflows for a consistent security posture and single source of truth. Closes base#2829
…ion (base#2856) * feat(transferable): add privileged flag to skip authorization on transfer Adds `privileged: bool` to `Transferable::transfer`, `transfer_from`, `transfer_with_memo`, and `transfer_from_with_memo`. When true (factory bootstrap window) the pause check and all policy guards are skipped, matching the `_isPrivileged()` bypass in the Solidity mock's `_transfer`. Balance invariants are always enforced regardless of privilege. All three dispatch variants (b20, b20_stablecoin, b20_security) now forward the existing `privileged` flag through to transfer calls. Adds coverage for balance boundaries, receiver overflow, external policy registry paths, and Transfer event field content. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Apply suggestion from @github-actions[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(transferable): prevent self-transfer balance inflation Debit the sender before crediting the receiver so aliased addresses match Solidity semantics, and add regression tests for repeated self-transfers. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…ase#2863) * feat(consensus): add EIP-8130 AA transaction types Introduces standalone type definitions for EIP-8130 Account Abstraction transactions in base-common-consensus: TxAa8130 (unsigned body), AaSigned (signed envelope with sender_auth and payer_auth), AccountChange tagged union (Create / ConfigChange / Delegation), and Call. Includes RLP and EIP-2718 round-trip coverage plus the two domain-separated signing-hash helpers. The new types are not yet wired into BaseTxEnvelope; that integration follows in a separate commit. * feat(consensus): wire EIP-8130 AA8130 variant into envelope/receipt/pool Plumb the new TxAa8130/AaSigned types into BaseTxEnvelope, BaseTypedTransaction, BasePooledTransaction, BaseReceipt, and BaseReceiptEnvelope at type byte 0x7D. Adds OpTxType::Aa8130, the EIP8130_TX_TYPE_ID constant, reth_compat Compact arms (unimplemented placeholders for the binary codec to be filled in later), and exhaustive match arms across all dispatch sites. AaSigned caches its EIP-2718 hash at construction so envelope hash() continues to return &B256. All 87 unit tests in base-common-consensus pass. * feat(evm,execution,rpc-types): handle EIP-8130 OpTxType::Aa8130 variants Add Aa8130 arms to every match site that dispatches on OpTxType/BaseReceipt across the EVM, execution, RPC, and flashblocks crates. The arms wire receipts through unchanged (Receipt<T> shape) and stub EVM execution with unimplemented! so consensus-layer changes stay decoupled from execution semantics until the 8130 verifier and gas accounting land. * chore(consensus): satisfy clippy on EIP-8130 modules Make address_opt_encoded_length const, collapse Option::Some match into map_or, merge identical Deposit/Aa8130 None arms, and rephrase a payer signature-hash docstring to avoid the doc-markdown false positive on nested bracket sequences inside backticked code. * fix(consensus): return RecoveryError for EIP-8130 EOA-path signer recovery Previously SignerRecoverable for BaseTxEnvelope::Aa8130 (and the same arm in BasePooledTransaction) returned Ok(explicit_sender.unwrap_or(ZERO)). On the EOA path (tx.sender == None) the spec requires recovering the signer from the 65-byte ECDSA sender_auth, which is not yet implemented; silently returning Ok(Address::ZERO) misrepresented unauthenticated transactions as having a valid recovered sender. The tx pool and any caller relying on SignerRecoverable would key on / log a zero address and accept the transaction as if recovery succeeded. Return Err(RecoveryError::new()) on the EOA path until real recovery lands. The configured-owner path (explicit_sender is Some) still returns that address. * fix(consensus): recompute EIP-8130 AaSigned hash on deserialize and arbitrary Replace the derived Serde and Arbitrary impls on AaSigned with manual ones that route through AaSigned::new, ensuring the cached hash field is always recomputed from the canonical EIP-2718 encoding rather than trusted from an on-wire value or generated independently of the payload. The Serialize path now omits the hash field entirely (it is fully derivable from the other fields), and Deserialize reconstructs the AaSigned through the constructor so a malicious or stale hash in the input cannot disagree with the transaction body. Adds two regression tests proving (a) the serialized form does not include hash and round-trips, and (b) a deliberately-zeroed hash in the input is ignored in favor of the recomputed value. * fix(consensus): use unimplemented! over unreachable! for EIP-8130 trait stubs The Aa8130 arms in BaseTypedTransaction's RlpEcdsaEncodableTx impl and in BasePooledTransaction's signature/signature_hash/into_envelope/From paths are reachable from generic alloy and reth Transaction code (e.g. anything that calls Transaction::tx_hash on a typed transaction without first checking the variant). unreachable! signals UB-on-violation, which is the wrong contract here: these arms are intentionally not-yet-implemented and will be filled in once EIP-8130 has its own encoding plumbing. unimplemented! conveys the correct semantics: 'this is a TODO that will panic if hit', not 'this can never happen'. * fix(consensus): debug-assert configured-owner is unset on Signed AA path The From<Signed<BaseTypedTransaction>> for BaseTxEnvelope conversion blindly stuffs the ECDSA signature bytes into AaSigned::sender_auth. That is correct for the EOA path (tx.sender == None), but for the configured-owner path (tx.sender == Some(addr)) the sender_auth is supposed to be an authentication payload bound to the configured owner, not a raw ECDSA signature over an unrelated digest. Guard the invariant with a debug_assert so misuse is caught in tests and debug builds while keeping release builds free of extra checks. Callers that need to wrap a configured-owner AA tx must construct BaseTxEnvelope::Aa8130(AaSigned::new(...)) directly with the correct sender_auth, not go through the ECDSA Signed wrapper. * fix(consensus): encode EIP-8130 Scope as a bare RLP byte EIP-8130 specifies Scope as a uint8. The derived RLP impls produced by alloy_rlp's #[derive(RlpEncodable)] always emit a list header, so Scope(0x05) was being encoded as [0xc1, 0x05] (single-element list) instead of [0x05] (bare byte). The same wrapping propagated to every container that reached Scope through a derived encoding (InitialOwner.scope, OwnerChange.scope). Hand-roll Encodable/Decodable for Scope to forward to u8's impls. The roundtrip tests still pass because they were symmetric; the new pinned wire-format test catches any future regression to the derived impl. * fix(consensus): also debug-assert payer.is_none() on Signed AA path Symmetric extension of the previous sender-assert. The From<Signed<BaseTypedTransaction>> for BaseTxEnvelope path constructs AaSigned with payer_auth = Bytes::new(). For sponsored AA transactions (tx.payer == Some(_)), this silently drops the payer authentication and would leave the resulting envelope unable to be validated against the sponsoring payer. Guard the invariant so callers must route sponsored AA transactions through BaseTxEnvelope::Aa8130 directly with the proper payer_auth populated. * fix(consensus,rpc-types): unimplemented! over default() for AA TransactionRequest conversions The four From<BaseTxEnvelope|BaseTypedTransaction> for TransactionRequest (both alloy and Base) arms previously returned Self::default() for the Aa8130 variant, silently handing callers an empty request with no chain id, gas, value, or sender. Any RPC path that hit one of these conversions with an AA transaction would see a blank request rather than a clear error. Match the convention established by the trait stubs in BaseTypedTransaction and BasePooledTransaction (commit 4be29ffd6) and panic via unimplemented!() with an explanatory message. AA transactions have no single recipient or value to project onto the legacy request shape, so silent default conversion was incorrect by construction. * fix(consensus): satisfy nightly fmt and no_std for EIP-8130 modules - aa8130/account_changes.rs missed an `alloc::vec::Vec` import (the crate is `#![no_std]` outside the std feature), breaking the no_std CI check - nightly rustfmt reorders the inner `use` block in aa8130/signed.rs and drops an unused `b256` import plus a redundant `.clone()` in tx.rs tests Caught by CI on the just-opened PR. * fix(consensus): early-return RecoveryError on AA path for the other two SignerRecoverable methods The earlier RecoveryError fix on BasePooledTransaction only covered recover_unchecked_with_buf; the sibling methods recover_signer and recover_signer_unchecked still unconditionally call self.signature_hash() and self.signature(), both of which unimplemented!() on the Aa8130 arm. That meant an AA transaction entering the mempool would panic the node the moment the pool tried to resolve its sender. Mirror the same early-return as the BaseTxEnvelope impl: defer to AaSigned::explicit_sender when present, otherwise return a RecoveryError so the caller can reject the tx cleanly. * docs(consensus): warn that reth Envelope::signature returns a zero placeholder for AA/Deposit reth_codecs::Envelope::signature must return &Signature, so there is no way to express absence the way BaseTxEnvelope::signature (Option<&Signature>) does for Deposit and EIP-8130 AA variants. Returning DEPOSIT_SIGNATURE (all zeros) is the least-bad option, but anyone passing that value into ECDSA recovery would silently get back garbage instead of a clear error. Add a comment naming the constraint and instructing callers not to feed the value into recovery. No behavior change. * fix(consensus): reject AA transactions in try_into_eth_pooled instead of panicking try_into_pooled returns Ok(BasePooledTransaction::Aa8130(...)) because AA txs DO live in our pool, but try_into_eth_pooled chained .map(Into::into), and that From<BasePooledTransaction> for alloy_consensus::PooledTransaction impl unimplemented!()s on Aa8130. So calling try_into_eth_pooled on an AA envelope would silently compile and then panic at runtime, violating the try_ contract. Match the pattern already used by try_into_eth_envelope: reject Aa8130 explicitly with a ValueError naming the variant, then delegate the remaining variants to the existing try_into_pooled path. No new variants added; pure correctness fix.
* test(policy): add PackedPolicy newtype unit tests (BOP-117) Add five targeted unit tests for the PackedPolicy newtype covering: round-trip fidelity for all four PolicyType discriminants, the zero-word == never-created invariant relied on by policyExists, the renounced-admin (zero admin + non-zero type) not being confused with never-created, and bidirectional bit-isolation between the admin field (bits 167:8) and the type field (bits 7:0). * chore: apply nightly fmt and fix clippy - Run cargo +nightly fmt --all - Fix b20_stablecoin/dispatch.rs to use ActivationFeature::B20Stablecoin.id() instead of the removed ActivationRegistryStorage::B20_STABLECOIN constant - Update PackedPolicy unit tests to match the refactored API: policy type is no longer stored in the packed word, exists() replaces is_zero(), and the constructor takes only an admin address Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * refactor(test): remove redundant PackedPolicy unit tests - Remove zero_word_means_never_created: subsumes packed_policy_zero_signals_never_created; fold the unique admin()==Address::ZERO assertion into the existing test - Remove zero_admin_is_not_confused_with_never_created: identical constructor args and assertions to packed_policy_zero_admin_is_non_zero - Remove admin_with_low_byte_ff_roundtrips: subsumed by packed_policy_new_roundtrips_admin_for_various_addresses which already tests the all-0xff address Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> --------- Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
* test(policy): add error path action tests for PolicyRegistry (BOP-109) Covers five error cases via full block execution (BerylTestEnv): Unauthorized, PolicyNotFound, IncompatiblePolicyType, StaticCallNotAllowed, and NoPendingAdmin. * chore: apply nightly fmt Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> --------- Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
…ase#2866) * refactor(consensus): rename Aa8130 -> Eip8130 for naming consistency Align EIP-8130 transaction types with the project's existing Eip7702 / Eip1559 / Eip2930 naming convention. The 'Aa' prefix was a transitional shorthand; using the EIP number matches every other typed transaction in the workspace and the upstream alloy convention. Rename map: Aa8130 -> Eip8130 (envelope/typed/receipt variants) AaSigned -> Eip8130Signed TxAa8130 -> TxEip8130 Aa8130Constants -> Eip8130Constants AA_TX_TYPE -> EIP8130_TX_TYPE AA_PAYER_TYPE -> EIP8130_PAYER_TYPE AA_BASE_COST -> EIP8130_BASE_COST is_aa8130() -> is_eip8130() as_aa8130() -> as_eip8130() aa_signed.rs (file content reference updates) aa8130/ (directory) -> eip8130/ Pure rename, no behavior change. All 90 base-common-consensus tests pass; full workspace builds clean. * refactor(consensus): reorder match arms so Deposit comes last Across every match expression that fans out over BaseTxEnvelope / BaseTypedTransaction variants, reorder the arms so: Legacy / Eip2930 / Eip1559 / Eip7702 / Eip8130 -> normal ECDSA path Deposit -> always last Rationale: the Deposit transaction is the special, unsigned, L2-only variant that requires distinct handling (e.g. no signature recovery, no pool admission, explicit `from` field). Keeping it as the final arm in every match makes the ECDSA path read top-to-bottom as a single cohesive block and makes the special-case handling visually obvious. Eip8130 is an ECDSA-class L2 transaction, so it sits with the other typed variants rather than next to Deposit. Pure reorder, no behavior change. Pipe-chain arms (e.g. `Self::Eip8130(_) | Self::Deposit(_)`) follow the same ordering rule. All 90 base-common-consensus tests pass; full workspace builds clean; nightly rustfmt clean.
* chore: upgrade reth to v2 (rev d2327cb) with migrate-v2 support Upgrades all reth dependencies from v1.11.3 to rev d2327cb14f4fc42b3ab7afd37dd1c9e6346ee620 (paradigmxyz/reth migrate-v2 PR branch) with associated API changes: - Update Cargo.toml workspace deps to reth v2 rev - Adapt to reth v2 type/trait API changes - Restore CompactBaseReceipt field order (OpTxType first) for DB compatibility - Remove duplicate trait impls conflicting with v2 blanket impls * add snapshot-manifest command wiring * chore: upgrade to reth v2.1.0 stable with alloy 2.0 * fix: resolve alloy 2.0 test breakage, fpvm-precompile fixes, deny.toml updates * fix: resolve post-merge alloy 2.0 test breakage and deprecation warnings * fix: resolve post-rebase build errors for reth v2.1.0 and alloy 2.0 - Rename OpPayloadBuilderAttributes -> BasePayloadBuilderAttributes across workspace - Rename OpMinerExtApi -> BaseMinerExtApi, OpDebugWitnessApi -> BaseDebugWitnessApi - Upgrade revm-inspectors 0.34.3 -> 0.39.0 to match revm v38 - Upgrade revm-precompile 32.0.0 -> 34.0.0 to unify with revm v38 - Update precompile APIs for revm-precompile v34 (3-arg execute, PrecompileHalt) - Update test code for alloy 2.0 (block_timestamp, ResultGas, Runtime::test()) - Remove unused alloy-node-bindings deps from succinct crates - Clean up deny.toml skip list for resolved duplicates * fix: update base-precompile-storage for revm-precompile v34 API - PrecompileError::OutOfGas -> PrecompileOutput::halt(PrecompileHalt::OutOfGas) - PrecompileOutput::new_reverted -> PrecompileOutput::revert with reservoir arg - PrecompileOutput::new takes 3 args (add reservoir=0) - JournalCheckpoint needs selfdestructed_i field * fix: resolve post-rebase build failures and pin SP1 deps * fix: resolve post-rebase build failures from 3rd rebase - Fix bls12_381.rs precompile closures for revm-precompile v34 API (3-arg execute, PrecompileError::Fatal, call_eth_precompile wrapper) - Fix macros.rs: PrecompileOutput::new_reverted -> revert with reservoir - Fix factory/storage.rs and activation/storage.rs: .reverted -> .is_revert() - Fix factory.rs: .install() -> PrecompilesMap::from_static(precompiles()) - Fix ingress-rpc main.rs: remove kafka code (removed upstream), use RootProvider::new_http, IngressService::new takes 4 args - Remove stale mod execute declaration (removed upstream in a00cb26) - Re-export BaseExecutorProvider from execution-evm lib.rs - Re-export JOVIAN precompile constants from precompiles lib.rs - Fix succinct client test for SP1-patched revm API - Add revm-primitives and revm-precompile to deny.toml skip list (SP1 patch brings v32/v22, workspace uses v34/v23) * chore: upgrade reth to v2.1.0, revm to v38, alloy to v2.0, and cleanup deny.toml - Upgrade reth from v1.11.4 to v2.1.0 - Upgrade revm from v34 to v38 - Upgrade alloy from v1.8 to v2.0 - Upgrade SP1 from v6.1.0 to v6.2.1 - Upgrade sp1-cluster from v2.1.5 to v2.3.2 - Upgrade ethereum_ssz from v0.9 to v0.10 - Migrate crates to crates.io: reth-codecs, reth-primitives-traits, reth-zstd-compressors - Update precompiles API for revm v38 (.install() instead of .precompiles()) - Add clippy::too_many_arguments lint suppression in factory/abi.rs - Cleanup deny.toml skip list: remove 25+ unnecessary entries, add 9 actual duplicates * chore: upgrade reth to v2.2.0, alloy-evm to 0.34.0, alloy to 2.0.4 * fix: remove ssz feature leak from workspace dep to fix no_std builds * fix: resolve post-rebase build failures from 4th rebase - Add ExecutionWitnessMode param to witness() and import from reth_trie_common - Inline storage_by_hashed_key into storage() (removed from StateProvider trait) - Replace .reverted with .is_revert() in test assertions (alloy-evm 0.34.0) - Replace IB20::Uninitialized with empty revert check (error removed from ABI) - Remove unused PrecompileError import in SP1 precompiles * fix(cli): use LenientRpcModuleValidator for custom 'base' RPC module reth v2.2.0 added RPC module validation at CLI parse time. DefaultRpcModuleValidator rejects unknown modules, causing a panic when http.api includes 'base'. LenientRpcModuleValidator accepts custom module names, which is required for our custom RPC namespace. * fix(flashblocks): reconstruct depositor AccountInfo from cached receipt Fixes deposit receipt nonce in the cached execution path. When get_tx_result builds a BaseTxResult for a deposit transaction, it now extracts deposit_nonce from the cached receipt and constructs an AccountInfo so commit_transaction can set deposit_nonce correctly. * fix clippy * fix(evm): update precompile over-max-input test assertion Jovian precompile wrappers return Err(Fatal(...)) for oversized inputs, not Ok(output) with a halt reason. Update the test assertion to match the actual behavior. * fix precompile failing test
* fix(precompiles): harden PolicyRegistry audit findings Enforce batch size and zero-address validation on membership updates, short-circuit pending admin lookups for built-in policies, and add regression tests for the new guards. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: apply rustfmt to PolicyRegistry storage tests Co-authored-by: Cursor <cursoragent@cursor.com> * fix(precompiles): rename batch limit error to BatchSizeTooLarge Return the max permitted batch size in the revert data so callers know the registry limit when createPolicyWithAccounts or membership updates exceed 64 accounts. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…torageProvider static enforcement (base#2871) Mutating operations in PolicyRegistryStorage called require_write() as an early static-context guard. The EVM storage provider already enforces this at sstore/tstore/emit_event, so the precompile-level check was redundant in production. The HashMapStorageProvider (used in unit tests) did not enforce the static flag on writes, which is why require_write existed in the first place. Fix the test provider to match EVM behavior, then remove the now-unnecessary early checks.
* feat(devnet): run devnet zk prover in dry-run mode Add the ZK prover service and local Postgres storage to the Docker devnet so proof requests can execute the dry-run backend against local L1/L2 nodes by default. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: address comments * chore: add healthcheck * chore: script executable * chore: add cache entry * chore: address comments --------- Co-authored-by: Cursor <cursoragent@cursor.com>
… and isB20Initialized (base#2865) * rename(factory): ITokenFactory -> IB20Factory, TokenVariant -> B20Variant, createToken -> createB20 Aligns the Rust precompile surface with base-std PR base#63. Renames: - ITokenFactory -> IB20Factory - TokenFactoryStorage -> B20FactoryStorage - TokenFactoryPrecompile -> B20FactoryPrecompile - TokenVariant -> B20Variant - TokenCreated event -> B20Created - createToken() -> createB20() - getTokenAddress() -> getB20Address() - isInitialized() -> isB20Initialized() (also adds B20 prefix guard: returns false for non-B20 addresses even if they have bytecode) - ActivationFeature::TokenFactory -> ActivationFeature::B20Factory - activation key "base.token_factory" -> "base.b20_factory" (0xceff...8a5b -> 0x7875...b800, matching base-std ActivationRegistryFeatureList) Functional changes: - UnsupportedVersion now carries the B20Variant as a second field, matching base-std - is_b20_initialized() guards on B20 prefix before checking bytecode presence 274 precompile tests pass. * fix: rename remaining token_factory references missed in initial pass - actions/harness/tests/beryl/env.rs and b20.rs - crates/proof/succinct/utils/client/src/precompiles/mod.rs - crates/common/precompiles/benches/base_precompiles.rs - b20_factory_feature() helper renamed from token_factory_feature() * fix: address PR review comments - devnet/src/b20.rs: fix stale doc comments referencing createToken and getTokenAddress; fix error message string - etc/scripts/devnet/check-factory-live.sh: rename createToken/getTokenAddress call signatures to createB20/getB20Address; remove getB20Variant cast call (function does not exist in IB20Factory ABI) * chore: rename src/factory/ -> src/b20_factory/ per nit * fix: benches/base_precompiles.rs: create_token -> create_b20 missed call site * fix: update stale createToken label string in devnet E2E test * fix(factory): align B20Variant discriminants with ABI enum ordinals (0,1,2) Previously B20Variant used internal discriminants 1,2,3 (reserving 0 as NONE_DISCRIMINANT), which caused the byte written at address[10] to differ from the ABI enum ordinal. A Solidity caller computing getB20Address for DEFAULT would get byte[10]=0, but the precompile produced byte[10]=1, resulting in different addresses for the same inputs. Fix: change to B20=0, Stablecoin=1, Security=2 so the discriminant written into address[10] equals uint8(B20Variant) in Solidity. Remove NONE_DISCRIMINANT — the B-20 prefix bytes [0..9] are the sole indicator that an address is factory-created; byte[10] does not need a sentinel. Update test_supported_variants_are_b20_prefixes to use discriminants 1 and 2 (was 2 and 3).
* fix(precompiles): align registry precompile addresses * test(precompiles): update registry address fixtures
* rename(b20): policyType -> policyScope in IB20 ABI and call sites (BOP-147) Aligns the Rust IB20 interface with base/base-std#66 which renames the bytes32 parameter from policyType to policyScope to eliminate the semantic collision with IPolicyRegistry.PolicyType (the BLOCKLIST/ALLOWLIST enum). The token's policyType was a bytes32 slot identifier (e.g. keccak256("TRANSFER_SENDER_POLICY")), entirely unrelated to the registry's PolicyType enum. Renaming to policyScope makes the distinction explicit. Changes: - b20/abi.rs: rename policyScope in IB20 error, event, and function params - All IB20/IB20Security call sites: .policyType -> .policyScope field accesses and struct literals across dispatch, storage, policies, and ops files IPolicyRegistry and its PolicyType enum are untouched. Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * rename(b20): policy_type -> policy_scope in Rust call sites (BOP-147) Renames the local variable `policy_type` (a `B256` bytes32 slot identifier) to `policy_scope` across all function parameters and call sites in the B-20 precompile crates. Completes the rename that started in the IB20 ABI layer. The shadowed locals that hold the converted `B20PolicyType` enum (produced by `require_policy_type` / `require_b20_policy_type`) are intentionally kept as `policy_type` to reflect their actual type. The `B20PolicyType` param in `B20Guards::ensure_policy_type` is also unchanged. Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * fix(b20): rename stale policy_type references in guards doc and test mock (BOP-147) - guards.rs: update "raw policy_type" doc comment to policy_scope - test_utils.rs: rename policy_type param to policy_scope in TokenAccounting mock impl Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> --------- Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
* test(policy): add renounceAdmin immutability action tests (BOP-112) Verify that after renounceAdmin, all mutating operations (updateAllowlist, updateBlocklist, stageUpdateAdmin, finalizeUpdateAdmin) revert, while read operations (isAuthorized, policyAdmin, policyExists, policyType) continue to return correct values. * fix(policy): remove nonexistent policyTypeCall and fix finalizeUpdateAdmin comment IPolicyRegistry has no policyType() view function, so the policyTypeCall assertion would not compile. Remove it. Also correct the finalizeUpdateAdmin comment: the revert reason is NoPendingAdmin (renounce_admin clears the pending entry before the Unauthorized check runs), not Unauthorized.
…ation for stablecoin currency (base#2882) * fix(precompiles): replace ISO 4217 allowlist with A-Z character validation for stablecoin currency Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * style: apply rustfmt formatting Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: refcell <abigger87@gmail.com>
…t creation (BOP-152) (base#2887) * feat(b20-security): default REDEEM_SENDER_POLICY to ALWAYS_BLOCK_ID at creation (BOP-152) Security token redemption was open by default because initialize() never wrote to redeem_policy_ids, leaving the slot at zero (ALWAYS_ALLOW_ID). Add write_redeem_default_policy_ids() helper that packs ALWAYS_BLOCK_ID into the REDEEM_SENDER_POLICY lane and call it from initialize(). Also: - Export REDEEM_SENDER_POLICY as pub from the crate so the mock can use it. - Update InMemoryTokenAccounting::policy_id() to return ALWAYS_BLOCK_ID for REDEEM_SENDER_POLICY when not explicitly set, matching production. - Update make_token() in dispatch tests to explicitly open redemption so non-policy tests are not blocked by the new default. Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * fix(b20-security): group REDEEM_SENDER_POLICY re-export with mod ids per CLAUDE.md convention Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com> * nit: rename write_redeem_default_policy_ids -> write_default_redeem_policy_ids --------- Signed-off-by: Eric Shenghsiung Liu <ericliu121187@gmail.com>
* fix(policy-registry): classify calldata before activation gate (BOP-378/PSRC-26) Unknown selectors, short calldata, and write calls with malformed arguments previously returned FeatureNotActivated when the policy registry was inactive, masking the real error and making dispatch behavior activation-state-dependent. Replace the is_view_selector / write-gate two-branch split with a single match on the first 4 calldata bytes. Short calldata and unknown selectors return UnknownFunctionSelector immediately; view selectors bypass the activation gate and reach inner directly; known write selectors are ABI-validated before ensure_activated is called so AbiDecodeFailed is always surfaced regardless of activation state. Add regression tests for all three cases: inactive unknown selector, malformed view selector, and malformed write selector. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix(precompile-storage): deduct gas before sload warms slot in journal (BOP-380) `internals.sload` marks the slot warm in the revm journal before gas is deducted. If either `deduct_gas` call then returns `OutOfGas` the spurious warm entry persists, causing a subsequent cold read of the same slot to be billed at warm cost instead of cold cost, breaking EIP-2929 accounting. Apply the same checkpoint/revert pattern already used by `sstore`: take a journal checkpoint before the read and revert it on any error so that a failed OOG sload leaves the slot's cold/warm state unchanged. Add a regression test that verifies an OOG sload does not warm the slot: a second unlimited-gas read of the same slot must still pay the full cold penalty. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * remove comment Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix(precompile-macros): track args presence with a flag instead of emptiness check (base#3405) The `args` option in `#[precompile]` used `!args.is_empty()` to detect duplicates, which fails to catch `args(), args()` or `args(), args(x: u8)` because an empty first occurrence leaves the vec empty. Replace the check with an `args_seen` boolean flag, matching the `reject_duplicate` pattern used by every other option (`id`, `storage`, `macro_path`, `install`). Adds two regression tests covering both previously-undetected cases. * fix(precompile-macros): forward all struct-level attrs through #[contract] (BOP-360) (base#3407) * fix(precompile-macros): forward all struct-level attrs through #[contract] (BOP-360) Previously gen_output kept only #[derive] attributes and silently discarded doc comments, #[cfg], #[cfg_attr], #[allow], #[serde], etc. Now all outer attributes except #[namespace] (the macro's own consumed attribute) are threaded into the generated layout struct. The generic fallback doc string is suppressed when the user supplies their own doc comment, preventing silent replacement. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix(precompile-storage): wrap offset_bytes in backticks in test doc comments Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(precompile-storage): replace saturating/unchecked slot arithmetic with checked_add (BOP-356) (base#3415) * fix(precompile-storage): replace saturating/unchecked slot arithmetic with checked_add (BOP-356) Cantina finding base#33: slot offset arithmetic used saturating_add (which silently aliases overflowing offsets to U256::MAX) and unchecked + (which panics in debug builds). Replace all slot additions with checked_add, returning BasePrecompileError::SlotOverflow in Result contexts and using expect in constructors/Index impls where returning Result would break trait contracts. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * chore(precompile-storage): apply nightly rustfmt Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(precompile-storage): restore all mutable fields in checkpoint_revert (BOP-359) HashMapStorageProvider::checkpoint_revert was only restoring `internals` and `events`, silently leaving `transient`, `accounts`, `gas_refunded`, and `state_gas_used` in their post-mutation state after a revert. This caused the test mock to diverge from production EVM semantics, where all state is fully rolled back on revert. Expand `Snapshot` to capture all four missing fields and restore them in `checkpoint_revert`. Add per-field regression tests to pin the behavior. * fix(precompile-storage): complete checked-add migration for BOP-356 Fixes three remaining sites missed by the initial BOP-356 PR (base#3415): - VecHandler::truncate: two bare + in packed-element branch now use checked_add().ok_or(SlotOverflow)? - VecHandler: rename compute_handler to try_compute_handler returning Result<T::Handler> so callers can propagate SlotOverflow via ?. Adds get_or_try_insert / get_or_try_insert_mut to HandlerCache to support fallible initialization in cache-closure call sites. - SetHandler::new: drops const fn, returns Result<Self> so the positions-slot arithmetic uses ok_or(SlotOverflow)? instead of expect(). StorableType::handle for Set<T> retains .expect() at the trait boundary since StorableType::handle is infallible by design. - ArrayHandler::compute_handler: Index/IndexMut are infallible traits and cannot propagate Result; documents the invariant that base_slot is a keccak256 output (never U256::MAX) and N <= 32. * fix(precompile-storage): bubble SlotOverflow from ArrayHandler instead of panicking Remove Index/IndexMut impls and change compute_handler to try_compute_handler returning Result, with at() and at_mut() returning Result<Option<>>. No external callers used the Index operator on ArrayHandler. * fix(precompile-storage): make SetHandler::new infallible via wrapping_add SetHandler::new was checking for U256::MAX overflow via checked_add and returning Result<Self>, requiring the StorableType::handle impl to call .expect(). Changing handle() to propagate a Result would require modifying the StorableType trait and all proc-macro-generated code, which is disproportionate. Use wrapping_add instead: slot addresses are keccak256 outputs uniformly distributed over [0, 2^256), so U256::MAX is unreachable in practice. This makes new() infallible, removing the expect() entirely. * fix(precompile-storage): update tests to use at()/at_mut() instead of Index * fix(precompile-storage): pass usize by value to at()/at_mut() in tests * style: fix rustfmt in contract tests * fix(precompile-storage): make SetHandler::new const fn * fix(precompile-storage): replace wrapping_add with checked_add in SetHandler::new * fix(precompile-storage): add missing import and remove duplicate test after cherry-pick --------- Co-authored-by: Rayyan Alam <rayyan.alam@coinbase.com> Co-authored-by: Claude <noreply@anthropic.com>
…it (BOP-350) (base#3406) (base#3454) * fix(precompile-storage): remove unused token arg from checkpoint_commit (BOP-350) alloy-evm's checkpoint_commit takes no token; the JournalCheckpoint arg was silently discarded in EvmPrecompileStorageProvider, making the trait API misleading. Drop the parameter from the trait and both implementations. HashMapStorageProvider now asserts non-empty snapshots internally instead. Generated with Claude Code * fix(precompile-storage): drop unused cp binding in checkpoint test Generated with Claude Code --------- Co-authored-by: Claude <noreply@anthropic.com>
…e Sepolia and Mainnet (BOP-382) (base#3463) * fix(chains): update B20 activation admin addresses for Base Sepolia and Mainnet Replaces the old admin addresses with the newly provisioned coreKMS keys for activation testing and smoke tests on Base Sepolia and Base Mainnet. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix(chainspec): update activation_admin_matches_chain_config test addresses Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix(precompile-macros): improve #[contract] macro diagnostic for unrecognized arguments (base#3388) The error for unrecognized argument keys now names the unknown key and lists the only supported argument, addr = "0x...". The previous message "only `addr` attribute is supported" also silently accepted `address` as an alias; that alias is removed so the canonical form is enforced. Fixes BOP-346 (PSRC base#25). * refactor(b20-asset, activation): remove unreachable announcement guard and redundant AlreadyDeactivated error (base#3253) * refactor(b20-asset): remove unreachable in_announcement guard The is_announcement_active() check in announce() could never fire: begin_announcement() is called after the check (so the flag is always false when the guard runs), and the only re-entry vector — the inner call loop — already rejects the announce selector before dispatch. The flag also had no reset path, leaving the token permanently stuck with in_announcement=true after announce() completed. The selector check in the inner loop is the sole recursion defense, matching the MockB20Asset reference implementation which carries no flag at all. Remove in_announcement, is_announcement_active(), and begin_announcement() from B20AssetToken, and drop the dead guard and call-site from dispatch. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * refactor(activation): remove redundant AlreadyDeactivated error AlreadyDeactivated and FeatureNotActivated both represent the same underlying state (features[feature] == false). The intended distinction between mutation context (deactivate) and query context (checkActivated) was never implemented: the mock collapses both into FeatureNotActivated. Remove AlreadyDeactivated from the ABI to eliminate the dead declaration and bring the Rust interface in line with the updated IActivationRegistry spec and MockActivationRegistry behavior. Also clarifies set_activated variable names to make the activate/deactivate branch intent explicit. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * style: apply rustfmt to activation/storage.rs Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * chore: clippy * style: apply rustfmt to activation/storage.rs Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(chainspec,activation): reject zero activation admin address (base#3344) * fix(chainspec,precompiles): reject zero activation admin address Closes a backdoor where a chain misconfigured with activation_admin_address == Some(Address::ZERO) would allow any deposit transaction with msg.sender == Address::ZERO to toggle Beryl activation state. Layer 1 (config-time): add ZeroActivationAdminAddress error variant to BaseChainSpecError and check for it in validate_beryl_activation_admin, covering try_from_genesis, try_from_chainspec, and try_build paths. Layer 2 (runtime defense-in-depth): add an unconditional zero-caller guard at the top of set_activated in ActivationRegistryStorage so that Address::ZERO callers are always rejected, even if a future code path were to bypass config-time validation. Adds tests for both layers. * docs(activation): clarify admin() returns Address::ZERO to mean no admin, not a valid zero admin Address::ZERO returned from admin() signals that no activation admin is configured (activation_admin_address was None). Config-time validation already rejects Some(Address::ZERO), so the zero return cannot mean a configured admin in a valid chain spec. Add a doc comment making this semantic explicit so future callers do not conflate the two cases. * style(chainspec): move Address import to mod-level in tests Two new test functions placed `use alloy_primitives::Address` inside their function bodies. Move it to the existing module-level alloy_primitives import block per project import placement rules. * refactor(chainspec): extract beryl_scheduled local in validate_beryl_activation_admin The Beryl fork condition was evaluated twice, once for the missing-admin check and once for the zero-admin check. Extract it into a single beryl_scheduled binding so both guards share the same expression and cannot drift independently. * fix(chainspec,precompiles): run cargo fmt, fix em dash, update stale doc comment - Run cargo +nightly fmt to fix the ci/Format failure (the beryl_scheduled refactor commit was not formatted before pushing) - Replace em dash with colon in admin() doc comment per project convention - Update validate_beryl_activation_admin doc to describe both guards (missing and zero address) rather than only the original missing-address check * refactor(chainspec): make ChainConfig.activation_admin_address required All Base chains have Beryl scheduled and need an activation admin. Using Address instead of Option<Address> lets the type reflect this; Address::ZERO is still rejected by validate_beryl_activation_admin. The missing-admin test for ChainConfig is removed since that code path is now impossible. The genesis and builder paths retain Option<Address> to handle JSON deserialization where the field may be absent. * fix(chainspec,proof): update callsites for ChainConfig.activation_admin_address: Address Three callsites that treated activation_admin_address as Option<Address>: - boot.rs: and_then -> map to produce Option<Address> from the now-bare Address - boot.rs test assert: wrap chain_config value in Some() for comparison - succinct client boot.rs: wrap in Some() when assigning to BootInfo field - spec.rs test: assign Address::ZERO directly instead of Some(Address::ZERO) * fix(chains): add backticks to Address::ZERO in doc comment * fix(precompile-storage): remove redundant drop in with_caller and harden CallerGuard (base#3404) * fix(precompile-storage): remove redundant drop in with_caller and harden CallerGuard::drop The explicit `let result = f(); drop(guard); result` pattern in `with_caller` was redundant since `CallerGuard`'s `Drop` impl already restores the previous caller on scope exit. Simplify to `let _guard = ...; f()` so RAII is the sole restore mechanism. Additionally, `CallerGuard::drop` previously called `with_storage` which uses `RefCell::borrow_mut()` and panics on a conflicting borrow. This could abort the process if `drop` ran during unwinding from a panic inside a borrowed storage scope. Switch to `try_borrow_mut` so a conflicting borrow silently skips the restore instead of panicking inside `Drop`. Fixes BOP-337. * fix(precompile-storage): harden CheckpointGuard::drop against double-panic Apply the same try_borrow_mut hardening from CallerGuard::drop to CheckpointGuard::drop. Using with_storage (which calls borrow_mut internally) risks a second panic during unwinding if the RefCell is already mutably borrowed, causing a process abort. Silently skipping the revert on a conflicting borrow is the safe alternative. * style(precompile-storage): collapse nested if-let in CallerGuard and CheckpointGuard drop * docs(precompile-storage): document commit vs drop borrow strategy in CheckpointGuard * fix(precompile-storage): replace let chains with nested if-let for edition compat * feat(precompile-storage): add tracing::warn in CallerGuard and CheckpointGuard drop failure paths * chore: update Cargo.lock for tracing dependency * fix(precompile-storage): propagate tracing/std through std feature * [backport] straggler fixes for releases/v1.1.0 Applies remaining small fixes and doc/test cleanups that were present on main but missing from releases/v1.1.0 after the batch backports: - set.rs: em-dash in test doc comment - vec.rs: truncate/clear tests from base#3384 - activation/storage.rs: test ordering alignment - b20_asset/token.rs: batch_mint authorization boundary doc (base#3367) - b20_stablecoin/dispatch.rs: BOP-349/PSRC-27 reference in comment - metrics.rs: use ctx.result_output() instead of into_precompile_result() Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Eric Liu <ericliu121187@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
* chore: update reth to v2.3.0 Align the workspace with the reth v2.3.0 release and migrate the related alloy and revm API changes. Also fix the follow-up clippy and test breakages surfaced by the requested Justfile validation targets. Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Fix reth 2.3 CI fallout Persist test-harness canonical blocks immediately so follow-up payloads can resolve parent headers under reth 2.3.0, and update Jovian fixture headers plus deny skips for the new dependency graph. Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Drop dead BAL post-execution check Reth 2.3.0 added a BAL hash argument to post-execution consensus validation for Amsterdam-capable Ethereum paths. Base does not have an execution-derived BAL hash to compare, so stop threading the header value through and remove the tautological check. Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Keep BAL hash at the trait boundary only Accept the reth 2.3.0 BAL hash argument in the Base consensus trait impl, but stop threading it through Base-only helpers and tests where it is unused. Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Fix rustfmt fallout in engine-tree validator Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Use branch-based base-anvil workflow checkouts Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Align release-branch precompile tests with reth 2.3 Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Refresh backport lockfile Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * Fix Jovian blob gas mismatch test fixture Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * ci: use default base-anvil branch Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * test(runner): avoid finalizing harness blocks Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * test(runner): trim harness persistence workaround Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * docs(execution): clarify reth 2.3 migration notes Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * fix(consensus): drop post-exec requests hash check Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * refactor(reth): trim non-essential migration behavior Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * ci: revert workflow-only reth migration changes Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * refactor(engine-tree): inline overlay builder construction Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> * ci: bump base-anvil workflow pin Amp-Thread-ID: https://ampcode.com/threads/T-019eb1f4-e95e-7346-b575-6af1be02f038 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
* Set Base EL peer defaults to 80 Apply Base-specific execution peer defaults in the execution CLI runtime config so EL nodes default to 80 inbound peers and 80 outbound peers when operators do not pass explicit overrides. Add regression tests to verify the new defaults and preserve explicit CLI values. Amp-Thread-ID: https://ampcode.com/threads/T-019eb8fc-371b-71ab-901d-499925b7f017 Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 41b523d) * Fix rustfmt import order in backport Amp-Thread-ID: https://ampcode.com/threads/T-019eb8fc-371b-71ab-901d-499925b7f017 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
Bump to 1.0.1
Conflicts resolved: - Cargo.toml: version bumped to 1.1.0, reth v2.2.0→v2.3.0, revm/alloy version bumps; preserved firehose-only deps (reth-db-models, reth-tokio-util, alloy-rpc-types-trace) - crates/common/chains/src/chain.rs: beryl activation test updated to upstream values (sepolia scheduled, zeronet timestamp updated) - crates/common/chains/src/config.rs: zeronet beryl timestamp updated to 1_780_678_800, added cobalt_timestamp field
Upstream v1.1.0 includes a backport of reth v2.3.0, which is binary-incompatible with reth-firehose (built against reth v2.2.0 / revm-inspector v19). Reverted all reth-v2.3.0-specific API changes to keep the workspace on reth v2.2.0 (streamingfast/reth firehose/2.x) while still landing the v1.1.0 upstream features (Beryl/Cobalt hardfork plumbing, chain config additions). Also adapts the firehose-flashblocks streamer for the upstream FlashblocksSubscriber API change (added ping_interval parameter).
Use the final streamingfast/reth v2.3.0-fh tag (reth v2.3.0, revm 40, alloy-evm 0.36) instead of the intermediate alpha. Patch alloy-evm to the SF fork so EVM system calls route through the Inspector, restoring Firehose tracing of the EIP-4788 beacon-roots system call.
Merge v1.1.0, bump reth to 2.3.0, evm-alloy to 0.36.0-fh Does generate a difference in system calls' gas limit: ``` - "gasLimit": "30000000", + "gasLimit": "31566720", ``` this is due to how reth upstream changed that limit to that new value, which we reflect in our tracing.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* chore(common): set mainnet activation date Co-authored-by: Codex <codex-noreply@coinbase.com> * fix ci after beryl mainnet scheduling Co-authored-by: Codex <codex-noreply@coinbase.com> * fix basectl unscheduled hardfork test Co-authored-by: Codex <codex-noreply@coinbase.com> --------- Co-authored-by: Codex <codex-noreply@coinbase.com>
* insert parent block hash into pending EVM * typed errors for FlashblockId, use pair of Atomics * fix test failures due to harness adjustment * fmt fix * chore: retrigger CI for release retarget
Release v1.1.1
v1.1.1 (PR base#3603) added a prev_flashblock_id predecessor-link arg to FlashblockSequenceValidator::validate and a NonSequentialPredecessor result variant. Pass metadata.prev_flashblock_id from the firehose processor, handle the new variant (reset + wait for base), and update test Metadata literals for the added field.
Tests for the v1.1.1 NonSequentialPredecessor path in the firehose flashblocks processor: mismatched prev_flashblock_id resets state, matching id is accepted, default (unset) id stays backward-compatible. Adds flash_delta_with_prev_id test helper. Docs under docs/firehose/ answer four review questions: the reset tests, Dockerfile.sf build status, Beryl block-model impact, and the pending-EVM parent-hash fix.
Merge v1.1.1 into firehose/1.x
Committed unintentionally via PR #13; these were review notes, not meant to land in the tree.
…rom precompiled (Beryl use case)
Author
|
wrong target for branch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
snapshotter(feat: introducesnapshotterbase/base#2550)BLOCKHASHdivergence bw pending and canonical EVM execution, harden sequence linkage base/base#3603 to releases/v1.1.0 (Backport PR #3603 to releases/v1.1.0 base/base#3634)