• OPTIMISM immunefi-logoRewards Smart Contract
      $0 $15,000 $50,000 <$2,000,042
      Websites and Applications
      $0 $0 $5,000 <$50,000
      Blockchain DLT
      $0 $15,000 $50,000 <$2,000,042

    fix(op-supernode/interop): propagate verifier read errors to super_authority

    ajsutton merged to ethereum-optimism/optimism at 2026-05-25 21:07:19

    fix(op-supernode/interop): propagate verifier read errors to super_authority VerifiedBlockAtL1 and LatestVerifiedL2Block now return an error, and FullyVerifiedL2Head / FinalizedL2Head signal use-local fallback when the verifier reports a read failure rather than returning (empty, false) which would tell op-node to fall back to L2 genesis. Fixes ethereum-optimism/optimism#20944

    by ajsutton

    chore: remove stale TODOs for closed issues

    ajsutton merged to ethereum-optimism/optimism at 2026-05-25 20:50:48

    chore: remove stale TODOs for closed issues Removes TODO comments referencing issues #16917, #16141, #14415, and #14129 where the planned work is no longer intended. Closes ethereum-optimism/optimism#16917 Closes ethereum-optimism/optimism#16141 Closes ethereum-optimism/optimism#14415 Closes ethereum-optimism/optimism#14129

    by ajsutton

    fix(ci): preserve mise.toml for kona-client docker build

    pauldowman merged to ethereum-optimism/optimism at 2026-05-25 18:39:57

    fix(op-program): preserve mise.toml for kona-client docker build

    by pauldowman

    chore(opd): update SCR dep for op-contracts/v7.0.0-rc.3 tag

    maurelian merged to ethereum-optimism/optimism at 2026-05-25 12:21:31

    chore(opd): update SCR dep for op-contracts/v7.0.0-rc.3 tag

    by maurelian

    chore(opd): update current tag

    by maurelian

    fix(opd): resolve SuperchainConfig from SCR for OPCMv2 OPCMv2 (op-contracts/v7) no longer exposes a superchainConfig() getter, so the OPCM-only init path was reverting. Look up the SuperchainConfig proxy from the Superchain Registry by L1 chainID instead.

    by maurelian

    docs(notices): add OP Mainnet date + contract to stake-based priority ordering

    donoso-eth merged to ethereum-optimism/optimism at 2026-05-25 06:44:31

    docs(notices): add OP Mainnet date + contract to stake-based priority ordering - Timeline: OP Mainnet target deployment set to May 26, 2026 — 10:00 EST (was TBD pending governance approval) - New "OP Mainnet deployment" subsection with the deployed PolicyEngineStaking contract address and the canonical OP token - Sepolia deployment subsection trimmed to match the new format (contract + staking token only; owner address dropped) - Key links table: new "Mainnet contract" row above the existing Sepolia contract row Co-Authored-By: Claude Opus 4.7 (1M context)

    by donoso-eth

    • LINEA immunefi-logoRewards Smart Contract
      $1,000 $5,000 $0 $100,000

    fix(maru): wire image handoff into e2e

    gauravahuja merged to Consensys/linea-monorepo at 2026-05-25 17:10:12

    fix(maru): wire image handoff into e2e Ticket: 2540

    by gauravahuja

    docs: weekly audit 2026-05-25

    cursor[bot] merged to Consensys/linea-monorepo at 2026-05-25 07:44:50

    docs: auto-fix markdown audit findings (weekly audit 2026-05-25) - Update stale prerequisite versions in docs/tech/development/README.md to match committed source/configuration files: * pnpm v10.28+ -> v10.32.1+ (package.json engines) * JDK 21 -> 25 (gradle JavaVersion.VERSION_25) * Gradle 8.5+ -> 9.4+ (gradle/wrapper 9.4.1) * Go 1.21+ -> 1.25.7+ (prover/go.mod) - Fix broken cross-reference in docs/security.md: absolute path /docs/audits.md -> relative audits.md (sibling file)

    by cursoragent

    fix(prover): Stronger soundness binding for euclidean division and crumb decomposition

    Tabaie merged to Consensys/linea-monorepo at 2026-05-25 05:28:28

    fix: advisories

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421

    by Tabaie

    revert: state-root binding

    by Tabaie

    revert: unnecessary newline

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421 Signed-off-by: Arya Tabaie

    by Tabaie

    fix: use the sound ToBytes32

    by Tabaie

    style: better looking euclidean division constraint

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421

    by Tabaie

    Merge branch 'main' into patch/aggregation-260421

    by Tabaie

    feat(prover): prover ray—adding a local to global constraints compiler

    bogdanbear merged to Consensys/linea-monorepo at 2026-05-25 05:19:53

    prover-ray (feat): add compiler from local to global constraints

    by bogdanbear

    prover-ray (feat): adding support for field extension cells and coins

    by bogdanbear

    prover-ray (refactor): more readable test names

    by bogdanbear

    prover-ray (fix): running the linter

    by bogdanbear

    prover-ray (fix): check for a potential anchor out of bounds

    by bogdanbear

    Merge branch 'main' into prover-ray/local-to-global-constraints-compiler

    by bogdanbear

    • CHAINLINK immunefi-logoRewards Smart Contract
      <$5,000 <$10,000 <$75,000 <$3,000,000
      Websites and Applications
      <$1,000 <$2,000 <$10,000 <$100,000

    chore: remove EVM approve-token changeset

    jkongie merged to smartcontractkit/chainlink at 2026-05-25 16:39:44

    chore: remove EVM approve-token changeset Delete `ApproveTokenGeneric` and `ApproveTokenForRouter` from `deployment/common/changeset/evm`. CCIP Solana v0.1.0 test helpers now approve ERC20 spend via gethwrappers instead of `cld-changesets` package.

    by jkongie

    chore: remove solana MCMS state views

    jkongie merged to smartcontractkit/chainlink at 2026-05-25 15:42:19

    chore: remove solana MCMS state views These MCMS state views were not being used. Only CCIP generates MCMS state views for solana, and they have their own view generation.

    by jkongie

    CRE-4405: Add gateway request tracing; use default HTTP transport

    cedric-cordenier merged to smartcontractkit/chainlink at 2026-05-25 15:21:16

    CRE-4405: Add request tracing, add default transport to outgoing HTTP requests

    by cedric-cordenier

    chore: move link token stateviews to v1_0 package

    jkongie merged to smartcontractkit/chainlink at 2026-05-25 13:50:13

    chore: move link token stateviews to v1_0 package This is a cleanup of the link token stateviews to move them to the CCIP v1_0 package.

    by jkongie

    chore: move link state to ccip shared stateview

    jkongie merged to smartcontractkit/chainlink at 2026-05-25 10:32:50

    chore: move link state to ccip shared stateview This is a refactor to move the link state to the ccip shared stateview. CCIP is is the only directoryu using this helper.

    by jkongie

    test: refactor cre test setup to use runtime.New

    jkongie merged to smartcontractkit/chainlink at 2026-05-25 10:32:08

    test: refactor cre test setup to use runtime.New wip

    by jkongie

    use runtime for setup

    by jkongie

    clean up and update some tests to use the new test harness

    by jkongie

    init the wrapper env with view only nodes. split onchain to functions

    by jkongie

    cleanup env setup

    by jkongie

    update more tests

    by jkongie

    refactor env setup with functional options

    by jkongie

    [CRE-491] Prepare evmregistry/v21 to be moved to chainlink-evm

    pavel-raykov merged to smartcontractkit/chainlink at 2026-05-25 10:07:48

    Minor.

    by pavel-raykov

    Minor.

    by pavel-raykov

    Minor.

    by pavel-raykov

    Minor.

    by pavel-raykov

    chore: refactor EVM token adapters

    chris-de-leon-cll merged to smartcontractkit/chainlink-ccip at 2026-05-25 13:40:17

    feat: token ref resolver

    by chris-de-leon-cll

    Merge branch 'main' into feat/infer-token-ref

    by chris-de-leon-cll

    fix: CI gomod issue

    by chris-de-leon-cll

    fix: move test

    by chris-de-leon-cll

    docs: re-word artifical address ref label comment

    by chris-de-leon-cll

    test: update configure_tokens_for_transfers_test

    by chris-de-leon-cll

    Merge branch 'main' into feat/infer-token-ref

    by chris-de-leon-cll

    fix: gomod CI

    by chris-de-leon-cll

    fix: typo in comment

    by chris-de-leon-cll

    fix: add nil check for token pool version

    by chris-de-leon-cll

    fix: no panic in decodeArtificialPoolAddressRef

    by chris-de-leon-cll

    fix: add zero address check for pool PDA

    by chris-de-leon-cll

    chore: copilot feedback

    by chris-de-leon-cll

    fix: update environment datastore in each loop iteration for manual reg.

    by chris-de-leon-cll

    chore: address copilot feedback

    by chris-de-leon-cll

    fix: use fully resolved ref in TPRL

    by chris-de-leon-cll

    chore: use underscore for unused datastore parameter

    by chris-de-leon-cll

    fix: only normalize if there is indeed something to normalize

    by chris-de-leon-cll

    chore: update comment in test

    by chris-de-leon-cll

    fix: block empty address refs after normalize

    by chris-de-leon-cll

    fix: copilot feedback

    by chris-de-leon-cll

    fix: add extra nil safety check

    by chris-de-leon-cll

    chore: clean up

    by chris-de-leon-cll

    fix: grammar in comment

    by chris-de-leon-cll

    fix: ensure env datastore is updated on each loop iteration

    by chris-de-leon-cll

    refactor: reuse helper function in findRef

    by chris-de-leon-cll

    fix: show derive error

    by chris-de-leon-cll

    chore: add clarifying note

    by chris-de-leon-cll

    chore: fix comment

    by chris-de-leon-cll

    fix: make log more informative

    by chris-de-leon-cll

    refactor: clean up code

    by chris-de-leon-cll

    fix: pass bundle

    by chris-de-leon-cll

    chore: fix gomod for CI

    by chris-de-leon-cll

    Merge branch 'main' into chore/refactor-evm-token-adapters

    by chris-de-leon-cll

    chore: revert noisy datastore formatting

    by chris-de-leon-cll

    feat: skip datastore if address is already present in the ref

    by chris-de-leon-cll

    fix: best-effort tidy token roles

    by chris-de-leon-cll

    test: enable address ref resolvers in v2 tokens_test

    by chris-de-leon-cll

    test: fix unpopulated token ref edge case

    by chris-de-leon-cll

    fix: token ref should not be overwritten

    by chris-de-leon-cll

    fix: bump go mod for CI

    by chris-de-leon-cll

    fix: update error message

    by chris-de-leon-cll

    fix: GetCurrentInboundRateLimit should fail if fast finality is true for pre-V2 adapters

    by chris-de-leon-cll

    fix: error format string

    by chris-de-leon-cll

    Merge branch 'main' into chore/refactor-evm-token-adapters

    by chris-de-leon-cll

    chore: prefer chain.Selector over input.Selector

    by chris-de-leon-cll

    docs: update stale comment

    by chris-de-leon-cll

    refactor: standardize DeployTokenPool

    by chris-de-leon-cll

    chore: bump gomod for ci

    by chris-de-leon-cll

    chore: rename ParseAllowList

    by chris-de-leon-cll

    fix: inverted condition

    by chris-de-leon-cll

    test: fixes

    by chris-de-leon-cll

    Merge branch 'main' into chore/refactor-evm-token-adapters

    by chris-de-leon-cll

    fix: ToNonZeroEVMAddress

    by chris-de-leon-cll

    refactor: rename TokenInfo to ERC20Decimals

    by chris-de-leon-cll

    fix: edge case zero address handling

    by chris-de-leon-cll

    fix: typo in comment Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

    by chris-de-leon-cll

    fix: remove duplicate import

    by chris-de-leon-cll

    Merge branch 'chore/refactor-evm-token-adapters' of github.com:smartcontractkit/chainlink-ccip into chore/refactor-evm-token-adapters

    by chris-de-leon-cll

    fix: use nonzero address for fetchTokenGovernor

    by chris-de-leon-cll

    fix: ResolveRouterAddress preserve behavior in comment

    by chris-de-leon-cll

    docs: update v2 token pool adapter comment

    by chris-de-leon-cll

    fix: add better error message for fetchTokenGovernor

    by chris-de-leon-cll

    fix: SetRateLimitAdmin now returns a slice of writes

    by chris-de-leon-cll

    fix: allow rate limit admin to be set to zero address (i.e. reset)

    by chris-de-leon-cll

    move package promutil out of sqlutil

    jmank88 merged to smartcontractkit/chainlink-common at 2026-05-25 21:47:06

    move package promutil out of sqlutil

    by jmank88

    • ENS immunefi-logoRewards Smart Contract
      $2,500 $10,000 <$100,000 <$250,000
      Websites and Applications
      $1,000 $2,500 <$20,000 $25,000

    feat: require hca interaction

    TateB merged to ensdomains/contracts-v2 at 2026-05-25 19:06:47

    feat: require hca interaction

    by TateB

    feat: hardcode deferred hca implementation

    by TateB

    style: format hca tests

    by TateB

    refactor: clean up hca factory interface

    by TateB

    refactor: remove nexus hca proxy dependency

    by TateB

    refactor: use yul hca proxy bytecode

    by TateB

    feat: update hca interaction flow

    by TateB

    feat: expose deferred hca implementation

    by TateB

    feat: record hca on account creation

    by TateB

    perf: compute hca account address

    by TateB

    test: simplify reverse registrar hca fixture

    by TateB

    merge: post-audit into hca interaction branch

    by TateB

    fix: restore reverse mirror deploy

    by TateB

    fix: update hca factory interface selector

    by TateB

    fix: restore contract namer deploy

    by TateB

    fix: avoid spaced hca coverage name

    by TateB

    chore: revert coverage script change

    by TateB

    fix: skip mainnet hca owner setup

    by TateB

    Add `IContractNamer`

    adraffy merged to ensdomains/contracts-v2 at 2026-05-25 15:46:15

    poc

    by adraffy

    add supports interface

    by adraffy

    fix rebase

    by adraffy

    foundry bug?

    by adraffy

    foundry bug??

    by adraffy

    fix lint?

    by adraffy

    add to registrar

    by adraffy

    fix derp

    by adraffy

    add fallthru

    by adraffy

    fix format

    by adraffy

    add adapter support, add AddressNamerLib

    by adraffy

    fix derp

    by adraffy

    fix integration tests

    by adraffy

    make more stuff nameable

    by adraffy

    fix lint?

    by adraffy

    improve isNamer, add naming to devnet

    by adraffy

    wip, naming more things, todo: LabelStore

    by adraffy

    add ContractNamer, refactor using DelegatedContractNamer

    by adraffy

    fix readme

    by adraffy

    fix merge

    by adraffy

    fix tests

    by adraffy

    fix prepareMigration

    by adraffy

    fix prepareMigration again

    by adraffy

    change ContractNamer to proxy

    by adraffy

    fix 1967 artifact

    by adraffy

    rename to AccountNamerLib

    by adraffy

    fix merge

    by adraffy

    remove AddrReverseResolver for IContractName support

    by adraffy

    fix merge

    by adraffy

    • BABYLON-LABS immunefi-logoRewards Websites and Applications
      $1,000 $3,000 <$7,500 <$70,000
      Blockchain DLT
      $1,000 <$5,000 <$15,000 <$500,000

    fix(vault): align deposit progress steps with polled status

    jeremy-babylonlabs merged to babylonlabs-io/babylon-toolkit at 2026-05-25 15:07:52

    fix(vault): align deposit progress steps with polled status Reconcile the deposit-flow stepper and pending-deposit cards with the actual polled status so the displayed step, status badge, and available action never disagree. - Suppress the phantom "Broadcast Pre-Pegin" prompt once the Pre-PegIn transaction is seen/confirmed on the Bitcoin network, so the broadcast prompt stays consistent across tabs (chain ground truth overrides the stale SDK action set). - Reconcile the WOTS resume modal with the polled vault-provider status: it advances off the WOTS step on a hung or duplicate submit instead of spinning forever, resolving to a closeable "Close & continue later" wait. - Collapse the vault-provider ingestion wait into the shared "Confirming deposit" step, distinguished by status message rather than a separate rung. - Surface a "Ready to activate" terminal milestone in the payout-signing resume flow once the vault provider posts verification on-chain. - Align the confirming-deposit copy with Bitcoin confirmation and relabel the WOTS step to "Set up Winternitz One-Time Signature (WOTS)".

    by jeremy-babylonlabs

    fix(vault): mount ProtocolParamsProvider above dashboard pending sect…

    jrwbabylonlab merged to babylonlabs-io/babylon-toolkit at 2026-05-25 12:37:01

    fix(vault): mount ProtocolParamsProvider above dashboard pending section (#1757)

    by jrwbabylonlab

    feat(vault): expired-refund maturity countdown

    by jrwbabylonlab

    feat(vault): pending utxos message + tooltip

    gbarkhatov merged to babylonlabs-io/babylon-toolkit at 2026-05-25 11:52:51

    feat(vault): pending utxos message + tooltip

    by gbarkhatov

    chore(pr): comments

    by gbarkhatov

    chore(pr): comments

    by gbarkhatov

    feat(vault): show nominated BTC address on pending withdraw cards

    jrwbabylonlab merged to babylonlabs-io/babylon-toolkit at 2026-05-25 10:58:45

    feat(vault): show nominated BTC address on pending withdraw cards

    by jrwbabylonlab

    fix(vault): surface wallet ownership mismatch on pending deposit cards

    jrwbabylonlab merged to babylonlabs-io/babylon-toolkit at 2026-05-25 07:30:45

    fix(vault): surface wallet ownership mismatch on pending deposit cards

    by jrwbabylonlab

    fix(vault): cache confirmed Pre-PegIn observations to stop redundant …

    jrwbabylonlab merged to babylonlabs-io/babylon-toolkit at 2026-05-25 00:00:54

    fix(vault): cache confirmed Pre-PegIn observations to stop redundant mempool polls

    by jrwbabylonlab

    fix(vault): treat confirmed-Pre-PegIn cache as authoritative in CTA consumer

    by jrwbabylonlab

    • POLYGON immunefi-logoRewards Smart Contract
      $0 $2,000 $10,000 <$250,000
      Blockchain DLT
      $0 $2,000 $10,000 <$250,000

    miner: format build-block log times as RFC3339Nano, gate on IsRunning

    kamuikatsurgi merged to maticnetwork/bor at 2026-05-25 17:53:16

    miner: format build-block log times as RFC3339Nano, gate on IsRunning

    by kamuikatsurgi

    miner: normalize build-block log timestamps to UTC prepareWorkStart and Header.ActualTime come from time.Now() (Local), while time.Unix(...) returns Local-zoned values as well. Mixing those into a single RFC3339Nano log line produces inconsistent offsets and makes cross-service correlation harder. Force UTC on every logged timestamp. Co-Authored-By: Claude Opus 4.7 (1M context)

    by kamuikatsurgi

    miner: drop PeerCount==0 gate in mainLoop

    cffls merged to maticnetwork/bor at 2026-05-25 10:42:01

    miner: drop PeerCount==0 gate in mainLoop The peer-count drop branch in `mainLoop` was introduced in #977 to delay block production until at least one peer was connected, scoped to BorMainnet/Mumbai (Amoy was added later in e8157bbe6). #2220 widened the gate from a chain-ID list to "any heimdall-connected node", which drew kurtosis devnets into the gate for the first time: in a single-validator kurtosis devnet PeerCount() is 0 by design (no other node to peer with), the gate drops every newWorkReq, and the veblop fallback timer re-fires straight back into the same drop. Veblop's primary/backup producer election already handles outage safety at the protocol level — peer count adds no safety, only a foot-gun. Strip the gate; `mainLoop` now routes every newWorkReq directly to `commitWork` (except the pre-existing DisablePendingBlock-on-non-validator short-circuit). Verified end-to-end on a kurtosis 1-validator devnet (chain ID 4927, veblop active).

    by cffls

    miner: drop stale PeerCount==0 gate references in test backends Follow-up to the gate removal. With no test exercising peer count anymore, the `testWorkerBackend.peerCount` atomic.Int32 plumbing in `worker_test.go` was just ceremony — drop the field, the `Store(1)` default, and simplify `PeerCount()` to return a constant. The `mockBackend` / `mockBackendBor` PeerCount comments in `miner_test.go` and `fake_miner.go` still named the removed gate; rewrite them to describe what the function does rather than what it no longer guards. No production change. Co-Authored-By: Claude Opus 4.7 (1M context)

    by cffls

    miner: drop dangling incident references in syncing-leak test docstring The doc comment and t.Fatalf message for TestCommitWorkLeaksPendingWorkBlockWhenSyncing framed it against the "PeerCount==0 race fixed for the 2026-05-07 incident" and the related val4 stall — context that disappeared from the tree with the gate removal and the sibling regression test in this branch's earlier commits. Rewrite the docstring to describe the leak on its own terms and trim the t.Fatalf tail so a future reader hitting the failure doesn't grep for a name that no longer exists in-tree. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context)

    by cffls

    tests/bor: drop dangling gate references in producer-recovery docstring TestProducerRecoversAfterMiningRestart's docstring framed itself against four leak paths; item (1) named the deleted unit test TestMainLoopClearsPendingWorkBlockOnPeerCountZero and the deleted gate (`realNetworkNode := bor.HeimdallClient != nil`). The integration-level limitations clause also leaned on Bug 1 / that gate. Drop both. Renumber the remaining three leak paths and add a short historical note that the fourth was closed by removing the gate itself in earlier commits on this branch. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context)

    by cffls

    tests/bor: drop dangling Bug 1 references in producer-recovery test After the previous commit renumbered the four-bug list down to three, three remaining "Bug 1" mentions in the docstring header and the test body's Phase 2 / Phase 3 comments became dangling (the enumeration no longer has a Bug 1 entry). Reword each to point at the generic "leak family" instead. The test's behavior is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context)

    by cffls

    • OASIS immunefi-logoRewards Websites and Applications
      $0 $0 $0 $10,000
      Blockchain DLT
      $0 $1,000 <$10,000 <$100,000

    contracts: Prepare 0.2.16 release

    matevz merged to oasisprotocol/sapphire-paratime at 2026-05-25 06:32:45

    contracts: Prepare 0.2.16 release

    by matevz

    • AUDIT-COMP-BASE-AZUL immunefi-logoRewards Smart Contract
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool
      Blockchain DLT
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool

    feat: increase max gas limit on zeronet

    wlawt merged to base/contract-deployments at 2026-05-25 15:09:35

    feat: increase max gas limit on zeronet

    by wlawt

    feedback

    by wlawt

    desc fixes

    by wlawt

    records: add execution artifacts and mark task EXECUTED

    by wlawt

    revert status to READY TO SIGN for signer UI

    by wlawt

    records: add SC approval execution artifacts

    by wlawt

    mark task EXECUTED

    by wlawt

    records: add final execution artifact and mark EXECUTED

    by wlawt

    bookkeeping

    by wlawt

    add artifacts to readme

    by wlawt

    chore: clean up l2 tests

    jackchuma merged to base/contracts at 2026-05-25 15:02:50

    clean up l2 tests

    by jackchuma

    • HATHORNETWORK immunefi-logoRewards Websites and Applications
      $0 $0 $0 $10,000
      Blockchain DLT
      $1,000 $0 $10,000 <$20,000

    feat: add nginx config support for testnet-shielded-outputs + fix Nginx config generation when using new @api_endpoint

    luislhl merged to HathorNetwork/hathor-core at 2026-05-25 18:53:18

    feat: add nginx config support for testnet-shielded-outputs - Add Makefile targets for GCP Hathor Testnet Shielded Outputs project - Add _lift_operation_extensions() to normalize OpenAPI extensions from operation level to path level, enabling new-style @api_endpoint resources - Fix --disable-rate-limits to use action='store_true' instead of type=bool Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

    by luislhl

    chore: add docker login step in MAkefile

    by luislhl

    fix: harden nginx OpenAPI extension resolution

    by luislhl

    fix: aws-login runs twice in the Makefile; Resources with no public methods; Leak in test overwriting modules

    by luislhl

    style: fix linters

    by luislhl

    style: fix linters

    by luislhl

    fix: upgrade wallet lib to v3.1.1 (#868)

    pedroferreira1 merged to HathorNetwork/hathor-wallet at 2026-05-25 14:32:39

    fix: upgrade wallet lib to v3.1.1 (#868)

    by pedroferreira1

    • ROOTSTOCKLABS immunefi-logoRewards Smart Contract
      $1,000 $2,500 <$10,000 <$100,000
      Websites and Applications
      $1,000 $1,500 $2,500 <$10,000
      Blockchain DLT
      <$2,500 <$5,000 <$10,000 <$200,000

    FLY-2264 Pegout - Wrong amount message when not enough liquidity in /acceptQuote endpoint

    TravellerOnTheRun merged to rsksmart/liquidity-provider-server at 2026-05-25 06:43:53

    fix(pegout): clarify acceptQuote liquidity error details (FLY-2264) Replace ambiguous Args.amount with quoteValue, gasFee, requiredLiquidity, and missingLiquidity when available. Preserve the liquidity provider error chain so missing satoshi text is not dropped. Non-liquidity errors from HasPegoutLiquidity are wrapped without being mislabeled as no liquidity.

    by TravellerOnTheRun

    fix(pegout): return typed insufficient liquidity error (FLY-2264) HasPegoutLiquidity now returns InsufficientLiquidityError with snapshotted amounts so accept pegout can populate missingLiquidity without a second AvailablePegoutLiquidity call.

    by TravellerOnTheRun

    Bump actions/download-artifact from 7.0.0 to 8.0.1

    dependabot[bot] merged to rsksmart/powpeg-node at 2026-05-25 20:30:04

    Bump actions/download-artifact from 7.0.0 to 8.0.1 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7.0.0 to 8.0.1. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/37930b1c2abaa49bbe596cd826c3c89aef350131...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    Bump docker/setup-buildx-action from 3.12.0 to 4.0.0

    dependabot[bot] merged to rsksmart/powpeg-node at 2026-05-25 19:45:47

    Bump docker/setup-buildx-action from 3.12.0 to 4.0.0 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.12.0 to 4.0.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/8d2750c68a42422c14e847fe6c8ac0403b4cbd6f...4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    Bump actions/dependency-review-action from 4.9.0 to 5.0.0

    dependabot[bot] merged to rsksmart/powpeg-node at 2026-05-25 18:50:45

    Bump actions/dependency-review-action from 4.9.0 to 5.0.0 Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4.9.0 to 5.0.0. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/2031cfc080254a8a887f58cffee85186f0e49e48...a1d282b36b6f3519aa1f3fc636f609c47dddb294) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    Bump docker/metadata-action from 5.10.0 to 6.0.0

    dependabot[bot] merged to rsksmart/powpeg-node at 2026-05-25 17:28:36

    Bump docker/metadata-action from 5.10.0 to 6.0.0 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.10.0 to 6.0.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/c299e40c65443455700f0fdfc63efafe5b349051...030e881283bb7a6894de51c315a6bfe6a94e05cf) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    Check that RIT workflow is executed from a PR

    marcos-iov merged to rsksmart/powpeg-node at 2026-05-25 14:30:50

    Check that RIT workflow is executed from a PR

    by marcos-iov

    Bump docker/build-push-action from 6 to 7.1.0

    dependabot[bot] merged to rsksmart/powpeg-node at 2026-05-25 13:42:30

    Bump docker/build-push-action from 6 to 7.1.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.1.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7.1.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    Update rit.yml to use slack-api v3

    marcos-iov merged to rsksmart/rskj at 2026-05-25 14:24:50

    Update rit.yml to use slack-api v3

    by marcos-iov

    Check that the workflow is triggered from a PR

    by marcos-iov

    • LIDO immunefi-logoRewards Smart Contract
      $1,000 <$50,000 <$250,000 <$2,000,000
      Websites and Applications
      $500 <$5,000 <$50,000 <$100,000

    feat: update meta group interface

    F4ever merged to lidofinance/lido-oracle at 2026-05-25 15:29:00

    feat: update meta group interface

    by F4ever

    fix: tests

    by F4ever

    • STARKNET immunefi-logoRewards Smart Contract
      $0 $0 $0 <$350,000
      Websites and Applications
      $0 $0 <$2,500 <$10,000
      Blockchain DLT
      $0 $0 $15,000 <$350,000

    blockifier_test_utils: add OS resources measurement contract

    dorimedini-starkware merged to starkware-libs/sequencer at 2026-05-25 15:12:55

    blockifier_test_utils: add OS resources measurement contract

    by dorimedini-starkware

    apollo_storage: revert add transaction_events table for event storage (#13461)

    ShahakShama merged to starkware-libs/sequencer at 2026-05-25 14:41:04

    apollo_storage: revert separate events from TransactionOutput (#13462)

    by ShahakShama

    apollo_storage: revert add transaction_events table for event storage (#13461)

    by ShahakShama

    blockifier: bump execute_max_sierra_gas 1.1B -> 1.11B (SNIP-40)

    matanl-starkware merged to starkware-libs/sequencer at 2026-05-25 14:11:09

    blockifier: bump execute_max_sierra_gas 1.1B -> 1.11B (SNIP-40) Per SNIP-40 "More Frequent Blocks", raise EXECUTE_MAX_SIERRA_GAS from 1,100,000,000 to 1,110,000,000 L2 gas. This 0.9% headroom is intended to keep storage-heavy transactions under the per-tx limit after the StorageRead/Write gas-cost bump in the next PR. Note: this PR touches constants.cairo but leaves program_hash.json and allowed_virtual_os_program_hashes unchanged. The OS program hash needs to be regenerated by recompiling the Cairo OS after both cairo-touching SNIP-40 PRs land (this one + the StorageRead/Write change on top). Spec: https://community.starknet.io/t/snip-40-more-frequent-blocks/116203 Co-Authored-By: Claude Opus 4.7 (1M context)

    by matanl-starkware

    blockifier: increase StorageRead/Write gas costs +33% (SNIP-40) (#14177) Per SNIP-40 "More Frequent Blocks": StorageRead: 18,070 -> 24,070 L2 gas (n_steps 180 -> 240) StorageWrite: 44,970 -> 59,970 L2 gas (n_steps 449 -> 599) The +33% bump offsets the cost reduction from fewer per-cell accesses per block at the new 1.5s block time, keeping per-block proving cost roughly flat. JSON drives constants.cairo via test_os_constants regeneration: STORAGE_READ_GAS_COST 18070 -> 24070 STORAGE_WRITE_GAS_COST 44970 -> 59970 program_hash.json regenerated via UPDATE_EXPECT=1 cargo test test_program_hashes (covers cairo deltas from this PR + the previous EXECUTE_MAX_SIERRA_GAS bump in the stack). Test fixtures updated: - expect! blocks via UPDATE_EXPECT=1 (call_contract, deploy, library_call, meta_tx, storage_read_write, transactions_test - declare/deploy/invoke/l1). - Hardcoded n_steps in deprecated_syscalls_test: 671 -> 881 (inner: +60r +150w), 710 -> 920 (outer with descendant deltas). - transactions_test::test_invoke_tx Cairo1 expected gas: 330470 -> 414470 (4 reads + 4 writes * delta = +84000). - execution_flavors_test transfer scenario step budget: +6104 -> +6944 (matches SNIP-37's +4332 -> +6104 pattern for 4r+4w deltas). Not changed: allowed_virtual_os_program_hashes still holds the two pre-SNIP-40 entries. Updating this list is a separate policy decision (authoritative virtual_os hash from the proof team) and is not strictly required for the gas-cost change to function. Spec: https://community.starknet.io/t/snip-40-more-frequent-blocks/116203 Co-authored-by: Claude Opus 4.7 (1M context)

    by matanl-starkware

    starknet_committer: support both layouts in fetch_patricia_paths

    ArielElp merged to starkware-libs/sequencer at 2026-05-25 13:41:28

    starknet_committer: abstract fetch_patricia_paths

    by ArielElp

    apollo_storage,apollo_batcher,apollo_reverts: write accessed keys instead of tx execution infos

    yoavGrs merged to starkware-libs/sequencer at 2026-05-25 13:40:41

    apollo_storage,apollo_batcher,apollo_reverts: write accessed keys instead of tx execution infos Replace the os_input-gated tx_execution_infos persistence path with an accessed_keys path: a per-block AccessedKeys aggregate the OS needs to replay the block. - apollo_storage: new accessed_keys module (table, file handler, OffsetKind, reader/writer traits), re-exporting blockifier's AccessedKeys struct and impl'ing StorageSerde on it. Replaces the tx_execution_info module. - apollo_batcher: Batcher::decision_reached now builds the set via compute_accessed_keys (visited storage entries + state-diff writes + ProofFacts block numbers + predicted alias-contract entries) and writes it through write_accessed_keys. The trait method and prod impl swap from write_tx_execution_infos to write_accessed_keys, gated under os_input. - apollo_reverts: revert path drops accessed_keys instead of tx_execution_infos. Co-Authored-By: Claude Opus 4.7 (1M context)

    by yoavGrs

    apollo_gateway_config: default allow_client_side_proving to true

    AvivYossef-starkware merged to starkware-libs/sequencer at 2026-05-25 13:35:07

    apollo_gateway_config: default allow_client_side_proving to true

    by AvivYossef-starkware

    blockifier: store per-block builtin instance limits, derive proving-gas weights

    Yoni-Starkware merged to starkware-libs/sequencer at 2026-05-25 12:56:59

    blockifier: store builtin instance limits in config, derive proving-gas weights BouncerConfig now holds BuiltinInstanceLimits (per-block bounds) instead of hard-coded BuiltinWeights. Per-Cairo-primitive proving-gas cost is derived as floor(block_max_capacity.proving_gas / limit). Default limits come from the SN-bounds spec (overrides: blake=1.8M, bitwise=10.5M). At the unchanged 5B budget this drops weights ~17% across the board and ecop ~95% (857850 -> 38461). A regression test pins the 11 induced weights against the defaults. Co-Authored-By: Claude Opus 4.7 (1M context)

    by Yoni-Starkware

    blockifier: increase StorageRead/Write gas costs +33% (SNIP-40)

    matanl-starkware merged to starkware-libs/sequencer at 2026-05-25 11:56:16

    blockifier: increase StorageRead/Write gas costs +33% (SNIP-40) Per SNIP-40 "More Frequent Blocks": StorageRead: 18,070 -> 24,070 L2 gas (n_steps 180 -> 240) StorageWrite: 44,970 -> 59,970 L2 gas (n_steps 449 -> 599) The +33% bump offsets the cost reduction from fewer per-cell accesses per block at the new 1.5s block time, keeping per-block proving cost roughly flat. JSON drives constants.cairo via test_os_constants regeneration: STORAGE_READ_GAS_COST 18070 -> 24070 STORAGE_WRITE_GAS_COST 44970 -> 59970 program_hash.json regenerated via UPDATE_EXPECT=1 cargo test test_program_hashes (covers cairo deltas from this PR + the previous EXECUTE_MAX_SIERRA_GAS bump in the stack). Test fixtures updated: - expect! blocks via UPDATE_EXPECT=1 (call_contract, deploy, library_call, meta_tx, storage_read_write, transactions_test - declare/deploy/invoke/l1). - Hardcoded n_steps in deprecated_syscalls_test: 671 -> 881 (inner: +60r +150w), 710 -> 920 (outer with descendant deltas). - transactions_test::test_invoke_tx Cairo1 expected gas: 330470 -> 414470 (4 reads + 4 writes * delta = +84000). - execution_flavors_test transfer scenario step budget: +6104 -> +6944 (matches SNIP-37's +4332 -> +6104 pattern for 4r+4w deltas). Not changed: allowed_virtual_os_program_hashes still holds the two pre-SNIP-40 entries. Updating this list is a separate policy decision (authoritative virtual_os hash from the proof team) and is not strictly required for the gas-cost change to function. Spec: https://community.starknet.io/t/snip-40-more-frequent-blocks/116203 Co-Authored-By: Claude Opus 4.7 (1M context)

    by matanl-starkware

    apollo_storage: revert separate events from TransactionOutput (#13462)

    ShahakShama merged to starkware-libs/sequencer at 2026-05-25 11:37:26

    apollo_storage: revert separate events from TransactionOutput (#13462)

    by ShahakShama

    starknet_transaction_prover: add --log-format text|json CLI flag

    avi-starkware merged to starkware-libs/sequencer at 2026-05-25 10:39:53

    starknet_transaction_prover: add --log-format text|json CLI flag Adds a LogFormat enum and `--log-format` / `LOG_FORMAT=text|json` selector that switches the tracing subscriber between the text and JSON formatters. Default is text. Matches the discovery-service convention. Co-Authored-By: Claude Opus 4.7 (1M context)

    by avi-starkware

    blockifier: take CommitmentStateDiff in AccessedKeys::new and predicted_alias_storage_entries

    yoavGrs merged to starkware-libs/sequencer at 2026-05-25 10:09:18

    blockifier: take CommitmentStateDiff in AccessedKeys::new and predicted_alias_storage_entries CommitmentStateDiff is the natural per-block state-diff type at the OS-replay boundary (the batcher's BlockExecutionArtifacts already carries one). Swap both AccessedKeys::new and predicted_alias_storage_entries to consume it directly: - AccessedKeys::new derives storage entries from state_diff.storage_updates, the modified-contracts union from storage_updates / address_to_nonce / address_to_class_hash, and the class-hash keys from address_to_class_hash + class_hash_to_compiled_class_hash. - predicted_alias_storage_entries now walks CommitmentStateDiff directly; the parity test converts its StateMaps fixture via CommitmentStateDiff::from. Co-Authored-By: Claude Opus 4.7 (1M context)

    by yoavGrs

    blockifier: include Blake opcodes in proving-vs-sierra gas-delta test

    Yoni-Starkware merged to starkware-libs/sequencer at 2026-05-25 10:09:18

    blockifier: include Blake opcodes in proving-vs-sierra gas-delta test `test_proving_gas_minus_sierra_gas_equals_builtin_gas` summed `.prover_builtins()` for CASM-hash resources, missing the Blake opcodes they actually use. The bug was masked because today's defaults set `blake_proving == blake_sierra == 3334`, so the missing Blake count contributed zero to the expected delta. Switch to `.prover_cairo_primitives()` and a `CairoPrimitiveCounterMap` accumulator so opcodes are included. Co-Authored-By: Claude Opus 4.7 (1M context)

    by Yoni-Starkware

    apollo_versioned_constants: reduce block gas_target 1.5B -> 1.04B (SNIP-40)

    matanl-starkware merged to starkware-libs/sequencer at 2026-05-25 09:47:57

    apollo_versioned_constants: reduce block gas_target 1.5B -> 1.04B (SNIP-40) Per SNIP-40 "More Frequent Blocks", reduce the EIP-1559 block gas target from 1,500,000,000 to 1,040,000,000 L2 gas. Empirical data showed blocks were hitting bouncer resource limits far more often than reaching the gas target; the new target rebalances toward the actual binding capacity. Spec: https://community.starknet.io/t/snip-40-more-frequent-blocks/116203 Co-Authored-By: Claude Opus 4.7 (1M context)

    by matanl-starkware

    apollo_consensus_orchestrator: add SNIP-35 fee_proposal validation

    sirandreww-starkware merged to starkware-libs/sequencer at 2026-05-25 08:52:27

    apollo_consensus_orchestrator: add SNIP-35 fee_proposal validation

    by sirandreww-starkware

    apollo_consensus_orchestrator: include fee_proposal_fri in proposal commitment hash

    sirandreww-starkware merged to starkware-libs/sequencer at 2026-05-25 08:17:37

    apollo_consensus_orchestrator: include fee_proposal_fri in proposal commitment hash

    by sirandreww-starkware

    apollo_starknet_client: read fee_proposal_fri from feeder gateway

    sirandreww-starkware merged to starkware-libs/sequencer at 2026-05-25 07:51:49

    apollo_starknet_client: read fee_proposal_fri from feeder gateway

    by sirandreww-starkware

    apollo_starknet_client: fix CI failure

    by ShahakShama

    blockifier_test_utils: add create_multicall_calldata helper

    AvivYossef-starkware merged to starkware-libs/sequencer at 2026-05-25 07:47:11

    blockifier_test_utils: add create_multicall_calldata helper Serializes a sequence of calls as `Array` for use as Cairo 1 account multicall calldata. Matches `starknet_rust::accounts::ExecutionEncoding::New`. Replaces ad-hoc serialization in `prove_and_verify_multicall_tx` and the private `single_multicall_data` helper in `cende_blob_regression_test`. Co-Authored-By: Claude Opus 4.7 (1M context)

    by AvivYossef-starkware

    apollo_batcher_config: reduce proposer_idle_detection_delay 2000 -> 1500ms (SNIP-40)

    matanl-starkware merged to starkware-libs/sequencer at 2026-05-25 07:43:05

    apollo_batcher_config: reduce proposer_idle_detection_delay 2000 -> 1500ms (SNIP-40) Per SNIP-40 "More Frequent Blocks", reduce the batcher's mempool idle-detection delay from 2.0s to 1.5s. Block cadence is driven by this delay, so this changes the typical block execution slot from ~2s to ~1.5s. Spec: https://community.starknet.io/t/snip-40-more-frequent-blocks/116203 Co-Authored-By: Claude Opus 4.7 (1M context)

    by matanl-starkware

    apollo_batcher: record ProofFacts block_number per tx

    yoavGrs merged to starkware-libs/sequencer at 2026-05-25 07:18:33

    apollo_batcher: record ProofFacts block_number per tx For each successfully-executed tx carrying non-empty SNOS proof facts, store the (tx_hash -> block_number) pair on BlockTransactionExecutionData. The batcher will fold these into the BLOCK_HASH_TABLE_ADDRESS entries it writes to the accessed-key set. Rollback flows alongside execution_infos via remove_last_txs. Co-Authored-By: Claude Opus 4.7 (1M context)

    by yoavGrs

    starknet_os_flow_tests: extract test contract constructor calldata helpers

    AvivYossef-starkware merged to starkware-libs/sequencer at 2026-05-25 06:54:54

    starknet_os_flow_tests: extract test contract constructor calldata helpers

    by AvivYossef-starkware

    • ZKSYNC-OS immunefi-logoRewards Blockchain DLT
      $0 $5,000 $20,000 <$100,000

    feat: field FMA opcode + blake special opcodes

    shamatar merged to matter-labs/zksync-airbender at 2026-05-25 11:57:27

    change definition

    by shamatar

    fix up to generator

    by shamatar

    regenerate everything

    by shamatar

    build binaries and run transpiler tests

    by shamatar

    clean

    by shamatar

    fix full statement verifier + format

    by shamatar

    make baseline using just rotation opcode

    by shamatar

    wip 2/n

    by shamatar

    fix tri-add opcode

    by shamatar

    add ext += ext * base via fma

    by shamatar

    test some E4 FMA options - negative for now

    by shamatar

    bump the compiler and fix issues

    by shamatar

    reoder E4 routine

    by shamatar

    conveniece

    by shamatar

    fmt

    by shamatar

    remove "use division" feature

    by shamatar

    Merge remote-tracking branch 'origin/av_gkr_compiler' into av_blake_opcode_experiments

    by shamatar

    regenerate flamegraphs

    by shamatar

    Merge remote-tracking branch 'origin/av_gkr_compiler' into av_blake_opcode_experiments

    by shamatar

    [WIP] feat: Expr IR

    popzxc merged to matter-labs/zksync-airbender at 2026-05-25 11:43:04

    Expr IR prototype

    by popzxc

    Remove Scale Expr variant

    by popzxc

    Migrate Circuit::choose and Boolean to use Expr

    by popzxc

    Migrate more helpers

    by popzxc

    Add converters from term/expr + migrate utils

    by popzxc

    Remove dead code

    by popzxc

    Port add_sub_family circuit

    by popzxc

    Commit compiled circuits

    by popzxc

    Merge remote-tracking branch 'origin/av_gkr_compiler' into popzxc-gkr-parentheses

    by popzxc

    Rearrange parentheses for add-sub family

    by popzxc

    Basic canonicalization

    by popzxc

    Basic constant folding

    by popzxc

    Migrate binary shifts family

    by popzxc

    Migrate mem_word_only

    by popzxc

    Migrate mem_subword_only

    by popzxc

    Migrate jump branch slt family

    by popzxc

    Migrate muldiv circuit

    by popzxc

    Migrate calculate_pc_next_no_overflows_with_range_checks

    by popzxc

    Migrate blake delegation

    by popzxc

    Migrate bigint

    by popzxc

    Migrate keccak circuit

    by popzxc

    Remove constraint usage from one helper

    by popzxc

    feat: Make non-determinism source more like iterator

    shamatar merged to matter-labs/zksync-airbender at 2026-05-25 09:29:10

    change definition

    by shamatar

    fix up to generator

    by shamatar

    regenerate everything

    by shamatar

    build binaries and run transpiler tests

    by shamatar

    clean

    by shamatar

    fix full statement verifier + format

    by shamatar

    • MOONBEAMNETWORK immunefi-logoRewards Websites and Applications
      $1,000 $1,500 <$2,000 $0
      Blockchain DLT
      <$1,000 <$2,000 <$3,000 <$5,000

    Add MPCQ Mainnet (262144)

    Kaushik-Questwalk merged to ethereum-lists/chains at 2026-05-25 17:39:28

    Add MPCQ Mainnet (262144)

    by Kaushik-Questwalk

    Merge branch 'master' into master

    by ligi

    Fix MPCQ chain file

    by Kaushik-Questwalk

    Merge branch 'master' of https://github.com/Kaushik-Questwalk/chains

    by Kaushik-Questwalk

    Fix MPCQ chain file

    by Kaushik-Questwalk

    Merge branch 'ethereum-lists:master' into master

    by Kaushik-Questwalk

    style: fix prettier formatting issues

    by Kaushik-Questwalk

    fix: correct explorer URL for MPCQ Mainnet

    by Kaushik-Questwalk

    Merge branch 'master' into master

    by ligi

    fixed prettier issue

    by Kaushik-Questwalk

    Merge branch 'master' of https://github.com/Kaushik-Questwalk/chains

    by Kaushik-Questwalk

    Merge branch 'master' into master

    by ligi

    Merge branch 'master' into master

    by ligi

    Merge branch 'master' into master

    by Kaushik-Questwalk

    fix: resolve EIP-3091 compliance and fix infoURL

    by Kaushik-Questwalk

    Merge branch 'ethereum-lists:master' into master

    by Kaushik-Questwalk

    Merge branch 'master' of https://github.com/Kaushik-Questwalk/chains

    by Kaushik-Questwalk

    Merge branch 'master' into master

    by ligi

    chore: format mpcq mainnet chain file

    by Kaushik-Questwalk

    Merge branch 'master' into master

    by ligi

    Merge branch 'master' into master

    by ligi

    Merge branch 'master' into master

    by ligi

    Add PLN Network (chainId 411994)

    mandywong040789-eng merged to ethereum-lists/chains at 2026-05-25 17:06:22

    Add PLN Network (chainId 411994) Add PLN Network, a private EVM-compatible PoA chain with Chain ID 411994. Native currency: PLN (18 decimals). RPC: https://oneagent.uk/rpc. Explorer: https://plnscan.com.

    by mandywong040789-eng

    Add PLN Network icon Add PLN Network icon

    by mandywong040789-eng

    Update eip155-411994.json

    by mandywong040789-eng

    Merge branch 'master' into master

    by ligi

    Update pln.json

    by mandywong040789-eng

    Update pln.json

    by mandywong040789-eng

    Update Sei icon to new brand mark (maroon)

    alexander-sei merged to ethereum-lists/chains at 2026-05-25 17:03:53

    Update Sei icon to new brand mark (maroon)

    by alexander-sei

    Add Bourse 343 icon

    capitalexchange merged to ethereum-lists/chains at 2026-05-25 08:18:15

    Add bourse.json with icon metadata

    by capitalexchange

    Add icon field to Bourse 343

    by capitalexchange

    Merge pull request Add bourse.json with icon metadata

    by capitalexchange

    Update Daily Network icon

    vps-working-us merged to ethereum-lists/chains at 2026-05-25 08:24:04

    Update Daily Network icon

    by vps-working-us

    Merge branch 'master' into master

    by vps-working-us

    Update RANNTA X-Chain native currency decimals to 18

    ilia144000 merged to ethereum-lists/chains at 2026-05-25 08:18:15

    Update RANNTA X-Chain native currency decimals to 18

    by ilia144000

    Right-size CI runner usage after migrating to Blacksmith, and remove stale documentation

    librelois merged to moonbeam-foundation/moonbeam at 2026-05-25 19:25:53

    CI: replace 32 vCPU runners by 16 vCPU runners The Build workflow now uses 16 vCPU runners for Rust compilation jobs instead of 32 vCPU. The 16 vCPU runners still provide 64 GB RAM and 750 GB storage, which is enough for this project while reducing per-minute cost.

    by librelois

    CI: fix check-links: remove mention to old generated rust doc

    by librelois

    doc: remove mentions to bare-metal

    by librelois

    CI: job cargo-clippy do not need a bug runner

    by librelois

    Opti ci 3

    librelois merged to moonbeam-foundation/moonbeam at 2026-05-25 15:29:11

    CI: run tracing & bridge tests only on master or PRs with labels

    by librelois

    CI: replace 8 vcpu runners by 4 vcpu runners

    by librelois

    Align XCM weight accounting with ERC20 transfer gas limits when ERC20 assets include a custom `gas_limit:` override

    librelois merged to moonbeam-foundation/moonbeam at 2026-05-25 14:47:28

    Account properly XCM custom gas limit

    by librelois

    CI: replace bare-metal by blacksmith runners & adapt rust cache

    librelois merged to moonbeam-foundation/moonbeam at 2026-05-25 14:15:52

    CI: replace bare-metal by blacksmith runners & adapt rust cache

    by librelois

    CI: install native build deps before each compilation Required for ephemeral runners

    by librelois

    human readable rust toolchain cache key

    by librelois

    apply coderabbit suggestions

    by librelois

    apply coderabbit comments

    by librelois

    CI: move rustup setup in a common template

    by librelois

    apply coderabbit suggestions

    by librelois

    • HEDERA immunefi-logoRewards Blockchain DLT
      $0 $3,000 <$10,000 <$30,000

    feat: added support for RegisteredNodeDeleteTransaction to POST /transactions

    ericleponner merged to hashgraph/hedera-transaction-tool at 2026-05-25 18:11:24

    Backend support for delete registered node transaction. Signed-off-by: Eric Le Ponner

    by ericleponner

    Added RegisteredNodeInfoParsed and parseRegisteredNodeInfo() Signed-off-by: Eric Le Ponner

    by ericleponner

    Added unit test for parseRegisteredNodeInfo() Signed-off-by: Eric Le Ponner

    by ericleponner

    Added MirrorNodeClient.fetchRegisteredNodeInfo() (to be used later). Signed-off-by: Eric Le Ponner

    by ericleponner

    TransactionSignatureService.computeSignatureKey() now handles registered node admin key. Signed-off-by: Eric Le Ponner

    by ericleponner

    Added unit tests for TransactionSignatureService.computeSignatureKey() extensions. Signed-off-by: Eric Le Ponner

    by ericleponner

    Added unit tests for MirrorNodeClient.fetchRegisteredNodeInfo(). Signed-off-by: Eric Le Ponner

    by ericleponner

    Fixed missing mock in transaction-signature.service.spec.ts Signed-off-by: Eric Le Ponner

    by ericleponner

    Removed unneeded test from TransactionSignatureService.addRegisteredNodeKeys() Signed-off-by: Eric Le Ponner

    by ericleponner

    • ASTARNETWORK immunefi-logoRewards Websites and Applications
      $0 $0 <$7,500 <$15,000
      Blockchain DLT
      $1,000 $3,000 <$50,000 <$250,000

    fix: offset 0 for runtime-benchmarks

    ipapandinas merged to AstarNetwork/Astar at 2026-05-25 23:29:49

    fix: offset 0 for runtime-benchmarks

    by ipapandinas

    fix: Pin install frame-omni bencher

    ipapandinas merged to AstarNetwork/Astar at 2026-05-25 19:45:16

    fix: Pin install frame-omni bencher

    by ipapandinas

    • LIDO-V3-BUG-BOUNTY-COMPETITION immunefi-logoRewards Smart Contract
      $0 Max: $50,000 - Min: 1,000 + *Portion of the bonus reward pool Max: $250,000 - Min: 10,000 + *Portion of the bonus reward pool Max: $2,000,000 - Min: 50,000 + *Portion of the bonus reward pool

    feat: update meta group interface

    F4ever merged to lidofinance/lido-oracle at 2026-05-25 15:29:00

    feat: update meta group interface

    by F4ever

    fix: tests

    by F4ever

    • ALEO immunefi-logoRewards Blockchain DLT
      $0 $0 <$10,000 <$65,000

    [Logs] Enhance low-level connection spans

    ljedrz merged to ProvableHQ/snarkOS at 2026-05-25 17:16:50

    logs: enhance low-level connection spans Signed-off-by: ljedrz

    by ljedrz

    Fail fast on nested `Process::lock()` calls from `ProcessExclusiveGuard`

    Copilot merged to ProvableHQ/snarkVM at 2026-05-25 14:00:27

    Initial plan

    by Copilot

    Fail loudly on nested Process lock Agent-Logs-Url: https://github.com/ProvableHQ/snarkVM/sessions/e7a72a0b-6030-4985-b2a1-68d925c01fee Co-authored-by: vicsn <24724627+vicsn@users.noreply.github.com>

    by Copilot

    feat(view): allow finalize bodies to call `view` functions

    mohammadfawaz merged to ProvableHQ/snarkVM at 2026-05-25 13:59:14

    feat(view): allow finalize bodies to call view functions Adds Eth-`view`-style invocation: a function's `finalize` body can call a view function (same-program or imported cross-program). Views themselves remain leaves — they still reject `is_call` at construction, so no recursion. Changes: - Cache view `FinalizeTypes` on `Stack` (previously recomputed per call). - Loosen `Finalize::add_command` to permit `call`; keep `call.dynamic` rejected. New `Command::is_dynamic_call` helper. - Type-check (`check_instruction_opcode`) resolves the target and allows `Opcode::Call` only when it lands on a view. `Call::output_types` gains a view branch alongside closure / function. - Runtime dispatch: `finalize_command_except_await` special-cases `Command::Instruction(Instruction::Call(_))` and defers to a new `evaluate_call_to_view` helper that loads inputs from the caller's registers, runs the view body against the live store with the caller's inherited `FinalizeGlobalState`, and writes outputs to the caller's destination registers. - Cost rollup: `cost_per_command` now folds the called view's `view_cost_for_single_view` into the caller's finalize cost, so the per-function `TRANSACTION_SPEND_LIMIT` check covers callee compute too. - V15 syntax gate: `Program::contains_v15_syntax` flags any `call` inside a finalize body (pre-V15 finalize forbade `call` entirely). - The view module is now unconditionally compiled (the in-block call path doesn't need the `history` feature); only the `evaluate_view_at_height` public API and `HistoricFinalizeStore` remain gated.

    by mohammadfawaz

    test(view): cover finalize-to-view call paths and V15 gating

    by mohammadfawaz

    test(view): cover multiple-call + interleaved write read-write-read

    by mohammadfawaz

    refactor(view): apply review fixes for finalize-to-view call

    by mohammadfawaz

    test(view): expand finalize-to-view coverage (negative paths + multi-output, struct return)

    by mohammadfawaz

    docs(view): address review comments on finalize-to-view call Drop the verbose explanation on the unconditional 'view' module declaration and correct the rationale for forbidding 'call.dynamic' in finalize: the real blocker is that we have not yet designed dynamic spend / gas tracking for runtime-resolved targets.

    by None

    refactor(view): split view-target handling out of Call::output_types Restore Call::output_types to its original transition-only behavior and introduce Call::output_types_for_view for the finalize-side view-call type-check. Finalize-types initialize dispatches Instruction::Call to the new helper, making the API surface self-document the split and removing the risk of a future transition-path caller accidentally accepting a view target through the generic output_types entry.

    by None

    Merge remote-tracking branch 'origin/staging' into mohammadfawaz/finalize_calls_query

    by None

    refactor(view): tighten finalize-to-view call paths Bail explicitly on `CallDynamic` in the finalize type-checker, add a per-operand input-type check in `Call::output_types_for_view`, and promote the post-view `finalize_operations.is_empty()` invariant to a release-time `ensure!`. Tests cover destination-count and input-type mismatches at deploy, runtime view failure, and branch interactions.

    by None

    feat(view): allow zero-output views (guard pattern) Relax `many1` → `many0` on view outputs in the parser, `FromBytes`/`ToBytes`, and `Program::add_view`. Enables Solidity-style cross-program precondition guards from finalize; rides the existing V15 gate.

    by None

    feat(view): allow empty bodies Relax `many1` → `many0` on view commands in the parser, `FromBytes`/`ToBytes`, and `Program::add_view`. Brings view arity in line with `function` (all-`many0`) and removes an arbitrary restriction; no use case in mind, just consistency. Rides the existing V15 gate.

    by None

    Revert "refactor(view): split view-target handling out of Call::output_types" This reverts commit cde8cb9793e5afef0d0a2922abbe2dfee5a14e04, folding the view-target branch back into `Call::output_types`. The per-operand input-type check introduced afterwards (ef0b1874e) is preserved inside the view branch.

    by None

    refactor(view): route finalize-context view calls through Call::finalize Replace the special case in `finalize_command_except_await` with a real `Call::finalize` that loads inputs from the caller's `FinalizeRegisters`, dispatches the view body through a new `StackTrait::evaluate_view` hook (implemented on `Stack` as a thin wrapper around `evaluate_view_inner`), and writes outputs back. The transition-side `evaluate_call_to_view` / `run_view_call` helpers in `process::view` are no longer needed and are removed. To plumb the finalize store into `Call::finalize`, `Instruction::finalize` gains a `store: &impl FinalizeStoreTrait` parameter and tightens the registers bound from `RegistersTrait` to `FinalizeRegistersState` (the latter implies the former). Each per-instruction `finalize` impl ignores the new `_store` argument; only `Call::finalize` uses it. The instruction-level tests in `synthesizer/program/tests/instruction/` pass a new `NoopFinalizeStore` shim — a `bail!`-only `FinalizeStoreTrait` fixture — to satisfy the signature without pulling `snarkvm-ledger-store` into the program crate's dev-deps for fixtures that never touch the store.

    by None

    Merge branch 'staging' into mohammadfawaz/finalize_calls_query

    by None

    refactor(view): take Option<&dyn FinalizeStoreTrait> in Instruction::finalize Lets tests pass `None` instead of a dummy store fixture. `Call::finalize` errors when the store is missing.

    by None

    Merge branch 'staging' into mohammadfawaz/finalize_calls_query

    by None

    Merge remote-tracking branch 'origin/staging' into mohammadfawaz/finalize_calls_query

    by vicsn

    feat(view): bound finalize view-calls and check views on upgrade Adds `MAX_CALLS = 32` (mirrors `MAX_TRANSITIONS`) enforced in `Finalize::add_command`, and extends `check_upgrade_is_valid` to require each old view's input/output types in the new program.

    by None

    Merge branch 'staging' into mohammadfawaz/finalize_calls_query

    by mohammadfawaz

    • FUEL-NETWORK-ATTACKATHON immunefi-logoRewards Smart Contract
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool
      Websites and Applications
      $0 Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool
      Blockchain DLT
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool

    fix help link that needs compiler version

    xunilrj merged to FuelLabs/sway at 2026-05-25 21:11:40

    fix help link that needs compiler version

    by xunilrj

    md lint issues

    by xunilrj

    Bump to 0.71.1

    ironcev merged to FuelLabs/sway at 2026-05-25 14:40:45

    Bump to 0.71.1

    by ironcev

    Attribute for checking of trivial encoding and decoding

    xunilrj merged to FuelLabs/sway at 2026-05-25 13:20:54

    trivial check attributes

    by xunilrj

    fmt and clippy issues

    by xunilrj

    update tests

    by xunilrj

    error message improvements

    by xunilrj

    improve docs

    by xunilrj

    improve docs

    by xunilrj

    improve docs

    by xunilrj

    better error message

    by xunilrj

    TrivialBool and TrivialEnum

    by xunilrj

    fmt and clippy issues

    by xunilrj

    remove sway-lib-std warnings

    by xunilrj

    better error message for tuples and arrays

    by xunilrj

    TrivialBool and TrivialEnum using auto-impl

    by xunilrj

    TrivialBool and TrivialEnum using auto-impl

    by xunilrj

    fmt and clippy issues

    by xunilrj

    correctly call is_decode_trivial

    by xunilrj

    correctly call is_decode_trivial

    by xunilrj

    fmt and clippy issues

    by xunilrj

    PR fixes

    by xunilrj

    fmt and clippy issues

    by xunilrj

    runninf forc-fmt

    by xunilrj

    PR fixes

    by xunilrj

    fmt and clippy issues

    by xunilrj

    fmt and clippy issues

    by xunilrj

    update tests

    by xunilrj

    fix tests

    by xunilrj

    update tests

    by xunilrj

    link to the final documentation url

    by xunilrj

    link to the final documentation url

    by xunilrj

    fixing typos

    by xunilrj

    error improvements and gas benchmark

    by xunilrj

    improve error message

    by xunilrj

    removing range from memory representation

    by xunilrj

    fmt and clippy issues

    by xunilrj

    update tests

    by xunilrj

    fmt and clippy issues

    by xunilrj

    update tests

    by xunilrj

    fixing typos

    by xunilrj

    moving ir check to inside the type phase

    by xunilrj

    rebase issues

    by xunilrj

    rebase issues

    by xunilrj

    removing intrinsic

    by xunilrj

    check abi fns

    by xunilrj

    require attribute for abis

    by xunilrj

    update tests

    by xunilrj

    ignore for gc test: it needs experimental features

    by xunilrj

    checking abi function for enums

    by xunilrj

    also check return type

    by xunilrj

    small refactor to the check code

    by xunilrj

    more tests

    by xunilrj

    fmt and clippy issues

    by xunilrj

    update tests

    by xunilrj

    update tests

    by xunilrj

    fmt and clippy issues

    by xunilrj

    remove redundant manager

    by xunilrj

    TrivialVec and tests

    by xunilrj

    rollback TrivialVec

    by xunilrj

    fmt and clippy issues

    by xunilrj

    new values for the attribute require

    by xunilrj

    fmt and clippy

    by xunilrj

    update tests

    by xunilrj

    PR adjustments

    by xunilrj

    pr adjustments

    by xunilrj

    fmt and clippy issues

    by xunilrj

    fmt and clippy issues

    by xunilrj

    fix attribute args quantity

    by xunilrj

    Add comprehensive in-language tests for all storage types

    ironcev merged to FuelLabs/sway at 2026-05-25 12:34:20

    Add comprehensive in-language tests for all storage types

    by ironcev

    • ALPEN-LABS immunefi-logoRewards Smart Contract
      $0 $0 <$2,000 <$5,000
      Websites and Applications
      $0 $0 $1,000 <$2,000

    fix(csm): reshape L1Checkpoint and fix ClientState finality (STR-2438)

    prajwolrg merged to alpenlabs/alpen at 2026-05-25 18:47:04

    refactor(csm): reshape L1Checkpoint to carry CheckpointTip (STR-2438) L1Checkpoint was a legacy carrier whose `batch_info: BatchInfo` field didn't match the data the CSM actually receives. The CSM only sees a `CheckpointTipUpdate` log carrying `CheckpointTip { epoch, l1_height, l2_commitment }`; to fit the legacy shape, the processor fabricated a `BatchInfo` with duplicate placeholder L1/L2 ranges. Semantically wrong, even if nothing read the bogus fields. Replace the inner `batch_info` with the external SSZ `CheckpointTip` directly — single source of truth for tip shape, no twin type, no synthesis. Field-level Borsh codec helpers bridge the orphan rule, and a manual `Arbitrary` impl mirrors the previous derive. Tighten `verify_checkpoint` to consume `&CheckpointTip` since only the epoch was ever read — resolves the long-standing "reduce this to actually just passing in the core information we really need" TODO. The unrelated recent/finalized split inside `ClientState` is out of scope here; the FIXME there now points at the real follow-up (two coexisting finality notions that can diverge).

    by prajwolrg

    fix(csm): derive ClientState finality from depth, not observation heuristic ClientState carried two notions of "finalized" that could diverge: `last_finalized_checkpoint`, populated by `next_client_state` the instant a successor's tip was observed on L1 (zero depth check), and the real depth-driven `CsmWorkerState::finalized_epoch`. Every consumer reading `get_declared_final_epoch` (fork choice, chain worker, RPC, strata context) was getting the heuristic value, not the truth. Source-of-truth flip: `next_client_state` now only sets `last_seen_checkpoint`, preserving the previous `last_finalized_*`. The service loop, after `advance_finalization` advances the depth-derived `finalized_epoch`, rewrites the committed `ClientState` to slot the just-finalized `L1Checkpoint` into `last_finalized_checkpoint` and re-persists. ClientState becomes a derived snapshot of the depth-based truth instead of a parallel heuristic. `advance_finalization` now returns `Option` (the freshly finalized record) so the service has the full payload to plug into ClientState. To keep this end-to-end, the observation containers (`PendingCsmUpdate.observations`, `CsmWorkerState.observed_checkpoints`) now carry `L1Checkpoint` directly rather than `(EpochCommitment, CheckpointL1Ref)`. Bootstrap reconstructs the full `L1Checkpoint` from the L1-observed payload + L1 ref, so a new `get_checkpoint_payload` context method exposes the L1-observed payload table.

    by prajwolrg

    refactor(csm): drop epoch_commitment_for helper and obsolete next_client_state Add `impl From<&L1Checkpoint> for EpochCommitment` in csm-types where `L1Checkpoint` lives, replacing the ad-hoc `epoch_commitment_for` helper that was duplicated in csm-worker. Same in csm-types for the prior private `epoch_commitment_for_tip`. The `From` impl is discoverable through the type and lets call sites read `EpochCommitment::from(&ck)` or use it directly as a `map(EpochCommitment::from)` function pointer. Inline `next_client_state`: the helper made sense when it carried the observation-of-successor heuristic, but after the previous commit that logic is gone. What's left is a 4-line wrapper around `ClientState::new` with a single caller — clearer inlined with a short comment on why `last_finalized_checkpoint` is forwarded as-is.

    by prajwolrg

    fix(csm): gate finalization writes and align bootstrap ClientState `process_input` always called `advance_finalization` and `refresh_finalized_checkpoint` after `process_asm_block` — even when `process_asm_block` failed. The refresh wrote a `ClientState` row keyed on the failed block, so `fetch_most_recent_client_state` on restart would treat the failed block as committed and silently skip the retry that the gap-fill path is meant to guarantee. Bail out early on error so the cursor stays pinned at the last contiguous block. Bootstrap derived `finalized_epoch` from on-disk L1 observations but left `last_committed_state` pointing at the stale loaded `ClientState`, then pruned the corresponding observation from the queue. If the node restarted after the observation was committed but before `refresh_finalized_checkpoint` durably landed, downstream consumers of `ClientState::get_declared_final_epoch()` (e.g. chain worker) would lag the worker's view until a later epoch finalized. Refresh and re-persist `ClientState` in `new()` whenever derived finality outpaces the baseline.

    by prajwolrg

    refactor(csm): extract apply_checkpoint_observation, accept IntoIterator `apply_observations` always built a Vec at the callsite and inlined the per-checkpoint folding loop. Splitting the per-observation logic into its own helper lets callers fold a single checkpoint without wrapping it in a Vec, and widening the iterator type sidesteps unnecessary allocations on future callers.

    by prajwolrg

    refactor(csm-types): drop field-level Borsh codec for CheckpointTip `CheckpointTip` already implements `BorshSerialize`/`BorshDeserialize` via `impl_borsh_via_ssz_fixed!` in `strata-asm-proto-checkpoint-types`, so the field-level `serialize_with`/`deserialize_with` shim and its standalone codec fns were dead weight. The rationale ("external type has no Borsh derive, orphan rule blocks adding one") was stale by the pinned asm version. A plain derive on `L1Checkpoint` works directly. The on-disk Borsh format of `L1Checkpoint.tip` shifts from "field-by-field Borsh" to "Borsh wraps the SSZ fixed-len bytes" via the asm macro — fine here because this PR already breaks `L1Checkpoint` storage compatibility. Fully un-borsh-ing the `ClientUpdateOutput` storage chain (per Trey's broader hint) requires switching the sled value codec to `impl_codec_value_codec!` and `#[derive(Codec)]` on the type chain; deferred.

    by prajwolrg

    docs(csm-worker): compact verbose explainer comments Reviewer feedback: the multi-paragraph rationale on the finality bail-out and the derive_finalized_checkpoint docs restated the surrounding code. Trim both to the load-bearing why.

    by prajwolrg

    doc(ol,asm): OL/ASM withdrawal/deposits/assignments logs

    storopoli merged to alpenlabs/alpen at 2026-05-25 17:48:36

    feat(ol): log bridge deposit and withdrawal milestones

    by storopoli

    feat(ee): log bridge payload milestones

    by storopoli

    feat: add `/healthz` endpoints for Strata services

    storopoli merged to alpenlabs/alpen at 2026-05-25 13:54:20

    feat(strata-common): add healthz HTTP helpers

    by storopoli

    feat(strata): expose standalone healthz endpoint

    by storopoli

    feat(strata-signer): expose standalone healthz endpoint

    by storopoli

    feat(alpen-client): expose standalone healthz endpoint

    by storopoli

    chore(docker): use healthz probes

    by storopoli

    fix(evm-ee): preserve bytecode code-hash keys in chunk witnesses

    irnb merged to alpenlabs/alpen at 2026-05-25 09:58:16

    fix(evm-ee): preserve bytecode code-hash keys in chunk witnesses

    by irnb

    fix(evm-ee): store canonical accessed bytecodes

    by irnb

    fix(reth): avoid absolute path in accessed bytecode test

    by irnb

    fix(ci): prevent transitive skip propagation in ci-build

    purusang merged to alpenlabs/alpen at 2026-05-25 07:18:13

    fix(ci): prevent transitive skip propagation in ci-build On workflow_dispatch, check-new-commits is skipped (schedule-only). prepare and build-sp1-artifacts handle this with if: always(), but build-and-push and dispatch-cd inherited the transitive skip since they lacked the guard. Add explicit if: always() with success checks on direct dependencies.

    by purusang

    feat!: make `max_retries` a `u16`

    storopoli merged to alpenlabs/bitcoind-async-client at 2026-05-25 16:20:33

    chore: toml fmt

    by storopoli

    feat!: make max_retries a u16

    by storopoli

    chore(deps)(deps): bump alloy-signer from 1.8.3 to 2.0.4

    dependabot[bot] merged to alpenlabs/strata-bridge at 2026-05-25 13:16:25

    chore(deps)(deps): bump alloy-signer from 1.8.3 to 2.0.4 Bumps [alloy-signer](https://github.com/alloy-rs/alloy) from 1.8.3 to 2.0.4. - [Release notes](https://github.com/alloy-rs/alloy/releases) - [Changelog](https://github.com/alloy-rs/alloy/blob/main/CHANGELOG.md) - [Commits](https://github.com/alloy-rs/alloy/compare/v1.8.3...v2.0.4) --- updated-dependencies: - dependency-name: alloy-signer dependency-version: 2.0.4 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    chore(deps)(deps): bump bitcoind-async-client from 0.10.2 to 0.11.0

    dependabot[bot] merged to alpenlabs/strata-bridge at 2026-05-25 12:05:40

    chore(deps): bump bitcoind-async-client from 0.10.2 to 0.11.0 Bumps [bitcoind-async-client](https://github.com/alpenlabs/bitcoind-async-client) from 0.10.2 to 0.11.0. - [Release notes](https://github.com/alpenlabs/bitcoind-async-client/releases) - [Commits](https://github.com/alpenlabs/bitcoind-async-client/compare/v0.10.2...v0.11.0) --- updated-dependencies: - dependency-name: bitcoind-async-client dependency-version: 0.11.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    chore(deps)(deps): bump bitcoin from 0.32.8 to 0.32.9 in the rust-dependencies group

    dependabot[bot] merged to alpenlabs/strata-bridge at 2026-05-25 12:05:24

    chore(deps)(deps): bump bitcoin in the rust-dependencies group Bumps the rust-dependencies group with 1 update: [bitcoin](https://github.com/rust-bitcoin/rust-bitcoin). Updates `bitcoin` from 0.32.8 to 0.32.9 - [Release notes](https://github.com/rust-bitcoin/rust-bitcoin/releases) - [Changelog](https://github.com/rust-bitcoin/rust-bitcoin/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-bitcoin/rust-bitcoin/compare/bitcoin-0.32.8...bitcoin-0.32.9) --- updated-dependencies: - dependency-name: bitcoin dependency-version: 0.32.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    fix(gsm): only transition to Aborted if both stake and payout connector are spent

    Rajil1213 merged to alpenlabs/strata-bridge at 2026-05-25 10:25:25

    refactor(gsm): replace stringly-typed Aborted reason with AbortReason enum

    by Rajil1213

    feat(gsm): track stake and payout-connector spends as local state fields

    by Rajil1213

    feat(gsm): replace SlashConfirmedEvent with StakeSpentEvent The new event fires when *any* tx consumes the operator's stake outpoint (this graph's slash, a sibling graph's slash, or unstaking). `process_stake_spent` disambiguates locally via `GraphState::expected_slash_txid` and dispatches: - matching → terminal Slashed - BridgeProofTimedout / Acked: only path was slash; abort directly - post-Claimed two-fact state with connector already spent: abort with AbortReason::Both - field-bearing states: record stake_spent and stay - everything else (pre-NoncesCollected / AllNackd / Withdrawn / Aborted / non-matching Slashed): rejected — allowed in protocol, no field to record on; only re-delivery of this graph's own slash returns Duplicate Classifier emits StakeSpent for any tx spending the stake outpoint via the new `spends_stake_outpoint` helper. Tests use a single table-driven scenario with an exhaustive match over GraphState — adding a new variant is a compile error until classified. docs(gsm): explain why direct-to-Slashed transition emits no cross-SM signal

    by Rajil1213

    feat(gsm): make process_payout_connector_spent state-sensitive

    by Rajil1213

    feat(gsm): proactively abort entering BridgeProofTimedout/Acked when stake is spent

    by Rajil1213

    feat(gsm,exec): refuse to publish graph partials when stake outpoint is already spent

    by Rajil1213

    feat(gsm): proactively abort entering AllNackd when payout connector is spent

    by Rajil1213

    fix(exec): only treat null gettxout result as spent in is_outpoint_unspent

    by Rajil1213

    fix(gsm): reject stake spent events whose tx does not spend the stake outpoint

    by Rajil1213

    fix(gsm): withhold GraphAvailable when stake outpoint is already spent

    by Rajil1213

    fix(gsm): make PayoutConnectorSpentEvent carry the tx and validate connector spend

    by Rajil1213

    fix(gsm): reject misrouted legitimate payout txs in process_payout_connector_spent

    by Rajil1213

    fix(tx-classifier): identify payout txs in CounterproofPosted state Also includes a regression test and an update to the doc comment on `is_payout_connector_spent` so that consumers are aware of the footgun. The better solution is to fix the predicate so that it does not pass on payout txs but that requires access to the summary that is not available in all states.

    by Rajil1213

    • ETHEREUM-PROTOCOL-ATTACKATHON immunefi-logoRewards Smart Contract
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool
      Blockchain DLT
      Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool

    Remove unused beacon REST API dependencies

    rolfyone merged to Consensys/teku at 2026-05-25 23:41:48

    Remove unused beacon REST API dependencies Drop direct beaconrestapi dependencies on jackson-module-kotlin, swagger-core, and swagger-ui. swagger-ui is still provided via infrastructure:restapi, where the Swagger UI builder lives.

    by rolfyone

    Merge branch 'master' into lib-cleanup-attempt

    by rolfyone

    added some ignores for agents

    rolfyone merged to Consensys/teku at 2026-05-25 19:49:17

    added some ignores for agents

    by rolfyone

    Merge branch 'master' into ignores

    by rolfyone

    Ethspecify phase0

    zilm13 merged to Consensys/teku at 2026-05-25 14:03:16

    Cleanup ignored definitions without sources

    by zilm13

    Add max constants

    by zilm13

    Revise gloas containers

    by zilm13

    Add PayloadAttributes#gloas

    by zilm13

    Add compute_time_at_slot_ms#phase0

    by zilm13

    link gloas methods

    by zilm13

    remove stale entry

    by zilm13

    fix ambiguous search

    by zilm13

    some more gloas functions

    by zilm13

    validate_on_attestation and get_attestation_score

    by zilm13

    another 2

    by zilm13

    last gloas functions

    by zilm13

    Merge branch 'master' into cleanup-ethspecify2

    by zilm13

    empty4

    by zilm13

    empty5

    by zilm13

    Merge branch 'master' into ethspecify-gloas

    by zilm13

    attempt to fix ci

    by zilm13

    add a comment about ci-skipped.yml

    by zilm13

    - is_not_from_future_slot#phase0 - is_within_slot_range#phase0

    by zilm13

    - is_not_from_future_slot#phase0 - is_within_slot_range#phase0

    by zilm13

    - get_aggregate_and_proof#phase0 - get_aggregate_signature#phase0 - get_attestation_deltas#phase0 - get_attesting_balance#phase0

    by zilm13

    - get_checkpoint_block#phase0 - get_current_store_epoch#phase0 - get_eligible_validator_indices#phase0 - get_filtered_block_tree#phase0

    by zilm13

    - get_forkchoice_store#phase0 - get_head#phase0 - get_inactivity_penalty_deltas#phase0 - get_inclusion_delay_deltas#phase0

    by zilm13

    - get_matching_head_attestations#phase0 - get_matching_source_attestations#phase0 - get_matching_target_attestations#phase0

    by zilm13

    - get_slots_since_genesis#phase0 - get_unslashed_attesting_indices#phase0 - get_voting_source#phase0 - is_candidate_block#phase0

    by zilm13

    - is_finalization_ok#phase0 - is_proposer#phase0 - on_tick_per_slot#phase0 - seconds_to_milliseconds#phase0

    by zilm13

    - store_target_checkpoint_state#phase0 - update_latest_messages#phase0 - update_unrealized_checkpoints#phase0 - validate_target_epoch_against_current_time#phase0

    by zilm13

    - compute_proposer_score#phase0 - get_attestation_score#phase0 - is_proposer_equivocation#phase0 - record_block_timeliness#phase0

    by zilm13

    - apply_parent_execution_payload#gloas - compute_merkle_branch_root#phase0 - is_non_strict_superset#phase0 - update_proposer_boost_root#phase0

    by zilm13

    Merge branch 'master' into ethspecify-phase0

    by zilm13

    Use MIN_SEED_LOOKAHEAD in proposer preferences

    zilm13 merged to Consensys/teku at 2026-05-25 11:17:27

    Use MIN_SEED_LOOKAHEAD in proposer preferences

    by zilm13

    address bot comment

    by zilm13

    Merge branch 'master' into min-lookahead-proposer-preferences

    by zilm13

    Merge branch 'master' into min-lookahead-proposer-preferences

    by zilm13

    add assertion on MIN_SEED_LOOKAHEAD == 1 to update code when it's not true

    by zilm13

    fix(test-client-clis): detect EELS-style OutOfGasError in GasExhaustionTraceComparator

    leolara merged to ethereum/execution-specs at 2026-05-25 16:32:33

    fix(test-client-clis): detect EELS-style OutOfGasError in GasExhaustionTraceComparator

    by leolara

    feat(test-benchmark): add more modexp precompile benchmark scenario

    GottfriedHerold merged to ethereum/execution-specs at 2026-05-25 14:11:03

    tests/benchmark/compute/precompile/test_modexp.py: Add tests for modexp with random bit patterns and relevant lengths. Add tests for modexp where the modulus is a power of 2.

    by GottfriedHerold

    remove newline

    by GottfriedHerold

    Fix typo

    by GottfriedHerold

    refactor: comment and helper function

    by LouisTsai-Csie

    Make snap/2 BAL fetching strict

    mirgee merged to hyperledger/besu at 2026-05-25 09:52:20

    Make BAL-fetching peer task retry on incomplete data Signed-off-by: Miroslav Kovář

    by mirgee

    Remove IncompleteResultsException Signed-off-by: Miroslav Kovář

    by mirgee

    execution/stagedsync: tests for finalize coinbase/burnt fee write invalidation

    mh0lt merged to ledgerwatch/erigon at 2026-05-25 22:40:24

    ci: matrix-test serial vs parallel exec across the test workflows Adds an exec_mode: [serial, parallel] axis to every test workflow that exercises the EL execution path so divergence between dbg.Exec3Parallel true/false is caught on the PR rather than after release. The matrix entries spawn separate runners and run concurrently — wall-clock unchanged, runner-minutes ~2x for affected workflows. The toggle is plumbed via ERIGON_EXEC3_PARALLEL — envLookup in common/dbg/dbg_env.go auto-prepends the ERIGON_ prefix to the source- side EXEC3_PARALLEL flag in common/dbg/experiments.go. Affected workflows: Always-on (matrix on every PR / dispatch / call): test-all-erigon.yml — unit tests, hosted, true parallel test-all-erigon-race.yml — race detector, hosted, true parallel test-hive.yml — engine API + devp2p, hive group runners test-hive-eest.yml — EEST consume-engine/-rlp, hive group test-kurtosis-assertoor.yml — kurtosis devnet suites, hosted Auto-fire on PRs touching their own YAML, dispatch otherwise: test-bench.yml — go bench qa-rpc-integration-tests-latest.yml — self-hosted, max-parallel=1 qa-rpc-performance-comparison-tests.yml — erigon-vs-geth, geth one-mode qa-txpool-performance-test.yml — kurtosis txpool, max-parallel=1 qa-stage-exec.yml — 3 modes × 2 exec_modes = 6 Skipped: test-integration-caplin.yml — runs cl/spectest only, doesn't exercise the EL exec path; matrix-doubling would just re-run identical CL tests. Plumbing notes: * For workflows that build erigon and run go tests directly, the env var is set on the test step's env: block. * For hive-based workflows (test-hive, test-hive-eest), an ENV ERIGON_EXEC3_PARALLEL=... line is appended to clients/erigon/Dockerfile during the existing sed patch loop so every hive-launched erigon inherits the toggle. * For kurtosis-based workflows (test-kurtosis-assertoor, qa-txpool-performance-test), a small follow-up docker build adds an ENV layer on top of test/erigon:current-base to produce test/erigon:current with the toggle baked in. Cheap (single layer) and doesn't invalidate earlier build-cache layers. * Self-hosted single-pool workflows use max-parallel=1 to serialize matrix entries cleanly when state on the runner box is shared (testbed datadir, reference datadir, etc.). * All artifact / enclave / testbed-dir names are disambiguated by exec_mode so the two matrix entries don't clobber each other's outputs. The pull_request: paths: filter on the perf workflows means they auto-fire only on PRs that touch their own YAML — i.e. this PR triggers them once each so the change can be observed end-to-end, and future regular PRs that don't touch them stay free of the cost.

    by mh0lt

    ci: suffix QA test_name with -parallel when exec_mode=parallel Addresses review feedback from @mriccobene on PR #21017: the QA dashboard filters results by test_name regex. Without a suffix the parallel and serial entries land under the same test_name and can't be distinguished in the Hive UI / Grafana dashboard. Per the reviewer's preferred convention, leave the serial entry's name unchanged and add `-parallel` only for the parallel matrix entry. Both `upload_test_results.py` invocations are updated: - qa-rpc-integration-tests-latest.yml:266 → rpc-integration-tests-latest[-parallel] - qa-rpc-performance-comparison-tests.yml:374 → rpc-performance-test-latest[-parallel]-$method The HDR-analysis PDF test_name (line 340 of the perf-comparison file) is intentionally left as `$client-$method` — that name only labels a local report file, which is already disambiguated by the artifact name's `-${{ matrix.exec_mode }}` suffix. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    ci: build the kurtosis erigon image once for the whole matrix The kurtosis matrix grew to suite × {serial, parallel} entries, and every entry ran its own buildx with `cache-to: type=gha,mode=max,scope=kurtosis-erigon-build` — ~a dozen jobs hammering the same GHA cache key concurrently, which the cache backend answers with 504s ("failed to parse error response 504" → `failed to build`; assertoor_pectra_parallel never reached the enclave). Add a `build-erigon-image` job that builds `test/erigon:current-base` once (the single buildx run, the single cache writer) and uploads it as a run-scoped artifact; the `assertoor_test` matrix `needs:` it, downloads + `docker load`s the image, and keeps only the cheap per-entry ENV-layer retag for ERIGON_EXEC3_PARALLEL. Wall-clock ≈ unchanged (the build moves to a prerequisite job instead of running per matrix entry). On cache-warming runs build-erigon-image alone warms the image cache, so the matrix is skipped there.

    by mh0lt

    ci: drop flaky third-party apt repos before apt-get update in setup-erigon The hosted runner image ships extra third-party apt sources (Google Chrome, Microsoft) that are periodically mid-mirror-sync and answer `apt-get update` with a Packages.gz size mismatch — failing the step and the whole job. erigon only installs build-essential from the Ubuntu archive, so remove those repos before updating and add Acquire::Retries for transient blips. Fixes the recurring "dl.google.com/linux/chrome-stable … File has unexpected size" flake (repro / reproducible-build, eest-spec, …).

    by mh0lt

    ci: gate parallel-suffix QA test_name on client==erigon The geth matrix entry uses exec_mode: parallel as a placeholder (geth ignores the toggle), but the unconditional `exec_mode == 'parallel'` gate on the test_name suffix meant geth results were uploaded under `rpc-performance-test-latest-parallel-$method` instead of the historical `rpc-performance-test-latest-$method`. Dashboard queries matching the unsuffixed name would silently break for geth going forward, and a `-parallel-` series would collide with the erigon parallel series. Tighten the gate to `matrix.client == 'erigon' && matrix.exec_mode == 'parallel'` so only the erigon parallel entry takes the suffix; geth stays on its historical name regardless of placeholder exec_mode. Reported by @yperbasis in #21017 review.

    by mh0lt

    ci: align test-hive devp2p sim-limit between serial and parallel matrix legs Before: serial ran sim-limit=eth|discv5, parallel ran sim-limit=eth. The asymmetry made the matrix display misleading (serial-side covered more than parallel-side) and contradicted the comment immediately above which says the sibling devp2p suites including discv5 are intentionally excluded due to unrelated pre-existing failures. discv5 doesn't exercise the EL execution path, so running it on both matrix legs would also waste runner-minutes without surfacing any serial-vs-parallel signal. Drop discv5 from the serial leg so both legs run sim-limit=eth, matching the comment's stated intent and giving a clean apples-to-apples exec-mode comparison. Reported by @yperbasis (nit 5) and Copilot (threads on lines 79 + 83) in #21017 review.

    by mh0lt

    ci: fix Targetting typo in test-hive-eest.yml s/Targetting/Targeting/. Reported by Copilot in #21017 review.

    by mh0lt

    cmd/integration: respect ERIGON_-prefixed EXEC3_PARALLEL in stages.go default stageExec was checking only the unprefixed EXEC3_PARALLEL env name when deciding whether to apply its default of dbg.Exec3Parallel=true. CI workflows set the ERIGON_-prefixed form because dbg.envLookup auto- prepends ERIGON_, so for the serial matrix entry: 1. Package init reads ERIGON_EXEC3_PARALLEL=false via envLookup → dbg.Exec3Parallel = false. 2. stageExec sees no unprefixed EXEC3_PARALLEL → flips it back to true. Both modes ended up running in parallel, with the matrix passing through silent equivalence rather than real CI signal. Fix per AskAlexSharov: move the env parse out of the command runtime and into a package init() that assigns dbg.Exec3Parallel directly via dbg.EnvBool, matching the dbg/experiments.go pattern. EnvBool checks both the bare and ERIGON_-prefixed forms via envLookup, so a workflow setting ERIGON_EXEC3_PARALLEL=false now correctly suppresses the integration tool's default; the default is true so callers that set nothing (typical local debugging) still get parallel mode. stageExec entry loses the 3-line runtime env-check entirely. Reported by @yperbasis on #21017 review.

    by mh0lt

    execution/stagedsync/rawdbreset: delete stage progress entries on reset, don't overwrite with 0 ResetExec → clearStageProgress was overwriting the Execution stage progress with 8 zero bytes via SaveStageProgress(tx, stage, 0). That conflated two distinct states: (a) stage never started — entry absent (len(bnBytes) == 0) (b) stage executed up to block 0 — entry present, value 0 SeekCommitment in commitmentdb/commitment_context.go uses this entry as a fallback when no commitment state is in the domain. Per its own comment at lines 651-660: blockNum=0 means "genesis executed", so it returns txNum = TxNums.Max(0) = 1 (not txNum=0) so the next exec cycle does not re-run the genesis init task. After ResetExec the actual state is (a) — domain tables wiped, no commitment at all. But because clearStageProgress wrote 0 instead of deleting, SeekCommitment saw state (b) and returned (txNum=1, blockNum=0). ExecV3's exec loop then started at txNum=1, skipping block 0's init task — the only place that re-runs the genesis allocation through the worker pool's LightCollector → applyVersionedWrites pipeline. Result: genesis-allocated addresses that no subsequent block touches end up with balance=0 in the parallel-exec view, producing wrong-trie-root mismatches on `qa-stage-exec (from-0, parallel)` (#21017 / #21138 / mainnet block 46147 / 0xA1E4380A3B1f749673E270229993eE55F35663b4). The engine-API InsertChain + FCU path doesn't hit this because it doesn't call ResetExec; it starts with no entry at all and falls into the (a) branch correctly. Fix: clearStageProgress now deletes the SyncStageProgress entries rather than writing 0. This is the integration-tool-side fix the user's diagnosis pointed at — make the integration path's reset state consistent with the FCU path's "fresh DB" state, rather than papering over the inconsistency in exec3.go / SeekCommitment. Adds a unit test that exercises the failing path in <100ms: TestFromZero_GenesisAllocPreservedAfterResetReExec Sets up a custom genesis allocating a dormant address, syncs 5 empty blocks via the engine-API InsertChain (passes pre-fix), then resets state via rawdbreset.ResetExec and drives stage execution via direct SpawnExecuteBlocksStage (the integration-tool path that fails pre-fix). Asserts the genesis-allocated balance is preserved across the reset + re-exec cycle. Pre-fix the test fails with `wrong trie root, block=5` (state diverges because genesis init never runs). Diagnosis credit: Mark Holt.

    by mh0lt

    execution/stagedsync: surface block-validity errors via blockResult.Err When a worker hits a legitimate block-validity failure (insufficient funds, wrong nonce, gas overflow, finalize error, scheduler-exhausted incarnations), nextResult returned (nil, err) and the exec loop bailed. That had three uncoordinated error sources racing for the surfaced diagnostic: 1. nextResult's wrapped ErrInvalidBlock (insufficient funds, …) 2. The apply-loop's channel-close completeness check observing block N's tx-results without a blockResult: "apply loop exited ... but 1 block(s) had tx-results without a blockResult: [N]" 3. The commitment calculator's ErrWrongTrieRoot, computed over partial sd.mem state from txs that succeeded before the failing one (root != header.Root, often != 0 for EEST tests setting expected=0 to mark "this block must be rejected") errors.Join welded these in pe.wait, so the engine API surfaced a doubled or wrong-causality error chain. EEST assertions on the underlying exception class (INTRINSIC_GAS_TOO_LOW, INSUFFICIENT_ACCOUNT_FUNDS) then failed even though the block was correctly rejected as invalid — the rejection reason just no longer matched what serial-exec produced. Fix: centralise block-validity error emission on the apply loop side, and prevent the exec loop and commitment calculator from racing with their own diagnostics for the same block. * nextResult returns blockResult{Err: ...} instead of (nil, err) for every block-validity bailout: skipCheck+OriginError, ConsumeRegular, ConsumeState, blob gas overflow, engine.Finalize, and too-many- incarnations. A new helper invalidBlockResult builds the synthetic blockResult carrying BlockNum/BlockHash/Err. * Apply loop's case *blockResult fast-paths Err != nil at the top: marks appliedBlocks[N] so the channel-close completeness check doesn't double-report as silent miss, drops pendingAccumulatorWrites (we never announce invalid blocks), and returns Err — the canonical error-surfacing point. * Exec loop exits immediately after sending an invalid blockResult (both the main and ctx-done-drain paths). Without this, the exec loop would scheduleNextPending() on top of partial / now-discarded state, racing the apply loop's Err return. * Commitment calculator's case *blockResult skips compute when Err is set. Without this, computeAndCheck would compute a root over the partial sd.mem state and emit ErrWrongTrieRoot through rootResults, which would win the errors.Join race against the apply loop's in-flight Err return — masking the original validation diagnostic. Stress repro (TestDeleteRecreateSlotsAcrossManyBlocks under GOMAXPROCS=2 -race count=30) goes from 5/30 fails with doubled error chains to 3/30 fails with clean single-line errors. The residual 3/30 is a separate dep-estimator stuck-at-0 bug — tracked separately. Discovered via #21017's serial-vs-parallel CI matrix; not visible on serial-exec.

    by mh0lt

    execution/stagedsync: capture-and-restore inMemHistoryReads around parallel exec The defer at exec3_parallel.go:206 was introduced in b72aa7b4f7 (#20805 parallel commitment calculator) and hardcoded the post-exec value to false. That overwrote whatever the caller had set: - Engine API path: caller leaves the default (true, set in NewTemporalMemBatch). Defer-to-false flipped it. Subsequent forkchoice_updated -> GetAsOf failed with "GetAsOf called on TemporalMemBatch with inMemHistoryReads disabled", or post-batch trie-root computation read partial state -> wrong-trie-root. - cmd/integration stage_exec path: caller explicitly sets false (cmd/integration/commands/stages.go:752). Here the defer-to-false happened to match the caller's intent, so no breakage was visible. Fix: capture the caller's setting on entry, restore it on exit. This keeps the engine API path correct (defaults to true, stays true) AND preserves the integration tool's explicit-false setting. Adds an InMemHistoryReads() getter on TemporalMemBatch + SharedDomains + the kv.TemporalMemBatch interface to support the capture. Repro: EEST test_gas_limit_below_minimum[fork_Cancun-gas_limit_5000] in parallel mode. The block is valid (5000 == MinBlockGasLimit, not below) so exec succeeds; the next forkchoice_updated then errored out with the GetAsOf failure. Serial mode passes the same test — parallel-only divergence, fixed by this patch (verified locally via hive simulator). Likely also fixes the mainnet from-0 parallel wrong-trie-root at block 131578 (confirmed consistent across two CI runs of qa-stage-exec); verification dispatched.

    by mh0lt

    execution/state: don't drop CodePath writes for newly-created accounts in SetCode SetCode has a cumulative-net-zero optimisation that deletes CodePath, CodeHashPath and CodeSizePath from the per-tx versionedWrites when the new code matches `stateObject.original.CodeHash`. The intent is to elide no-op writes from the EIP-7702 set/reset-delegation flow. For a CREATE2 reincarnation (or any fresh contract creation), the same condition fires whenever the new bytecode happens to match the destroyed contract's bytecode. `stateObject.original` carries the PRE-CREATION snapshot from the previous incarnation via createObject(addr, previous), so a "match" against `original` is structural coincidence — not a real revert-to-base. When the writes are dropped, FlushVersionedWrites omits them, and a later tx in the same block reading CodeHashPath gets MVReadResultNone from the versionMap. The read falls through to the recursive AddressPath read, which returns the stale snapshot captured at createObject time (CodeHash=EmptyCodeHash, before SetCode mutated newobj.data). That empty hash serialises into the account at end-of-block and corrupts the trie root. The serial path is unaffected because it has no per-tx versionedWrites or versionMap reads, so the snapshot/cache divergence cannot exist. Restricting case (2) to !stateObject.newlyCreated preserves the EIP-7702 net-zero optimisation for existing accounts while making CREATE2 reincarnations emit their code writes unconditionally. Reproducer: TestGeneratedTraceApiCollision with EXEC3_PARALLEL=true (also TestDeleteRecreateSlotsAcrossManyBlocks under the stress flag, and EEST test_dynamic_create2_selfdestruct_collision). All pass with this fix.

    by mh0lt

    execution/stagedsync: reject blocks containing a tx with gas > block gas limit geth's core/block_validator.go::ValidateBody rejects any tx in a block whose declared gas limit exceeds the block's header.GasLimit, before execution starts. Erigon had no equivalent body-level check, so a bad block reached the per-tx pipeline and failed there with the wrong exception class: - With a low feeCap, preCheck's EIP-1559 fee-cap branch fired before the gas-pool branch, producing ErrFeeCapTooLow (TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS). - Without a low feeCap, the tx executed and tripped the gas-used mismatch in the header-vs-computed check (BlockException.INVALID_GAS_USED). Both shapes mis-map in EEST/Hive's geth-calibrated ExceptionMapper for tests like: tests/frontier/validation/test_transaction.py::test_tx_gas_limit tests/static/state_tests/stEIP1559/lowGasLimitFiller.yml::lowGasLimit A prior attempt added the check at the top of TxnExecutor.preCheck. That broke simulation paths (TestSimulatedBackend_CallContractRevert, TestSimulatedBackend_PendingAndCallContract) which intentionally pass tx.gas=50_000_000 against arbitrary block contexts -- preCheck is shared between block execution and eth_call / eth_simulateV1 / trace_call. PR #21236 reverted; this change moves the check to the per-block setup inside executeBlocks (parallel) and exec3_serial.go (serial), where simulation paths never traverse: - eth_call -> protocol.ApplyMessage directly - eth_simulateV1 -> jsonrpc.eth_simulation per-call EVM - trace_call -> trace_adhoc per-call EVM The check wraps rules.ErrInvalidBlock so the existing bad-block handling (POSSync ReportBadHeaderPoS, unwind, BadBlock(hash, err)) all fire on the same code path as a wrong-trie-root rejection. No new sentinel and no new plumbing required. Both executor paths get the same check because the parallel and serial exec dispatchers are separate code files; a single shared helper above both would change call signatures in deeper unrelated functions. Unblocks the GAS_ALLOWANCE_EXCEEDED EEST tests on the parallel-axis matrix in #21017 without regressing simulation tests.

    by mh0lt

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    set all eest spec test shards to max-allowed-failures: 0

    by taratorio

    Revert "execution/stagedsync: reject blocks containing a tx with gas > block gas limit" This reverts commit 4d25ea57ec84d33c62089615ab096c41ea69be22.

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    execution: EIP-8037 inclusion uses per-dimension contribution CheckBlockGasInclusion now takes (regularGas, stateGas) and rejects the tx when either exceeds the matching reservoir. Pre-Amsterdam the state contribution is 0 (state dim never consumed). Amsterdam onwards regular contribution is min(MaxTxnGasLimit, tx.gas) and state is tx.gas — matches the EIP-8037 reservoir semantics. Replaces the prior intrinsic-floor variant which was too weak (let a tx through when tx.gas exceeded the reservoir but intrinsic fit) and the original tx.gas-only check which over-rejected EIP-8037 valid multi-dimensional cases (block_2d_gas_valid_when_cumulative_exceeds_limit, block_state_gas_limit_boundary[exact_fit]). Parallel post-exec verification passes BlockRegularGasUsed / BlockStateGasUsed directly — same shape, just realised contributions instead of declared. Verified against stEIP1559/test_low_gas_limit (Amsterdam) and the full statetests-devnet shard.

    by mh0lt

    execution: fix parallel-exec SD-then-resurrect Two coordinated changes for the same scenario family — a contract is selfdestructed by an earlier TX in the block and the current TX touches the address again (CREATE2-recreate, value-transfer-resurrect, or empty-touch under pre-Spurious-Dragon rules). 1. IntraBlockState.CreateAccount marks journal.dirty(addr) when previous is selfdestructed. resetObjectChange.dirtied() returns false, so without the explicit mark the parallel worker's MakeWriteSet revert- non-dirty block drops every resurrect write (test_double_kill / EIP-6780 family on the parallel shard). The mark is confined to the CreateAccount path so the GetOrNewStateObject AddBalance path is unaffected — that path goes through TestSelfDestructReceive and must not gain a dirty mark here. 2. normalizeWriteSet only emits post-SD defaults (Balance=0, Nonce=0, Incarnation=0, CodeHash=EmptyCodeHash) when the current TX wrote CreateContractPath. A value-transfer resurrect (no CreateContractPath) inherits pre-SD account fields via the versionMap last-write-wins chain — matching GenerateChain's accumulate-across-txs behaviour (no per-tx FinalizeTx). Forcing defaults here resets nonce/codeHash against the canonical state (wrong trie root: TestSelfDestructReceive). CREATE/CREATE2 paths still get the defaults (TestDeleteRecreate*, TestCVE2020_26265). Verified end-to-end: TestSelfDestructReceive, TestDeleteRecreate*, TestCVE2020_26265 (parallel) pass; full EEST blocktests-stable-parallel (69256/0) and blocktests-devnet (82896/0) shards pass.

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    ci: fix upload_test_results.py arg name in qa-stage-exec PR #21208 changed both --result_file → --result-file in qa-stage-exec.yml to match run_and_check_stage_exec.py's CLI. But upload_test_results.py (line 122) uses underscore — every other QA workflow that calls it (qa-constrained-tip-tracking, qa-tip-tracking, qa-sync-with-externalcl, qa-sync-from-scratch, qa-rpc-integration-tests-latest, etc.) passes --result_file. CI: "upload_test_results.py: error: unrecognized arguments: --result-file" after the stage_exec smoke test itself runs to completion. Restore underscore at the upload_test_results.py call site only. Line 88's run_and_check_stage_exec.py call keeps --result-file (its own CLI).

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix # Conflicts: # .github/workflows/test-hive-eest.yml

    by mh0lt

    execution/stagedsync: disable trie warmup value-cache on parallel exec The commitment trie warmuper reads paraTrieDB (persisted state). During a multi-block uncommitted batch (parallel fork validation) sd.mem holds in-flight writes not yet in paraTrieDB, so the warmuper's value cache serves stale account/storage values to the trie and produces wrong roots (hive engine-api "Re-Org Back into Canonical Chain ... Execute Side Payload on Re-Org"). Short-term gate: keep the value cache only on the serial path until the full fix lands. The MDBX page-cache warmer is unaffected.

    by mh0lt

    Merge branch 'main' into mh/ci-exec-mode-matrix

    by AskAlexSharov

    Merge branch 'main' into mh/ci-exec-mode-matrix Sync with origin/main (95567f1: execution/state: per-path revival in versionedRead MVReadResultNone branch + bc4145744: execution: flag for kzg ctx warmup). Key resolutions: - execution/stagedsync/exec3.go: drop b9f6208 short-term EnableWarmupCache(!isApplyingBlocks && !parallel) guard; take main's simplified form EnableWarmupCache(!isApplyingBlocks) — the underlying warmup-cache correctness issue is addressed by 95567f1's per-path revival fix - execution/state/versionedio.go: take 95567f1's per-path revival resolution in the MVReadResultNone SD short-circuit (replaces the account-wide LatestTxIndex scan introduced in 8008e0e) - execution/state/versionedio_test.go: new file from 95567f1 Co-authored-by: milen

    by github-actions[bot]

    Revert "Merge branch 'main' into mh/ci-exec-mode-matrix" This reverts commit 2b87a9d0dffd415b50ab4204297ba99f26a40e6c.

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    execution/stagedsync: revert warmup-cache parallel gate from this branch Reverts b9f6208. This branch is the CI-matrix config and should carry only .github/ changes; the parallel-exec warmup-cache fix moves to a dedicated Go-fix PR.

    by mh0lt

    Revert "execution/stagedsync: revert warmup-cache parallel gate from this branch" This reverts commit f02c5dde9cb7b2c6cc6ce8d46e681c659c539175.

    by mh0lt

    execution/execmodule: chain fork-validation SD to currentContext for head-extending payloads ValidateChain creates a fresh SharedDomains with no parent. FCU's MergeExtendingFork leaves the latest canonical state in currentContext.mem; MDBX is committed only later under memory pressure. Between an FCU and the next newPayload the fresh doms reads stale MDBX, so parallel fork-validation computes a wrong trie root — nondeterministic, depending on whether a background commit has fired (hive engine-api "Re-Org Back into Canonical Chain ... Execute Side Payload on Re-Org" failed at block 14/15 across runs). Set the doms parent to currentContext when the payload extends the canonical head, so validation sees the fresh in-memory state. Head-extending only: a fork payload needs unwindToCommonCanonical to revert doms to the common ancestor, which the parent link would shadow. Temporary on this CI-matrix branch to keep parallel CI green; cherry-picked from mh/perf-caches-pr (733dad53).

    by mh0lt

    execution/stagedsync: stamp finalize coinbase/burnt fee writes at incarnation+1 Parallel exec runs tx bodies with shouldDelayFeeCalc=true, so the worker never credits the coinbase tip / burnt fee — finalizeTxSimple authors those as implicit writes. They were stamped with the worker's own Version, so a later tx that speculatively read the coinbase/burnt before this finalize ran recorded a version the validator could not tell apart from a fresh read (checkVersion compares (TxIndex,Incarnation) only). The stale read passed validation, the dependent tx was never re-executed, and the prior tx's fee was silently dropped — surfacing as an intermittent wrong trie root under the parallel-exec CI matrix. Stamp the implicit coinbase/burnt fee writes at incarnation+1 so they are a distinct version: a dependent that read the pre-fee value now fails validation and is re-executed against the post-fee balance.

    by mh0lt

    execution/stagedsync: tests for finalize coinbase/burnt fee write invalidation Lock in the invariant introduced by the parallel-exec lost-coinbase-fee fix: finalize's implicit coinbase/burnt fee writes are stamped at incarnation+1, so a later tx that speculatively read the coinbase/burnt before this finalize ran fails MVCC validation and is re-executed. - FeeWriteInvalidatesStaleCoinbaseRead: drives the early-read and late-read timings through ValidateVersion and asserts the resulting VersionInvalid / VersionValid outcomes. - BurntFeeWriteBumpsIncarnation: mirror assertion for the burnt path. Both fail against the pre-fix code (the stale read was silently accepted) and pass with the fix in place.

    by mh0lt

    Merge branch 'main' into mh/test-finalize-fee-invalidation

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/test-finalize-fee-invalidation

    by mh0lt

    ci: matrix-test serial vs parallel exec across the test workflows

    mh0lt merged to ledgerwatch/erigon at 2026-05-25 19:58:24

    ci: matrix-test serial vs parallel exec across the test workflows Adds an exec_mode: [serial, parallel] axis to every test workflow that exercises the EL execution path so divergence between dbg.Exec3Parallel true/false is caught on the PR rather than after release. The matrix entries spawn separate runners and run concurrently — wall-clock unchanged, runner-minutes ~2x for affected workflows. The toggle is plumbed via ERIGON_EXEC3_PARALLEL — envLookup in common/dbg/dbg_env.go auto-prepends the ERIGON_ prefix to the source- side EXEC3_PARALLEL flag in common/dbg/experiments.go. Affected workflows: Always-on (matrix on every PR / dispatch / call): test-all-erigon.yml — unit tests, hosted, true parallel test-all-erigon-race.yml — race detector, hosted, true parallel test-hive.yml — engine API + devp2p, hive group runners test-hive-eest.yml — EEST consume-engine/-rlp, hive group test-kurtosis-assertoor.yml — kurtosis devnet suites, hosted Auto-fire on PRs touching their own YAML, dispatch otherwise: test-bench.yml — go bench qa-rpc-integration-tests-latest.yml — self-hosted, max-parallel=1 qa-rpc-performance-comparison-tests.yml — erigon-vs-geth, geth one-mode qa-txpool-performance-test.yml — kurtosis txpool, max-parallel=1 qa-stage-exec.yml — 3 modes × 2 exec_modes = 6 Skipped: test-integration-caplin.yml — runs cl/spectest only, doesn't exercise the EL exec path; matrix-doubling would just re-run identical CL tests. Plumbing notes: * For workflows that build erigon and run go tests directly, the env var is set on the test step's env: block. * For hive-based workflows (test-hive, test-hive-eest), an ENV ERIGON_EXEC3_PARALLEL=... line is appended to clients/erigon/Dockerfile during the existing sed patch loop so every hive-launched erigon inherits the toggle. * For kurtosis-based workflows (test-kurtosis-assertoor, qa-txpool-performance-test), a small follow-up docker build adds an ENV layer on top of test/erigon:current-base to produce test/erigon:current with the toggle baked in. Cheap (single layer) and doesn't invalidate earlier build-cache layers. * Self-hosted single-pool workflows use max-parallel=1 to serialize matrix entries cleanly when state on the runner box is shared (testbed datadir, reference datadir, etc.). * All artifact / enclave / testbed-dir names are disambiguated by exec_mode so the two matrix entries don't clobber each other's outputs. The pull_request: paths: filter on the perf workflows means they auto-fire only on PRs that touch their own YAML — i.e. this PR triggers them once each so the change can be observed end-to-end, and future regular PRs that don't touch them stay free of the cost.

    by mh0lt

    ci: suffix QA test_name with -parallel when exec_mode=parallel Addresses review feedback from @mriccobene on PR #21017: the QA dashboard filters results by test_name regex. Without a suffix the parallel and serial entries land under the same test_name and can't be distinguished in the Hive UI / Grafana dashboard. Per the reviewer's preferred convention, leave the serial entry's name unchanged and add `-parallel` only for the parallel matrix entry. Both `upload_test_results.py` invocations are updated: - qa-rpc-integration-tests-latest.yml:266 → rpc-integration-tests-latest[-parallel] - qa-rpc-performance-comparison-tests.yml:374 → rpc-performance-test-latest[-parallel]-$method The HDR-analysis PDF test_name (line 340 of the perf-comparison file) is intentionally left as `$client-$method` — that name only labels a local report file, which is already disambiguated by the artifact name's `-${{ matrix.exec_mode }}` suffix. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    ci: build the kurtosis erigon image once for the whole matrix The kurtosis matrix grew to suite × {serial, parallel} entries, and every entry ran its own buildx with `cache-to: type=gha,mode=max,scope=kurtosis-erigon-build` — ~a dozen jobs hammering the same GHA cache key concurrently, which the cache backend answers with 504s ("failed to parse error response 504" → `failed to build`; assertoor_pectra_parallel never reached the enclave). Add a `build-erigon-image` job that builds `test/erigon:current-base` once (the single buildx run, the single cache writer) and uploads it as a run-scoped artifact; the `assertoor_test` matrix `needs:` it, downloads + `docker load`s the image, and keeps only the cheap per-entry ENV-layer retag for ERIGON_EXEC3_PARALLEL. Wall-clock ≈ unchanged (the build moves to a prerequisite job instead of running per matrix entry). On cache-warming runs build-erigon-image alone warms the image cache, so the matrix is skipped there.

    by mh0lt

    ci: drop flaky third-party apt repos before apt-get update in setup-erigon The hosted runner image ships extra third-party apt sources (Google Chrome, Microsoft) that are periodically mid-mirror-sync and answer `apt-get update` with a Packages.gz size mismatch — failing the step and the whole job. erigon only installs build-essential from the Ubuntu archive, so remove those repos before updating and add Acquire::Retries for transient blips. Fixes the recurring "dl.google.com/linux/chrome-stable … File has unexpected size" flake (repro / reproducible-build, eest-spec, …).

    by mh0lt

    ci: gate parallel-suffix QA test_name on client==erigon The geth matrix entry uses exec_mode: parallel as a placeholder (geth ignores the toggle), but the unconditional `exec_mode == 'parallel'` gate on the test_name suffix meant geth results were uploaded under `rpc-performance-test-latest-parallel-$method` instead of the historical `rpc-performance-test-latest-$method`. Dashboard queries matching the unsuffixed name would silently break for geth going forward, and a `-parallel-` series would collide with the erigon parallel series. Tighten the gate to `matrix.client == 'erigon' && matrix.exec_mode == 'parallel'` so only the erigon parallel entry takes the suffix; geth stays on its historical name regardless of placeholder exec_mode. Reported by @yperbasis in #21017 review.

    by mh0lt

    ci: align test-hive devp2p sim-limit between serial and parallel matrix legs Before: serial ran sim-limit=eth|discv5, parallel ran sim-limit=eth. The asymmetry made the matrix display misleading (serial-side covered more than parallel-side) and contradicted the comment immediately above which says the sibling devp2p suites including discv5 are intentionally excluded due to unrelated pre-existing failures. discv5 doesn't exercise the EL execution path, so running it on both matrix legs would also waste runner-minutes without surfacing any serial-vs-parallel signal. Drop discv5 from the serial leg so both legs run sim-limit=eth, matching the comment's stated intent and giving a clean apples-to-apples exec-mode comparison. Reported by @yperbasis (nit 5) and Copilot (threads on lines 79 + 83) in #21017 review.

    by mh0lt

    ci: fix Targetting typo in test-hive-eest.yml s/Targetting/Targeting/. Reported by Copilot in #21017 review.

    by mh0lt

    cmd/integration: respect ERIGON_-prefixed EXEC3_PARALLEL in stages.go default stageExec was checking only the unprefixed EXEC3_PARALLEL env name when deciding whether to apply its default of dbg.Exec3Parallel=true. CI workflows set the ERIGON_-prefixed form because dbg.envLookup auto- prepends ERIGON_, so for the serial matrix entry: 1. Package init reads ERIGON_EXEC3_PARALLEL=false via envLookup → dbg.Exec3Parallel = false. 2. stageExec sees no unprefixed EXEC3_PARALLEL → flips it back to true. Both modes ended up running in parallel, with the matrix passing through silent equivalence rather than real CI signal. Fix per AskAlexSharov: move the env parse out of the command runtime and into a package init() that assigns dbg.Exec3Parallel directly via dbg.EnvBool, matching the dbg/experiments.go pattern. EnvBool checks both the bare and ERIGON_-prefixed forms via envLookup, so a workflow setting ERIGON_EXEC3_PARALLEL=false now correctly suppresses the integration tool's default; the default is true so callers that set nothing (typical local debugging) still get parallel mode. stageExec entry loses the 3-line runtime env-check entirely. Reported by @yperbasis on #21017 review.

    by mh0lt

    execution/stagedsync/rawdbreset: delete stage progress entries on reset, don't overwrite with 0 ResetExec → clearStageProgress was overwriting the Execution stage progress with 8 zero bytes via SaveStageProgress(tx, stage, 0). That conflated two distinct states: (a) stage never started — entry absent (len(bnBytes) == 0) (b) stage executed up to block 0 — entry present, value 0 SeekCommitment in commitmentdb/commitment_context.go uses this entry as a fallback when no commitment state is in the domain. Per its own comment at lines 651-660: blockNum=0 means "genesis executed", so it returns txNum = TxNums.Max(0) = 1 (not txNum=0) so the next exec cycle does not re-run the genesis init task. After ResetExec the actual state is (a) — domain tables wiped, no commitment at all. But because clearStageProgress wrote 0 instead of deleting, SeekCommitment saw state (b) and returned (txNum=1, blockNum=0). ExecV3's exec loop then started at txNum=1, skipping block 0's init task — the only place that re-runs the genesis allocation through the worker pool's LightCollector → applyVersionedWrites pipeline. Result: genesis-allocated addresses that no subsequent block touches end up with balance=0 in the parallel-exec view, producing wrong-trie-root mismatches on `qa-stage-exec (from-0, parallel)` (#21017 / #21138 / mainnet block 46147 / 0xA1E4380A3B1f749673E270229993eE55F35663b4). The engine-API InsertChain + FCU path doesn't hit this because it doesn't call ResetExec; it starts with no entry at all and falls into the (a) branch correctly. Fix: clearStageProgress now deletes the SyncStageProgress entries rather than writing 0. This is the integration-tool-side fix the user's diagnosis pointed at — make the integration path's reset state consistent with the FCU path's "fresh DB" state, rather than papering over the inconsistency in exec3.go / SeekCommitment. Adds a unit test that exercises the failing path in <100ms: TestFromZero_GenesisAllocPreservedAfterResetReExec Sets up a custom genesis allocating a dormant address, syncs 5 empty blocks via the engine-API InsertChain (passes pre-fix), then resets state via rawdbreset.ResetExec and drives stage execution via direct SpawnExecuteBlocksStage (the integration-tool path that fails pre-fix). Asserts the genesis-allocated balance is preserved across the reset + re-exec cycle. Pre-fix the test fails with `wrong trie root, block=5` (state diverges because genesis init never runs). Diagnosis credit: Mark Holt.

    by mh0lt

    execution/stagedsync: surface block-validity errors via blockResult.Err When a worker hits a legitimate block-validity failure (insufficient funds, wrong nonce, gas overflow, finalize error, scheduler-exhausted incarnations), nextResult returned (nil, err) and the exec loop bailed. That had three uncoordinated error sources racing for the surfaced diagnostic: 1. nextResult's wrapped ErrInvalidBlock (insufficient funds, …) 2. The apply-loop's channel-close completeness check observing block N's tx-results without a blockResult: "apply loop exited ... but 1 block(s) had tx-results without a blockResult: [N]" 3. The commitment calculator's ErrWrongTrieRoot, computed over partial sd.mem state from txs that succeeded before the failing one (root != header.Root, often != 0 for EEST tests setting expected=0 to mark "this block must be rejected") errors.Join welded these in pe.wait, so the engine API surfaced a doubled or wrong-causality error chain. EEST assertions on the underlying exception class (INTRINSIC_GAS_TOO_LOW, INSUFFICIENT_ACCOUNT_FUNDS) then failed even though the block was correctly rejected as invalid — the rejection reason just no longer matched what serial-exec produced. Fix: centralise block-validity error emission on the apply loop side, and prevent the exec loop and commitment calculator from racing with their own diagnostics for the same block. * nextResult returns blockResult{Err: ...} instead of (nil, err) for every block-validity bailout: skipCheck+OriginError, ConsumeRegular, ConsumeState, blob gas overflow, engine.Finalize, and too-many- incarnations. A new helper invalidBlockResult builds the synthetic blockResult carrying BlockNum/BlockHash/Err. * Apply loop's case *blockResult fast-paths Err != nil at the top: marks appliedBlocks[N] so the channel-close completeness check doesn't double-report as silent miss, drops pendingAccumulatorWrites (we never announce invalid blocks), and returns Err — the canonical error-surfacing point. * Exec loop exits immediately after sending an invalid blockResult (both the main and ctx-done-drain paths). Without this, the exec loop would scheduleNextPending() on top of partial / now-discarded state, racing the apply loop's Err return. * Commitment calculator's case *blockResult skips compute when Err is set. Without this, computeAndCheck would compute a root over the partial sd.mem state and emit ErrWrongTrieRoot through rootResults, which would win the errors.Join race against the apply loop's in-flight Err return — masking the original validation diagnostic. Stress repro (TestDeleteRecreateSlotsAcrossManyBlocks under GOMAXPROCS=2 -race count=30) goes from 5/30 fails with doubled error chains to 3/30 fails with clean single-line errors. The residual 3/30 is a separate dep-estimator stuck-at-0 bug — tracked separately. Discovered via #21017's serial-vs-parallel CI matrix; not visible on serial-exec.

    by mh0lt

    execution/stagedsync: capture-and-restore inMemHistoryReads around parallel exec The defer at exec3_parallel.go:206 was introduced in b72aa7b4f7 (#20805 parallel commitment calculator) and hardcoded the post-exec value to false. That overwrote whatever the caller had set: - Engine API path: caller leaves the default (true, set in NewTemporalMemBatch). Defer-to-false flipped it. Subsequent forkchoice_updated -> GetAsOf failed with "GetAsOf called on TemporalMemBatch with inMemHistoryReads disabled", or post-batch trie-root computation read partial state -> wrong-trie-root. - cmd/integration stage_exec path: caller explicitly sets false (cmd/integration/commands/stages.go:752). Here the defer-to-false happened to match the caller's intent, so no breakage was visible. Fix: capture the caller's setting on entry, restore it on exit. This keeps the engine API path correct (defaults to true, stays true) AND preserves the integration tool's explicit-false setting. Adds an InMemHistoryReads() getter on TemporalMemBatch + SharedDomains + the kv.TemporalMemBatch interface to support the capture. Repro: EEST test_gas_limit_below_minimum[fork_Cancun-gas_limit_5000] in parallel mode. The block is valid (5000 == MinBlockGasLimit, not below) so exec succeeds; the next forkchoice_updated then errored out with the GetAsOf failure. Serial mode passes the same test — parallel-only divergence, fixed by this patch (verified locally via hive simulator). Likely also fixes the mainnet from-0 parallel wrong-trie-root at block 131578 (confirmed consistent across two CI runs of qa-stage-exec); verification dispatched.

    by mh0lt

    execution/state: don't drop CodePath writes for newly-created accounts in SetCode SetCode has a cumulative-net-zero optimisation that deletes CodePath, CodeHashPath and CodeSizePath from the per-tx versionedWrites when the new code matches `stateObject.original.CodeHash`. The intent is to elide no-op writes from the EIP-7702 set/reset-delegation flow. For a CREATE2 reincarnation (or any fresh contract creation), the same condition fires whenever the new bytecode happens to match the destroyed contract's bytecode. `stateObject.original` carries the PRE-CREATION snapshot from the previous incarnation via createObject(addr, previous), so a "match" against `original` is structural coincidence — not a real revert-to-base. When the writes are dropped, FlushVersionedWrites omits them, and a later tx in the same block reading CodeHashPath gets MVReadResultNone from the versionMap. The read falls through to the recursive AddressPath read, which returns the stale snapshot captured at createObject time (CodeHash=EmptyCodeHash, before SetCode mutated newobj.data). That empty hash serialises into the account at end-of-block and corrupts the trie root. The serial path is unaffected because it has no per-tx versionedWrites or versionMap reads, so the snapshot/cache divergence cannot exist. Restricting case (2) to !stateObject.newlyCreated preserves the EIP-7702 net-zero optimisation for existing accounts while making CREATE2 reincarnations emit their code writes unconditionally. Reproducer: TestGeneratedTraceApiCollision with EXEC3_PARALLEL=true (also TestDeleteRecreateSlotsAcrossManyBlocks under the stress flag, and EEST test_dynamic_create2_selfdestruct_collision). All pass with this fix.

    by mh0lt

    execution/stagedsync: reject blocks containing a tx with gas > block gas limit geth's core/block_validator.go::ValidateBody rejects any tx in a block whose declared gas limit exceeds the block's header.GasLimit, before execution starts. Erigon had no equivalent body-level check, so a bad block reached the per-tx pipeline and failed there with the wrong exception class: - With a low feeCap, preCheck's EIP-1559 fee-cap branch fired before the gas-pool branch, producing ErrFeeCapTooLow (TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS). - Without a low feeCap, the tx executed and tripped the gas-used mismatch in the header-vs-computed check (BlockException.INVALID_GAS_USED). Both shapes mis-map in EEST/Hive's geth-calibrated ExceptionMapper for tests like: tests/frontier/validation/test_transaction.py::test_tx_gas_limit tests/static/state_tests/stEIP1559/lowGasLimitFiller.yml::lowGasLimit A prior attempt added the check at the top of TxnExecutor.preCheck. That broke simulation paths (TestSimulatedBackend_CallContractRevert, TestSimulatedBackend_PendingAndCallContract) which intentionally pass tx.gas=50_000_000 against arbitrary block contexts -- preCheck is shared between block execution and eth_call / eth_simulateV1 / trace_call. PR #21236 reverted; this change moves the check to the per-block setup inside executeBlocks (parallel) and exec3_serial.go (serial), where simulation paths never traverse: - eth_call -> protocol.ApplyMessage directly - eth_simulateV1 -> jsonrpc.eth_simulation per-call EVM - trace_call -> trace_adhoc per-call EVM The check wraps rules.ErrInvalidBlock so the existing bad-block handling (POSSync ReportBadHeaderPoS, unwind, BadBlock(hash, err)) all fire on the same code path as a wrong-trie-root rejection. No new sentinel and no new plumbing required. Both executor paths get the same check because the parallel and serial exec dispatchers are separate code files; a single shared helper above both would change call signatures in deeper unrelated functions. Unblocks the GAS_ALLOWANCE_EXCEEDED EEST tests on the parallel-axis matrix in #21017 without regressing simulation tests.

    by mh0lt

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    set all eest spec test shards to max-allowed-failures: 0

    by taratorio

    Revert "execution/stagedsync: reject blocks containing a tx with gas > block gas limit" This reverts commit 4d25ea57ec84d33c62089615ab096c41ea69be22.

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    execution: EIP-8037 inclusion uses per-dimension contribution CheckBlockGasInclusion now takes (regularGas, stateGas) and rejects the tx when either exceeds the matching reservoir. Pre-Amsterdam the state contribution is 0 (state dim never consumed). Amsterdam onwards regular contribution is min(MaxTxnGasLimit, tx.gas) and state is tx.gas — matches the EIP-8037 reservoir semantics. Replaces the prior intrinsic-floor variant which was too weak (let a tx through when tx.gas exceeded the reservoir but intrinsic fit) and the original tx.gas-only check which over-rejected EIP-8037 valid multi-dimensional cases (block_2d_gas_valid_when_cumulative_exceeds_limit, block_state_gas_limit_boundary[exact_fit]). Parallel post-exec verification passes BlockRegularGasUsed / BlockStateGasUsed directly — same shape, just realised contributions instead of declared. Verified against stEIP1559/test_low_gas_limit (Amsterdam) and the full statetests-devnet shard.

    by mh0lt

    execution: fix parallel-exec SD-then-resurrect Two coordinated changes for the same scenario family — a contract is selfdestructed by an earlier TX in the block and the current TX touches the address again (CREATE2-recreate, value-transfer-resurrect, or empty-touch under pre-Spurious-Dragon rules). 1. IntraBlockState.CreateAccount marks journal.dirty(addr) when previous is selfdestructed. resetObjectChange.dirtied() returns false, so without the explicit mark the parallel worker's MakeWriteSet revert- non-dirty block drops every resurrect write (test_double_kill / EIP-6780 family on the parallel shard). The mark is confined to the CreateAccount path so the GetOrNewStateObject AddBalance path is unaffected — that path goes through TestSelfDestructReceive and must not gain a dirty mark here. 2. normalizeWriteSet only emits post-SD defaults (Balance=0, Nonce=0, Incarnation=0, CodeHash=EmptyCodeHash) when the current TX wrote CreateContractPath. A value-transfer resurrect (no CreateContractPath) inherits pre-SD account fields via the versionMap last-write-wins chain — matching GenerateChain's accumulate-across-txs behaviour (no per-tx FinalizeTx). Forcing defaults here resets nonce/codeHash against the canonical state (wrong trie root: TestSelfDestructReceive). CREATE/CREATE2 paths still get the defaults (TestDeleteRecreate*, TestCVE2020_26265). Verified end-to-end: TestSelfDestructReceive, TestDeleteRecreate*, TestCVE2020_26265 (parallel) pass; full EEST blocktests-stable-parallel (69256/0) and blocktests-devnet (82896/0) shards pass.

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    ci: fix upload_test_results.py arg name in qa-stage-exec PR #21208 changed both --result_file → --result-file in qa-stage-exec.yml to match run_and_check_stage_exec.py's CLI. But upload_test_results.py (line 122) uses underscore — every other QA workflow that calls it (qa-constrained-tip-tracking, qa-tip-tracking, qa-sync-with-externalcl, qa-sync-from-scratch, qa-rpc-integration-tests-latest, etc.) passes --result_file. CI: "upload_test_results.py: error: unrecognized arguments: --result-file" after the stage_exec smoke test itself runs to completion. Restore underscore at the upload_test_results.py call site only. Line 88's run_and_check_stage_exec.py call keeps --result-file (its own CLI).

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix

    by mh0lt

    Merge remote-tracking branch 'origin/main' into mh/ci-exec-mode-matrix # Conflicts: # .github/workflows/test-hive-eest.yml

    by mh0lt

    execution/stagedsync: disable trie warmup value-cache on parallel exec The commitment trie warmuper reads paraTrieDB (persisted state). During a multi-block uncommitted batch (parallel fork validation) sd.mem holds in-flight writes not yet in paraTrieDB, so the warmuper's value cache serves stale account/storage values to the trie and produces wrong roots (hive engine-api "Re-Org Back into Canonical Chain ... Execute Side Payload on Re-Org"). Short-term gate: keep the value cache only on the serial path until the full fix lands. The MDBX page-cache warmer is unaffected.

    by mh0lt

    Merge branch 'main' into mh/ci-exec-mode-matrix

    by AskAlexSharov

    Merge branch 'main' into mh/ci-exec-mode-matrix Sync with origin/main (95567f1: execution/state: per-path revival in versionedRead MVReadResultNone branch + bc4145744: execution: flag for kzg ctx warmup). Key resolutions: - execution/stagedsync/exec3.go: drop b9f6208 short-term EnableWarmupCache(!isApplyingBlocks && !parallel) guard; take main's simplified form EnableWarmupCache(!isApplyingBlocks) — the underlying warmup-cache correctness issue is addressed by 95567f1's per-path revival fix - execution/state/versionedio.go: take 95567f1's per-path revival resolution in the MVReadResultNone SD short-circuit (replaces the account-wide LatestTxIndex scan introduced in 8008e0e) - execution/state/versionedio_test.go: new file from 95567f1 Co-authored-by: milen

    by github-actions[bot]

    Revert "Merge branch 'main' into mh/ci-exec-mode-matrix" This reverts commit 2b87a9d0dffd415b50ab4204297ba99f26a40e6c.

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into mh/ci-exec-mode-matrix

    by taratorio

    execution/stagedsync: revert warmup-cache parallel gate from this branch Reverts b9f6208. This branch is the CI-matrix config and should carry only .github/ changes; the parallel-exec warmup-cache fix moves to a dedicated Go-fix PR.

    by mh0lt

    Revert "execution/stagedsync: revert warmup-cache parallel gate from this branch" This reverts commit f02c5dde9cb7b2c6cc6ce8d46e681c659c539175.

    by mh0lt

    execution/execmodule: chain fork-validation SD to currentContext for head-extending payloads ValidateChain creates a fresh SharedDomains with no parent. FCU's MergeExtendingFork leaves the latest canonical state in currentContext.mem; MDBX is committed only later under memory pressure. Between an FCU and the next newPayload the fresh doms reads stale MDBX, so parallel fork-validation computes a wrong trie root — nondeterministic, depending on whether a background commit has fired (hive engine-api "Re-Org Back into Canonical Chain ... Execute Side Payload on Re-Org" failed at block 14/15 across runs). Set the doms parent to currentContext when the payload extends the canonical head, so validation sees the fresh in-memory state. Head-extending only: a fork payload needs unwindToCommonCanonical to revert doms to the common ancestor, which the parent link would shadow. Temporary on this CI-matrix branch to keep parallel CI green; cherry-picked from mh/perf-caches-pr (733dad53).

    by mh0lt

    execution/stagedsync: stamp finalize coinbase/burnt fee writes at incarnation+1 Parallel exec runs tx bodies with shouldDelayFeeCalc=true, so the worker never credits the coinbase tip / burnt fee — finalizeTxSimple authors those as implicit writes. They were stamped with the worker's own Version, so a later tx that speculatively read the coinbase/burnt before this finalize ran recorded a version the validator could not tell apart from a fresh read (checkVersion compares (TxIndex,Incarnation) only). The stale read passed validation, the dependent tx was never re-executed, and the prior tx's fee was silently dropped — surfacing as an intermittent wrong trie root under the parallel-exec CI matrix. Stamp the implicit coinbase/burnt fee writes at incarnation+1 so they are a distinct version: a dependent that read the pre-fee value now fails validation and is re-executed against the post-fee balance.

    by mh0lt

    execution/exec: parallel-worker fresh per-task gas pool The parallel exec path never sets a per-task gas pool, so the worker's preCheck saw st.gp==nil and CheckBlockGasInclusion silently short- circuited (the nil-guard in gaspool.go was added so workers couldn't race on the shared block pool — but that left no in-worker gas-allowance check at all). For a tx whose gas exceeds the block limit, preCheck then advanced to the next check; if the tx also had feeCap < baseFee, the worker returned ErrFeeCapTooLow. Serial preCheck catches the same tx earlier with ErrGasLimitReached. The merge-queue's hive-eest parallel matrix (cancun/prague/paris- shanghai/osaka) was failing on this divergence: eest asserts the serial error variant (GAS_ALLOWANCE_EXCEEDED) and rejects the parallel one (INSUFFICIENT_MAX_FEE_PER_GAS). Make TxTask.GasPool() hand out a fresh per-invocation pool sized to the block gas limit when no pool has been set. Workers still can't share the shared block pool (that one is consumed in the post-execution validation loop), but each worker now has a real pool for in-worker preCheck — CheckBlockGasInclusion fires for "tx alone exceeds the block limit" exactly as in serial. Pool depletion across multiple txs in the same block stays caught by the validation loop's CheckBlockGasInclusion against the shared pool. Serial is untouched: ResetGasPool sets t.gasPool before execution, the new lazy path is skipped.

    by mh0lt

    execution/stagedsync: parallel apply loop defers wrong-trie-root so block-validation wins The parallel apply loop pulls block results and per-block commitment results from two channels concurrently. Either side can produce an error: a blockValidator (post-execution receipts/gas/bloom checks) returns ErrInvalidBlock from the applyResults branch; the commitment calculator returns ErrWrongTrieRoot via rootResults. With both running in parallel, the apply-loop select picks whichever fires first, so a trie-root mismatch can win the race against a more specific block-validation failure for the same (or a later) block. Serial processes validation strictly before commitment, so its error ordering is deterministic and aligns with eest's validation-error taxonomy (the test expects the specific block-level error, not the downstream trie consequence). Stash ErrWrongTrieRoot in deferredRootErr and keep draining. Surface it only after applyResults closes (post-drain, post-missing-blocks check) so any block-validation error that fires meanwhile returns first. Other commitment errors (non-trie-root) stay fast-fail. The rotation in handleIncorrectRootHashError still runs at the moment the calculator detects the mismatch — only the *error* is deferred, not the side effect. Precaution rather than a known failure cause; it just enforces an invariant that's currently implicit in the parallel-vs-serial contract.

    by mh0lt

    execution/stagedsync: parallel nextResult surfaces raw worker errors as ErrInvalidBlock For txs whose TxTask.Reset rejects the message (e.g. an EIP-7702 SET_CODE tx with an empty authorization list — eest's fork_Prague test_empty_authorization_list), the worker returns a TxResult whose Err is the raw decoding/validation error, not a wrapped ErrExecAbortError. nextResult's "non-ErrExecAbortError" branch was returning (nil, err), which exits the exec loop silently — no blockResult ever reaches the apply loop. The apply-channel-closed branch then sees blks=0 and fabricates ErrLoopExhausted, which the stage loop reports as "unexpected state step has more work" and the engine API mis-reports as a state-machine error instead of the block-validation failure. Serial, by contrast, wraps the same raw err with rules.ErrInvalidBlock and rejects the block cleanly. Match serial: emit the failure through blockResult.Err (the apply loop's canonical block-validity error path). The apply loop sees applyResult.Err, marks the block applied so the completeness check is satisfied, and returns ErrInvalidBlock with the original err preserved in the message. Engine API now reports the real reason.

    by mh0lt

    Merge branch 'main' into mh/ci-exec-mode-matrix

    by mh0lt

    execution/engineapi: re-validate on empty bad-block cache entry instead of returning 'previously known bad block' When an earlier ReportBadHeader populates the badHeaders cache for a hash (or one of its ancestors) without a validation message — the err pointer was nil at the call site — every subsequent newPayload for that hash hit the cache, fell into the `cachedErr == ""` branch, and returned the generic "previously known bad block" string. The cache write at the same site then overwrote any future re-derivation with that same fallback, permanently degrading the entry. eest's ErigonExceptionMapper buckets the response by the validation error string — "previously known bad block" maps to no category, so the test reports "Undefined exception message" even when the underlying block has a deterministic, specific rejection reason (INVALID_BLOCK_ACCESS_LIST, INITCODE_SIZE_EXCEEDED, etc.). Issues #21363 + #21364 Mode A. On a cache hit with empty cachedErr, fall through to the normal validation pipeline so the rejection category is re-derived. The proper string then gets re-cached via the ReportBadHeader at line 1017 on the BadBlock path. Cache hits with a real cached message still take the fast path unchanged.

    by mh0lt

    execution/state: mirror createObjectChange dirty-tracking on resetObjectChange journal.go defined two journal entry types for the same logical "createObject" event with non-symmetric dirtied() returns: func (ch createObjectChange) dirtied() (accounts.Address, bool) { return ch.account, true } func (ch resetObjectChange) dirtied() (accounts.Address, bool) { return accounts.NilAddress, false } createObject in intra_block_state.go picks between them on `previous == nil` — first-creation goes through createObjectChange, recreation (e.g. SD-revival via GetOrNewStateObject) goes through resetObjectChange. Both represent the same operation ("a stateObject was placed at this address"); they differ only in revert behaviour. The asymmetry bites parallel-exec when tx1 selfdestructs an address and tx2 hits CreateAccount or GetOrNewStateObject on the same address: * Serial: tx1's writer already DeleteAccount'd the addr, so getStateObject returns nil → createObject(addr, nil) appends createObjectChange → marks journal.dirties. * Parallel: versionedRead returns the contract's base-state account and reads tx1's SelfDestructPath=true; createObject synthesises a non-nil previous with selfdestructed=true → appends resetObjectChange → with the old return, does NOT mark journal.dirties. At MakeWriteSet the worker IBS computes isDirty from journal.dirties. With no mark, updateAccount falls through both DELETE and UPDATE branches → LightCollector.UpdateAccountData never fires → result.CollectorWrites is missing the empty-account write (test_double_kill / EEST EIP-6780 family on the parallel shard). Symmetric tracking restores the dirty mark for the recreate path without changing first-create behaviour. Verified on TestEngineApiBAL*, TestEIP7708BurnLog*, TestDeleteRecreate* under EXEC3_PARALLEL=true. ## Known regression — see #21217 TestSelfDestructReceive fails under EXEC3_PARALLEL=true after this change with a wrong-trie-root for block 1. The validator's stateObject reconstruction for an SD-then-revived address emits different field values (`nonce=1, codehash=emptyHash`) than the unfixed canonical (`nonce=0, codehash=`). The empty-touch / CreateAccount paths the fix addresses don't have this issue; the AddBalance(non-zero) on an SD'd address does. Filed as #21217 with full repro and the two failed narrow-fix attempts (unconditional symmetry; conditional SD-revival + SelfDestructPath=false re-emit). Lands as the last commit in this stack so the broader structural direction is visible together; the TestSelfDestructReceive regression is the explicit "more work needed" marker before final merge. Stacks on #21212.

    by mh0lt

    execution/stagedsync: parallel finalize reads worker coinbase write from TxOut, not CollectorWrites Two related bugs caused from-0 parallel re-exec to diverge from canonical mainnet on early-Frontier blocks where the miner is also a tx sender (e.g. block 200606 and block 218957): 1. finalizeTxSimple's coinbase/burnt override loop scanned result.CollectorWrites when it should have scanned result.TxOut. CollectorWrites is the IBS's "net change" set — for sender == coinbase Frontier self-sends the per-tx net balance change is zero in the IBS journal so the Balance entry is suppressed. But the worker, running with shouldDelayFeeCalc=true, still debited gas-used from the coinbase at execution time and that debit lives in result.TxOut. Scanning CollectorWrites meant the finalize missed the worker's debit and added the fee tip onto the pre-tx versionMap value — over-crediting the coinbase by one tip per such tx. Canonical mainnet block 218957 vs parallel: diverge by exactly 1.05e15 wei = one tip. 2. SetAccountBalanceOrDelete re-emitted the full account (Balance + Nonce + Incarnation + CodeHash) from a pre-block snapshot whenever no BalancePath entry existed in the writeset. If the worker had already written a different field (e.g. Nonce bump on a miner self-send), the trailing pre-block Nonce from the full-account emission would land after the worker's bumped Nonce and win under last-wins downstream merge — the trie would see the pre-bump nonce. Both surface on the same class of tx (sender == coinbase) and together produced the wrong trie root the from-0 parallel matrix has been catching intermittently. Verified locally: re-exec 0..300000 in parallel mode now matches serial against mainnet snapshots-only datadir. Co-authored-by: Claude Opus 4.7

    by mh0lt

    execution/stagedsync: narrow finalize coinbase/burnt TxOut scan to sender==coinbase/burnt only The previous commit's TxOut scan was too broad: it picked up ANY coinbase BalancePath entry in result.TxOut as the worker's post-execution value. TxOut can contain artifact entries from non-execution paths (e.g. SELFDESTRUCT bookkeeping that touches the zero address when the test coinbase happens to be the zero address), so the broad scan misattributed those artifact values as the worker's coinbase debit and produced wrong finalize results. Surfaced as TestSelfDestructReceive failing under EXEC3_PARALLEL=true. The actual class of write that the previous commit was after — the worker's gas-pre-pay debit when sender == coinbase — only happens when sender == coinbase. Gate the TxOut scan on exactly that condition; fall back to the original CollectorWrites scan for all other cases (where CollectorWrites' net-change view is correct because the worker's coinbase write was an explicit balance transfer, not the suppressed-net-zero miner-self-send shape). Same source-selection rule applied symmetrically to the burnt contract override (use TxOut only when sender == burntAddr). Verified local: - TestSelfDestructReceive (the regression) passes, with and without -race - from-0 parallel re-exec to block 300000 passes (still covers 218957's miner-self-send tx[1] via the sender==coinbase branch) Co-authored-by: Claude Opus 4.7

    by mh0lt

    eliasfano32: Seek returns position alongside value

    AskAlexSharov merged to ledgerwatch/erigon at 2026-05-25 12:15:21

    eliasfano32: Seek returns position alongside value EliasFano.Seek now returns (value, position, bool) instead of (value, bool), where position is the 0-based index of the returned element in the sorted sequence. The internal searchForward already computed the position (the loop counter j); this change stops discarding it. Same signature change cascaded to RebasedEliasFano, SimpleSequence, SequenceReader, and their package-level Seek helpers. Call sites in db/state that don't need the position use _. Variable names in searchForward/searchReverse updated: nextV/nextI → val/pos, loop j → pos. Tests: new TestEliasFanoSeekPosition (25 table cases + 1000-element exhaustive loop) and TestEliasFanoSeekPositionLarge covering block (q=256) and superblock (superQ=16384) boundaries, skewed distributions, and exponential gaps that force the interpolation guess to be maximally wrong.

    by AskAlexSharov

    build(deps): bump github/gh-aw from 0.73.0 to 0.74.8

    dependabot[bot] merged to ledgerwatch/erigon at 2026-05-25 11:43:59

    build(deps): bump github/gh-aw from 0.73.0 to 0.74.8 Bumps [github/gh-aw](https://github.com/github/gh-aw) from 0.73.0 to 0.74.8. - [Release notes](https://github.com/github/gh-aw/releases) - [Changelog](https://github.com/github/gh-aw/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/gh-aw/compare/4d44d0e89851a877f4ddc0cb6c0197e42b1016c5...0feed75a980b06f247abbbf80127f8eb2c19e2c5) --- updated-dependencies: - dependency-name: github/gh-aw dependency-version: 0.74.8 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    build(deps): bump actions/setup-python from 5 to 6

    dependabot[bot] merged to ledgerwatch/erigon at 2026-05-25 11:33:04

    build(deps): bump actions/setup-python from 5 to 6 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    build(deps): bump actions/setup-node from 4 to 6

    dependabot[bot] merged to ledgerwatch/erigon at 2026-05-25 11:33:04

    build(deps): bump actions/setup-node from 4 to 6 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]

    by dependabot[bot]

    execution,cl: add TargetGasLimit to PayloadAttributesV4

    taratorio merged to ledgerwatch/erigon at 2026-05-25 08:51:19

    execution,cl: add TargetGasLimit to PayloadAttributesV4

    by taratorio

    add test for engineapi

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into worktree-payload-attr-v4-target-gas-lim

    by taratorio

    address review comment

    by taratorio

    Parallel-exec correctness fixes (PR #3 of the perf stack)

    mh0lt merged to ledgerwatch/erigon at 2026-05-25 08:09:00

    execution/stagedsync, execution/state: parallel SD-of-pre-existing-contract fixes Fixes the SD/recreate cluster under EXEC3_PARALLEL=true: TestSelfDestructReceive, TestCVE2020_26265, TestEIP161AccountRemoval, TestDeleteRecreateAccount, TestDeleteRecreateSlots, TestDeleteRecreateSlotsAcrossManyBlocks. normalizeWriteSet: - when an address was self-destructed by an earlier TX in the block and this TX re-creates it, fill missing account fields with post-destruction defaults instead of the stale pre-SD values still in the versionMap - drop StoragePath writes for SD'd addresses (an SSTORE made after a SELFDESTRUCT in the same TX is wiped); the SD cascade re-emits explicit per-slot deletes - gate EIP-161 empty-account-removal on SpuriousDragon being active - storage no-op filter: when the address was SD'd since the slot's last write, the baseline is 0, not the value still in the versionMap/domain applyVersionedWrites / BlockStateCache: route the selfdestruct account+code+storage-prefix delete through the block cache so it's recorded in writeLog order — a later SELFDESTRUCT must supersede an earlier put for the same address in the same block, which a direct domain delete (applied before the block-end Flush replays the earlier put) did not. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/stagedsync: clean exit when single-block batch already covered maxBlockNum Fixes the engine-API cluster under EXEC3_PARALLEL=true: TestEngineApi* (Builder, BAL, Fcu, NewPayload, multi-block sequence, reorg recovery) and TestEthGetLogsDoNotGetAffectedAfterNewPayloadOnSideChain — all previously failed with "unexpected state step has more work". When the exec loop exits through execLoopExitCheck (rws.ResultCh closed or rws.Drain returned closed — the clean-drain paths for a small batch), it doesn't flip reachedMaxBlock, since that flag is only set by execLoopShouldExit / the maxBlockNum check in the main loop's blockResult branch. For a single-block fork-validation batch the result heap empties before that branch ever fires, so the apply loop's channel-close path saw reachedMaxBlock=false and returned ErrLoopExhausted — the stage loop interpreted that as "has more work" and the engine API surfaced "unexpected state step has more work". Treat the apply-loop exit as clean when lastBlockResult.BlockNum has reached maxBlockNum and no block is missing from appliedBlocks: every requested block was applied, so there is no more work regardless of which exec-loop branch closed the channel. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/state: don't emit StoragePath=0 writes from IBS.Selfdestruct Fixes the eip6780-selfdestruct gas cluster under EXEC3_PARALLEL=true (EEST cancun/eip6780_selfdestruct/test_create_selfdestruct_same_tx[_increased_nonce], test_selfdestruct_created_in_same_tx_with_revert, test_selfdestruct_created_same_block_different_tx, test_selfdestruct_pre_existing, frontier/create/test_create_suicide_store). IBS.Selfdestruct recorded versionWritten(StoragePath, key, 0) for every dirty slot to feed the parallel commitment calculator a per-slot DELETE. But versionedRead consults versionedWrites before the stateObject, so for pre-Cancun (and CALL-based SELFDESTRUCT generally) — where the account stays alive until end-of-tx and re-entered code reads its storage — those spurious zero writes made the re-read return 0: wrong gas (SSTORE_SET vs dirty-update, +19900 per affected slot, so block gasUsed over-counted by a multiple of 19900) and a wrong written value. normalizeWriteSet's SD cascade (sdStorageSlots = vm.StorageKeys ∪ domainStorageKeys, added earlier) already emits the per-slot DELETEs the calculator needs, so the Selfdestruct-side emission was redundant. Drop it. Repurposes the obsolete TestSelfDestructRecordsStorageDeletes unit test into TestSelfDestructKeepsDirtyStorageReadableSameTx, which asserts the fixed behavior. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/stagedsync: clear calc Deleted on a non-SD account write even when zero The commitment calculator kept Deleted=true when a self-destructed address later received a zero-valued account-field write — that was a within-tx guard for the trailing BalancePath=0 that IBS.Selfdestruct emits. But across transactions a zero account-field write means the address is genuinely alive at end of tx (e.g. a 0-value transfer that re-creates a previously-destroyed address as an empty account on a pre-EIP-161 fork), so Deleted must be cleared. ApplyWrites now pre-scans the tx's writeset for SelfDestructPath=true (last entry wins) and only suppresses the Deleted-clear for addresses this tx self-destructed; for any other address an account-field write clears Deleted regardless of value. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/tests: gate known parallel-exec failures behind EXEC3_PARALLEL, tracked in #21136 Lands the serial/parallel exec-mode CI matrix green. These 6 failures are all parallel-only (serial coverage unaffected) and all in the same family — the post-execution wrapper re-derives the per-tx writeset/commitment and diverges from serial's MakeWriteSet on a SELFDESTRUCT/recreate, fork- transition, or coinbase edge case: - EEST frontier/opcodes/test_double_kill - EEST cancun/eip6780_selfdestruct/test_dynamic_create2_selfdestruct_collision_two_different_transactions - EEST prague/eip7002_el_triggerable_withdrawals/test_system_contract_deployment - EEST prague/eip7251_consolidations/test_system_contract_deployment - TestLegacyBlockchain/ValidBlocks/bcEIP3675/tipInsideBlock (gasUsed over-count ~4800) - TestEIP7708BurnLogWhenCoinbaseSelfDestructs (minIBS doesn't know coinbase was SD'd) Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/stagedsync: install the per-block changeset accumulator before any of the block's writes Under EXEC3_PARALLEL the parallel executor keeps a single per-block changeset accumulator (pe.currentChangeSet) installed/cleared by the exec loop. It was installed only at exec start (for startBlockNum) and at the rotation site after each block's blockResult ("install for blockResult+1 if its executor is already in the map"). But a block whose executor isn't in the map at that moment — e.g. processRequest scheduling the first block of a new request after pe.blockExecutors went empty mid-batch — gets scheduled with no accumulator installed; its ApplyStateWrites then write into a nil domainWriters[i].diff, so the block's changeset stays empty and its diffset is never saved/flushed. A later unwind/FCU across that block then fails with "domains.GetDiffset(N, 0x..): not found" — load-sensitive (depends on whether the executors map empties in that window), so it surfaces as intermittent fork-choice / reorg / RPC test flakes under concurrent test load. No memory data race involved. Make changeset capture robust: track pe.currentChangeSetBlock, and ensureChangesetAccumulator(blockNum) installs a fresh accumulator iff one isn't already installed for blockNum. Call it from processResults (the single exec-loop point that drains worker results) before each be.nextResult, so every block's accumulator is installed before its first apply regardless of how the block was scheduled — plus at exec start, at the rotation site (fast path), and at the blockResult save point (empty blocks). All SetChangesetAccumulator mutations stay in the exec loop (single-writer invariant unchanged). Tracked in https://github.com/erigontech/erigon/issues/21138. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/stagedsync: drop the stale sd.mem 'Trim old version entries' comment It described trimming that was never implemented and would be wrong once changeset generation moves post-validation (the calc must keep sd.mem's versioned history for GetAsOf). No code change. Co-Authored-By: Claude Opus 4.7 (1M context)

    by mh0lt

    execution/stagedsync: O(1) CollectorWrites fee-balance update, drop dead VersionedWrites.SetBalance After a tx finalizes, parallel exec re-applies the fee-adjusted balances into the result's CollectorWrites. CollectorWrites is a flat slice, so replacing a BalancePath entry by address is a linear scan; doing that once per addWrites entry is O(len(addWrites)·len(CollectorWrites)). When finalize is a full block-end IBS reconstruction both can be ~one entry per account the block touched, so a block whose tx pays ~100k accounts (execution/tests' invalid-receipt-hash-high-mgas corner) hits ~10^10 comparisons — TestInvalidReceiptHashHighMgas ran >11 min under EXEC3_PARALLEL + -race and tripped mock_cl's 10-min per-call deadline (serial: ~10s). Index CollectorWrites' BalancePath entries by address once and update in O(1); the test now matches serial (~12s vs ~10s, no -race). VersionedWrites.SetBalance had no other callers — removed. No behaviour change: the new path mutates the same *VersionedWrite in place and appends a new entry for an unseen address, exactly as the linear-scan SetBalance did, including same-address re-updates within the loop. Tracked alongside the parallel-exec CI matrix (#21017 / #21136).

    by mh0lt

    execution/stagedsync: first-match-wins in CollectorWrites BalancePath index Defensive tweak to the O(1) CollectorWrites balance-index (629cc23566): keep the first matching BalancePath entry per address in the pre-scan, exactly mirroring the linear-scan CollectorWrites.SetBalance(addr) it replaced (which updated the first match). Guards against a CollectorWrites that holds more than one BalancePath entry for the same address.

    by mh0lt

    execution/stagedsync: emit EIP-7708 Burn log under parallel-exec when coinbase self-destructs The parallel-exec post-apply path in finalizeTxSimple was applying TxOut (including SelfDestructPath=true for a coinbase contract that destructed itself in the same tx), then calling postApplyMessageFunc on a fresh IBS that had the coinbase marked selfdestructed with balance=0 — because the parallel worker runs with shouldDelayFeeCalc=true and the priority fee is accumulated onto the version-map base separately, never landing on this post-apply IBS. LogSelfDestructedAccounts' GetRemovedAccountsWithBalance filters for non-zero balance, so the residual-balance Burn log specified by EIP-7708 was never emitted; receipts.DeriveSha drifted from the serial producer's; consumers rejected the block as BadBlock. Mirror serial-exec (txn_executor.go:674): after ibs.ApplyVersionedWrites, credit FeeTipped to coinbase and FeeBurnt to burnt (when London applies). AddBalance leaves the selfdestruct flag intact (Selfdestruct only fires on the addr→clear transition, not on subsequent balance writes), so the account ends up selfdestructed with the priority fee as residual balance — exactly the state the serial path produces. LogSelfDestructedAccounts then sees the account in source 2 (ibs.GetRemovedAccountsWithBalance) and emits the Burn log. Also capture the post-apply IBS's logs back onto result.Logs — without this the burn log is stranded on the discarded ibs and never reaches the receipt, so even with the emission fix the receipts root would still diverge. Removes the t.Skip on TestEIP7708BurnLogWhenCoinbaseSelfDestructs guarded behind dbg.Exec3Parallel. Closes the case under #21136; the remaining items in that issue (if any) are unrelated.

    by mh0lt

    execution/state: mirror ReadAccountData SD-revival check into versionedRead versionedStateReader.ReadAccountData already handles "self-destructed then revived" semantics (versionedio.go:273-293): when versionMap shows SelfDestructPath=true at depIdx, but BalancePath/NoncePath/CodeHashPath has a write at TxIndex > depIdx, the account was re-created and the SD must not short-circuit the read. versionedRead — the generic worker-side read path used by ibs.GetBalance, GetNonce, GetCodeHash etc. — was missing the same check. Workers got the post-revival reads wrong, returning zero for any field on an SD-flagged address regardless of a later revival write. This surfaces under EIP-161 + delayed-fee parallel exec: finalizeTxSimple emits SelfDestructPath=true for the coinbase when a tx with FeeTipped=0 touches it (empty-removal); a later tx whose FeeTipped > 0 writes BalancePath at the higher TxIndex. The serial equivalent is AddBalance(amount>0) on a previously-deleted stateObject, where GetOrNewStateObject implicitly recreates a fresh object — the next tx that does BALANCE(coinbase) sees the post-revival balance. Under parallel exec, the worker's versionedRead short-circuited on the SD entry without consulting the revival writes; the BALANCE returned zero, the contract SSTORE'd zero into a previously-non-zero slot, and EIP-2200's SSTORE_CLEAR_REFUND (4800 gas) fired spuriously — TestLegacyBlockchain/ValidBlocks/bcEIP3675/tipInsideBlock failing with gas exactly 4800 short under ERIGON_EXEC3_PARALLEL=true. The fix mirrors ReadAccountData's revival check (LatestTxIndex on BalancePath, NoncePath, CodeHashPath > destructTxIndex). When any of those have a later write, fall through to the normal versionMap.Read of the requested path — making the worker observe the revived state exactly as serial does. Verified: - bcEIP3675/tipInsideBlock 5/5 parallel (was 0/5) - TestEngineApiBAL* 8/8 parallel (no regression) - SD-family: TestDeleteRecreate*, TestSelfDestruct*, TestEIP161*, TestCVE2020_26265, TestEIP7708 all pass parallel - Full TestLegacyBlockchain pass parallel - make lint clean

    by mh0lt

    execution/tests, rpc/jsonrpc: drop two stale EXEC3_PARALLEL t.Skips Addresses taratorio's review comments on PR #21153 — "these tests should not be skipped" / "this one seems to be the last Skip pending removal". (1) execution/tests/block_test.go: drop the SkipLoad of ValidBlocks/bcEIP3675/tipInsideBlock.json under dbg.Exec3Parallel. The 4800-gas mismatch was the EIP-161 coinbase empty-removal + delayed-fee race: tx 0's finalize emits SelfDestructPath=true for the coinbase (empty-removal: FeeTipped=0 + coinbaseEmptyPre=true); tx 1's finalize then credits FeeTipped > 0, reviving the account; tx 2's worker reads coinbase BALANCE and versionedRead's SD-check branch short-circuits to zero without consulting the later revival write — so the contract SSTOREs 0 over a previously-non-zero slot and EIP-2200's SSTORE_CLEAR_REFUND (4800) fires spuriously. Resolved by the prior commit (cherry-picked from #21177) which mirrors ReadAccountData's existing revival check into versionedRead — the fixture now passes 5/5 under ERIGON_EXEC3_PARALLEL=true. The bug described in #21136 (tipInsideBlock parallel-exec gas mismatch) is fixed; the issue can be closed when this lands. Also drops the unused dbg import. (2) rpc/jsonrpc/gen_traces_test.go: drop the dbg.Exec3Parallel-gated t.Skip in TestGeneratedTraceApiCollision. The skip referenced "intra-block SELFDESTRUCT + CREATE2 reincarnation not yet supported by parallel executor — fixed on exec3/remove-rwtx- threading branch". Verified the test passes 8/8 under ERIGON_EXEC3_PARALLEL=true and 3/3 serial on the current branch — the capability has landed somewhere upstream of this PR's base. The trace output for the collision case matches the expected golden under both execution modes. Also drops the unused dbg import. The remaining unconditional t.Skip in execution/commitment/hex_patricia_hashed_test.go:3366 (Test_ModeUpdate_SiblingConsistency, #20961) is intentionally left as a regression marker — confirmed the underlying ModeUpdate vs ModeDirect sibling-encoding divergence still reproduces; the fix is in commitment cell-cache invalidation, out of scope for the parallel-exec PR stack.

    by mh0lt

    execution/stagedsync: drop TestReceiptHashFromRPC unit-suite RPC integration test This was an integration smoke test that required a running erigon node on localhost:8545 holding mainnet block 24363971. It was misclassified as a unit test: - When no node is running, rpcCall t.Skip's — best-case it just adds noise. - When *any* other node is running (different chain, unsynced, wrong block), the test falls through to compare an empty-trie hash against a zero hash and produces a fake pass/fail unrelated to erigon's DeriveSha logic. DeriveSha itself has unit coverage that doesn't depend on RPC. This file tested a node setup, not erigon code, so it doesn't belong in \`go test ./...\` — especially under the new EXEC3_PARALLEL matrix where the test harness is doubled and any shared-runner 8545 listener becomes a flake source.

    by mh0lt

    execution/cache, db/state/execctx: SD-transparent ethHash bypass for CodeDomain Adds a third map (`ethHashToCode`) to CodeCache, keyed by the 32-byte Ethereum codeHash (keccak256). New methods `GetByEthHash` and `PutWithEthHash` expose direct L2b access without going through the addr→maphash→code two-level path. The byte storage duplicates L2 in the worst case (2x code-bytes memory at the cap); accepted for the per-key fast path on many-addrs-one-code workloads. `SharedDomains.GetLatest(CodeDomain, ...)` consults L2b transparently: when the addr-keyed cache misses, resolve the codeHash from the AccountsDomain (typically warm because the EVM just loaded the account), probe `stateCache.GetCodeByHash` before falling through to the file accessor stack. On miss, fill both L1 and L2b via PutCodeWithHash. The fast path is unchanged. Workload shape this targets: many addresses sharing one codeHash (proxies, factory-deployed clones, ERC-20 holders, OpenZeppelin templates). Today's addr-keyed cache misses on every fresh address even when the bytecode is already cached. With this change a single L2b entry serves N addresses after the first population. Microbench results: - BenchmarkCodeCache_GetByEthHash_Hit: 17.01 ns/op - BenchmarkCodeCache_GetByEthHash_Miss: 15.45 ns/op - BenchmarkCodeCache_Get_AddrLevel_Hit: 32.44 ns/op (existing) - BenchmarkCodeCache_GetByEthHash_ManyAddrs: 17.02 ns/op L2b hit is ~2x faster than the existing two-level addr path (one map probe vs two), and enables hits on workloads where L1 would miss. Cross-client research at agentspecs/cross-client-state-access-2026-05-14.md notes geth's separate codeSizeCache as the further (geth-proven) win for EXTCODESIZE/EXTCODEHASH and addrToHash LRU as a one-line behaviour fix; both queued as follow-up surgical commits. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache, db/state, execution/state: codeSizeCache for EXTCODESIZE / EXTCODEHASH Adds a third caching layer to CodeCache (alongside L1 addr→maphash and L2b ethHash→bytes): codeSizeByEthHash maps the 32-byte Ethereum codeHash to its byte length. Tiny per-entry footprint (32B key + 8B value vs 5-10 KB for full bytes) so the same memory budget gives ~1000x the hit surface. Capped at 1M entries (geth core/state/database_code.go uses the same size). EXTCODESIZE / EXTCODEHASH callers — historically the slowest opcodes on the lab dashboard's bench — answer from a single map probe without paying the file accessor stack cost of the full bytes. Geth-proven; cross-client writeup at agentspecs/cross-client-state-access-2026-05-14.md notes this as the largest single available win for the synthetic bench. Wiring: - CodeCache.GetCodeSizeByEthHash / PutCodeSizeByEthHash — direct accessors. - PutWithEthHash now populates the size layer alongside L2b, so every bytes-load creates a future fast-path entry "for free". - StateCache wrappers GetCodeSizeByHash / PutCodeSizeByHash. - SharedDomains.GetCodeSize(tx, addr) — the SD-transparent fast path: resolve codeHash via the AccountsDomain cache chain, probe the size cache, then L2b, then file-read+populate. Returns (0, false, nil) for EOAs and no-code accounts without paying any file read. - temporalGetter.GetCodeSize so callers reach it via the existing getter. - ReaderV3.ReadAccountCodeSize type-asserts on a codeSizeGetter interface and routes through the fast path when the underlying getter supports it; falls back to GetLatest+len otherwise. No kv.TemporalGetter interface change. Limitation: capacity is no-op-when-full, not LRU. A separate surgical commit will swap to real LRU eviction; mirrors the addrToHash fix queued from the same cross-client writeup. Tests: 3 new (PopulatedAlongsideBytes, DirectPutAndGet, EmptyHashOrNegativeIsNoOp). All existing CodeCache tests pass. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/exec, execution/execmodule: BlockReadAheader populates cache.StateCache The BlockReadAheader has always prefetched BAL-listed (and access-list) addresses' account/code/storage via a fresh ReaderV3 on a separate RoTx. Its prefetches warmed OS page cache + RoTx cursors — disconnected from the process-global cache.StateCache that SharedDomains.GetLatest probes on the EVM hot path. The two layers were two separate caches; nothing the prefetcher loaded ever reached the EVM's lookup path. Reth's structural advantage on EXTCODESIZE-loop benches is that its prewarm writes to the same hashmap the EVM reads from (crates/engine/execution-cache/src/cached_state.rs:663). When EVM enters, every BAL-listed addr's first read is a 20 ns cache probe — no file accessor stack, no decompression CPU. PR #21128 swapped this from mini-moka to a lock-free fixed-cache for a measured +10.8 % mgas/s. This commit closes the equivalent gap on Erigon: a thin cache-populating TemporalGetter wrapper writes successful reads through to cache.StateCache as a side effect. ReaderV3 is unchanged; the wrapper sits in front. When the prefetcher already has the codeHash from a preceding account read, the next CodeDomain read routes through StateCache.PutCodeWithHash so the L2b (ethHash → bytes) + size-cache layers fill alongside the bare addr-keyed L1. Wiring: - BlockReadAheader.SetStateCache(*cache.StateCache) setter. - ExecModule construction calls readAheader.SetStateCache(domainCache), so the same StateCache the FCU/canonical path wires onto SD is the one the prefetcher warms. - cachePopulatingGetter wraps the worker's ttx; both BAL-warming and tx-warming paths gain the same treatment. Fgprof on the EXTCODESIZE-EXISTING_CONTRACT-30M bench had shown 95 % of EVM wall-clock in seg.Getter.nextPos (Huffman decompression of code values). With this commit, every BAL-listed addr's lookup should hit the cache and skip the file accessor stack entirely — eliminating the dominant cost. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/state, execution/cache: stateObject.code populate + addrToHash LRU Two surgical commits bundled (both touch the code-read hot path): 1. IntraBlockState.GetCodeSize now loads the full bytes via stateReader.ReadAccountCode on first touch and populates stateObject.code, so subsequent same-addr EXTCODESIZE / EXTCODEHASH / CALL within the tx are in-struct slice-len calls (~50 ns), not full reader round-trips. Mirrors geth's pattern at core/state/state_object.go ~Code() — pay one read per addr per tx, free for the rest. 2. CodeCache.addrToHash switched from a no-op-when-full maphash.Map[versionedAddressID] to an LRU lru.Cache[[20]byte, versionedAddressID] (hashicorp/golang-lru/v2, already imported elsewhere). Cap derived from the existing byte budget at ~28 bytes/entry (~580 k entries for the 16 MB default). Fresh-address workloads (mainnet thousands of new addrs per block) now warm up the addr layer over time instead of silently dropping new entries forever; matches geth's lru.Cache at core/state/database_code.go. The hashToCode layer is unchanged (content-addressed bytes, immutable, byte-capped with new-entry no-op when full — the same semantic as before since code bytes by codeHash never change). Bench on the EXTCODESIZE-EXISTING_CONTRACT-30M family: 62.34 mgas/s (was 61.50). The marginal gain is small on this bench because BAL prefetch already populates the cache layers; neither lever fires heavily. The expected wins are on non-BAL workloads where EXTCODESIZE-loop patterns repeat within a tx (#1) and fresh-address-churn mainnet blocks fill the addr layer (#2). Updated TestCodeCache_AddrCapacityLimit to assert LRU eviction (was asserting no-op-when-full); the prior behaviour was the bug. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache, db/state/execctx: addr → codeHash LRU above SD Nethermind-style addr → 32-byte codeHash LRU sitting above SharedDomains.codeHashForAddr. When the EVM-known codeHash for an address has already been resolved once, subsequent lookups skip the entire AccountsDomain chain (sd.mem → sd.parent.mem → sd.stateCache → tx.GetLatest) and the account-RLP decode. Wiring: - CodeCache adds addrToEthHash *lru.Cache[[20]byte, [32]byte] sized to the existing addrCapacityB budget; methods GetAddrCodeHash / PutAddrCodeHash / DeleteAddrCodeHash. - StateCache wrappers route to the CodeCache instance. - SD.codeHashForAddr probes the LRU first; on miss falls through to the existing chain and populates on the way out (including the zero-hash sentinel for missing-or-EOA accounts — repeat lookups return immediately). - Invalidation: SD.DomainPut for AccountsDomain drops the entry (CREATE / CREATE2-replace path); SD.DomainDel for AccountsDomain also drops the entry (SELFDESTRUCT); StateCache.RevertWithDiffset drops on unwind. Helps non-BAL workloads where codeHashForAddr is currently the cold account-domain probe. On the EXISTING_CONTRACT bench (BAL prefetch already populates everything), this is within noise; the lever is for mainnet workloads where many addresses miss the BAL-prefetch window but the cache is warm from prior lookups. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/exec: cachePopulatingGetter caches negative results The cache-populating wrapper on the read-ahead worker's TemporalTx previously gated cache writes on `len(v) > 0`. That dropped negative results — i.e. missing accounts, empty storage slots, no-code probes — on the floor. Repeated probes of the same missing address re-paid the file accessor stack walk every time, instead of hitting a cached negative entry. Mirrors the revm pattern that drives reth's 1700-3400 mgas/s on account_access NON_EXISTING / EXISTING_EOA variants: revm represents a missing address as a real CacheAccount{ account: None, status: LoadedNotExisting } and reth's ExecutionCache.account_cache uses FixedCache> where None is a first-class cacheable value. Bottom of the reth path is: BAL prewarm calls basic_account once → returns None → cache hit forever for that addr. The cycle-2 sweep on account_access[EXTCODESIZE/NON_EXISTING/30M] showed 3.65 → 494 mgas/s without this fix; with the fix the same bench reports 508 mgas/s (within run-to-run noise but trending right). Most of the win was already captured by the readAhead-populates- cache.StateCache wiring (commit cbe9044e52) and the balcache port (d41e2e84bb) — those raised the cache hit rate on populated entries enough that the EVM rarely fell through to the file accessor on this bench. The fix is mechanically correct regardless and should matter more on workloads with mixed populated / negative probes across blocks. See agentspecs/reth-missing-eoa-fastpath-2026-05-15.md for the detailed mechanism analysis and the three concrete copy-able patterns from reth. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache: surface fill-and-freeze cliff via inserts/dropped counters GenericCache.Put has no eviction policy. When the byte budget is reached, new keys are silently dropped until Clear/ClearWithHash/ValidateAndPrepare- mismatch resets the cache. On a long-running node this manifests as a monotonic miss-rate climb that's hard to attribute without instrumentation. Add two counters next to hits/misses: inserts - new keys accepted dropped - new keys rejected at the budget check (the existing branch at the new-key cap; not a behaviour change) PrintStatsAndReset logs both. Sets up the diagnostic baseline before the eviction-policy swap in the follow-up commits on this branch. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache: replace GenericCache map with sharded LRU + Mode Replaces the maphash.Map[T] backing store in GenericCache with freelru.ShardedLRU[uint64, entry[T]] (same lib as db/state/cache.go; already in go.mod). Adds a Mode constructor flag: - ModeEvictLRU (default): per-shard LRU evicts the oldest entry on insert when its slot cap is reached. OnEvict drops bytes from currentSize. - ModeNoOp: preserves the historical fill-and-freeze behaviour (silently drop new keys at the byte cap; counted via dropped). Kept as the diagnostic baseline so the regression bench can compare A/B. Per-shard eviction is a known trade-off of freelru.ShardedLRU — RemoveOldest is shard-local, not globally LRU. Matches the trade-off db/state/cache.go / execution/cache/code_cache.go / execution/balcache/balcache.go already accept. LFU (W-TinyLFU, the policy reth uses) is scan-resistant by design and would slot in behind the same Mode wrapper as a follow-up; the seam is documented at policy.go. Key shape: pre-hash via common/maphash.Hash (Go's randomized stdlib hasher, already used by the previous maphash.Map) into uint64; entry stores the full key for collision check. Same pattern as db/state/cache.go. Byte-budget translation: per-domain avg-entry constants in state_cache.go (avgAccountEntryBytes / avgStorageEntryBytes / avgCommitmentEntryBytes) — account / storage are near-fixed sizes so the translation is reliable. capacityBytes becomes a sizing hint plus telemetry (SizeBytes / PrintStatsAndReset). Code domain is unchanged; CodeCache wraps its own LRUs. Adds metrics: inserts, evictions, dropped — all exposed in PrintStatsAndReset alongside the existing hits / misses / hit_rate. Mode is also logged. Touches one external call site: execution/vm/contract.go's jumpDestCache now constructs with ModeEvictLRU. Tests: TestDomainCache_PutCapacityLimit renamed to ..._NoOpMode and asserts the fill-and-freeze contract under explicit ModeNoOp. New TestDomainCache_PutEvictsWhenFull_EvictMode asserts eviction under ModeEvictLRU using a small entry-count cap (the byte→entry translation is approximate; the test uses the entry-count knob via the in-package newGenericCacheEntries constructor to make the assertion deterministic). Pre-existing lint issues on mh/sd-code-cache (intra_block_state.go nilness, preload_parallel.go prealloc) are surfaced by lint non-determinism but are out of this commit's scope. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache: STATE_CACHE_MODE env override at NewStateCache time Single env knob read once at NewStateCache. Default ModeEvictLRU, recognised override "noop" (for the regression-bench baseline so ModeEvictLRU and ModeNoOp can be compared on the same binary). Unrecognised values fall back to evict with a warn log. ModeNoOp engagement is logged at info level because the fill-and-freeze behaviour is a deliberate diagnostic state, not a production setting. Pattern matches db/state/cache.go's D_LRU_ENABLED / D_LRU knobs (dbg.EnvString from common/dbg). Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache: correct the LFU rationale in Mode docstring The previous comment asserted "reth uses W-TinyLFU for state caches" — that is wrong on the execution hot path. Reth's cross-block state cache is `fixed-cache` (PR #21128, v1.11.0): a lock-free direct-mapped / set-associative array with collision-evict semantics. No LRU list, no LFU sketch. Their published wins (~25% newPayload p50 / +33% gas/s) came from *removing* LRU/LFU bookkeeping, not adding LFU. Where reth uses real LRU/LFU it's deliberate and not the execution cache (schnellru::LruMap for networking; moka in precompile_cache.rs explicitly configured with eviction_policy(EvictionPolicy::lru())). The docstring now reflects two follow-up policies both real: - ModeEvictFixedCache (reth's actual choice, more interesting structural option than LFU) - ModeEvictLFU (W-TinyLFU; helps mainnet steady-state, not the cycle-2 bloat fixtures which are pure cold scans) Decision criterion (per agentspecs/lfu-vs-lru-state-cache-decision-2026-05-15.md): ship ModeEvictLFU only if a 24h mainnet replay shows current sharded-LRU hit-rate < 90 % on Account/Storage. Otter is the only credible Go W-TinyLFU library; ristretto has documented correctness bugs and is disqualified for an EL hot path. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    execution/cache: reduce default cache caps to 100 MB each (bench knob) Investigation knob, NOT a permanent default. Account / Storage / Code each capped at 100 MB so the bench measures layer contributions instead of being dominated by preallocated cache memory pressure (1 GB / 1 GB / 512 MB defaults push sys past the GC/page-cache pressure band on this hardware/workload mix). Permanent defaults stay at 1 GB / 1 GB / 512 MB; this commit will be reverted or dynamically gated by relative-to-available sizing. Co-Authored-By: Claude Opus 4.7 (1M context)

    by None

    Merge origin/mh/parallel-exec-fixes into PR #3 branch Brings the 13 parallel-exec correctness commits from mh/parallel-exec-fixes onto the StateCache LRU base. Conflicts resolved in 3 files (versionedio.go, rw_v3.go, exec3_parallel.go) by keeping HEAD's typed-readset / per-path revival shape and confirming HEAD already absorbs each fix's intent: - versionedio.go: HEAD's per-path versionMap.Read(addr,path,key,...) supersedes the older 3-path BalancePath|NoncePath|CodeHashPath scan. - rw_v3.go: HEAD has rs.trace as atomic.Bool — keep .Load() form. - exec3_parallel.go (5 regions): keep HEAD's runPostApplyMessageOnMinIBS refactor (already includes the EIP-7708 burn-log fix from a0ecfc7e12), HEAD's BalanceChangeReason field name, HEAD's hasCreateContract guard on the post-SD defaulting path. Co-Authored-By: Claude Opus 4.7

    by None

    [wip] p2p/sentry: fix shared PeerStore version filter in findBestPeers, findPeerByMinBlock, PeerEvents

    AskAlexSharov merged to ledgerwatch/erigon at 2026-05-25 05:15:19

    p2p/sentry: filter shared PeerStore by eth version in findBestPeers, findPeerByMinBlock, PeerEvents With the shared PeerStore introduced in #21335, all GrpcServers see every peer regardless of which eth protocol version they negotiated. Three rangePeers loops were missing the per-sentry version filter that Peers() and SimplePeerCount() already apply: - findBestPeersWithPermit: used by SendMessageByMinBlock to pick target peers. Without the filter an eth/71 sentry could select an eth/69 peer, encode the request with eth/71 wire codes, and send it over the eth/69 peer's rw — the remote peer would receive an unknown code and disconnect. - findPeerByMinBlock: same path, single-peer variant. - PeerEvents replay: emitted Connect events for every peer in the shared store, including peers owned by other-version sentries. Those peers never generate a Disconnect on this sentry's peersStreams, leaving the subscriber with ghost peers that are never cleaned up. Fix: apply the same `pv == 0 || pv != ss.ethVersion` guard used by Peers() and SimplePeerCount() to all three loops. Three new tests cover the fixed behaviour.

    by AskAlexSharov

    execution: ci change eest-spec-shards definition file to yaml

    taratorio merged to ledgerwatch/erigon at 2026-05-25 04:54:33

    execution: ci change eest-spec-shards definition file to yaml

    by taratorio

    execution: fix exec to not return ErrLoopExhausted on last block

    taratorio merged to ledgerwatch/erigon at 2026-05-25 04:02:22

    execution: fix parallel exec to not return ErrLoopExhausted on last block

    by taratorio

    Merge branch 'main' of github.com:erigontech/erigon into worktree-state-step-err-loop-exhausted

    by taratorio

    common, ethash: bound unsafe slice views

    LarryArnault45 merged to ledgerwatch/erigon at 2026-05-25 02:53:04

    common, ethash: bound unsafe slice views

    by LarryArnault45

    XDC Refactor HotStuff

    batrr merged to NethermindEth/nethermind at 2026-05-25 14:06:29

    refactor

    by ak88

    merged

    by ak88

    fix

    by ak88

    fix

    by ak88

    review comments

    by ak88

    DI hookup

    by ak88

    Merge branch 'master' into sign-tx2

    by ak88

    feat: Add snapshot recovery mechanism

    by batrr

    feat: Enhance logging for snapshot recovery process

    by batrr

    feat: Improve snapshot recovery logic and add unit test for non-snapshot blocks

    by batrr

    feat: Refactor import statements in snapshot manager files for improved organization

    by batrr

    feat: Update event handling in snapshot manager for main chain updates

    by batrr

    feat: Remove unused crypto import from SnapshotManagerTests

    by batrr

    Merge master

    by batrr

    Refactor SignTransactionManager to improve dependency injection and encapsulation

    by batrr

    remove unused

    by batrr

    refactor(xdc): move QC initialization and commit into QuorumCertificateManager

    by batrr

    test(xdc): add OnUpdateMainChain tests for QC initialization and commit

    by batrr

    refactor(xdc): clean up QuorumCertificateManager initialization logic

    by batrr

    refactor(xdc): remove unnecessary genesis block initialization in QuorumCertificateManager

    by batrr

    refactor(xdc): simplify genesis block initialization in QuorumCertificateManager

    by batrr

    Merge branch 'refactor/qc-manager' into refactor/xdc-hotstuff

    by batrr

    Merge branch 'refactor/sign-tx' into refactor/xdc-hotstuff # Conflicts: # src/Nethermind/Nethermind.Xdc/XdcModule.cs

    by batrr

    Refactor XdcHotStuff and XdcPlugin to remove unused dependencies and improve structure

    by batrr

    Refactor TimeoutCertificateManager and XdcConsensusContext for improved thread safety and cleanup logic

    by batrr

    cheat

    by batrr

    revert cheat fix

    by batrr

    merge master

    by batrr

    feat: Enhance logging in snapshot recovery process for better error visibility

    by batrr

    fix tests

    by batrr

    Merge branch 'master' into refactor/qc-manager

    by batrr

    fix comments

    by batrr

    Merge branch 'refactor/qc-manager' of github.com:NethermindEth/nethermind into refactor/qc-manager

    by batrr

    Merge branch 'master' into refactor/sign-tx

    by batrr

    Merge remote-tracking branch 'origin/master' into refactor/sign-tx

    by batrr

    refactor(XdcHotStuff): improve dependency injection for SignTransactionManager

    by batrr

    refactor(SignTransactionManager): add nullability check for ExtraConsensusData

    by batrr

    refactor: ensure thread safety

    by batrr

    refactor: remove redundant timeout vote test case

    by batrr

    refactor: simplify timeout threshold checks in TimeoutCertificateManager

    by batrr

    remove comment

    by batrr

    Merge branch 'refactor/qc-manager' into refactor/xdc-hotstuff

    by batrr

    Merge branch 'refactor/sign-tx' into refactor/xdc-hotstuff

    by batrr

    Merge branch 'refactor/round-lock' into refactor/xdc-hotstuff

    by batrr

    Merge branch 'feat/xdc-snapshot-recovery' into refactor/xdc-hotstuff

    by batrr

    refactor: move CleanupTimeouts call to ProcessTimeoutCertificate method

    by batrr

    Merge branch 'refactor/round-lock' into refactor/xdc-hotstuff

    by batrr

    refactor: improve round task initiation logic and visibility

    by batrr

    refactor: replace CancellationTokenSource with a running flag for task management

    by batrr

    refactor(qc): enhance commit logic and improve block validation in QuorumCertificateManager

    by batrr

    Merge branch 'refactor/qc-manager' into refactor/xdc-hotstuff

    by batrr

    refactor(xdc): enforce argument validation and improve null handling in XdcHotStuff

    by batrr

    Merge remote-tracking branch 'origin/master' into refactor/sign-tx

    by batrr

    Merge branch 'refactor/sign-tx' into refactor/xdc-hotstuff

    by batrr

    refactor(SignTransactionManager): simplify constructor and implement IStartable interface

    by batrr

    refactor(SignTransactionManager): change constructor parameters to Lazy for improved dependency injection

    by batrr

    add comment

    by batrr

    refactor(xdc): enhance logging and track round advancement details in XdcHotStuff

    by batrr

    fix conflicts

    by batrr

    fix conflicts

    by batrr

    refactor(XdcHotStuff): change log level from Info to Debug for voting round messages

    by batrr

    refactor(XdcHotStuff): improve StopAsync method to await running round task and enhance synchronization check

    by batrr

    refactor(XdcHotStuff): enhance round task management with locking mechanism

    by batrr

    feat: enhance gas benchmark workflow with comments for start and results

    cbermudez97 merged to NethermindEth/nethermind at 2026-05-25 13:48:50

    feat: enhance gas benchmark workflow with comments for start and results

    by cbermudez97

    feat: add .gitignore for mock testing files

    by cbermudez97

    Merge branch 'master' into workflows/gas-benchmarks-prs Resolve .github/workflows/run-gas-benchmarks.yml, preserving the fork-PR gate from #11684, the create-github-app-token@v3 bump, and the free-disk-space swap-storage flag from master. Harden the two new comment jobs added by #10350: - Move pull-requests/issues write permissions from workflow scope to the post-start-comment and post-results-comment jobs only; keep workflow-scoped permissions at contents: read. - Pass filter (and gas-benchmark result) into actions/github-script via env so the JS body no longer interpolates job outputs through ${{ ... }}. Drop empty src/Nethermind/.gitignore (mock testing scaffold). Co-Authored-By: Claude Opus 4.7 (1M context)

    by cbermudez97

    fix(workflows): distinguish skipped gas-benchmark result from cancelled post-results-comment runs with `if: always()` and falls through to an `else` that labeled both `skipped` and `cancelled` as "Cancelled". gas-benchmark is reported as `skipped` (not `cancelled`) when an upstream job like `setup` or `publish-docker` fails, so PR authors saw a misleading "Cancelled" message instead of an indication that a setup step broke. Addresses review feedback on #10350. Co-Authored-By: Claude Opus 4.7 (1M context)

    by cbermudez97

    Add validation for nested ABI array depth

    Radovenchyk merged to NethermindEth/nethermind at 2026-05-25 12:48:23

    Add validation for nested ABI array depth

    by Radovenchyk

    Fix tuple false-positive, move depth tests to own file Track array depth per recursion chain rather than counting all '[' in the raw type string, which previously rejected valid tuples like (uint256[],uint256[],...) with many array-typed fields. Move AbiTypeConverterDepthTests to its own file with file-scoped namespace and replace LINQ usage with a StringBuilder helper.

    by LukaszRozmej

    Parameterize depth tests; collapse throw to one line

    by LukaszRozmej

    fix: update copyright year to 2026 Co-authored-by: Alex

    by Radovenchyk

    feat: increase MaxArrayDepth from 32 to 1024

    by Radovenchyk

    test: update depth test cases to match new limit of 1024

    by Radovenchyk

    Validate FCU safe/finalized by ancestry when main-chain markers are outdated

    marcindsobczak merged to NethermindEth/nethermind at 2026-05-25 11:47:10

    tests

    by marcindsobczak

    more clear comments

    by marcindsobczak

    keep only regression test

    by marcindsobczak

    fix

    by marcindsobczak

    simplify comment

    by marcindsobczak

    one more comment simplification

    by marcindsobczak

    fix comment as requested in review

    by marcindsobczak

    test: improve test coverage in Nethermind.State.Flat

    asdacap merged to NethermindEth/nethermind at 2026-05-25 11:01:42

    test: improve branch coverage in Nethermind.State.Flat Adds targeted parameterised tests for low-coverage hotspots and previously-untested classes. Branch coverage 58.6% -> 63.0%, line coverage 70.1% -> 73.4% (+64 tests). Per-class branch uplift: ResourcePool 32% -> 93%, SlotValue 58% -> 100%, FlatSnapTrieFactory 0% -> 75%, FlatStateRootIndex 0% -> 83%, FlatSnapStateTree 0% -> 100%, BloomFilter 43% -> 49%. Includes a coverage.runsettings scoping coverage to the Nethermind.State.Flat module for re-runs. Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    test: cover Importer and ReadOnlySnapshotBundle Adds ImporterTests (trie -> flat copy + cancellation) and ReadOnlySnapshotBundleTests (snapshot lookup, persistence fallback, self-destruct boundary, dispose guard). Branch coverage 63.0% -> 66.4%, line coverage 73.4% -> 76.8% (+22 tests). Importer 0% -> 100% line/branch; ReadOnlySnapshotBundle 41% -> 91% branch. Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    test: cover FlatStateReader and FlatReadOnlyTrieStore Adds unit tests for the read-only state surface: FlatStateReader (account/storage/code lookup, null-bundle short-circuit, code-empty shortcut) and FlatReadOnlyTrieStore (HasRoot, scope lifecycle, resolve before/after BeginScope, null-bundle throw). Branch coverage 66.4% -> 67.9%, line 76.8% -> 78.2% (+17 tests). FlatStateReader 0% -> 74% line / 79% branch; FlatReadOnlyTrieStore 0% -> 85% line / 70% branch. Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    test: remove unnecessary using directives Fixes IDE0005 lint warnings in FlatSnapTreesTests and FlatSnapTrieFactoryTests. Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: address review feedback in Nethermind.State.Flat - Remove all #region/#endregion blocks from BloomFilterTests - Use Assert.ThatAsync for the async cancellation assertion in ImporterTests - Replace the timed CancellationTokenSource loop in Add_ConcurrentWithMightContain_ShouldWork with a bounded iteration count - Extract the duplicated MakeBundle helper into FlatTestHelpers - Drop the inaccurate empty-filter false-positive comment Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: remove unused using directives The Nethermind.State.Flat.Persistence using became unnecessary after the MakeBundle helper was extracted into FlatTestHelpers (IDE0005). Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: parameterize FlatStateReader tests with StateReader Move FlatStateReaderTests from Nethermind.State.Flat.Test to Nethermind.State.Test and run the same bodies against both StateReader and FlatStateReader via [TestFixture("Standard")] / [TestFixture("Flat")]. The tests now exercise the IStateReader contract end-to-end through a real IWorldState instead of mocking IFlatDbManager, so both implementations are held to the same observable behavior. Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: merge FlatStateReaderTests into StateReaderTests Fold the new contract cases into the existing StateReaderTests and parameterize the whole fixture with [TestFixture("Standard")] / [TestFixture("Flat")] so every existing test now runs against both StateReader and FlatStateReader via IStateReader. No tests required gating; the dbProvider-specific setup was replaced with a Context helper that picks the factory and owns container disposal. Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: align StateReaderTests with bool useFlat convention and dedup Switch the fixture parameter from string ("Standard"/"Flat") to bool useFlat to match the convention used by the other parameterized tests in this directory (ScopeProviderTests, StateProviderTests, StorageProviderTests, TracedAccessWorldStateTests). Drop two redundant new cases and fold their unique coverage into the existing parallel test: - GetStorage_ExistingSlot_ReturnsValue: fully duplicated Get_storage. - TryGetAccount_ExistingAccount_ReturnsTrue: balance coverage already came from Can_ask_about_balance_in_parallel via reader.GetBalance; the nonce assertion (the only novel part) is now folded into the parallel reader loop, which now reads via TryGetAccount and checks both balance and nonce. Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: satisfy IDE0028 in FlatTestHelpers Collapse the two-line list construction + Add into a single collection initializer so the Debug build (which treats IDE0028 as an error) is green. Co-Authored-By: Claude Opus 4.7

    by asdacap

    test: dedupe Nethermind.State.Flat test boilerplate - Fold IsInvalidContractSender_* single-shot tests into the parameterized IsInvalidContractSender_BasicCases via an extra `delegated` flag. - Reuse Context.CommitAndCapture in Can_collect_stats, Can_accepts_visitors, and Can_dump_state. - Add SeedTree + _importer field in ImporterTests; drop repeated build/seed scaffolding from every test. - Promote MakeSnapshot/SnapshotList helpers to FlatTestHelpers; collapse ReadOnlySnapshotBundleTests pool boilerplate into [SetUp]. - Move FlatReadOnlyTrieStore construction to [SetUp]; add [TearDown] for NUnit1032 compliance. - Extract BuildIndex/AppendBlock helpers in FlatStateRootIndexTests. Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    test: second-pass dedup with helpers and TestCaseSource - BloomFilterTests: introduce `Bloom` using-alias to remove FQN noise, fold Add_SingleItem + Add_MultipleItems into one parameterized test, add NewBloom factory to centralize default args. - SlotValueTests: extract IncrementingBytes helper and FullSlotHex constant. - FlatSnapTreesTests: NewStateTree/NewStorageTree/PathHash helpers; parameterize StateTree_IsPersisted via TestCaseSource; merge State and Storage tree Dispose tests with a tree-builder delegate source. - StateReaderTests: merge Can_collect_stats / Can_accepts_visitors / Can_dump_state / HasStateForBlock_CommittedBlock_ReturnsTrue into one Reader_OnCommittedAccount driven by a TestCaseSource of Action. Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    test: dispose ISnapTree instances in FlatSnapTrieFactoryTests Addresses the Low-severity review finding: CreateStateTree and CreateStorageTree return IDisposable; wrap returned trees in `using` to mirror disposal hygiene across the rest of the test suite. Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    Merge remote-tracking branch 'origin/master' into pr-11695 # Conflicts: # src/Nethermind/Nethermind.State.Flat.Test/Persistence/BloomFilter/BloomFilterTests.cs

    by LukaszRozmej

    fix: remove unused Nethermind.Core using directive Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    test(sync): un-ignore Can_cancel_seal_validation

    0xDevNinja merged to NethermindEth/nethermind at 2026-05-25 10:37:13

    test(sync): un-ignore Can_cancel_seal_validation `[Ignore("Fails OneLoggerLogManager Travis only")]` was added back when the repo still ran on Travis CI. Travis was retired years ago and the test has been silently skipped since. Re-running locally on the current `Nethermind.Synchronization.Test` project the test passes cleanly — 20 consecutive standalone runs and 39 sibling `ForwardHeaderProvider*` tests in the same fixture all green. Drop the attribute so it executes in normal CI again and gives us real coverage of `IForwardHeaderProvider.GetBlockHeaders` cancellation when seal validation is slow.

    by 0xDevNinja

    fix(sync): accept receipts with zero bloom from peers

    obchain merged to NethermindEth/nethermind at 2026-05-25 10:02:56

    fix(sync): accept receipts with zero bloom from peers (#8508) `TxReceipt.Bloom`'s getter only falls back to `CalculateBloom` when the stored bloom is null. Some peers — Erigon serving old receipts — ship `Bloom.Empty` over the wire even when the receipt has logs, so the locally computed receipts-trie root diverged from the header's `ReceiptsRoot` and the peer was treated as having sent invalid receipts (leading to a disconnect). Recompute the bloom from `Logs` in `TryPrepareReceipts` only when the stored value is exactly `Bloom.Empty` and the receipt actually carries logs. A peer that ships a non-zero but wrong bloom is still caught by the receipts-root comparison.

    by obchain

    test(sync): parameterize NormalizeZeroBlooms tests and trim remarks Collapses three near-identical NormalizeZeroBlooms_* tests into one [TestCase]-parameterized test driven by hasLogs/startBloomEmpty/ expectRecompute. Trims the verbose block on NormalizeZeroBlooms to keep only the load-bearing context. Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    test(sync): trim NormalizeZeroBlooms comments Drops the block and the regression-comment header; the now states the contract directly without referencing the issue number. Co-Authored-By: Claude Opus 4.7 (1M context)

    by LukaszRozmej

    test: bump executePayloadV1_accepts_already_known_block timeout to 60s

    LukaszRozmej merged to NethermindEth/nethermind at 2026-05-25 09:35:03

    test: bump executePayloadV1_accepts_already_known_block CancelAfter to 60s Test has flaked again on Flat DB CI at the 30s cap (originally bumped from 10s in #11380). bestBlockProcessed.WaitAsync exceeds 30s on slow runners. Aligning with the 60s NewPayloadBlockProcessingTimeout already used in MergeTestBlockchain.

    by LukaszRozmej

    Update OP Superchain chains

    core-repository-dispatch-app[bot] merged to NethermindEth/nethermind at 2026-05-25 09:14:42

    Update OP Superchain chains

    by emlautarom1

    Auto-update fast sync settings

    core-repository-dispatch-app[bot] merged to NethermindEth/nethermind at 2026-05-25 09:14:34

    Auto-update fast sync settings

    by rubo

    Refactor sign tx

    ak88 merged to NethermindEth/nethermind at 2026-05-25 08:23:18

    refactor

    by ak88

    merged

    by ak88

    fix

    by ak88

    fix

    by ak88

    review comments

    by ak88

    DI hookup

    by ak88

    Merge branch 'master' into sign-tx2

    by ak88

    Merge master

    by batrr

    Refactor SignTransactionManager to improve dependency injection and encapsulation

    by batrr

    remove unused

    by batrr

    Merge branch 'master' into refactor/sign-tx

    by batrr

    Merge remote-tracking branch 'origin/master' into refactor/sign-tx

    by batrr

    refactor(XdcHotStuff): improve dependency injection for SignTransactionManager

    by batrr

    refactor(SignTransactionManager): add nullability check for ExtraConsensusData

    by batrr

    Merge remote-tracking branch 'origin/master' into refactor/sign-tx

    by batrr

    refactor(SignTransactionManager): simplify constructor and implement IStartable interface

    by batrr

    refactor(SignTransactionManager): change constructor parameters to Lazy for improved dependency injection

    by batrr

    add comment

    by batrr

    Fix flaky TransactionReceiptsSubscription tests + observe subscription worker faults

    smartprogrammer93 merged to NethermindEth/nethermind at 2026-05-25 07:11:40

    Fix flaky TransactionReceiptsSubscription tests + observe subscription worker faults Closes #11737 The flaky `TransactionReceiptsSubscription_failed_tx_still_delivered` test (and its siblings) created `TransactionReceiptsSubscription` instances via helper methods that never disposed them. Each subscription spins up a dedicated `LongRunning` thread blocked on `Channel.Reader.WaitToReadAsync()` that only exits when the channel is completed via `Subscription.Dispose()`. Combined with `[Parallelizable(ParallelScope.All)]` and `[FixtureLifeCycle(LifeCycle.InstancePerTestCase)]`, every test leaked a dedicated thread plus captured mock references, eventually destabilizing the test host on CI. Also fixed a latent bug in `Subscription.ProcessMessages()`: `Task.Factory.StartNew(async () => ...)` returns `Task` whose outer task completes at the first `await`, so the attached `ContinueWith` fired immediately and never observed faults from the worker loop. Added `.Unwrap()` so the continuation runs on the inner task, and gated it with `OnlyOnFaulted | ExecuteSynchronously` so the success path skips the continuation entirely. Switched `SendChannel.Writer.Complete()` to `TryComplete()` so `Dispose()` is idempotent per the IDisposable contract. Co-Authored-By: Claude Opus 4.7 (1M context)

    by smartprogrammer93

    Simplify Subscription worker: drop Task.Factory.StartNew + LongRunning Per review feedback: avoid the Task footgun entirely by extracting the worker body into a regular async method and discarding the returned task. The previous code paid for a dedicated LongRunning OS thread that spent ~all its time awaiting on a channel, and relied on Unwrap() to make ContinueWith observe faults. A top-level try/catch around the async loop covers both per-action exceptions (inner catch) and any fault from the channel wait or loop scaffolding (outer catch). Co-Authored-By: Claude Opus 4.7 (1M context)

    by smartprogrammer93

    Fix Geth genesis deposit contract fallback to use zero address

    smartprogrammer93 merged to NethermindEth/nethermind at 2026-05-25 06:36:15

    Fix Geth genesis deposit contract fallback to use zero address When a Geth-style genesis enables Prague but omits depositContractAddress (e.g. the genesis Hive supplies for non-mainnet test chains), the loader was silently substituting the mainnet deposit contract address. Geth itself leaves the field as the zero address, so eth_config / EIP-7910 must report 0x000...000 to match. Fall back to Address.Zero and update the test that codified the old fallback. Co-Authored-By: Claude Opus 4.7 (1M context)

    by smartprogrammer93

    Fix DbTracker repeatedly logging ObjectDisposedException after disposal

    stdevMac merged to NethermindEth/nethermind at 2026-05-25 03:13:21

    Fix DbTracker repeatedly logging ObjectDisposedException after disposal When the Autofac LifetimeScope (or the shared cache SafeHandle) is disposed while MonitoringService's timer is still scheduled, `_sharedBlockCache.Value` in `UpdateDbMetrics` throws `ObjectDisposedException` via Autofac's LazyRegistrationSource. The generic catch logs it at Error and the callback stays registered, so the same exception re-fires on every metric interval — producing dozens of identical errors per minute on affected nodes. Catch `ObjectDisposedException` explicitly and short-circuit subsequent ticks via a `_stopped` flag. Adds a regression test that disposes the container and asserts the callback neither throws nor logs on repeated invocations. Fixes #11719

    by stdevMac

    Address review: debug-log first stop, drop redundant CreateDb in test - Log at Debug level in the new `ObjectDisposedException` branch so there is a (no-cost on production) signal that DbTracker has stopped updating metrics, rather than only inferring it from the absence of further Error logs. - Remove the duplicate `CreateDb` call in the regression test — the helper `ConfigureMetricUpdater` already registers the test DB. - Disable `TestLogger.IsDebug` in the regression test so the new Debug message does not trip the `LogList.Should().BeEmpty()` assertion; the test still asserts no Error-level spam, which was the bug.

    by stdevMac

    Merge remote-tracking branch 'origin/master' into fix/dbtracker-disposed-scope-race # Conflicts: # src/Nethermind/Nethermind.Db.Test/DbTrackerTests.cs

    by stdevMac

    Address review: make DbTracker IDisposable, drop redundant comment - Implement IDisposable on DbTracker so Autofac proactively sets _stopped during scope teardown, short-circuiting subsequent monitoring ticks before they touch disposed resources. The catch (ObjectDisposedException) remains as a backstop for the race where a tick is already executing when Dispose runs. - Mark _stopped as volatile since it is now written from the disposing thread and read from the monitoring timer thread. - Drop the inline comment in the catch block; the Debug log message already conveys the same information.

    by stdevMac

    Merge remote-tracking branch 'origin/master' into fix/dbtracker-disposed-scope-race

    by stdevMac

    fix: satisfy IDE0028 in FakeRecordedBalStore

    asdacap merged to NethermindEth/nethermind at 2026-05-25 02:23:00

    fix: satisfy IDE0028 in FakeRecordedBalStore Master fails to build after #11708 enforced IDE0028 — the dictionary initializer introduced by #11700 still uses `new()` instead of `[]`. Co-Authored-By: Claude Opus 4.7

    by asdacap

    Move BAL spec-switch and BAL attachment to the branch processor for BalRecorder plugin

    asdacap merged to NethermindEth/nethermind at 2026-05-25 01:37:58

    Move BAL spec-switch and BAL attachment to the branch processor The block cache prewarmer decides whether to do BAL read-warming inside BranchProcessor.Process, before BlockProcessor.ProcessOne runs. The BAL recorder previously attached the replayed BAL and flipped the EIP-7928 spec switch inside ProcessOne, so the prewarmer never saw either. Split the interception: a new BalRecordingBranchProcessor decorates IBranchProcessor and applies BAL attachment and the spec switch before delegating, so the prewarmer sees both. BalRecordingBlockProcessor keeps only recording, which belongs at ProcessOne where it runs for every processed block without a read-only gate. Co-Authored-By: Claude Opus 4.7

    by asdacap

    Increase block MGas/s histogram bucket count from 30 to 35 Co-Authored-By: Claude Opus 4.7

    by asdacap

    Address review feedback - Assert ForceConstructGeneratedBlockAccessList is set in BalRecordingBlockProcessor tests - Hoist loop-invariant store reads out of ShouldFlip Co-Authored-By: Claude Opus 4.7

    by asdacap

    perf(db): account native rocksdb memory via GC.AddMemoryPressure

    asdacap merged to NethermindEth/nethermind at 2026-05-25 01:28:52

    perf(db): account native rocksdb memory via GC.AddMemoryPressure Tell the GC about native allocations RocksDB makes so its heap heuristics reflect actual process memory: - HyperClockCacheWrapper: add/remove pressure for the cache capacity on construct/release. - DbOnTheRocks: per instance, account for one full write buffer plus the per-DB block cache size when the DB is not using the shared cache (configured value, else the rocksdb 32MB default). Shared-cache DBs contribute no extra pressure since the shared wrapper already accounts for it. Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    fix(db): address PR review on memory pressure accounting - HyperClockCacheWrapper: skip add/remove when the native handle is invalid so SafeHandle's contract (no ReleaseHandle on invalid) stays balanced. - DbOnTheRocks: don't double-count cache when dbConfig.BlockCache is provided (the wrapper that owns it already reports pressure). Document that rocksdb defaults to a 32MB block cache when none is specified in the options string. - DbOnTheRocks: accumulate write-buffer + own-cache pressure inside BuildOptions so ColumnsDb (one BuildOptions call per column family) reports the sum across all columns instead of only the last. Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    fix(db): drop noisy comments per review Co-Authored-By: Claude Opus 4.7 (1M context)

    by asdacap

    fix: 🇵🇱 polish BAL error story

    pepyakin merged to paradigmxyz/reth at 2026-05-25 15:06:10

    fix: polish BAL error story In this changeset we go over different error paths with the goal of properly classifying them. This is important for not aborting the whole node in case an invalid block was received.

    by pepyakin

    chore(bench): raise significance floors

    mediocregopher merged to paradigmxyz/reth at 2026-05-25 14:09:50

    chore(bench): raise significance floors

    by invalid-email-address

    perf(network): use FbBuildHasher for transaction manager maps

    i-m-aditya merged to paradigmxyz/reth at 2026-05-25 14:01:08

    perf(net): use FbBuildHasher for transaction manager maps

    by i-m-aditya

    adding with_hasher api

    by i-m-aditya

    refactor(network): add lru with_hasher constructors

    by mattsse

    fix(network): make lru hasher constructors const

    by mattsse

    feat: support disabling pipeline stages

    klkvr merged to paradigmxyz/reth at 2026-05-25 13:50:07

    feat: support disabling pipeline stages

    by klkvr

    fix(stages): fix off-by-one bug

    cuiweixie merged to paradigmxyz/reth at 2026-05-25 12:48:37

    fix(stages): fix off-by-one bug

    by cuiweixie

    Merge branch 'main' into off-by-one

    by mattsse

    fix: recompute hashed state on state root task failures

    klkvr merged to paradigmxyz/reth at 2026-05-25 12:47:49

    fix: recompute hashed state on state root task failures

    by klkvr

    fix validate span

    by klkvr

    feat(trie): add open-ended ordered root builder

    mattsse merged to paradigmxyz/reth at 2026-05-25 12:14:12

    feat(trie): add open-ended ordered root builder

    by mattsse

    chore(trie): update lockfile

    by mattsse

    fix(rpc): preserve legacy block rlp serialization

    mattsse merged to paradigmxyz/reth at 2026-05-25 12:00:31

    fix(rpc): preserve legacy block rlp serialization

    by mattsse

    ci: suppress mixed bench on-win Slack notifications

    decofe merged to paradigmxyz/reth at 2026-05-25 11:53:31

    ci: suppress mixed bench on-win slack notifications

    by decofe

    perf: fast-path forward cursor seeks

    tempoxyz-bot merged to paradigmxyz/reth at 2026-05-25 11:49:54

    perf: fast-path forward cursor seeks Avoid re-searching when an in-memory cursor is already positioned at the requested key and scan small remaining slices by index. This reduces repeated Nibbles comparisons in trie overlay walks. Amp-Thread-ID: https://ampcode.com/threads/T-019e5116-a8d7-73db-ad4b-597c21398249 Co-authored-by: Amp

    by None

    fix(rpc): guard eth_simulateV1 with blocking IO semaphore

    mattsse merged to paradigmxyz/reth at 2026-05-25 11:42:10

    fix(rpc): guard eth_simulateV1 with blocking IO semaphore

    by mattsse

    perf: reserve proof branch rlp nodes

    tempoxyz-bot merged to paradigmxyz/reth at 2026-05-25 11:19:02

    perf: reserve proof branch rlp nodes Reserve the recycled proof-v2 RLP node buffer before draining branch children and reuse the computed child count for the debug assertion. This avoids growth checks and a repeated mask popcount in the proof worker branch-pop path. Amp-Thread-ID: https://ampcode.com/threads/T-019e5403-29b2-74dc-8494-e5e08861d661 Co-authored-by: Amp

    by None

    feat(evm): add WithTxEnv constructor

    mattsse merged to paradigmxyz/reth at 2026-05-25 10:32:09

    feat(evm): add WithTxEnv constructor

    by mattsse

    fix(consensus): validate Amsterdam header fields

    mattsse merged to paradigmxyz/reth at 2026-05-25 10:09:39

    fix(consensus): validate Amsterdam header fields

    by mattsse

    fix(rpc): guard eth_callMany with blocking IO semaphore

    mattsse merged to paradigmxyz/reth at 2026-05-25 10:05:37

    fix(rpc): guard eth_callMany with blocking IO semaphore

    by mattsse

    fix: use tx_hash for transaction identity

    mattsse merged to paradigmxyz/reth at 2026-05-25 10:03:17

    fix: use tx_hash for transaction identity

    by mattsse

    fix: import tx hash trait in e2e test

    by mattsse

    fix: keep alloy eips for stages tests

    by mattsse

    perf(txpool): add best transaction size hints

    mattsse merged to paradigmxyz/reth at 2026-05-25 10:03:17

    perf(txpool): add best transaction size hints

    by mattsse

    feat(txpool): add retain_contains helper

    mattsse merged to paradigmxyz/reth at 2026-05-25 09:53:37

    feat(txpool): add retain_contains helper

    by mattsse

    test(txpool): remove retain_contains test

    by mattsse

    chore: use mainnet inplace of forks/osaka for hive

    Rimeeeeee merged to paradigmxyz/reth at 2026-05-25 07:05:20

    chore: use mainnet inplace of forks/osaka for hive

    by Rimeeeeee

    Merge branch 'main' into hive-osaka

    by Rimeeeeee

    perf(evm): preallocate chain transaction hashes

    mattsse merged to paradigmxyz/reth at 2026-05-25 07:05:00

    perf(evm): preallocate chain transaction hashes

    by mattsse

    docs(engine): fix is_opstack comment

    RidaMichofi merged to paradigmxyz/reth at 2026-05-25 06:54:53

    docs(engine): fix is_opstack comment

    by RidaMichofi

    refactor(evm): add chain transaction hash iterator

    mattsse merged to paradigmxyz/reth at 2026-05-25 06:54:33

    refactor(evm): add chain transaction hash iterator

    by mattsse

    Don't mutate live head state in getLatePayloadAttribute

    terencechain merged to prysmaticlabs/prysm at 2026-05-25 23:46:20

    Don't mutate live head state in getLatePayloadAttribute Route through ProcessSlotsIfNeeded so the read-only head state is never cast to a writable BeaconState and advanced in place. Refactor ProcessSlotsIfNeeded to do at most one Copy(): cache hit reuses the already-private copy returned by NextSlotState; cache miss copies st once.

    by terencechain

    >= is better

    by terencechain

    Merge branch 'develop' into gloas-late-payload-no-head-mutation

    by terencechain

    Fix UpdateHead doc: caller must NOT hold forkchoice lock

    terencechain merged to prysmaticlabs/prysm at 2026-05-25 23:37:57

    blockchain: correct UpdateHead lock-ordering doc The previous comment claimed callers must hold the forkchoice lock, but the function acquires it internally — a caller that followed the doc would deadlock on the non-reentrant RWMutex.

    by terencechain

    beacon-chain/execution: remove double metrics Observe in getBlobsV3

    fjl merged to prysmaticlabs/prysm at 2026-05-25 21:26:07

    beacon-chain/execution: remove double metrics Observe in getBlobsV3 The engine_getBlobsV3 implementation records two measurements into the metrics histogram. The first measurement will always be zero, which can cause issues in later stages of metrics processing.

    by fjl

    Add macro to simplify `into_full_block` implementations

    macladson merged to sigp/lighthouse at 2026-05-25 01:29:34

    Add macro to shrink full block boilerplate

    by macladson

    Merge branch 'unstable' into full-block-macro

    by macladson

    Add support for jemalloc memory profiling

    macladson merged to sigp/lighthouse at 2026-05-25 01:21:27

    Add support for jemalloc-profiling

    by macladson

    Ensure we can serve blocks and columns after `head` event is emitted

    eserilev merged to sigp/lighthouse at 2026-05-25 05:09:38

    Add a fallback mechanism to serve blcoks and columns from the early attester cache if they havent been written to disk yet

    by eserilev

    comments

    by eserilev

    Add regression test

    by michaelsproul

    Fix test for different forks

    by michaelsproul

    Check more in test

    by michaelsproul

    Fix non-canonical payload attestation processing

    michaelsproul merged to sigp/lighthouse at 2026-05-25 05:06:27

    Fix non-canonical payload attestation processing

    by michaelsproul

    Restore whimsy

    by michaelsproul

    Add basic test for fork boundary case

    by michaelsproul

    Handle Gloas fork boundary epoch

    by michaelsproul

    Rename func for clarity

    by michaelsproul

    Check that PTCs exist when inserting into the cache

    by dapplion

    Improve error handling

    by michaelsproul

    Merge remote-tracking branch 'origin/unstable' into payload-attestation-committee-cache

    by michaelsproul

    Update cache size comment

    by michaelsproul

    Remove outdated Pending/Full comment

    by michaelsproul

    Update comment

    by michaelsproul

    Merge remote-tracking branch 'sigp/unstable' into payload-attestation-committee-cache # Conflicts: # beacon_node/beacon_chain/src/payload_attestation_verification/tests.rs

    by dapplion

    Clean up shuffling cache leftovers from PR #9305 - Remove unused `BeaconChainError::MissingPtcForGloasShuffling` variant (no producers remained after the earlier cleanup). - Drop the `Result<(), BeaconChainError>` return type from `ShufflingCache::insert_committee_cache`; both match arms are infallible. Update callers in `beacon_chain.rs`, `state_advance_timer.rs`, `shuffling_cache.rs` and the unit tests accordingly. - Trim stale "Replace the committee if it's not present" comment in `insert_committee_cache`; the Committee arm is now a no-op so only the `Promise(_) | None` whimsy line remains.

    by dapplion

    Centralise Gloas boundary skip in CachedPTCs::try_from_state CachedPTCs::try_from_state now returns Result, _> and internalises the boundary rule (pre-Gloas state, Gloas shuffling epoch => Ok(None)). Callers (block import priming, state advance timer, with_cached_shuffling miss path) just skip insertion on None instead of duplicating the guard. The unit test exercises the three boundary cases against a pre-Gloas state.

    by dapplion

    Merge remote-tracking branch 'origin/unstable' into payload-attestation-committee-cache

    by michaelsproul

    Deprecate some `reorg`-related CLI flags and read from spec

    chong-he merged to sigp/lighthouse at 2026-05-25 02:11:27

    delete reorg parent and head cli

    by chong-he

    test

    by chong-he

    delete reorg max cli flag

    by chong-he

    simplify test

    by chong-he

    update cli help text

    by chong-he

    update book

    by chong-he

    test lint

    by chong-he

    fix http reorg test

    by chong-he

    fix error

    by chong-he

    fix ef-test

    by chong-he

    put default

    by chong-he

    revise

    by chong-he

    revise

    by chong-he

    remove reorg cutoff

    by chong-he

    Merge branch 'unstable' into cli-flags-reconcile

    by chong-he

    remove mut

    by chong-he

    cli

    by chong-he

    cli fmt and book

    by chong-he

    revise

    by chong-he

    fix test

    by chong-he

    revise

    by chong-he

    cfg debug

    by chong-he

    test

    by chong-he

    fmt

    by chong-he

    add some asserts

    by chong-he

    simplify

    by chong-he

    reduce diff

    by chong-he

    add warning log for deprecated flags

    by chong-he

    combine test

    by chong-he

    Merge branch 'unstable' into cli-flags-reconcile

    by chong-he

    fmt

    by chong-he

    Enable partial data columns by default on Hoodi and Sepolia

    dknopik merged to sigp/lighthouse at 2026-05-25 01:44:43

    enable partials for non-mainnet

    by dknopik

    Gloas dont enforce peer column custody on block import

    eserilev merged to sigp/lighthouse at 2026-05-25 00:21:17

    Post gloas we cannot enforce that peers who have imported a block also have columns available

    by eserilev

    cleanup

    by eserilev

    Merge branch 'unstable' of https://github.com/sigp/lighthouse into gloas-dont-enforce-peer-column-custody-on-block-import

    by eserilev

    Add `parent_block_root` to bid filtering key

    etan-status merged to status-im/nimbus-eth2 at 2026-05-25 21:21:57

    Add `parent_block_root` to bid filtering key The gossip rule was changed from: > [IGNORE] This bid is the highest value bid seen for the corresponding > slot and the given parent block hash to: > [IGNORE] this bid is the highest value bid seen for the tuple > (bid.slot, bid.parent_block_hash, bid.parent_block_root)`. - https://github.com/ethereum/consensus-specs/pull/5001 This way, someone can't just abuse a reorg to bid a large amount on a non-canonical branch to purge the canonical bid. Catch up with spec. Further, clean up the `parentExecHash != bid.parent_block_hash` check which is not from spec and rejected bids building on the timeline where the parent block's payload was withheld, by tracking the bids in the pool separately based on timeline.

    by etan-status

    extend getBlobs in gloas

    agnxsh merged to status-im/nimbus-eth2 at 2026-05-25 16:59:06

    extend getBlobs in gloas

    by agnxsh

    reviews

    by agnxsh

    more reviews

    by agnxsh

    Merge branch 'unstable' into eg

    by agnxsh

    reviews + getBlobsV3 gloas support

    by agnxsh

    Merge branch 'unstable' into eg

    by agnxsh

    rm unused peer_pool functions

    tersec merged to status-im/nimbus-eth2 at 2026-05-25 12:25:05

    rm unused peer_pool functions

    by tersec

    • PYTHNETWORK immunefi-logoRewards Smart Contract
      <$2,500 <$10,000 <$50,000 <$250,000
      Websites and Applications
      $1,000 $2,500 <$20,000 <$50,000

    docs: update ORE Solana push feed account

    dl-bot-integrations merged to pyth-network/pyth-crosschain at 2026-05-25 15:50:35

    docs: update ore solana push feed account

    by dl-bot-integrations

    lazer/sui: Update V2 API

    matej-douro merged to pyth-network/pyth-crosschain at 2026-05-25 12:37:40

    lazer/sui: add `pyth_lazer::channel_v2`, deprecate `pyth_lazer::channel`

    by matej-douro

    lazer/sui: add `pyth_lazer::update_v2`, deprecate `pyth_lazer::update`

    by matej-douro

    lazer/sui: update tests, fix warnings

    by matej-douro

    lazer/sui: test 1000ms channel, check v1 behavior

    by matej-douro

    lazer/sui: update SDK and docs with V2 API

    by matej-douro

    lazer/sui/sdk: bump version

    by matej-douro

    • AUDIT-COMP-CELO immunefi-logoRewards Smart Contract
      $0 Portion of the Reward Pool Portion of the Reward Pool Portion of the Reward Pool

    Restore CeloSuperchainConfig scripts & tests

    Mc01 merged to celo-org/optimism at 2026-05-25 12:08:53

    Upgrade celo superchain config in v5. Restores the deploy-side scaffolding for CeloSuperchainConfig (CSC) lost during the v2.0.0 rebase. Pure plumbing — no changes to OPContractsManager or its upgrade flow. CSC management remains a v4.1 one-time concern; v5's OPCM keeps its existing two-arg upgrade(OpChainConfig[], bool) signature unchanged. - DeployImplementations.s.sol: + ICeloSuperchainConfig import + Output.celoSuperchainConfigImpl field + deployCeloSuperchainConfigImpl() helper (createDeterministic) + run() now invokes deployCeloSuperchainConfigImpl + assertValidOutput includes the new impl in its address-array check - ChainAssertions.sol: dioToContractSet maps celoSuperchainConfigImpl - Deploy.s.sol: _proxies() ContractSet entry sourced from artifact - DeployOPChain.s.sol: _assertValidDeploy ContractSet entry (address(0)) - Types.sol: ContractSet gets address CeloSuperchainConfig - op-deployer Go DeployImplementationsOutput: CeloSuperchainConfigImpl field Note: IOPContractsManager.Implementations struct is INTENTIONALLY unchanged. The OPCM-level CSC upgrade was a one-time v4.1 migration helper and does NOT belong on v5's recurring OPCM upgrade path.

    by Mc01

    Port celo superchain config deployment. Restores the in-memory deploy path that was present at tag celo-contracts.L1/v1.8.0--1 but lost during the v2.0.0 rebase. Adapts the v1.8 helpers to v5 APIs (artifacts.mustGetAddress, superchainProxyAdmin.upgradeAndCall, _proxies()) without touching OPContractsManager. Deploy.s.sol - setupCeloSuperchainConfig(): deploys ERC1967 proxy under SuperchainProxyAdmin and invokes initializeCeloSuperchainConfig - initializeCeloSuperchainConfig(): upgrades + initializes the CSC proxy with guardian + external SuperchainConfig reference, then runs ChainAssertions - _run(): calls setupCeloSuperchainConfig between deployImplementations and deployOpChain so ContractSet resolution works - deployImplementations: artifacts.save('CeloSuperchainConfigImpl', ...) ChainAssertions.sol - checkCeloSuperchainConfig(): validates guardian, paused flag, and the superchainConfig() pointer on the initialized CSC proxy (CHECK-CSC-{10..40}) test/setup/Setup.sol - ICeloSuperchainConfig celoSuperchainConfig state var + artifact resolution - vm.label for the proxy to improve test traces

    by Mc01

    Restore celo superchain config tests. Ports packages/contracts-bedrock/test/L1/CeloSuperchainConfig.t.sol as it existed at tag celo-contracts.L1/v1.8.0--1. Was dropped during the v2.0.0 fresh-rebase along with the rest of the CSC scaffolding and never restored across v3.0.0, v4.1.0, or v5.0.0. Drift required for v5 (minimal): - Import paths rebased from src/{L1,universal}/interfaces/ to interfaces/{L1,universal}/ per v5 layout. - Upstream SuperchainConfig API changed: pause(string) -> pause(address), unpause() -> unpause(address). Celo-side CSC keeps original signatures. Replaced the 3 upstream-facing calls with pause/unpause(address(0)). - Event-name collision: upstream SuperchainConfig Paused(address)/Unpaused(address) events (brought in via CommonTest -> Events.sol) shadow CSC's Paused(string)/Unpaused() interface events. Added a local CeloSuperchainConfigEvents helper contract declaring CSC's signatures so vm.expectEmit matches correctly. Suite: 15 tests pass, 0 fail, 1 skipped (superchainGuardian variant).

    by Mc01

    Provide external SuperchainConfig in deploy config. Forward-port of celo-org/optimism#352 (commit 12ee7116fc) onto v5.0.0. Allows CeloSuperchainConfig to wrap an externally-provided SuperchainConfig (e.g. the upstream Optimism Superchain Registry's SC for Celo Mainnet) instead of always deploying a fresh local one. DeployConfig.s.sol - new `address public externalSuperchainConfig` field, read from JSON key `externalSuperchainConfig` (defaults to address(0)) - new `setExternalSuperchainConfig` setter for test-time overrides Deploy.s.sol - new `runCelo(address payable _protocolVersionsProxy)` entrypoint: deploys a fresh OP Stack wrapping cfg.externalSuperchainConfig() as the SuperchainConfig (Mainnet flow). ProtocolVersions is passed in as a parameter, mirroring runWithSuperchain. - new `run(bool _needsSuperchain)` testing entrypoint - _run else-branch: when _needsSuperchain=false AND no SuperchainConfigProxy artifact has been pre-populated, fall back to cfg.externalSuperchainConfig() test/setup/Setup.sol - `bool needsSuperchain = true` flag toggled via withoutSuperchain() - deploy.run is now invoked as deploy.run(needsSuperchain) - new virtual hook `applyCfgOverrides()` runs AFTER deploy is etched but BEFORE deploy.run, so subclasses can push cfg fields the deploy reads test/setup/CommonTest.sol - new `enableExternalSuperchainConfig(address)` helper mirrors enableInterop / enableCustomGasToken - applyCfgOverrides override pushes externalSuperchainConfig into cfg BEFORE the deploy script reads it test/setup/ExternalSuperchainConfig.t.sol (new file) - verifies the JSON read-or-default path defaults to address(0) - verifies setExternalSuperchainConfig overrides the cfg field - end-to-end deploy flow remains exercised by integration deployments using runCelo() Note: the v1.8 baseline also added an ExternalSuperchainConfig field to op-chain-ops/genesis/config.go. On v5 op-deployer no longer drives Celo deploys via that Go config — DeployConfig.s.sol reads the JSON directly via stdJson — so the Go field is unnecessary. Tests: 163 pass, 0 fail (CSC 15, OPCM 24, Container 3, StandardValidator 108, DeployImpl 11, ExternalSuperchainConfig 2).

    by Mc01

    Add CeloSuperchainConfig snapshots. Restores the ABI + storage-layout snapshots and semver-lock entry that were present at tag celo-contracts.L1/v1.8.0--1 but lost during the v2.0.0 rebase. - snapshots/abi/CeloSuperchainConfig.json (regenerated) Captures the v5 CSC ABI including the forward-compat `paused(address)` overload that was added on top of the v1.8 baseline. - snapshots/storageLayout/CeloSuperchainConfig.json (regenerated) Slot map for the OpenZeppelin Initializable parent. CSC's own state lives in unstructured slots (keccak256-derived) and is therefore correctly invisible to forge inspect — matching the v1.8 layout. - snapshots/semver-lock.json Adds the new `src/celo/CeloSuperchainConfig.sol:CeloSuperchainConfig` entry. Other entries that drifted during `just snapshots-no-build` (OPCM, SystemConfig, etc.) are NOT included here — those are pre-existing snapshot drift on the v5 base, unrelated to this hot-fix, and belong in a separate housekeeping PR. Files were generated via `just snapshots-no-build` against the v5 build of src/celo/CeloSuperchainConfig.sol (version 1.0.0-celo). Auxiliary Celo-specific contract snapshots that the same command would have generated (CeloRegistry, FeeCurrency, GoldToken, etc.) are also left out of this commit for the same reason — they are pre-existing un-snapshotted contracts, not CSC scope.

    by Mc01

    Add CELO.md. Documents the L1-side deltas between Celo's fork and upstream OP at v5.0.0 (dual-guardian, SystemConfig indirection, external SuperchainConfig, OPCM upgrade exclusion, CGT, L2 fee currency). The v1.8.0 Celo.README.md was lost during the v2.0.0 rebase; this rewrites it for v5's architecture instead of porting verbatim. File renamed to CELO.md to match the all-caps top-level README convention.

    by Mc01

    Fix fork-mode tests for CeloSuperchainConfig. Fork-mode runs revealed two issues: ForkLive.s.sol — the previous unconditional 'save SystemConfig.superchainConfig() as CeloSuperchainConfigProxy' wrongly seeded the upstream SuperchainConfig address on non-Celo forks (e.g. OP Mainnet). Tests would then call CSC methods on what's actually upstream's SuperchainConfig and revert. Now probe with SUPERCHAIN_CONFIG_SLOT() — a method only CSC exposes — and only seed the artifact when the probe succeeds. CeloSuperchainConfig.t.sol — the unit suite assumes a Celo deploy environment and can't run against a non-Celo fork (no CSC exists there). Add skipIfForkTest in the shared setUp; same pattern SuperchainConfig.t.sol uses. Tested against: - Mainnet fork (https://mainnet.gateway.tenderly.co/...) — CSC suite skipped cleanly; the 7 remaining failures (6 OPContractsManager_Upgrade, 1 OptimismPortal2 UnexpectedRootClaim) are pre-existing on op-deployer/v5.0.0 base, unrelated to this PR. - Sepolia fork — pre-existing UnsupportedChainId() in ForkLive (only Mainnet is supported for upgrade tests). Unrelated to this PR. - Non-fork: 163 tests still pass across CSC + OPCM + StandardValidator + DeployImpl + ExternalSuperchainConfig suites.

    by Mc01

    Cleanup.

    by Mc01

    CR.

    by Mc01

    fix: seed SuperchainProxyAdmin in runWithSuperchain before calling _run(false) Agent-Logs-Url: https://github.com/celo-org/optimism/sessions/20c78b56-6021-47db-9877-48a766e410b4 Co-authored-by: Mc01 <2324400+Mc01@users.noreply.github.com>

    by Copilot

    Test deployment with external SuperchainConfig to Mainnet and Sepolia.

    by Mc01

    Cleanup.

    by Mc01

    Add snapshots & extend tests.

    by Mc01

    CR.

    by Mc01

    • GEAR immunefi-logoRewards Blockchain DLT
      $1,000 $2,000 $10,000 $25,000

    fix(gear/lazy-pages): forward faults outside managed regions

    grishasobol merged to gear-tech/gear at 2026-05-25 19:05:47

    fix(lazy-pages): chain to previous SIGSEGV handler for faults outside managed regions The process-wide SIGSEGV handler installed by `gear_lazy_pages::init` panicked when a fault was raised on a thread that never entered a lazy-pages WASM execution. For such a thread `user_signal_handler` returns `Error::GlobalContext(ContextError::RuntimeContextIsNotSet)`, which `handle_sigsegv` did not forward — it hit the `_ => false` arm and `panic!`ed. Panicking is not async-signal-safe, so this aborted otherwise-healthy validator nodes whenever an unrelated SIGSEGV was raised (observed on ethexe testnet validators: RocksDB arena allocation on RPC threads). - `handle_sigsegv`: forward `Error::GlobalContext(_)` to the previously installed handler, alongside the existing out-of-WASM-memory cases. A context error means the thread is not inside a lazy-pages execution, so the fault cannot be a lazy-pages page fault. - `old_sig_handler`: when no chainable previous handler exists (`SigDfl`/`SigIgn`, or nothing captured at install time), restore the default disposition and report success instead of returning `false` (which made the caller `panic!`). The re-executed faulting instruction is then terminated by the kernel's default action. Adds a regression test that installs the handler and raises a SIGSEGV on a thread without a runtime context, asserting the process is not aborted by a handler panic. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(lazy-pages): forward GlobalContext faults in the Windows handler The Windows vectored exception handler had the same defect as the unix one: a fault from a thread with no lazy-pages runtime context yields `Error::GlobalContext(ContextError::RuntimeContextIsNotSet)`, which was not in the forward list, so the handler `panic!`ed instead of returning `EXCEPTION_CONTINUE_SEARCH`. Add `Error::GlobalContext(_)` so such faults are handed back to the OS exception chain. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    Merge branch 'master' into gsobol/protocol/fix-uninit-lazy-page

    by grishasobol

    fix(gear/lazy-pages): classify faults before non-async-signal-safe work (#5497)

    by grishasobol

    Merge branch 'master' into gsobol/protocol/fix-uninit-lazy-page

    by grishasobol

    fix(lazy-pages): drop pre-classification logging in the Windows handler `exception_handler` logged via `log::trace!` for non-access-violation exceptions before classifying the fault — a non-async-signal-safe call on the early-skip path, inconsistent with classify-first. Drop it. Also refresh `tests/sigsegv_handler.rs`: its module doc and an inline comment described the original error-forwarding fix; reword them for the address-classification design and rename the test to match. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(lazy-pages): address review notes on fault classification - old_sig_handler returns () instead of an always-true bool - document why ACTIVE_WASM_REGION is not synced at the GasLimitExceeded whole-buffer unprotect - note the static-linking assumption behind the TLS read's async-signal-safety Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    Merge branch 'master' into gsobol/protocol/fix-uninit-lazy-page

    by grishasobol

    Apply suggestion from @ark0f Co-authored-by: Arsenii Lyashenko

    by grishasobol

    docs(lazy-pages): reword Windows VEH handler note to match Microsoft's contract ark0f correctly pointed out that "async-signal-safe" is a POSIX concept that has no analogue in the Windows vectored-exception-handler model. Replace the unix-flavoured wording with the Windows constraint set the `PVECTORED_EXCEPTION_HANDLER` remarks actually impose (no process-heap allocation, no SEH re-entry, no logging that may take a lock the interrupted thread already holds).

    by grishasobol

    chore(typos): allow SEH (Windows Structured Exception Handling) `SEH` is a Windows kernel term used in protocol/lazy-pages/src/sys/windows.rs to reference the structured-exception dispatcher. The typos action was flagging it as a misspelling of `SHE`.

    by grishasobol

    Merge branch 'master' into gsobol/protocol/fix-uninit-lazy-page

    by grishasobol

    feat!(ethexe): malachite

    grishasobol merged to gear-tech/gear at 2026-05-25 16:59:28

    initial

    by grishasobol

    +_+_+ correcting

    by grishasobol

    feat(ethexe): add CompactPromise primitives and DB storage (task #1 foundation) Restores the foundational types from commit 4138374dd: - ReplyInfo::to_hash() in gear-core - PromiseEmissionMode in ethexe-common primitives - CompactPromise / SignedCompactPromise + helpers in ethexe-common - Mock impls for Promise - InjectedStorage{RO,RW} extended with promise/compact_promise getters and setters - Database/RawDatabase impls for the new storage methods This is the foundation that downstream pieces (processor BoundPromiseSink, compute PromisePolicy wiring, modular RPC injected API, gossipsub compact-promise topic) build on. The marker comments for those follow-ups remain. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe): rename DB types to MB/EB terminology Apply +_+_+ rename markers across Rust + Solidity sources: - `AnnouncesCommitted{,Event}` → `MBCommitted{,Event}` (Rust struct, enum variant, Solidity event) - `LastAdvancedEthBlockCommitted{,Event}` → `EBCommitted{,Event}` (Rust struct, enum variant, Solidity event) - `ANNOUNCES_COMMITTED` → `MB_COMMITTED`, `LAST_ADVANCED_ETH_BLOCK_COMMITTED` → `EB_COMMITTED` (constants) - `announces_committed` → `mb_committed`, `last_advanced_eth_block_committed` → `eb_committed` (methods) - `last_committed_advanced_eth_block` → `last_committed_eb` (field in BlockMeta / PreparedBlockData) - `last_advanced_block` → `last_advanced_eb` (field in MbMeta) - `latest_synced_block` → `latest_synced_eb`, `latest_prepared_block_hash` → `latest_prepared_eb_hash` (DBGlobals) - `CompactBlock` → `CompactMB` (struct) - camelCase counterparts in Solidity Forge build regenerated ABI JSON for Router/Mirror/Middleware/POAMiddleware/WrappedVara. `ensure_types_unchanged` hash bumped to reflect the type-name changes (SCALE encoding unchanged). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-common): rename mb.rs to malachite.rs The module owns Malachite-sequencer application types (`Transaction`, `Transactions`, etc.) so `malachite` is the more accurate name. Updates all import paths and the `ensure_types_unchanged` hash for the new module path. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-consensus): rename wait_for_eth_block to idle The validator state more accurately is the "idle" state (waiting for chain head, then sync, then prepare before electing a role). Renames: - module `wait_for_eth_block` → `idle` - struct `WaitForEthBlock` → `Idle` - display tag `WAIT_FOR_ETH_BLOCK` → `IDLE` Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe-node-loader): remove ping_rate_load binary The rate-stepping promise-latency experiment runner lives on a separate branch now; drop it from the main branch. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-db): restore migrations framework (no migrations yet) Add a `Migration` trait and `migrate()` driver that walks ascending schema versions in `migrations()`. The vector is empty for now — the old v1/v2/... entries had no live consumers and were removed earlier. Wire `migrate()` into `initialize_db()` so an on-disk version below `LATEST_VERSION` runs the framework instead of bailing. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-network): implement ProgramIds db-sync on MB program states The handler now reads `mb_program_states(at)` and returns the set of `ActorId`s present there, instead of warning and returning an empty response. Added `MbStorageRO` to the `DbSyncDatabase` trait so the network layer can reach the MB stores. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-service): remove unused network db_sync fetcher The MB-driven path has no active consumers of db_sync responses: every incoming response was being logged-and-dropped, and every failure was just re-issued forever. Drop the `network_fetcher` future, the `Event::Fetching` variant, and their imports. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-service): reorder tests in mod.rs to match master Renumbers the test list to mirror master's ordering for tests common to both branches; new MB-specific tests (`multiple_validators_ping`, `reorg_within_quarantine`, `reorg_deeper_than_quarantine`) slot in where their thematic neighbors live. Also drop the now-stale `Event::Fetching` variant from the `TestingEvent` mirror — it was already gone from the runtime enum. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-malachite): connect nodes also start the Malachite engine `MalachiteService::new` now takes `Option`: - `Some(pk)` → `NodeRole::Validator`, validator key extracted from the signer. - `None` → `NodeRole::FullNode`, ephemeral secret used only as the libp2p peer identity. The service's call site no longer skips Malachite when no validator key is configured, so connect/full nodes also join the gossip mesh and receive proposals + sync responses. Test harness call sites updated to pass `Some(pub_key)`. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-malachite): persist injected tx inside the mempool Move `db.set_injected_transaction(tx)` into `InjectedTxMempool::insert` so the network and RPC handlers don't have to remember to do it themselves. The two service-side call sites lose the duplicated persistence calls. Persistence happens before pool insertion so a producer that picks the tx on the very next round is guaranteed to find it via `injected_getTransactions`. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-cli): wire computation_check to walk MB chain `ethexe check --computation` now walks `latest_finalized_mb_hash` back through `CompactMB.parent` and asserts that every MB has its cached `mb_program_states` / `mb_outcome` / `mb_schedule` records plus `MbMeta { computed: true }`. Re-execution through the processor (asserting cached records match fresh execution) is intentionally left out — it requires loading every code blob and reconstructing the runtime, which the CLI doesn't have the context for. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-db): split state-dump collection into MB and Eth-block entry points Add `StateDump::collect_from_mb_storage(storage, mb_hash, block_hash)` as the malachite-native entry point — state lives per-MB, so callers that already know which MB to dump shouldn't have to round-trip through `BlockMeta::last_committed_mb`. The existing `collect_from_storage(block_hash)` becomes a thin wrapper that derives the MB and forwards. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-service tests): drop manual force-mine select loops `WaitForUploadCode`, `WaitForProgramCreation`, and `WaitForReplyTo` each had an inline `select! { sleep => evm_mine, … = wait => break }` loop that duplicated the `KickingStream::find_map` kick mechanism. Each `wait_for` now hands the `(provider, block_time*3)` kick to the receiver via `set_kicks` before consuming it with `filter_map_block_synced`; the resulting `KickingStream` triggers `evm_mine` on idle automatically. `KickExt` retains its `EventReceiver` impl so `WaitFor*` can mutate kicks pre-conversion. Replaced the marker on `extend_malachite_endpoints` with a TODO note — pulling endpoint setup forward into `TestEnv::new` needs a wider tests refactor and is left for a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-rpc): split injected API into modular submodules Promotes `apis/injected.rs` to `apis/injected/` and splits it into: - `mod.rs` — module entry, public re-exports - `trait.rs` — JSON-RPC trait definition (`Injected`) - `promise_manager.rs` — `PromiseSubscriptionManager` owns the `tx_hash → oneshot::Sender` map plus `try_register_subscriber`, `cancel_registration`, and `dispatch_promise` - `relay.rs` — `TransactionsRelayer` does the per-validator fan-out and the single-recipient fallback when the era's validator vector isn't known yet - `spawner.rs` — `spawn_pending_subscriber` bridges a registered subscriber to a jsonrpsee subscription sink with timeout / cleanup - `server.rs` — `InjectedApi` orchestrates all of the above Adds the `injected_getTransactionPromise` method that reads `db.promise(tx_hash)` and `db.compact_promise(tx_hash)` and reconstructs the `SignedPromise` via `SignedCompactPromise::restore`. This is the user-facing payoff of the CompactPromise primitives added in the foundation commit. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-processor): introduce BoundPromiseSink Replaces every `Option>` field / parameter in the processor with `Option`. The sink wraps an `UnboundedSender<(H256, Promise)>` and pre-binds each send to the MB hash the executor is currently working on, so worker threads no longer have to thread the binding through manually. Ripples: - `host::threads::ThreadParams.promise_out_tx` → `promise_sink` - `clear_promise_out_tx` → `clear_promise_sink` - `CommonRunContext.promise_out_tx` → `promise_sink` - compute's per-MB channel now carries `(H256, Promise)`; the `MbPromisesStream` reads the hash from each message instead of storing it in a field - compute constructs `BoundPromiseSink::new(sender, target_hash)` for the target MB and passes `None` for predecessor MBs (unchanged semantics) - processor unit tests upgrade their channel to `(H256, Promise)` and wrap senders in `BoundPromiseSink::new(_, H256::zero())` Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-compute): wire PromisePolicy / PromiseEmissionMode through compute_mb Closes the remaining `+_+_+` marker on `MbComputeRequest`: - `MbComputeRequest` gains a `promise_policy: PromisePolicy` field - `ComputeSubService::receive_mb(mb_hash, policy)` records it - `compute()` constructs a `BoundPromiseSink` for the target MB only when `policy == Enabled`, preserving the rule that ancestor MBs always replay with promises disabled - `ComputeService` carries a `PromiseEmissionMode` (default `ConsensusDriven`) and offers `with_promise_mode(...)`. In `AlwaysEmit` it overrides the per-call policy to `Enabled` - service-side `compute_mb` call passes `PromisePolicy::Enabled` for `MalachiteEvent::BlockProposal` (consensus may still narrow it via the emission mode) Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    style(ethexe): apply rustfmt + fix clippy warnings - `cargo fmt --all` across all touched files (line-wrap reorganisation only). - `Migration::from_version` → `source_version` (clippy: `wrong_self_convention`). - ProgramIds db-sync handler uses `BTreeMap::into_keys()` instead of `into_iter().map(|(k, _)| k)` (clippy: `iter_kv_map`). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-db): restore migration.rs and version-anchored MIGRATIONS Splits the migrations module back into the historical shape: - `migration.rs` — `Migration` trait (now `Sync` so the slice can be `&'static`). `migrate(&InitConfig, &RawDatabase)` returns a pinned boxed future so `&dyn Migration` is dyn-compatible. - `v5.rs` — schema-version anchor. Holds `pub const VERSION: u32 = 5;` and nothing else. Future schema bumps add `v6.rs`, `v7.rs`, … each with their own `VERSION` and (where applicable) a `migration_from_v(N-1)` function. - `mod.rs` — re-introduces the user-requested constants: pub const OLDEST_SUPPORTED_VERSION: u32 = v5::VERSION; pub const LATEST_VERSION: u32 = v5::VERSION; pub const MIGRATIONS: &[&dyn Migration] = &[]; const _: () = assert!( (LATEST_VERSION - OLDEST_SUPPORTED_VERSION) as usize == MIGRATIONS.len(), "Wrong number of migrations available" ); The const-assert guarantees every step in the supported version range has a corresponding migration entry — adding a new schema version without a migration step (or vice versa) now fails to compile. Both anchor constants point at `v5::VERSION` for now; splits into distinct OLDEST/LATEST anchors when the next migration lands. - `init.rs` — `migrate(&config, &db).await` (was `migrate(&db)`). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-service tests): drop KickExt impl for EventReceiver `EventReceiver` no longer carries a `kicks: Option<…>` field nor implements `KickExt`. Kicks live exclusively on the `KickingStream` wrapper, and `TestingEventReceiver` / `ObserverEventReceiver` are now type aliases for `KickingStream>`. Side effects: - `channel(db, kicks)` returns `(EventSender, KickingStream>)`. - `KickingStream` gains `Debug + Clone` derives (the inner `EventReceiver` is `Debug + Clone`) and forwards `FusedStream` from its inner stream. - `TestingEventReceiver::find_map_with_db` and `ObserverEventReceiver:: filter_map_*` switch from `self.db`/`self.kicks` field access to `self.db()`/`self.take_kicks()` helpers on the wrapper. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-service tests): replace WaitFor*::hack with with_kicks builder `WaitForUploadCode`, `WaitForProgramCreation`, and `WaitForReplyTo` no longer carry an `Option<(RootProvider, Duration)> hack` field — the receiver itself is now a `KickingStream`, so the kick lives there. Each waiter gains a public `fn with_kicks(self, kicks: Option<(Duration, RootProvider)>) -> Self` builder that forwards into `receiver.set_kicks` / `clear_kicks`. `force_mine_hack` is renamed to `default_wait_kicks` and produces the `(block_time * 3, provider)` tuple in the shape the kick consumes directly — no more in-call `* 3` math inside `wait_for`. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    docs(ok.md): log 200 black-box tests run across ethexe crates 200 corner-case / hack tests exercised the public APIs of `ethexe-malachite-core`, `ethexe-malachite`, `ethexe-consensus`, and `ethexe-service`. Every iteration ran a fresh test; passing tests are listed here so future iterations don't repeat coverage. All 200 passed; no test code remains in the working tree. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore: stop tracking ok.md (kept locally) The black-box test log lives alongside the working tree; no need to ship it through git. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-cli): processor-based computation_check via compute helper `ethexe check --computation` now re-executes every persisted MB through a fresh `Processor` and asserts the cached `mb_program_states` / `mb_outcome` / `mb_schedule` match the fresh run — instead of just asserting the cached records exist. To avoid duplicating the live-pipeline's parent-state lookup, expose `ethexe_compute::prepare_executable_for_mb(db, mb_hash)`. It resolves the parent MB's program states / schedule / `last_advanced_eb`, reads the MB's `Transactions` blob, and assembles the same `ExecutableData` the `compute_mb` sub-service feeds to the processor. The CLI runs it over `processor.clone().overlaid()` so re-execution writes don't touch on-disk state. Adds `--chunk-size` (default 2) for the verification `Processor`. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-service): wire PromiseEmissionMode based on RPC presence Restores the wiring from #5377: when this node carries an RPC server, force `ComputeService` into `PromiseEmissionMode::AlwaysEmit` so the RPC subscribers see promises regardless of the per-MB consensus decision. Pure validator/peer nodes stay on the default `ConsensusDriven` and let the consensus layer pick the policy per MB. Without this, an RPC node running alongside a non-emitting validator role would drop replies on the floor. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-compute): forward PromiseEmissionMode into ComputeSubService The service-level wiring (`ComputeService::with_promise_mode`) translated the per-MB policy for the *target* but the SubService still silenced every walked predecessor unconditionally. An RPC node catching up in `AlwaysEmit` therefore missed the replies for every ancestor MB it had to re-execute. - `ComputeSubService` gains a `promise_emission_mode` field plus a `with_promise_mode(db, processor, mode)` constructor; `new` keeps defaulting to `ConsensusDriven` - `ComputeService::with_promise_mode` forwards the mode through - `compute()` builds a `BoundPromiseSink` per predecessor when the mode is `AlwaysEmit`; under `ConsensusDriven` predecessors stay silent as before (their promises were already gossiped) The target MB still follows `req.promise_policy` (already translated to `Enabled` for `AlwaysEmit` at the service layer), so the behaviour of pure-validator nodes is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor!(workspace): add global separation of syscall kind (#5401)

    by StackOverflowExcept1on

    ci(cache): Enable multi-level caching for sccache (#5418)

    by ark0f

    feat(ethexe-rpc, network, service): restore compact promise pipeline Producer-signed compact promise (hash+signature) now travels over gossip, while every node persists the locally computed Promise body and the RPC subscription manager joins the two halves into a full SignedPromise via SignedCompactPromise::restore. This brings back the master-era split delivery so injected_getTransactionPromise can again serve persisted promises and gossip carries the compact signature instead of the full reply body. - ethexe-rpc: PromiseSubscriptionManager regains waiting_for_compute buffer, on_compact_promise / on_computed_promise; dispatch_promise is private; InjectedApi derefs into the manager and metric decrement moves into the spawner finalize callback. - RpcService exposes receive_compact_promise / receive_computed_promise in place of provide_promise / provide_promises. - ethexe-network: Message::Promise, NetworkEvent::PromiseMessage and publish_promise now carry SignedCompactPromise; ValidatorTopic verify_promise mirrors the new payload type. - ethexe-service: ComputeEvent::Promise feeds the body into RPC, then (for validators) signs a compact form locally, hands it to RPC, and gossips it via the network. NetworkEvent::PromiseMessage delivers the compact form to RPC for body-join. - Tests: four new unit tests in promise_manager covering body-first, compact-first, duplicate subscriber, and mismatched signature. Existing cleanup/concurrent tests adapted to feed Promise + compact pairs. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-db): port MB iterator + verifier walk back from master Restores the post-execution sweep over per-MB rows that `ethexe check --integrity-check` lost during the announce→MB refactor. The walk now descends from each block's `BlockMeta.last_committed_mb` into the matching CompactMB, its MbMeta, and — for computed MBs — into the program states, schedule (with per-height tasks) and outcome rows, mirroring the master Announce-side layout one-to-one. - iterator.rs: new MbNode / MbMetaNode / MbProgramStatesNode / MbScheduleNode / MbScheduleTasksNode / MbOutcomeNode placed in the same positions where master had the Announce-side equivalents. iter_block_meta pushes the MB anchor; iter_mb pushes MbMeta and (if computed) mb_schedule / mb_outcome / mb_program_states. The four iter_mb_* helpers mirror the master iter_announce_* siblings. - verifier.rs: visit_mb_schedule_tasks rejects schedules whose bucket height is already reached by the MB, returning MbScheduleHasExpiredTasks { mb_hash, expiry, tasks }; MbNotFound surfaces when the schedule references an unknown MB. - visitor.rs: extra imports so the `for_each_node!` macro can name the new node field types. - Tests: walk_mb_program_states / walk_mb_schedule_tasks / walk_mb_schedule / walk_mb_outcome ported from walk_announce_*, plus test_mb_schedule_has_expired_tasks_error ported from test_block_schedule_has_expired_tasks_error. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-compute): hard-error instead of unwrap_or on missing parent MB rows CLAUDE.md hard rule: outside tests, an Option/Result whose None branch is supposedly impossible must not silently fall through. Compute violated this in prepare_executable_with_parent_state and build_executable_data by papering over missing parent_mb rows, block_events for advance-chain blocks, and the anchor block header with `.unwrap_or_default()` / `.unwrap_or((0, 0))` / `.unwrap_or(...)`. That fallback path is consensus-poisonous: an MB cannot be computed before all of its ancestors are computed, so missing parent_mb_states or parent_mb_schedule is DB inconsistency, not "empty world". The silent fall-through executes the MB against an empty ProgramStates + empty Schedule + height 0 / timestamp 0 — a deterministically wrong state hash that still hashes and gossips, i.e. a possible nondeter- minism / fork. - New ComputeError variants: ParentMbStatesMissing, ParentMbScheduleMissing, AdvanceBlockEventsMissing, AnchorBlockHeaderMissing. - prepare_executable_with_parent_state branches on the Option once and returns the explicit errors when any of the three parent rows are missing; documents the invariant inline. - AdvanceTillEthereumBlock walk surfaces missing block_events. - Synthetic anchor header lookup surfaces missing block_header. - collect_uncomputed_predecessors propagates MbBlockNotFound instead of swallowing the lookup with H256::zero(). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-compute): restore mb_processing_latency histogram Per-MB execution wall-clock was the only Prometheus histogram in `ethexe_compute_compute`; it was lost during the refactor. Restore it under the MB-era name so dashboards can surface validator execution slowness again. - ethexe/compute/Cargo.toml: re-add future-timing workspace dep. - compute.rs: Metrics struct with `mb_processing_latency` Histogram, ComputationFuture wraps `BoxFuture` in `future_timing::Timed`, poll_next records `(busy + idle).as_secs_f64()` on completion. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-db): restore assert_migration_types_hash helper A migration runs against a (possibly old) on-disk schema, so every SCALE type it touches must stay byte-stable across the codebase. Once the next migration ships, this helper lets the test pin the type registry hash so a stray rename/field-order change blows up loudly instead of silently corrupting upgrades. The helper itself is master-verbatim; only the dev-deps (indoc, sha3) and the surrounding doc-comment are wired up so it's ready for the first post-v5 migration. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-cli): honor node_params.chunk_processing_threads in `ethexe check` Previously the node-side `chunk-processing-threads` parsed from the shared NodeParams was discarded (`let _node_params = ...`), so `ethexe check` always ran with `--chunk-size` (default 2) — diverging from the operator's `ethexe run` configuration. Now the node param takes precedence; `--chunk-size` stays as an explicit override. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe-ethereum): add EBCommittedEventBuilder + RouterEvents::eb_committed Symmetric with MBCommittedEventBuilder/mb_committed — the EBCommitted event signature was already registered and decoded via try_extract_event, but downstream code had no filtered subscription helper. ~20 lines of boilerplate next to the MB variant. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-service): forward eip1559_max_fee_per_gas_in_gwei to EthereumBuilder The CLI / config field has always been parsed and stored in `config.ethereum`, but the validator-side EthereumBuilder dropped the `.eip1559_max_fee_per_gas_in_gwei(...)` call during the refactor. Operators that set a fee cap (the common production override against gas-price spikes) silently lost protection — restore the builder call to match master. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-service): fast_sync stub now bails instead of silently no-op `--fast-sync` and `fast_sync = true` are still wired through CLI / config, but the implementation is a stub since the MB-driven recovery path hasn't been ported yet. A `warn!() + Ok(())` lets operators boot the node thinking sync is active while it silently does nothing. Replace with a hard `bail!()` so the misconfiguration surfaces at startup; restoring fast-sync is tracked separately (TODO +_+_+). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    docs(ethexe): TODO +_+_+ markers + process_programs doc fix (17) `DEFAULT_COORDINATOR_AGGREGATION_DELAY_MS` is 0 but the docstring above used to claim ~1.5s; smoke tests still wire 1500. Tag with TODO +_+_+ so we revisit and pick a final value. (20) Processor docs referenced a non-existent `Processor::process_transitions`. The real entry point is `process_programs`; update the rustdoc table, the consumer list, the inline comment in ComputeSubService::poll_next, and the crate-level doc in ethexe-compute. (21) Add TODO +_+_+ near the consensus utilities pointing back at the removed `block_touched_programs` helper — it's likely needed for MB validation; track restoring it (or pointing at the ethexe-malachite equivalent) as a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe): restore era proptest, add commitment_delay_limit test, mark relay TODO (9) restore proptest_message_era_is_checked_against_snapshot_era in network/validator/topic.rs: - EraRelation::{TooOld, Old, Current, Next, TooNew} + strategy, - 64-case proptest covering Accept / Cache / Ignore / Reject against random snapshot eras, - payload swapped from Announce to BatchCommitmentValidationRequest to match the post-refactor message envelope. (6) add create_batch_commitment_writes_commitment_delay_limit_into_expiry unit test in consensus/validator/batch/utils.rs. Sweeps [1, 3, 5, 32, 255] and asserts BatchCommitment.expiry == limit so the operator-configured delay is preserved end-to-end through the batch builder. (catch_up integration tests intentionally left out per scope.) (11) Cannot restore master's relay unit tests verbatim because the underlying `calculate_next_producer` was deleted in favor of `current_validators` + `fan_out`. Left a TODO +_+_+ in rpc/apis/injected/relay.rs documenting the three concrete unit tests the new strategy still lacks (`test_fan_out_uses_all_validators_in_era`, `_falls_back_to_send_single_when_validators_empty`, `_returns_last_reject_when_no_accept`). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    Merge branch 'master' into gsobol/ethexe/malachite-new

    by grishasobol

    chore(ethexe): revert trivial moves and cosmetic-only diffs to match master Five parallel passes over the changed-file set audited every hunk between origin/master and HEAD and reverted the ones that carried no semantic meaning — pure position shifts, comment/doc rewordings, parameter renames, log-message wording, ordering of `use` blocks and re-exports, and a few one-liner restorations that branch had silently dropped. The intentional refactor (Announce→MB renames, Mb* post-execution storage, compact promise pipeline, MB integrity walk, malachite plumbing, etc.) is left untouched. Highlights: - ethexe/common/src/mock.rs: `reservation_id_strategy`, `impl Arbitrary for {MessageType, StateHashWithQueueSize}` moved back to their master positions (and bodies aligned). - ethexe/observer/src/sync.rs: `log::trace!("✅ block ... synced, events: ...")` line restored. - ethexe/db/src/database.rs: `promise`/`compact_promise` parameter names + trace messages + return shape back to master form. - ethexe/processor/src/{lib,host/mod,handling/run/mod}.rs: three master-side step comments inside `process_programs` restored, comment rewordings reverted; ethexe/processor/src/tests.rs: shared `BoundPromiseSink` reverted to master's single-construction-per-test shape (cuts ~70 lines of churn). - ethexe/rpc/{src/apis/mod.rs,src/apis/injected/{server,spawner,trait,mod}.rs, Cargo.toml}: six files now 0-diff vs master; promise_manager.rs and relay.rs reduced to year-only copyright + intentional changes. - ethexe/network/src/{lib,validator/topic,db_sync/{mod,responses}}.rs: `compact_promise` parameter renames, `Promise(compact_promise)` match-arm body, doc rewraps, and `InnerProgramIdsResponse::new` helper dropped in favor of tuple-struct constructor. - ethexe/consensus/src/{lib,utils,validator/{mod,coordinator,participant}}.rs: copyright years and module/function rustdoc rewordings reverted. - ethexe/service/{Cargo.toml,src/lib.rs,src/tests/mod.rs}: restored the missing `demo-mul-by-const` dev-dep, log/comment wording, the master ordering of `let rpc = config.rpc.clone().map(...)`, and the in-test step comments inside `uninitialized_program` / `validators_election` / `injected_tx_fungible_token{,_over_network}`. Result vs origin/master: - 143 → 136 changed files (seven files now byte-identical). - ~522 fewer diff lines (16701+/13587- vs prior 16934+/13876-). All 287 ethexe unit tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe): second pass — revert remaining trivial moves and noise hunks Tighter second sweep over the file-set the first pass missed. Five focused agents walked each file hunk-by-hunk and reverted everything that carried no semantic meaning while leaving the intentional refactor (Announce→MB renames, malachite plumbing, ParentMb* errors, EBCommitted builder, etc.) untouched. Highlights: - ethexe/common/src/injected.rs: full revert to master modulo the single "per announce" → "per MB" rename. The `serde_hex` module is back to its master position (it had migrated past the test block with no body change); `SignedCompactPromise` struct moved back below `CompactPromise` per master ordering; `Safety by implementation` comment, `[SignedPromise]` backticks, `signature().clone()` → `*…` and `private_key.clone()` patches all rolled back. injected.rs diff went 149 → 13 lines. - ethexe/common/src/db.rs: removed stray blank lines inside `DBGlobals` (no other revert possible — `ensure_types_unchanged` hash bakes in doc-comment captures, so doc-only reverts on `#[derive(TypeInfo)]` types force a hash mismatch). - ethexe/common/src/primitives.rs: reverted three cosmetic doc tweaks inside `PromiseEmissionMode` (`[…]` backticks, period punctuation), kept the MB-specific rewording. - ethexe/consensus: lib.rs, validator/{mod,coordinator,participant}.rs — reverted doc/trait-method rewordings, dropped unused `pub use` exports, dropped `pub` field visibility added on `CommitmentSubmitted`, collapsed the new "coordinator: …" / "participant: …" trace log noise (no behavior change), restored master's tight match-arm formatting in coordinator submission path. Consensus diff trimmed by ≈114 lines. - ethexe/processor: lib.rs / promise.rs / tests.rs — reverted module and struct doc rewordings on `BoundPromiseSink`, master step-comments in `process_programs` table, stray blank lines inside `ExecutableData { height: …, timestamp: … }` literals. - ethexe/service/src/tests/mod.rs: `RecordingCommitter` restored as a top-level item (it was inlined into a single test); `use futures:: StreamExt;` re-imported; `uninitialized_program` returns to master's chained-stream form; `injected_tx_fungible_token` cleaned of two alias `use`s and the `RouterEvent::BatchCommitted` no-op stub, four dropped `tracing::info!("✅ …")` lines restored, explanatory comments put back. - ethexe/service/src/tests/utils/env.rs: three more chained-vs-split reverts on the `WaitFor*::wait_for` helpers and the `let rpc = …` binding. Result vs origin/master: - 16701+/13587- → 16508+/13434- (≈346 fewer diff lines this pass). - Cumulative since the prior `chore: revert trivial moves` commit: ≈869 diff lines pruned from the branch's diff against master. All 261 ethexe unit tests across the touched crates (common, consensus, processor, ethereum, db, rpc[+client], network, compute) still pass; `cargo check -p ethexe-service --tests` compiles cleanly. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactoring and tasks

    by grishasobol

    fix(ethexe-service): route MB compute to non-proposers so injected promises reach RPC `injected_tx_fungible_token_over_network` consistently timed out: Alice (RPC, non-validator) subscribed via `injected_sendTransactionAndWatch`, the RPC fan-out delivered the mint TX to Bob (validator), Bob's Malachite committed it and Bob's compute emitted the `Promise` body, but Alice never received the body — only the `SignedCompactPromise` arrives over the network — so her RPC subscription manager could never reconstruct a `SignedPromise` and the 20s spawner timeout fired. Two gaps were hiding behind this: 1. `MalachiteEvent::BlockFinalized` was a log-only handler. Only the proposer's `BlockProposal` path triggered `compute_mb`, so non-proposer validators and every full/RPC node had no mechanism to compute the MB locally and emit the promise body. The compact pipeline assumes all nodes have the body — without local compute that assumption breaks. Now `BlockFinalized` also calls `compute_mb(block_hash, PromisePolicy::Enabled)`; calls are idempotent (`mb_meta.computed` short-circuit) so the proposer doesn't re-execute the same MB. 2. The test harness `env.rs` only started Malachite for validator nodes (the guard predated the b9506af03 production change that lets full nodes join the mesh as `NodeRole::FullNode`). Without Malachite, a full node like Alice never receives `BlockFinalized` at all and #1 is moot for tests. `start_service` now always boots Malachite: validators reuse the pre-allocated endpoint from `malachite_endpoints`; full nodes bind a fresh 127.0.0.1:0 listener and use all active validators as `persistent_peers` (`MalachiteService::new` is passed `None` as the validator pub key, so the engine starts in `NodeRole::FullNode`). `malachite_home` is now allocated for every node (full nodes need a WAL dir too); the `malachite_listener` reservation stays validator-only since `malachite_endpoints` doesn't know about full-node addresses. Verified: - `tests::injected_tx_fungible_token_over_network` passes in 21s (was 60s timeout). - `tests::invalid_code`, `tests::uninitialized_program` keep passing individually. - `cargo nextest run -p 'ethexe-*'` outside the service crate stays green (259 tests in common/consensus/compute/processor/ethereum/ db/rpc/network). - `cargo fmt --check`, `cargo clippy -p ethexe-service --all-targets -- -D warnings` clean. The parallel-execution failures the user noted in `invalid_code` / `uninitialized_program` are a pre-existing nextest resource-contention issue (the same 12 tests time out in parallel both with and without this change; sequentially or with `-j 4` everything except the unrelated `smoke::constructor` and `reorg_within_quarantine` passes). Those remain to address separately. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): treat anvil/geth "unknown block" as a transient reorg; let smoke constructor build twice Two tests on this branch failed deterministically before this change: 1. `tests::reorg_within_quarantine` (and `reorg_deeper_than_quarantine`): the test takes an `anvil_snapshot`, mines past it, then `anvil_revert`s to the snapshot. Between revert and the new fork's first block the `subscribe_blocks` stream still has the now-orphaned heads queued; when `ChainSync::sync` walks `load_chain` for one of them, the provider returns JSON-RPC `-32000 "unknown block"`. The error bubbled up through `observer.select_next_some()` and crashed the service main loop ("Service finished work with error: failed to get logs"). This is a normal reorg, not a fatal condition. Fix: - `ethexe-observer::utils`: classify `RpcError::ErrorResp` whose payload message contains "unknown block" into a typed `BlockReorgedError { hash }` (uses `thiserror`). - `ChainSync::sync` downcasts the error from `sync_inner`; on `BlockReorgedError` it logs a warning and returns the previously synced tip (`db.globals().latest_synced_eb.hash`) instead of erroring out. The next canonical chain head from the alloy header subscription drives the next sync attempt. - Other `get_logs` failure modes (transport down, real RPC errors) keep their previous behaviour — only the structured "unknown block" response is downgraded. 2. `smoke::constructor`: `Service::new` started failing because the branch's strict `build_malachite_validator_set` requires every on-chain validator address to map to a Malachite public key in `config.malachite.validator_pub_keys`. The smoke test was passing `Default::default()` (empty map) while the Hoodi router lists a real validator set. Then the second `Service::new` failed on the same RocksDB path because the first service's Malachite engine keeps a background app task that holds the DB handle — drop alone doesn't release it. Fix in `ethexe/service/tests/smoke.rs`: - Resolve the live validator set via `RouterQuery::validators()` and synthesize fresh Malachite pub keys for each address. The keys are never used (service is built then dropped), so any populated map satisfies the constructor. - The second `Service::new` (with optional services enabled) re-uses the same in-memory config except for the database path: it switches to `tmp_dir.join("db2")` so it doesn't fight the first instance's still-draining Malachite engine. Verified locally with `-j 4` (Ubuntu host OOMed under default parallelism earlier — keep the lower bound for the full suite): - `ethexe-service` — 26/26 pass (including `tests::reorg_within_quarantine`, `tests::reorg_deeper_than_quarantine`, `smoke::constructor`, `tests::injected_tx_fungible_token_over_network` from the previous commit). - Other ethexe crates — 368/368 pass across `ethexe-common`, `ethexe-consensus`, `ethexe-compute`, `ethexe-processor`, `ethexe-ethereum`, `ethexe-db`, `ethexe-rpc`, `ethexe-network`, `ethexe-blob-loader`, `ethexe-observer`, `ethexe-malachite`, `ethexe-malachite-core`, `ethexe-cli`, `ethexe-prometheus`, `ethexe-runtime-common`. - `cargo fmt --check` + `cargo clippy -- -D warnings` clean. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-observer): broaden BlockReorgedError classifier + pin the ensure_validators gap Follow-up to the three independent Opus reviews of c4584e469 / 098835b76. Addresses review items #1 (broaden the message-match set) and #2 (unit tests on the classifier), and pins review item #3 (`ensure_validators` reorg gap) with a deterministic failing-but- flipped regression guard before fixing it. What changed: 1. Widen `REORG_MARKERS` in `ethexe/observer/src/utils.rs` from the single anvil/geth phrase "unknown block" to the cross-client set seen in practice: - "unknown block" — anvil/geth `eth_getLogs` (code -32000) - "resource not found" — anvil/geth `eth_call` (code -32001, EIP-1474 standard for block-by-hash against an orphaned block) - "block not found" — reth, erigon, some nethermind paths - "header not found" — infura LB + some geth paths (already treated as retryable by alloy's `ErrorPayload::is_retry_err`) - "could not be found" — nethermind block-by-hash response - "missing trie node" — reth/geth state-pruned paths We deliberately don't gate on JSON-RPC code — even on a single anvil instance the same reorg condition uses -32000 from `eth_getLogs` and -32001 from `eth_call`. Codes diverge further between clients. `REORG_MARKERS` is now `pub(crate)` so the integration tests can walk the same set. 2. Unit-test the classifier (`utils::tests`). Four cases: - `classifier_recognises_known_reorg_wordings` — table of every wording above, asserts each one downcasts to `BlockReorgedError`. Add a new wording here when adding a new client. - `classifier_passes_non_reorg_errors_through` — rate limits, internal errors, bad params, large queries. None must be classified as a reorg, otherwise the service loses real RPC failures. - `classifier_ignores_transport_errors` — `RpcError`s without an `ErrorPayload` (e.g. `LocalUsageError`) must not be touched. - `reorg_error_carries_the_block_hash` — pins the `Display` / hash-carrying contract so log/metrics consumers don't break. 3. New integration test `validators_at_on_orphaned_block_is_unclassified_reorg` in `ethexe/observer/src/tests.rs` proves the review-#3 gap is real. The test: - spins anvil + deploys the router, - snapshots, mines one block, records its hash, - sanity-checks that `validators_at(latest)` succeeds, - `anvil_revert`s the snapshot — the recorded hash is now orphaned, - calls `router_query.validators_at(orphaned_hash)` and asserts BOTH that (a) the underlying RPC wording IS in `REORG_MARKERS` (so a classifier would detect it) AND (b) the returned `anyhow::Error` is NOT a `BlockReorgedError`, because nothing on the `eth_call` path is wired through the classifier today. Part (a) confirms the reorg signal is detectable. Part (b) confirms `ensure_validators` is still on the wrong side of the classifier wiring — Opus #3's claim is real and load-bearing. When the gap is closed, assertion (b) flips from `assert!(reorged.is_none())` to `assert!(reorged.is_some())` and this test becomes the regression guard. The discovery moment: running this test against the previous marker set failed assertion (a), not (b) — `eth_call` returns "Resource not found" rather than "unknown block", which is why the broadened marker set above is part of THIS commit rather than a separate one. Without the "Resource not found" entry the classifier would still mis-handle the `eth_call` path even after `ensure_validators` is wired through. 4. `ethexe/observer/Cargo.toml`: add the `json-rpc` alloy feature so `alloy::rpc::json_rpc::ErrorPayload` is constructible in tests. What did NOT change: the `ChainSync::sync` recovery wiring. Closing the `ensure_validators` gap is the next commit's job; this one only verifies the bug and locks in the classifier coverage that fix will rely on. Verified locally: - `cargo nextest run -p ethexe-observer` — 7/7 PASS (4 unit, 3 integration) on first run. - `cargo nextest run -p ethexe-service -E 'test(reorg_)'` — 2/2 PASS, confirms the broadened marker set is still backward- compatible with the existing reorg integration tests. - `cargo fmt --check` + `cargo clippy -- -D warnings` clean. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-observer): single SyncError classifier + Poll::Pending recovery Replaces the per-error `BlockReorgedError` + `REORG_MARKERS` + `classify_get_logs_error` machinery from 1541914aa with a single `SyncError` enum at the sync-layer boundary, classified by the type present in the anyhow source chain rather than by substring match of the Display string. Recovery moves up to `ObserverService::poll_next` which logs, increments a Prometheus counter, wakes itself, and returns `Poll::Pending` — the alloy header subscription delivers the next canonical chain head shortly. Closes Opus review #3 (the `ensure_validators` reorg gap) by construction: ANY future caller in the sync pipeline that talks to the Ethereum RPC inherits recovery for free, no per-callsite wiring needed. The previously-failing regression-guard test now passes. What changed structurally: 1. `ethexe/observer/src/sync.rs`: - New `pub enum SyncError { RpcError(anyhow::Error), Fatal(anyhow::Error) }` plus `pub type SyncResult`. - `From for SyncError` walks `err.chain()` looking for an `alloy::transports::RpcError` OR an `alloy::contract::Error::TransportError(_)`. The second branch is load-bearing: `thiserror`'s `#[error(transparent)]` + `#[from]` on `contract::Error::TransportError` forwards `source()` to the wrapped `TransportError`, so the inner `RpcError` is NOT a distinct item in `chain()`. We catch it by downcasting the outer `contract::Error` and matching on the variant. - `ChainSync::sync(self, chain_head) -> SyncResult` (was `anyhow::Result`). The `sync` / `sync_inner` split from the previous commit is gone — the wrapper isn't needed once errors auto-classify via `From`. - `ensure_validators` no longer needs callsite-specific wrapping; its `validators_at` / `make_election_at` errors flow into the same classifier via the `?` operator. - `pre_load_data`'s "Too much to sync" still surfaces as Fatal (it's our protocol invariant, not an RPC failure). 2. `ethexe/observer/src/utils.rs`: - Removed `BlockReorgedError`, `REORG_MARKERS`, `is_reorg_indication`, `classify_get_logs_error`, and all 4 unit tests that pinned the substring-match contract. They were a workaround for the lack of a type-level classifier, now obsolete. - `EthereumBlockLoader::load` swaps the per-error wrapping (`classify_get_logs_error(block, err)`) for the cheaper `anyhow::Error::from(err)`. Importantly this keeps the alloy `RpcError` reachable in the anyhow source chain so the classifier in `sync.rs` finds it. 3. `ethexe/observer/src/lib.rs`: - `pub use sync::SyncError` so callers / tests can match on it. - `SyncFuture` retypes from `BoxFuture<_, Result>` to `BoxFuture<_, SyncResult>`. - `poll_next` consumes the sync future result and matches: Ok(hash) => emit `BlockSynced(hash)`. Err(SyncError::RpcError) => log warn, bump counter, `cx.waker().wake_by_ref()` so queued headers are picked up immediately, return Pending. Err(SyncError::Fatal) => propagate `Err` to the service main loop as before. - The `cx.waker().wake_by_ref()` is intentional: without it, if `block_sync_queue` still has buffered headers from a burst, the runtime won't re-poll us until an external signal arrives. With the waker call we immediately start the next sync. 4. `ObserverMetrics`: - New `recoverable_sync_errors: Counter`. Operators can graph this to see if upstream RPC is unhealthy without parsing logs. 5. `ethexe/observer/src/tests.rs`: - Flipped `validators_at_on_orphaned_block_is_unclassified_reorg` into a positive regression guard `validators_at_on_orphaned_block_is_recoverable_rpc_error`. It drives `validators_at` on an `anvil_revert`'ed block and now asserts that `SyncError::from(err)` lands on `RpcError`, not `Fatal`. This test would have caught the bug if it had existed at the time of the original `BlockReorgedError`-only fix. 6. `ethexe/observer/Cargo.toml`: drop the `json-rpc` alloy feature (was only needed to construct fake `ErrorPayload`s in the unit tests we just deleted). Verified: - `cargo nextest run -p ethexe-observer` — 3/3 PASS. - `cargo nextest run -p ethexe-service -E 'test(reorg_)'` — 2/2 PASS (`tests::reorg_within_quarantine` + `tests::reorg_deeper_than_quarantine` still green, confirming the end-to-end recovery path works with the new wiring). - `cargo fmt --check`, `cargo clippy -p ethexe-observer --all-targets -- -D warnings`, and the same on `ethexe-service` — all clean. Net diff: 178 insertions, 257 deletions (-79 lines). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe-observer): trim oversized doc comments per CLAUDE.md Removes narrative/rationale prose from SyncError, sync(), poll_next RpcError arm, ObserverMetrics field, and the orphaned-block test. Keeps only one-liner WHY comments where the code is non-obvious (e.g. the contract::Error transparent-source workaround in the classifier). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-service): drop async+Result from new_from_parts The test-only constructor takes already-built sub-services and just stuffs them into a struct literal — no fallibility, no await points. Closes the '_+_+_: why async and Result added? remove them' marker. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    refactor(ethexe-compute): drop redundant height from MbComputed event The height was only used for a log field on the service side; mb_hash is enough — height can be looked up in DB if ever needed elsewhere. Collapsing to a single-field tuple variant also removes the `#[unwrap(ignore)]` workaround for `derive_more::Unwrap`. Closes the '_+_+_: the height here is redundant' marker. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-service): use TestEnv::default() in default-config tests Sweeps every `TestEnv::new(Default::default()).await.unwrap()` call site over to the simpler `TestEnv::default().await` helper. Closes the '_+_+_: use TestEnv::default() here and in other places' marker. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-service): drop redundant per-builder with_kicks calls Kicks are configured once at channel creation via env.kicking_per_blocks; the receiver returned by new_observer_events already carries them. The WaitFor*::with_kicks setters were re-applying the same value on every builder return. Also drop the now-unused with_kicks methods on WaitForUploadCode/WaitForProgramCreation/WaitForReplyTo, the KickExt::set_kicks/clear_kicks trait methods, and TestEnv::default_wait_kicks — none had any callers left. Closes the '_+_+_: remove here and in other places' marker. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    docs(ethexe-rpc): document TransactionsRelayer::fan_out Closes the '_+_+_: append doc' marker. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-network): drop unused _right_db, clarify why external_data_provider is ignored The marker '_+_+_: do this TODO, looks like ProgramIds already adapted for MB' turned out to be wrong: tracing through the test setup, `fill_data_provider` populates the REQUESTER's data provider, while the responder side has nothing to serve from — un-ignoring the test hangs the swarm on `Swarm did not emit an event within 10s`. The real fix is a responder-side fixture, which is a larger piece of test infrastructure work. Drop the unused `_right_db` parameter (the responder uses the `ExternalDataProvider` trait now, not direct DB access), keep the test ignored, and replace the marker + stale TODO with a clearer ignore reason. Also drops the same `_bob_db` in the network/lib.rs integration variant. Closes the '_+_+_: do this TODO' and '_+_+_ re-enable and adapt for MB' markers as 'investigated, follow-up needed'. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe): strip _+_+_ branch-internal task markers CLAUDE.md forbids in-source references to current task/PR; these markers were branch-internal notes (tests to re-add, types to introduce, follow-ups to track). They belong in the PR description / issue tracker. 18 markers removed across cli, common, compute, consensus, db, network, service. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe-service): strip branch-introduced emojis from log lines CLAUDE.md: 'Avoid writing emojis to files unless asked.' Pre-existing emojis (🌐 ⚙️ 📦 etc) are project convention and kept; the four branch-added Malachite-specific ones (🪨 🛠️ 🧱 ✅) are removed. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): hard-error on missing parent MB / finalized-block invariant violations CLAUDE.md rule: don't unwrap_or to paper over a None whose presence is supposed to be guaranteed by an invariant. Two production sites were silently mapping invariant violations to H256::zero(): - ethexe/consensus/src/validator/batch/utils.rs: collect_uncommitted_predecessors walks the parent chain from a known-computed MB; the parent must exist or the DB is corrupt. Replace unwrap_or with ok_or_else(anyhow!). - ethexe/malachite/core/src/app.rs: GetValue (proposer path) and assemble_and_validate (validator path) both ask the store for finalized_block_at(h-1) when working on height h. Malachite's strict-ordering guarantee makes h-1 always-finalized at that point; silently mis-pointing parent_hash here forks the chain. Replace with ok_or_else(anyhow!). The lenient walks in is_finalized_locally and collect_computed_uncommitted_predecessors are left as-is — the unwrap_or there does map None to a meaningful semantic value (walk terminator / 'nothing yet'). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): surface validator-set / mb_program_states absence instead of silently defaulting Two unwrap_or_default sites were masking real errors: - rpc/apis/injected/relay.rs::TransactionsRelayer::relay was using current_validators(...).unwrap_or_default() to fall through to the single-recipient path on any error from era_from_ts / validators lookup. Replace with explicit Match + warn so misconfigured timelines and missing era validators are visible in logs. - network/db_sync/responses.rs::ProgramIds handler was returning an empty actor-id set on a DB miss with no log line. Restore the warn (this was lost during the AnnounceProgramStates -> mb_program_states rename). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    test(ethexe-service): drop /* Original body */ comment blocks CLAUDE.md forbids '// removed'-style preserved old code in source — git history is the authoritative record. Three port-to-MB test bodies (fast_sync, re_genesis_with_state_dump, re_genesis_delayed_message) were kept inside /* ... */ blocks 'so the original assertions are visible to whoever ports them'. Drop the blocks; the test stubs (or removal for fast_sync) plus the existing #[ignore] reason already signal the intent. Anyone porting can read the pre-refactor commit. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    docs(ethexe): convert markdown tables in crate //! docs to bullet lists CLAUDE.md (project rule from this branch) bans tables in added text. Two crate-level docs used method/event tables; flatten to bullets. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe): trim wordy field docs and refactor-narration inline blocks CLAUDE.md tier ceilings: - private struct fields: at most a one-liner WHY - inline comments in fn bodies: 1 line Trims in service/lib.rs Service struct (consensus, validator_pub_key, shutdown_rx field docs), in Service::run_inner pre-select prelude, the OutboundAcceptance match arm, the malachite/canonical_quarantine note, the connect-node-skips-consensus comment, the RPC-promises mode hint, and the dead bail! left commented out near the foundry version check. Also collapses the residual sweep #2 hangover comments in observer (sync.rs classifier note, utils.rs load() rationale, lib.rs self-wake note). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-rpc): reject non-null `at` in calculate_reply_for_handle The post-MB refactor stubbed out the announce-level `at` parameter with `let _ = at;` plus a TODO comment, silently returning the latest-finalized snapshot regardless of what the caller asked for. Reject non-null `at` with bad_request so callers get a clear signal until the MB↔block index lands; null preserves current behaviour. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): surface mempool insert rejection through Accept/Reject Iter-1 review #1 (high): every inbound injected tx was returning Accept regardless of whether the mempool actually queued it. Mempool silently dropped on AlreadyCommitted / Duplicate / ExpiredRefBlock / PoolFull, so RPC clients couldn't distinguish "queued, will execute" from "silently discarded" — the promise subscription on Alice would hang for 20s on every duplicate-tx case. - New MempoolInsertError enum (thiserror) with four reject variants. - Mempool::insert and MalachiteService::receive_injected_transaction now return Result<(), MempoolInsertError>. - Both service-side handlers (network InboundTransaction + RPC InjectedTransaction) convert the result via the existing From> for InjectedTransactionAcceptance impl, so rejections surface as Reject{reason} instead of Accept. - ForgetTracker mempool stub in externalities tests + mempool unit tests updated for the new signature. 29/29 ethexe-malachite tests pass. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-observer): retry header subscription instead of crashing Iter-1 review #3 (medium): a transient WS hang-up during subscribe_blocks reconstruction would tear down the service — the same failure mode the SyncError classifier was designed to avoid for in-flight syncs. Mirror that recovery here: log a warn, increment the recoverable counter, schedule a fresh subscribe_blocks future, and return Poll::Pending. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-compute): dedup receive_mb to prevent MbComputed double-emit Iter-1 review #3 (medium): BlockProposal and BlockFinalized both queue compute_mb for the same head_mb_hash. The second request short-circuits inside compute() at the mb_meta.computed guard, but still emits MbComputed via the result map — duplicating the event. receive_mb now skips if the hash is already computed, currently in flight, or sitting in input. Track the in-flight head in a new field so the check covers all three states. Idempotent test contract changes from 'fires MbComputed once' to 'stream stays pending'. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-observer): exponential backoff on subscribe_blocks retry Iter-2 review A+B: the retry loop introduced by 3f10d3c1a had no backoff. A permanently-broken endpoint (bad URL, auth refused, DNS NXDOMAIN) would peg a CPU core and flood logs with 'header subscription failed'. Wrap each retry attempt in 'tokio::time::sleep(backoff) → subscribe' where backoff is 500ms * 2^attempt capped at 30s. Reset on success. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe-service): fan-out keeps every parked oneshot under tx_hash Iter-2 review A+B (high): network_injected_txs was a HashMap keyed by tx_hash. fan_out inserts N entries with the same tx_hash (one per recipient validator), so each insert clobbered the previous. The dropped Sender resolved as Err in the relay's FuturesUnordered, silently swallowed at the 'Err(_) => {}' arm — only the last-sent validator's response could surface. If validator B accepted and validator C (sent later) rejected, the relay returned the reject and the user never saw the accept. Switch to Vec: every fan-out leg parks under the same hash; OutboundAcceptance pops one per response. injected_tx tests pass (no regression). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): split latest_finalized_mb_hash into finalized + computed pointers Iter-2 review A#3: malachite's mark_block_as_finalized advanced globals.latest_finalized_mb_hash before compute persisted the MB's per-row state. RPC paths reading the new pointer then hit mb_program_states/mb_outcome = None and returned 'db error'. Right shape (per user direction): keep two distinct pointers in DBGlobals. - latest_finalized_mb_hash: BFT-finalized, written by malachite's mark_block_as_finalized as before (unchanged contract). - latest_computed_mb_hash: NEW. Written by the service's ComputeEvent::MbComputed handler — guaranteed that the per-row state for this hash is on disk. Trails latest_finalized_mb_hash until compute catches up. ethexe-rpc::utils::latest_finalized_mb now reads latest_computed_mb_hash so RPC callers never see a finalized-but- not-yet-computed pointer. The function name is kept for API stability; the doc comment explains the new semantic. Updates DBGlobals SCALE schema → bump EXPECTED_TYPE_INFO_HASH in ensure_types_unchanged; add the new field to every DBGlobals constructor (db init, mock Arbitrary, RawDatabase::memory bootstrap). 29/29 ethexe-malachite tests pass (restart_resilience uses the finalized pointer, unchanged). ethexe-service integration tests (invalid_code, ping, injected_tx, injected_tx_over_network) all green. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix(ethexe): align RPC pointer name, guard monotonicity, seed MB rows on re-genesis Iter-3 review consolidated three high/medium findings into one commit: - C-high: utils::latest_finalized_mb returned latest_computed_mb_hash and the error string said 'finalized'. Rename to latest_computed_mb + match error wording. Two call sites updated. - A-medium: MbComputed for an ancestor MB (catch-up replay) could retreat the RPC tip non-monotonically. Compare CompactMb.height before mutating; advance only if new_height >= prev_height. - A-high carry-over (R-C #2 from iter 2): re-genesis from StateDump bound the dump's program_states + schedule to '_' and never wrote the per-MB rows. After bootstrap a node served zero RPC reads until the first post-genesis MB landed. Now genesis_data_initialization returns mb_hash too; initialize_empty_db seeds set_mb_compact_block, set_mb_program_states, set_mb_schedule, set_mb_outcome, marks mb_meta.computed=true with last_advanced_eb=genesis, and points both latest_finalized_mb_hash AND latest_computed_mb_hash at the dump's mb_hash. Also drops the dead 'let (_, _) = (mb_hash, block_hash);' compile- warning shim around the genesis info log. 96/96 db+rpc+malachite unit tests pass; 4/4 service integration smoke tests (invalid_code, injected_tx, injected_tx_over_network, ping) pass. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    ethexe iter4: harden genesis MB seed, watch dedup, MbComputed monotonicity - db init: persist empty Transactions blob and reference it from genesis CompactMb.transactions_hash so post-init walkers (ethexe check, prepare_executable_for_mb) don't trip on a zero hash. - rpc injected watch: when the relayer reports a duplicate submission, keep the subscription open so the promise still reaches the caller. - service MbComputed: replace silent unwrap_or(0) on CompactMb height lookups with expect()s tied to the invariant that the row is written before the event fires; treat zero latest_computed_mb_hash as "no predecessor yet" instead of "height 0". Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    ethexe iter5: typed AlreadyPooled acceptance, observer stream-end backoff InjectedTransactionAcceptance now carries an `AlreadyPooled` variant that the mempool emits for both `AlreadyCommitted` and `Duplicate` — the promise will fire in both cases, so the watch path should retain the subscription. The brittle substring matcher on the `Reject` reason is gone, replaced by a typed `classify_insert_outcome` helper next to `MempoolInsertError`. A unit test pins each variant's classification so future error-string edits cannot silently regress the watch flow. The RPC fan-out now prefers `AlreadyPooled` over `Reject` when racing validator responses, so a duplicate-pooled reply from one validator is not buried by a transient failure from another. The observer's headers-stream-ended branch now goes through the same exponential-backoff path as a failed subscribe via a new `schedule_subscription_retry`. Previously an upstream that accepted the WS subscribe but immediately closed the stream could tight-loop with no sleep until the next subscribe call actually failed. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    Merge remote-tracking branch 'origin/master' into gsobol/ethexe/malachite-new # Conflicts: # Cargo.toml

    by grishasobol

    docs(CLAUDE.md): simplify added sections, drop the comment-sizing table Per the `_+_+_` instruction at the top of the new sections: trim the prose and replace the four-row table with a bullet list. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    ci: drop dead dep, fix rustdoc intra-doc links, refresh ABIs - ethexe-service: drop unused `demo-mul-by-const` dependency (cargo-shear error in `check / unused-deps`). - ethexe-observer: SyncError doc was linking the private fn `ChainSync::sync` — reword to avoid the broken-doc-link. - ethexe-compute: crate-level `//!` linked `Transaction::AdvanceTill...` and `ethexe_malachite::MalachiteService::...` which aren't in scope for rustdoc; switched both to non-link references. - ethexe/ethereum/abi/*: regenerate from `forge build` to match the current solc output (out-of-date since master merge). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    docs: fix remaining rustdoc broken-intra-doc-links - ethexe-consensus: crate-level `//!` linked `BatchCommitment`, which is not in scope at the doc site; switch to plain text. - ethexe-common::malachite: doc linked `ethexe_db` and `CompactMb` — neither is in scope here (the type is referenced via a path comment for context, not an actual link target). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    ci: empty commit to retry macos-aarch64 clippy runner The previous run failed with a rustup-init/cargo PATH mix-up on the macos-aarch64 runner — `cargo clippy` was invoked but the bootstrapper intercepted the args: error: unexpected argument 'clippy' found Usage: rustup-init[EXE] [OPTIONS] Code is unchanged; locally `cargo clippy --workspace --all-targets --all-features --locked` passes. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix uninitialized_program test

    by grishasobol

    test: reproduce bugs #1 (compute advance-chain) and #4 (filler checkpoint) Two failing tests pinning issues surfaced in the PR review: 1. `compute::tests::collect_advance_chain_errors_on_missing_intermediate_header` — `collect_advance_chain` currently `break`s and returns a truncated `Ok(...)` when an intermediate `block_header` is missing. Validators with different sync completeness would then emit different advance chains for the same MB. Test expects `AdvanceMissingHeader`. 2. `validator::batch::filler::tests::include_chain_commitment_keeps_checkpoint_with_no_transitions` — `include_chain_commitment` early-returns on empty `transitions`, silently dropping checkpoint commitments produced by `try_include_checkpoint_chain_commitment` (which intentionally builds empty-transitions commitments with a non-zero `last_advanced_eth_block` to push the on-chain Ethereum anchor). Test expects `has_chain_commitment()` to be true after include. Both tests fail on `master`; fixes will follow in a separate commit so the regressions are visibly tied to a test contract. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix: hard-error missing advance-chain header, keep checkpoint commitments #1 — `ethexe-compute::collect_advance_chain` no longer falls back to a silently truncated `Ok(...)` when an intermediate `block_header` is absent. The walk now returns `AdvanceMissingHeader` for the first hash without a header, so peers with different sync depth either both compute the full advance chain for an MB or both fail loud. #4 — `ethexe-consensus::BatchFiller::include_chain_commitment` only drops a commitment when both `transitions` is empty AND `last_advanced_eth_block` is zero. Checkpoint commitments produced by `try_include_checkpoint_chain_commitment` carry empty transitions together with a non-zero advanced anchor; the previous early-return silently dropped them and the on-chain Ethereum anchor never moved during quiet stretches. Pinning tests added in the previous commit now go green. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    fix quadratic time complexity

    by grishasobol

    simplify quarantine validation logic

    by grishasobol

    docs(ethexe): update example TOMLs for malachite + new node knobs The shipped `.ethexe.example*.toml` templates fell behind the params schema: a stale `chain-deepness-threshold` would have been rejected on first uncomment (deny_unknown_fields), and there was no template for the `[malachite]` section that validator nodes now require. Rename the stale entry to `uncommitted-chain-len-threshold`, document the three other knobs added since (`coordinator-aggregation-delay-ms`, `commitment-delay-limit`, `genesis-state-dump`), and ship a fully templated `[malachite]` block. Also add two `Params`-level parse tests that pin both example files against the live schema so future drift fails CI instead of the operator's first run. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    feat(ethexe): port TxValidityChecker + size/touched caps to MB world Adapts the announce-era tx pipeline from ethexe-consensus into the Malachite Block (MB) world and wires the full per-tx + per-MB shape gate into both producer (`build_block_above`) and validator (`validate_block_above`). Per-tx (TxValidityChecker) * 8 master variants (NonZeroValue, Outdated, NotOnCurrentBranch, Duplicate, UnknownDestination, UninitializedDestination, InsufficientBalanceForInjectedMessages, Valid). * Dedup walk now traverses `mb_compact_block(..).parent` and decodes each MB's `transactions` blob; `latest_states` is taken from the most recent `mb_meta.computed` ancestor via `mb_program_states`. Per-MB caps (#5, #6) * `MAX_INJECTED_TRANSACTIONS_SIZE_PER_MB = 127 KiB` in `ethexe-common` next to `MAX_INJECTED_TX_PAYLOAD_SIZE`. * `eb_touched_programs(db, last_advanced_eb, advanced_eb)` walks `(last_advanced_eb, advanced_eb]` oldest-first so a `ProgramCreatedEvent` populates `known` before any later `MirrorEvent` on the new actor. * Producer applies both caps after TxValidity filtering; an oversize tx is skipped but smaller subsequent ones still get a chance. * Validator re-checks #6 only (master parity) and rejects on first overflow. Mempool * `MempoolInsertError::NonZeroValue` rejects #5083-style value txs at insert so the pool never holds one a proposer could accidentally select. Tests * BlockChain mock extended (`mbs`, `MbFullData`, `MockComputedMbData`, `mb_at*` accessors) so chain setup auto-seeds a parallel MB chain. * All 8 `tx_validation::tests::*` ported into `tx_validity::tests::*` with the same scenarios. * 4 integration tests on `build/validate_block_above` ported from master's `tx_pool::tests::*` and `announces::tests::*` (`build_emits_valid_tx_and_drops_non_zero_value`, `build_caps_touched_programs`, `build_caps_total_encoded_size`, `validate_rejects_mb_with_too_many_touched_programs`). Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe): tx/MB validation audit follow-ups Address the points raised in the post-port audit: - tx_validity::eb_touched_programs walk: document why it's safe to leave the parent-walk unbounded — both `advanced_eb` and the parent's `last_advanced_eb` have already passed `canonical_quarantine` (weak finality on the Eth chain), so under any non-catastrophic reorg they share a branch and the walk terminates in a few EBs. - tx_validity::eb_touched_programs: explicit "best-effort approximation" note. The cap is the only consumer; false positives just tighten the cap, false negatives are absorbed by the per-MB cap slack at the runtime layer. - tx_validity::is_reference_block_within_validity_window: use `saturating_add` to avoid the (purely theoretical, ~30 years out) u32 height overflow. - externalities::validate_block_above: comment the three `?` paths (TxValidityChecker constructor / per-tx check / eb_touched_programs). Each fires only on a local DB invariant or sync race, never on malicious tx-data — propagating the error up is correct. - externalities::validate_block_above (4): note that the validator intentionally relies on Malachite's 1 MiB encoded-Block cap for the per-MB size budget (mirrors master parity). - mempool::insert: drop the inner mutex around the DB write so RPC inserts don't serialise behind disk I/O; re-acquire and re-run the dedup / capacity gates afterward to absorb concurrent inserts. - mempool::DEFAULT_POOL_CAPACITY: TODO +_+_+ — a single signer can still flood the pool to capacity. Per-sender quota is a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe-malachite-core): TODO + ignored regression tests for two DoS vectors Two memory-DoS findings surfaced by 3-agent cross-audit (≥2/3 votes each). Both pinned with regression tests and tracked under TODO +_+_+ in the production code path. 1. `PartStreamsMap` (streaming.rs:189) grows without bound. A single peer can either (a) open many `stream_id`s and never `Fin`, or (b) send one `Fin{sequence=u64::MAX/2}` so the `buffer.len() == total_messages` gate is never reachable. Slots live until process restart. Mitigation in deployment: `persistent_peers_only = true` in the Malachite P2pConfig + a validator-peer-id allowlist on `ReceivedProposalPart` entry. Real fix: per-peer slot cap + height/round-driven GC + bounded `seen_sequences`/`buffer`. Pinned by: `streaming::tests::part_streams_map_grows_unbounded_under_fin_sequence_attack`. 2. Future-height pending proposal-parts (app.rs:227-230) accumulate in RocksDB indefinitely. `prune_engine_state` only sweeps rows whose `height <= current_height`. A peer can flood with `value_id`-unique (content-addressed → trivial to vary) parts at arbitrary heights. Fix: height-window cap (refuse to persist beyond `current_height + N`) + per-peer rate limit. Pinned by: `store::tests::pending_proposal_parts_at_future_heights_persist_after_prune`. Both tests are `#[ignore]` until the corresponding fixes land — they assert the *intended* post-fix behaviour, so leaving them un-ignored would have blocked CI. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    simplify

    by grishasobol

    feat(ethexe-malachite): shape + ordering + gas_allowance checks in validate_block_above Adds 5 missing checks to the participant-side validation of an incoming MB: 1. `ProcessQueues.limits.gas_allowance <= DEFAULT_GAS_ALLOWANCE` — reject MBs that would force participants into an unbounded queue drain. 2. MB must contain exactly one `ProgressTasks` tx in the bookend position. 3. MB must contain exactly one `ProcessQueues` tx as the last tx. 4. `AdvanceTillEthereumBlock` (if present) must be the very first tx — otherwise EB events are not the first action of the MB and the compute pipeline runs queues against stale state. 5. Nothing follows `ProcessQueues` — protects against trailing malicious payloads. A single forward walk over the payload enforces all five at once: [AdvanceTillEthereumBlock]? Injected* ProgressTasks ProcessQueues The walk supersedes the previous standalone "more than one Advance" count — a second Advance now falls into the `Injected*` / `ProgressTasks` position and is rejected by shape. 5 regression tests added (one per missing check, all failed before the implementation landed and pass now). Three existing tests (`validate_rejects_two_advances`, `validate_abstains_without_chain_head`, `validate_accepts_quarantine_passed_advance`, plus the touched-programs integration test) updated to carry the full shape so they exercise their actual intended branch instead of being early-rejected. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    chore(ethexe-malachite): 10-iteration cross-audit — TODO+_+_+ for confirmed findings Ran 10 iterations of 3-opus-subagent cross-audit. Per-iteration ≥2/3 agreement threshold; cumulative 5 confirmed findings out of 68 raw. New TODO +_+_+ and regression tests added this round: Iter 2 (3/3): - `codec.rs` `From` silently aliases out-of-range rounds to `Round::Nil`. Reproduced by `codec::tests::raw_proposed_value_silently_aliases_invalid_round_to_nil` (ignored). Iter 2 (2/3): - `app.rs::StartedRound` removes pending parts before validate + propagates `?` on RocksDB error, stalling consensus on a single DB hiccup. TODO+_+_+ in code (test requires full engine fake). Iter 3 (2/3): - `externalities.rs::validate_block_above` quarantine-poll loop blocks the single-threaded app task for up to 2 s and never awaits `chain_head_notify`. TODO+_+_+ in code. Iter 5 (2/3): - `mempool.rs::purge_expired` retains pool entries whose `ref_block` is unresolved indefinitely (`None => true`), while `seen` retain is `_ => false`. Public RPC `injected_send` can permanently exhaust the pool via random ref_blocks. Reproduced by `mempool::tests::pool_retains_unresolved_ref_block_indefinitely` (ignored). Iter 8 (2/3): - `externalities.rs::validate_block_above` never enforces `is_strict_descendant_of(advance, parent.last_advanced_eb)` (producer does). A byzantine proposer can regress `mb_meta.last_advanced_eb` to an older EB; downstream `compute_mb` replays already-processed EB events. Reproduced by `externalities::tests::validate_rejects_advance_that_regresses_last_advanced_eb` (ignored). Iterations 1, 4, 6, 7, 9, 10: 0 confirmed (lots of duplicates of prior singletons / agents independently re-flagging known items). Total: 5 new TODO+_+_+ markers, 3 new ignored regression tests, 0 existing tests broken. fmt/clippy clean. 103/103 pass. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    remove redundant proposals removal

    by grishasobol

    make app infallible to fit malachite guarantees

    by grishasobol

    chore(ethexe-malachite): TODO+_+_+ for partial-finalize engine/app drift If `state.commit()` succeeds but `ingest_finalized` fails partway through `cascade_save` / `cascade_finalize`, the engine advances to h+1 (we send `Next::Start`) while the app side never observes the block. Document the split-commit fix; no behaviour change here. Co-Authored-By: Claude Opus 4.7 (1M context)

    by grishasobol

    remove loop break in case of storing undecided proposals break

    by grishasobol

    fix validate_rejects_advance_that_regresses_last_advanced_eb

    by grishasobol

    fix problem with infinet tx holding in mem-pool

    by grishasobol

    fix problem with future heights proposals

    by grishasobol

    fix problem with chain commitment checkpoint

    by grishasobol

    fix block proposal handling

    by grishasobol

    feat(ethexe/processor): instrument code lazily inside processing

    playX18 merged to gear-tech/gear at 2026-05-25 03:19:39

    feat(ethexe/processor): instrument code lazily inside processing

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    clippy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    feat(ethexe/processor): only create one instrumentation instance per spawn_chunk_execution.

    by playX18

    remove InstrumentationFailed case

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    instrument code outside of chunk_execution_spawn

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18

    Merge branch 'master' into ap/process-instrument-lazy

    by playX18