Skip to content

Resolve open node issues with bounded, evidence-backed changes - #1687

Closed
metaphoric-dev wants to merge 112 commits into
mainfrom
feat/resolve-node-issues
Closed

metaphoric-dev wants to merge 112 commits into
mainfrom
feat/resolve-node-issues

Conversation

@metaphoric-dev

@metaphoric-dev metaphoric-dev commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

This draft publishes the complete feat/resolve-node-issues branch: 100 commits, 388 files, +97,284/-7,254 against origin/main at f024fc377. It covers the 25 in-scope open issues, excluding post-quantum research #1625. All committed changes and refactors are included. Untracked local .worktrees/, local/, and plans/ artifacts are excluded.

Major changes

  • Repairs synchronization, chainstate, mempool, RPC, compact-block, and node-composition ownership.
  • Adds scoped CPFP submission, BIP331 ancestor packages, BIP332 stale tips, BIP337 compressed transactions, and BIP434 negotiation.
  • Adds bounded descriptor scans, JSON-RPC envelope fixes, and public/management RPC separation.
  • Adds opt-in Tor/I2P transports and native Stratum V1/V2 mining with durable PPLNS accounting.
  • Unifies exact block payload ownership and adds typed historical-prefix queries.
  • Adds verified snapshot seeding, Core v2 snapshot export, portable index bundles, and sealed AssumeUTXO activation.
  • Adds indexed Core-file corpus custody and a foreground offline importer through the production settlement owner.
  • Records performance, Lightning, Erlay, storage, and upstream dispositions without adopting unqualified candidates.

Synchronization impact

This branch touches authoritative sync, validation, and commit paths. Relevant contract clauses are SYNC-01 through SYNC-07, with the per-unit boundaries and evidence map in docs/contracts/synchronization.md. The smallest proofs are the existing chainstate, node recovery, index watermark, P2P, RPC-notification, and process-level acceptance suites. Portable restore additionally passed all five process cases with 77 checks.

Native pool module consolidation (42307c5)

Stratum V1/V2 and the durable PPLNS ledger now live under bitcoin_rs_mining::pool; the three standalone workspace crates were removed. The shared PoolCore was extracted from the SV1 session. Existing pool/pool-sv2 feature switches, ledger model/codecs/keyspace, accounting policy, and protocol behavior are preserved.

This consolidation moves the mining caller but does not edit the authoritative synchronization, validation, or commit implementations. Both protocols still submit through MiningControl; chain observation and lifecycle composition remain node-owned. Relevant preserved obligations are SYNC-03 (bounded pool locks/queues), SYNC-04 (submission/settlement failure classification), SYNC-05 (commit-before-success boundary), and SYNC-06 (existing refresh/drain drivers). The smallest evidence-map proof, chain_effects::tests::mining_reports_a_committed_settlement_failure_as_accepted, passed; the pool SV2 host proof also passed.

Validation on Windows: 242 mining/pool tests, 26 node pool/configuration/settlement tests, 7 pool RPC tests, the single settlement proof above, and the workspace dependency-direction gate passed (277 total). Pool-off and SV1-only binary checks, the SV2-enabled binary/test build, formatting, and strict all-targets mining Clippy passed. The normal dependency graph excludes pool storage and Noise when pool is off, and excludes SV2/Noise with SV1 only. Unix authority-file/process-crash and external interoperability campaigns were not rerun; those existing platform/deep lanes remain the evidence boundary.

Main merge reconciliation (69626f0)

Merged main at f024fc377. Conflicting public HTTP implementations now use main's RpcSurface, public_bind / --public-bind, independently configurable connection budgets, REST placement on the public listener, and rpc.* metrics. The superseded ListenerRole implementation and draft rpc_public_bind configuration were removed. Pool-aware Context construction, the mining::pool consolidation, the branch's JSON-RPC envelope behavior, and extracted transport proofs remain.

The merge does not edit authoritative synchronization, validation, or commit implementations. It reconciles listener binding, cancellation and worker ownership at node startup/teardown (SYNC-03, SYNC-04, SYNC-06); both listeners bind before workers start, and pool admission starts afterward. Existing lifecycle rollback/shutdown tests and the evidence-map event-loop proof event_loop::tests::telemetry_uses_elapsed_time_not_wake_count passed.

Windows verification: 56 RPC transport tests, 21 lifecycle tests, 21 auth integration tests, 2 public-listener configuration tests, 1 CLI test, 1 overlap-refusal unit test, and 1 event-loop test passed (103 total). Formatting and strict RPC library/test Clippy with --no-deps passed. Full-dependency Clippy is still blocked by the pre-existing non-Unix index::portable::sync_dir unnecessary-wraps lint; unrelated source was left intact. Unix/deep campaigns were not rerun.

Verification status

Draft created before final publication gates, as requested.

Passed on the final source-bound binary:

  • All five portable bundle process cases: 77 checks, 0 failures.
  • Feature-enabled portable unit suite: 8 passed.
  • Real two-block mainnet offline import and idempotent reopen.
  • Integrated AssumeUTXO focused suites and strict targeted Clippy.
  • Offline importer and relocated query/API ownership tests.

The complete all-profile gate and final native pool-feature gate must be read before merge. No better-than-Core or mainnet qualification claim is made.

Remaining external limits

  • Cmodern corpus qualification lacks the required archive and storage envelope.
  • Same-key I2P restart remains unresolved in the official-provider control.
  • Physical per-family device attribution is unavailable on shared ZFS.
  • ScriptHistory v6 promotion still needs representative storage evidence.
  • Unprovisioned Lightning targets remain unexercised.

RetriggerView in GreptileConfidence Score: 3/5

Do not merge until the overlay callers are updated and offline-import retries verify the archive before certifying success.

Findings

  1. P1 Overlay checks cannot start ▶
  2. P1 Retries certify unchecked archives ▶

Summary

This revision tightens overlay configuration, repairs amount parsing, and adds producer-manifest support.

  • Operators can export and restore portable transaction-index bundles.
  • Block sync and chain updates share clearer ownership of block data and displaced tips.
  • The index worker can seed live-script data from a verified snapshot artifact.
  • Index callers can request typed historical-prefix and bounded scan results.

Reviews (6) · Last reviewed commit: "Merge remote integration branch into fea..." · Reviewed by Greptile

metaphorics and others added 30 commits October 24, 2026 08:39
The contract cited a false P2P-05 commit authority, dead
transitions_* proof paths, and closed trackers as owners, and
it lacked the required ownership map. Readers followed stale
evidence for SYNC-01 through SYNC-07.

Point every clause at its live owner and smallest real proof,
state the unproven seed_live_from_utxo hold and the missing
process-level settlement scenario explicitly, and add the
seven-row ownership table plus the settlement-closure row.
The invalid_core_snapshots scenario sends the UTF-8 name
core200.dat over RPC; the non-UTF-8 target name appears only
after canonicalization, and std::fs::rename fails with EILSEQ
on an incapable macOS filesystem before any RPC runs.

State the arbitrary-byte-filename prerequisite next to the
recovery instructions. An incapable lane is BLOCKED, never a
reason to skip the scenario or weaken its assertions. The
test and production code stay unchanged.
ApplyScratch repackaged facts apply_block_admitted already
held and serialized raw transactions before the Propose
return and coinbase verification, so the wire bytes existed
on paths that never committed.

Hold txids, the same-block spent set, and the two UTXO
capacity locals directly, and serialize raw transactions
only in the commit tail when capture_rawtx asks for them.
A new regression applies an external spend plus a
same-block spend with the flag off and on and requires
identical UTXO membership, txids, tip, and commit identity,
with undo restoring the same state.
The first form of the test proved undo only through
post-disconnect membership. Compare the persisted undo
records byte for byte so a capture-flag-dependent durable
record cannot pass silently.
ordered checked package structure and submit_package_with_times
repeated the same check, so local submission paid two ordered
passes over the same transactions.

Snapshot restore calls only submit_package_with_times, so that
site stays the single authoritative structural gate. No result
is cached in another facts type.
block_by_hash only delegated to record_for_hash, two names
for one lookup. block_hash_at_height repeated the in-view
branches, next_applied_block_hash wrapped one checked
successor computation that two other surfaces inlined (one
with saturating_add, which made a u32::MAX record its own
successor), and handlers repeated confirmation arithmetic
the render owner already had.

Fold the lookup into block_by_hash, route the height read
through the in-view form, give every successor computation
the same checked form, and delegate confirmation depth to
render::confirmations. REST, Core RPC, and Esplora keep
their distinct serializers and error precedence.
NodeState::blocks handed out the raw RwLock<BlockLog> and
NodeState::shutdown duplicated the chainstate shutdown
handle. Both had canonical owners already: BlockLogReader
for reads and Chainstate::shutdown_handle for the atomic.

Migrate every caller, preserving each load and store
ordering, and keep the pointer-identity assertion on the
test-only raw_handle. The generic composition visitors stay:
they preserve concrete KvStore types across backend erasure
and have live Fjall, redb, and RocksDB consumers.
Pending.fallback kept terminal reconstruction state alive
after failure, and compact follow-ups published fetch
ownership through two separate marks that the enqueue could
race. A failed send could leave an orphan mark suppressing
recovery from another peer.

Absence of the pending entry now means terminal, releasing
filled transactions and retained bytes at once. One
enqueue_owned_body_fetch holds the exact-source peer-table
guard across the scheduler lock, the nonblocking send, and
ownership publication under the 16-entry deferred cap; on
failure it publishes nothing. The header-carried ownership
flag and its second publisher are deleted.
effective_includes now credits each accepted member with the wtxids
that actually subsidize it: self plus descendants in the package, so a
bumped parent reports [parent, child] while the paying child reports
itself.

The residency recheck distinguishes the removal cause: a resident txid
with a different witness reports DifferentWitness, and a fully absent
member reports MissingInputs rather than a capacity eviction.

check_structure classifies duplicate members before the topology
guard, so [tx, tx] reports PackageDuplicates instead of a topology
refusal.

The submitpackage handler bounds maxburnamount at the monetary
ceiling and stops echoing raw hex in the decode error.

Review: PR #1667 submit_package.rs:441
POL-03 names the pre-script check_package_max_feerate exception, and
POL-02, POL-05, MPL-04 and the embedding citation gain clause-local
proofs for the RPC package surface.

Review: PR #1667
effective_fee_rate now sums modified fees and vsize over the same
members each row reports in effective_includes: the bumped parent
reports the package rate, the paying child its own. A failed
modified-fee lookup nulls the rates instead of falling back to base
fees, matching the old aggregate's fail-closed behavior.

The CPFP test asserts the package rate on the parent row and the
child's own rate on the child row.

Review: PR #1667 submit_package.rs:485
…ember

Core 31.1 atomically commits a package as one subpackage: every member
reports the full package's aggregate effective-feerate and the complete
member set in effective-includes, including the paying child. The branch
priced each member's own subpackage instead, diverging on the partial-
acceptance harness row.

Classify unordered duplicate pairs as topology violations before the
structural verdicts, matching Core's -25 'package topology disallowed'
for [parent,parent] submissions; the dedicated duplicates branch was
unreachable for unordered pairs.

Gate: ci-pr.sh fmt + clippy passed in the pre-commit run; all test
profiles re-run green on this tree (rpc no-default-features, binary
rocksdb/fjall/redb harness incl. submitpackage parity cases, workspace
kernel-free 1365, rpc zmq 641); cargo deny clean (advisory fetch needed
GIT_CONFIG_GLOBAL=/dev/null to bypass the git-manager rewrite).
sats_from_btc took an f64, so values like 1e-9 rounded
through binary floating point before the satoshi check.
Parse the JSON number or string as exact decimal text,
expand e/E notation with integer shifts, and normalize
trailing zeros the way Core ParseFixedPoint does before
the eight-decimal precision check. 1e-8 is one satoshi;
1e-9 is Invalid amount. Every amount caller now shares
this one parser.

Also forward maxfeerate into both package passes, clamp
signed modified fees at zero before the fee-rate cap so a
negative prioritisation delta can never become u64::MAX,
and keep the single structural gate in
submit_package_with_times.
Core ParseFixedPoint requires a digit on each side of a
decimal point, but the exact parser accepted "1." and
".1". Require the integer part, and a non-empty fraction
when a point is present, so malformed amounts fail closed
instead of silently taking a value Core refuses.
Callers had to implement BIP337 contextual bit packing and
signature recovery themselves. One pure codec behind a
runtime opt-in now serves compressrawtransaction and
decompressrawtransaction, resolving prevouts and flat
output indexes through one bounded RPC resolver over the
existing chain and body owners.

The codec records the five reference readings where the
draft disagrees with itself (Core VARINT over the 7-bit
prose, the missing pkh row, the closed signature set, the
reference minimum-height rule, and compressed outpoints
only with confirmed context). All budgets are charged
before allocation; oversize, structural, and budget
failures keep distinct error codes.

The four published vectors restore byte-for-byte, and the
checked-in fixture rows are derived from real mainnet
bodies at heights 833265 through 833280; an ignored truth
test re-derives every field from those bodies. Measured on
the vectors: 52 to 67 percent of raw size, encode 1.5 to
3.8 us, decode 1.1 to 314 us by script type.
Closes #1599 item 1. API-02 already claimed that envelopes, batches,
notifications, and error ordering follow the pinned Core 31.1 contract, but
the transport accepted any jsonrpc value as legacy and passed any params
shape to dispatch.

- Add JsonRpcVersion::classify, mirroring Core's JSONRPCRequest::parse
  (src/rpc/request.cpp:206-260): a present jsonrpc field must be a string and
  must be "1.0" (kept as legacy for compatibility) or "2.0"; a present
  params field must be an array, an object, or null; method must be present
  and a string. A violation is -32600 with Core's message and the method
  never runs.
- Map legacy HTTP statuses as Core does (src/httprpc.cpp:41-56): -32600 ->
  400, -32601 -> 404, every other code -> 500. v2 dispatch errors stay inside
  HTTP 200. An envelope violation is detected before the claimed version is
  trusted, so it takes the legacy mapping in either dialect.
- A batch now always answers HTTP 200 and carries per-member errors in its
  array (httprpc.cpp:200-201); an all-notification batch still answers 204.
- Add the missing Bad Request and Not Found reason phrases.

Tests: 11 new crates/rpc/src/server.rs cases cover each rule and were
confirmed to fail before the change for the intended reason, plus the
listener-level crates/rpc/tests/auth.rs case now pins 404 for a legacy
unknown method instead of the previous 500.

The pre-commit hook's p2p profile hit
listener::writer_shutdown_tests::writer_exit_shuts_down_the_reader_socket_clone,
a socket-timing flake outside this change (crates/rpc only); it passes on
rerun and in the five consecutive runs used to confirm the flake.
…laims

Addresses the review of #1643:

- `RpcError::InvalidRequest` rendered an `invalid request: ` prefix, so the
  envelope errors did not carry Core's message text. The payload is now
  rendered verbatim, and the tests assert the exact strings Core produces
  (`jsonrpc field must be a string`, `JSON-RPC version not supported`,
  `Params must be an array or object`).
- Add `a_rejected_envelope_never_dispatches_the_method`: it first shows the
  probe method (`getrpcinfo` without a configured log path) fails with
  `-32603` when dispatched, then that three malformed envelopes produce
  `-32600` instead — so the contract's "the method never runs" now has an
  observable assertion.
- Add `an_empty_batch_is_rejected_as_an_invalid_request` and state that
  behavior as local (the pinned Core source does not specify an empty batch),
  rather than as parity.
- API-02 now says an explicit-null `jsonrpc` is legacy, matching the parser,
  and qualifies the batch 200 rule as applying to non-empty batches.
…bution

Addresses the review of #1643:

- Add `an_all_notification_batch_answers_204`, which API-02 now cites for
  the 204 claim (previously the clause had no clause-local proof).
- The empty-batch test comment attributed the rejection to Core; the contract
  already records that the pinned Core source does not specify an empty
  batch, so the comment now describes `-32600` as local behavior.
Core's parser assigns the JSON-RPC version before it validates method
and params (request.cpp:206-260), so a v2 request that fails a later
envelope check still replies in the v2 envelope — but takes HTTP 400
from the outer error path (httprpc.cpp:189-194) rather than the
dialect's 200. Adopt that mapping and align the remaining envelope
details with the pinned Core source:

- an explicit "method":null is "Missing method" (Core checks null
  before the string check),
- absent or explicit-null params dispatch as [] so no-argument
  methods apply their defaults,
- a rejected envelope provably never executes the method, now
  covered by a setnetworkactive dispatch probe.

Also extract the server test module into src/server/tests.rs per the
source-organization policy.
…y-batch cases

- v2 requests refused on method/params validation answer HTTP 400 with
  the v2 envelope kept (the jsonrpc field itself was already accepted);
  a rejected jsonrpc field still falls back to the legacy envelope.
- Explicit "method":null is "Missing method", matching Core's
  isNull()-before-isStr() order (request.cpp:228-232).
- A top-level scalar/array-non-object is -32700 "Top-level object parse
  error" at HTTP 500 with a null id (httprpc.cpp final else).
- An empty batch answers HTTP 200 [] (Core's batch reply path).
- Keep the historical 'invalid request: ' prefix on the malformed-HTTP
  body; update API-02 to the corrected status/dialect mapping.
getrpcinfo always answered an empty active_commands array
because nothing tracked in-flight calls. Handler::dispatch
now registers each call after registry resolution and
blocking-quota acquisition, so unknown or refused methods
never appear; an RAII guard removes exactly its own entry
on every exit path, and getrpcinfo renders method plus
elapsed microseconds oldest first, including itself.

The gettxoutproof fallback scan gains record and body-byte
counters. The candidate bounds (10,000 records, 64 MiB of
bodies) are not adopted: the scan runs forward from
genesis, so a late-window success at a 972,861 tip must
visit about 973k records and read bodies orders of
magnitude past 64 MiB (the 16 sampled mainnet bodies at
833265-833280 average 1.73 MB). That fails the four-times
headroom gate, so the current scan stays and the bound
remains blocked on representative evidence for a scan
order or index change that makes late-window cost small.

Also restores the server tests the envelope candidate's
test-module extraction dropped (accept loop, head-auth,
and drain suites) and corrects the README HTTP mapping.
scantxoutset rejected ranged and multipath descriptors,
forcing wallets to pre-expand them client-side, and
scanobject_descriptor discarded the range it had parsed.

The existing descriptor owner now expands ranges with
aggregate preflight against the remaining 1,024-script
and 1 MiB budgets before deriving anything, checks
cancellation before every derivation, expands
index-major/branch-inner, and keeps first-wins
attribution for duplicate scripts. Fixed descriptors
validate and ignore the range; the whitelist, checksum,
private-key, and network refusals are unchanged.
One source-IP admission pool let idle public keep-alive
sockets exhaust every slot before authentication could run,
starving the management surface. An optional public
listener now carries only Esplora routes behind its own
128-connection budget while the existing bind becomes the
16-connection management listener for JSON-RPC and REST,
both over one Context. Route filtering happens after the
request head and before authentication, so a public POST /
is 404, never a dispatch. Without rpc_public_bind the
single all-surfaces listener is unchanged.

Admission now reports Admitted, PoolFull, or PerSourceLimit
and emits connection, rejection, and latency series under
closed surface and reason labels.
Peer identity keyed by SocketAddr cannot name Tor or I2P peers and
lets a proxy loopback address stand in for the logical peer. A typed
endpoint now carries identity through the peer table, addrman, and
RPC surfaces, while the transport address stays socket-local.

Addrman records migrate to version 9 through the existing backup
path with byte-identical IP records. Overlay dials fail closed until
the SOCKS and SAM transports land; direct IP dialing is unchanged.
Several earlier changes landed without running the formatter, so
the fmt gate fails on files no current change touches. One sweep
restores a clean gate and keeps later diffs free of format noise.
The fmt gate still failed on files from earlier changes after the
first sweep landed only one file. Format the rest so the gate is
clean for the remaining steps.
The base commit passes a socket address to a typed peer API.
Convert the benchmark call so all workspace targets compile.

This repair must precede the feature chain because the base fails
the required all-targets check.
Update ctutils to 0.4.4 to remove RUSTSEC-2026-0385.
Keep dependency additions with their owning features.
Check process behavior and durable peer state instead of unstable
message text. Preserve the restart and lifecycle guarantees.
metaphorics added 3 commits October 28, 2026 10:54
Core treats I2P port zero as an unspecified service. Keep IP and Tor v3 port zero malformed, preserve the explicit zero through addrv2 round trips, and keep textual dialing rules unchanged.
Accept a persisted ED25519-V3 key with Core's prefix, validate the bare blob, and emit exactly one prefix when publishing the onion service. A doubled prefix remains corrupt.
Bring in the native mining refactor, main listener design, and remote CI fixes. Resolve RPC conflicts in favor of the remote single-surface design; keep local I2P/Tor, DNS, index, offline import, and amount exponent fixes.
Comment thread crates/node/src/config.rs
Comment on lines +815 to +818
anyhow::ensure!(
!privacy_route || !self.p2p.dns_seeds_enabled,
"proxy/overlay routing requires --dns-seeds-enabled=false; DNS seeds resolve via local DNS and would bypass the privacy route"
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Overlay checks cannot start

The new DNS guard rejects existing callers that configure overlay routes without disabling DNS seeds. bitcoin_conf_core_keys_map_into_config now fails at load_conf(...)?. The nodes launched by run-p2p-overlay-interop.sh also exit before the campaign can connect, because regtest leaves DNS seeds enabled by default.

Keep the guard, but update the configuration fixture and campaign launcher to disable DNS seeds explicitly.

metaphoric-dev pushed a commit that referenced this pull request Oct 28, 2026
Adds opt-in Tor SOCKS5/ControlPort and IVNP SAM connectivity through the
existing admission, PeerTable/PeerLease, relay and BlockSync owners.
Logical IP/Tor-v3/I2P destinations remain separate from local
proxy/router sockets.

- Keep destination types routable-only. Anonymous inbound Tor circuits
use lease connection ids in the runtime session layer; their RPC handles
remain visible and disconnectable but cannot enter configuration,
AddrMan or address gossip.
- Read/write one explicitly identified, checksummed AddrMan v1. Its
version stays 1 before the first official release. Historical
development decoders and upgrade fixtures are removed. Unmarked
pre-release books are preserved byte-for-byte before fresh discovery is
published; corrupt or unsafe inputs still block replacement. Current
validation, network scoping, ASMap regrouping, anchors and atomic
publication remain.
- Use one outbound retry owner for fixed peers and persistent addnode
entries on every route. The fixed-peer worker resolves desired
destinations only. Completion drives bounded backoff, ready connections
reset it, and canonical identities prevent duplicate dials.
Route-specific AddrMan failure attribution stays with the
transport/listener.
- Let the SAM lifecycle worker publish/unpublish epochs and wake only
leases carrying the retired epoch marker. Every payload reader observes
the same lease cancellation predicate, including mid-frame epoch
revocation. Late failures cannot cancel a replacement epoch.
- Retain allowed-network policy, no local DNS/direct fallback in
overlay-only mode, persistent application identities, SAFECOOKIE
validation, network RPC projections, and the existing manual
Tor/pinned-IVNP process workflow.

### Synchronization impact

Peer identity and transport delivery touch the input/recovery boundary
of authoritative BlockSync scheduling and receive paths. Header/body
validation, authoritative frontier implementation and chainstate commit
mechanics are unchanged. Relevant clauses are SYNC-02 (frontier
continuity), SYNC-04 (peer-loss/replacement recovery) and SYNC-06
(delivery/work drivers).

The synchronization contract's smallest executed proofs are
frontier_recovery (12 tests) and
tick_fetches_new_tip_headers_from_at_tip_peers (1). Expiry-strike,
addrman_restart_e2e and full process convergence retain their existing
deep lanes and were not rerun in these follow-ups.

### Validation and remaining evidence

Windows focused checks passed:
- Canonical AddrMan suite (69); pinned policy/TCP retry regressions (3)
and existing service suite (42).
- Anonymous admission/attribution, peer table, parent requests,
transaction policy and endpoint checks; RPC network suite (53) during
the runtime split.
- At the final integrated head: exact-epoch wakeup, local/epoch
mid-payload cancellation, mocked overlay recovery/protocol filter (26
passed, 1 external Tor test ignored), the anonymous RPC regression, and
the 13 synchronization proofs above.
- Strict P2P library/test Clippy, node/RPC all-target checks, formatting
and diff checks. The runtime split also passed P2P/node/RPC/mempool
all-target checks and strict library/test Clippy.

One AddrMan anchor-consumption test failed once in a parallel suite; its
isolated rerun and the full 69-test rerun passed. The cause is
unconfirmed; this is not evidence of stable passing behavior across
repeated Windows persistence campaigns.

Real Tor/IVNP interoperability, process convergence and privacy
qualification remain unrun. #1687 still needs to adopt the same
canonical fixture/layout and identity/netgroup rules before merge;
application-key compatibility across the branches is not qualified.
Password/Unix ControlPort support and broader provider-backoff timing
qualification remain outside these refactors. No bidirectional
historical AddrMan migration is intended under #1688.

Refs #1601, #1688. Keep #1601 open for external qualification.



<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=87919822"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1684"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The latest changes appear safe to
merge; no new blocking defect was found.

<details><summary><h3>Summary</h3></summary>

The PR adds opt-in Tor and IVNP I2P routes through the existing peer
sessions. The latest changes make reads stop when their SAM session is
revoked.
- Peer sessions keep overlay identities separate from their local
network sockets.
- Operators can route allowed peer networks through configured SOCKS5 or
SAM endpoints.
- Tor and I2P can accept inbound Bitcoin peers using saved service
identities.
- The address book can store and share Tor and I2P peer destinations.
- Network RPC and operator guides describe configured overlay routes and
live service state.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[SAM session fails] --> B[Revoke that session's marker]
  B --> C[PeerLease::is_cancelled returns true]
  C --> D[CountingStream stops reading]
  D --> E[Connection owner closes its session]
  A --> F[run_sam starts a replacement]
  F --> G[New streams use a separate marker]
```
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (16) · Last reviewed commit: ["fix(p2p): observe lease
epochs during
pa..."](8c8eac2)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 4e1f8e1
Full repository gate: native-gate-20261027T232832Z-1404447
(scripts/ci-pr.sh all, exit 0).

Scope: Lightning docs and probe.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464685"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1700?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 4/5</h2>

<!-- greptile-risk -->

The encoding change appears safe, but the repository's required
synchronization-impact explanation must be supplied before merging.

<h2>Findings</h2>

1. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Synchronization impact is undocumented** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1700#discussion_r4397302226">▶</a>

<details><summary><h3>Summary</h3></summary>

This stack adds Lightning integration docs and an external qualification
runner, alongside changes to checkpoint recovery, block requests, RPC
reads, and transaction notifications.
- Lightning clients can be checked with a repeatable interoperability
probe.
- Wallet broadcasts can use the legacy fee flag and notify
raw-transaction subscribers.
- Peer block requests recover from not-found replies, and locator header
replies follow the applied chain.
- Checkpoints retain eligible side headers so branch state survives
restart.
- Checkpoint file reads and renames stay within regular files and
single-name paths.
- RPC block results use one retained applied-chain view for shared
height and confirmation data.
- Synchronization contracts name each work item's owner and recovery
path.
</details>

<!-- greptile_confidence_score:4 -->

<sub>Reviews (3) · Last reviewed commit: ["Use consensus bytes for ZMQ
rawtx
public..."](813ae02)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->

**Sync impact: YES.** `block_not_found` changes how the node releases
and retries block requests. Affected clauses: SYNC-04 (recovery closure)
and SYNC-06 (work drivers). Smallest proof:
`crates/p2p/src/sync/tests.rs` notfound-only and historical-notfound
regressions.
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 53f6ba2
Full repository gate: native-gate-20261027T224851Z-928445
(scripts/ci-pr.sh all, exit 0).

Scope: sync and chainstate.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464455"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1691?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 4/5</h2>

<!-- greptile-risk -->

The new notification change looks sound, but the required sync proof
mapping must be added before merging.

<h2>Findings</h2>

1. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Sync proof mapping is missing** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1691#discussion_r4396887899">▶</a>

<details><summary><h3>Summary</h3></summary>

The stack updates sync request ownership, checkpoint recovery,
applied-chain reads, and transaction notifications.
- Chainstate checkpoints keep valid side branches for the next restart.
- Block downloads switch peers when a requested body is unavailable.
- Locator-based header replies and chain views follow the applied
branch.
- Mempool admissions publish transaction hashes and optional raw bodies
over ZMQ.
- `sendrawtransaction` accepts the legacy false fee flag as the default
limit.
- Checkpoint reads and no-overwrite renames stay inside the checkpoint
directory.
- Package submissions use the shared checks for package shape.
</details>

<!-- greptile_confidence_score:4 -->

<sub>Reviews (3) · Last reviewed commit: ["Publish hashtx for mempool
admissions"](bba52b1)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->

**Sync impact: YES.** `headers_after` serves locator-based `getheaders`
replies from the applied chain. Affected clauses: SYNC-02 (canonical
applied progress) and SYNC-05 (coherent applied-tip views). Smallest
proof:
`crates/p2p/tests/core_compat.rs::getheaders_serves_active_chain_with_stop_hash_and_limit`
plus the `chain_query` applied-chain tests.
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 796fce6
Full repository gate: native-gate-20261028T000017Z-2220212
(scripts/ci-pr.sh all, exit 0).

Scope: tools and docs.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687








**Sync impact: YES.** Touches authoritative paths: checkpoint restore
writes side branches into the block tree in
`crates/chainstate/src/checkpoint/headers.rs` and its v2 artifact, and
sync request recovery routes unavailable-body retries through the sync
owner. Affected clauses: SYNC-04 (recovery closure), SYNC-05 (durable
progress), and SYNC-06 (work drivers). Smallest proofs:
`crates/p2p/src/sync/` body-rejection regressions,
`crates/chainstate/src/checkpoint/tests/side_branches.rs`, and
`crates/node/tests/overhaul_durable_head.rs`.


<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464718"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1702?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The PR appears safe to merge; no new
blocking issue was established.

<details><summary><h3>Summary</h3></summary>

This stack adds checkpoint side-branch retention, routes unavailable
block bodies back through sync scheduling, and adds accepted-transaction
bodies to ordered mempool notifications.

- Checkpoints keep eligible side branches when the node restarts.
- Sync retries block bodies after a peer reports that it lacks one.
- Locator-based header replies follow the validated applied chain.
- Mempool observers can receive accepted transaction bodies for ZMQ
`rawtx`.
- `sendrawtransaction` accepts the legacy `false` fee argument.
- Checkpoint file operations avoid blocking on substituted pipes and
limit rename paths.
- The contracts and validation notes describe current sync, checkpoint,
and tooling behavior.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Peer answers notfound] --> B{Exact current owner?}
  B -->|No| C[Leave request unchanged]
  B -->|Yes| D[Release owned request]
  D --> E[Remember peer cannot serve this hash]
  E --> F[Wake sync]
  F --> G[Plan request for another peer]
  E --> H[Retry interval expires]
  H --> I[Original peer becomes eligible again]
```
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (4) · Last reviewed commit: ["Adapt merged sync tests to
branch
owners..."](8d2382f)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 1b18364
Full repository gate: native-gate-20261027T231422Z-1260404
(scripts/ci-pr.sh all, exit 0).

Scope: AssumeUTXO.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687










**Sync impact: YES.** Touches authoritative sync and commit paths:
`SyncChain::commit_window` and `connect_historical`, as a borrow-only
refactor from owned `Block` plus `Bytes` to borrowed `BlockPayload`
slices; outcomes, follower order, and settlement are unchanged. Affected
clauses: SYNC-02, SYNC-05, SYNC-06, SYNC-04, and ARCH-07b. Smallest
proofs: `crates/node/tests/sync_smoke.rs`,
`crates/node/tests/overhaul_durable_head.rs`,
`chain_effects.rs::committed_connect_settlement_failure`, and
`crates/node/tests/crash_recovery.rs`.


<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464645"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1698?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 4/5</h2>

<!-- greptile-risk -->

The large-bundle restore finding remains blocking; restricting export
does not remove restore's whole-bundle limit.

<h2>Findings</h2>

1. <img alt="P1"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p1.svg?v=9"
align="top">&nbsp;**Large exports cannot restore** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1698#discussion_r4397930554">▶</a>

<details><summary><h3>Summary</h3></summary>

The AssumeUTXO stack adds verified snapshot state, snapshot-backed index
seeding, portable index bundles, and borrowed `BlockPayload` paths.

The latest changes:
- Snapshot imports carry verified UTXO state into activation.
- Nodes can export and restore verified transaction-index bundles.
- Index queries can return history only through a covered chain point.
- Checkpoint headers retain side branches for later replay.
- Sync passes block data as one borrowed payload.
- A peer's not-found reply releases its matching block request.
- RPC, embedding, and storage APIs gain bounded data paths.
</details>

<!-- greptile_confidence_score:4 -->

<sub>Reviews (5) · Last reviewed commit: ["Match export and restore
bundle
position..."](3e26c10)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 0704754
Full repository gate: native-gate-20261028T001206Z-2627348
(scripts/ci-pr.sh all, exit 0).

Scope: docs cleanup (high certainty only; child of 09).
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






## Cross-PR implementation clarification (7cf8e73)

Window attribution is implemented in sibling PR #1701 (audited head
994e82a): chainstate emits
transition_held_us and flush_wait_us, and sync_pipeline::main dispatches
--window-attribution. Those changes are absent from #1703, so its guide
now describes an integration dependency instead of claiming the
infrastructure is unimplemented project-wide. No campaign execution or
measurement result is inferred.

The strict-Rust qualification guide explicitly scopes availability to
this checkout. Source/target checks across all 20 open PR heads found no
k256 verifier or overhaul_consensus_matrix / overhaul_native_crypto
targets. Those qualification gaps remain distinct from #1701's
implemented measurement infrastructure.

Validation: git diff --check and the documented Cargo target/feature and
relative-link checks passed. This clarification changes Markdown only;
no additional sync impact.

## Documentation follow-up (c451135)

The validation guide now describes the implemented secp256k1-backed
native verifier, names runnable regression targets, and marks missing
strict-Rust implementation and qualification coverage as BLOCKED.
Current index query behavior lives in the index crate guide; the
superseded brainstorm and stale task-number comments are removed.

Validation on WSL/Linux, Rust 1.99.0:
- Five script integration targets: 31 passed.
- Four consensus integration targets: 14 passed.
- Changed-file rustfmt and git diff --check: passed.
- Cargo metadata confirms all five documented regression/benchmark
commands name existing package targets and features. Relative Markdown
links resolve; source changes are comments only and Cargo manifest
semantics are unchanged.
- Whole-workspace cargo fmt --all -- --check fails on pre-existing
formatting in crates/p2p/src/download_window.rs (lines 104 and 1737),
unchanged by this follow-up.
- Benchmark campaigns, strict-Rust qualification and full-mainnet replay
were not run. The full repository gate recorded above belongs to the
earlier stack revision; it does not qualify this new commit.

No additional sync impact from this follow-up: only documentation and
comments change. It crosses no authoritative sync, validation, commit,
persistence or lock boundary; no additional SYNC-* clause is affected.
The existing sync-impact declaration below continues to describe the
earlier runtime changes.



**Sync impact: YES.** Foreground and historical download batches now
exclude bodies an owner refused and pin the carried cursor to the lowest
excluded height. Affected clauses: SYNC-04 (recovery closure) and
SYNC-06 (work drivers). Smallest proof: `crates/p2p/src/sync/tests.rs`
notfound and `sync/tests/historical.rs` historical-notfound regressions.




<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464748"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1703?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The latest documentation changes appear
safe to merge.

<details><summary><h3>Summary</h3></summary>

The latest change clarifies which branch contains the window benchmark
code.
- Restarts keep eligible side branches in the header tree.
- Peer sync replans blocks after a peer says it cannot provide them.
- Compact-block follow-up requests publish ownership when they are sent.
- Locator-based header replies now follow the applied chain.
- ZMQ publishes accepted transaction bodies on the `rawtx` topic.
- `sendrawtransaction` accepts `false` as the default fee limit.
- Block responses use one applied-chain view for their chain details.
- Checkpoint file access rejects unsafe entries and rename paths.
- The Lightning guide and runner describe interoperability checks and
their evidence.
- Guides distinguish implemented behavior from proposed work and missing
evidence.
- Supporting build and test updates keep the affected workflows aligned.

No new actionable issues found. The previous threads were rechecked;
none requires another comment. No tests or benchmark campaigns were run
during this review.
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (5) · Last reviewed commit: ["docs: distinguish sibling PR
implementat..."](7cf8e73)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 5c39599
Full repository gate: native-gate-20261027T234159Z-2602207
(scripts/ci-pr.sh all, exit 0).

Scope: performance and evidence.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464699"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1701?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The changes appear safe to merge; the
previous batch-request blocker is fixed.

<details><summary><h3>Summary</h3></summary>

This stack adds performance evidence and changes several supporting
paths:
- Checkpoint restores keep eligible side branches in the block tree.
- Sync releases unavailable body requests and tries other peers.
- Chain replies and RPC views use validated applied-chain state.
- Mempool observers can skip accepted transaction bodies they do not
need.
- Staged block gauges show decoded and retained memory separately.
- Window-pipeline runs record timing evidence for the existing apply
path.
- The benchmark helper reports write counters only for attributable
storage.
- Checkpoint file operations stay inside the checkpoint directory.

Since the last review, block requests now filter unavailable hashes
instead of rejecting entire batches. The numbered finding is fixed. The
two unnumbered filesystem findings are also fixed: partitions check
their parent’s backing devices, and mount-table reads preserve carriage
returns. No new actionable issues were found. No performance or mainnet
qualification is inferred.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Plan peer batch] --> B[Remove hashes this peer lacks]
  B --> C{Any entries remain?}
  C -->|No| D[Try next peer without marking]
  C -->|Yes| E[Send remaining entries]
  E --> F[Mark sent entries pending]
  F --> G[Keep cursor at earliest excluded height]
```
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (3) · Last reviewed commit: ["Exclude unavailable blocks
per P2P
reque..."](994e82a)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 2785fd8
Full repository gate: native-gate-20261027T223049Z-1567775
(scripts/ci-pr.sh all, exit 0).

Scope: corpus and offline import.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464675"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1699?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The PR appears safe to merge, with the
remaining restore performance issue non-blocking.

<h2>Findings</h2>

1. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Restore repeatedly parses whole blocks** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1699#discussion_r4396318380">▶</a>

<details><summary><h3>Summary</h3></summary>

This stack adds verified corpus tooling, foreground offline import,
portable transaction-index bundles, and snapshot-backed index seeding.

Since the previous review:
- Operators can import a checked block archive and write certified
state.
- Operators can export and restore portable transaction-index bundles.
- Index queries can return historical results with their coverage point.
- Restored nodes seed ScriptLive from verified snapshots and keep other
indexes moving.
- Block validation and storage carry each decoded block with its exact
bytes.
- Storage paging and RPC boundary handling cover additional real-world
cases.

No new actionable issues were found.
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (3) · Last reviewed commit: ["Stream corpus index pages and
separate
s..."](fae5a35)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 0416119
Full repository gate: native-gate-20261027T201054Z-310371
(scripts/ci-pr.sh all, exit 0).

Scope: RPC.
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687










<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464515"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1693?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 4/5</h2>

<!-- greptile-risk -->

The code fixes the earlier cache and ZMQ findings, but the required
synchronization-impact declaration must be added before merging.

<h2>Findings</h2>

1. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Sync impact is not explained** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1693#discussion_r4397431897">▶</a>

<details><summary><h3>Summary</h3></summary>

This stack adds optional BIP337 transaction compression, scoped
`submitpackage`, ranged descriptor scans, RPC compatibility updates, and
ordered ZMQ admission notices.
- Package submission keeps standalone successes and retries eligible
parent-child pairs together.
- Two optional RPC methods convert raw transactions to and from BIP337
form.
- `scantxoutset` accepts ranged descriptors and keeps its scan work
bounded.
- JSON-RPC requests are checked and answered using the matching protocol
version.
- Block sync releases requests after a peer says a body is unavailable
and can retry elsewhere.
- Checkpoint files retain replayable side headers and recovery validates
them before restoring.
- ZMQ subscribers receive accepted transaction notifications in mutation
order.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Compressed transaction RPC] --> B[Capture stable chain view]
  B --> C[Parse bytes and resolve spent outputs]
  C --> D[Release chain lock]
  D --> E[Recover signatures]
  E --> F[Recheck chain view and return]
```
</details>

<!-- greptile_confidence_score:4 -->

<sub>Reviews (5) · Last reviewed commit: ["Charge retained RPC
transaction
allocati..."](dbc3911)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->

**Sync impact: YES.** `enqueue_owned_body_fetch` changes how block sync
sends and records body requests. Affected clauses: SYNC-04 (recovery
closure) and SYNC-06 (work drivers). Smallest proof:
`crates/p2p/src/sync/tests.rs` notfound and owned-body-fetch
regressions.
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: ffeb1b8
Full repository gate: native-gate-20261027T191330Z-1920978
(scripts/ci-pr.sh all, exit 0).

Scope: protocol (BIP331, BIP332, BIP434, stale tip, tx ingress, addrv2).
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464613"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1697?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The reviewed changes appear safe to
merge; both previous findings are addressed.

<details><summary><h3>Summary</h3></summary>

This stack adds package relay, stale-tip relay, transaction ingress
changes, and overlay networking.

The latest changes address both previous findings:
- Peers can request and send transaction packages.
- Nodes can announce recent stale branches and keep them across
restarts.
- Configured Tor and I2P routes can carry peer connections.

No new actionable issues were found in the changes since the previous
review.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Automatic peer candidate] --> B{Network and route allowed?}
    B -->|No| C[Skip before queuing a dial]
    B -->|Yes| D[Dial and complete handshake]
    D --> E[Ready session with exact connection identity]
    F[Anonymous inbound peer] --> E
    E --> G[Foreground or historical block request]
    G --> H[Check identity before sending]
```
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (3) · Last reviewed commit: ["Fix anonymous peer serving
and route
pre..."](f58daa5)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: 80be603
Full repository gate: native-gate-20261027T194739Z-194405
(scripts/ci-pr.sh all, exit 0).

Scope: index and snapshots (portable bundles, restore, query).
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687








<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464601"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1696?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 4/5</h2>

<!-- greptile-risk -->

Do not merge until the observer lock regression is fixed and the
explicit repository requirements are met.

<h2>Findings</h2>

1. <img alt="P1"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p1.svg?v=9"
align="top">&nbsp;**Observer calls can deadlock** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1696#discussion_r4400771825">▶</a>
2. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Seed reopen can block application** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1696#discussion_r4400771841">▶</a>
3. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Required sync evidence is missing** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1696#discussion_r4400771845">▶</a>
4. <img alt="P2"
src="https://greptile-static-assets.s3.amazonaws.com/badges/p2.svg?v=9"
align="top">&nbsp;**Private tests bypass required layout** <a
href="https://github.com/gosuda/bitcoin-rs/pull/1696#discussion_r4400771858">▶</a>

<details><summary><h3>Summary</h3></summary>

Adds portable transaction-index bundles, snapshot-backed `ScriptLive`
seeding, and covered-prefix queries for embedders.
- Operators can move verified `TxLookup` bundles between nodes.
- `ScriptLive` seeds from a verified snapshot and catches up from its
height.
- Historical index queries return the chain point that covers each
answer.
- Block flows carry decoded blocks together with their exact bytes.
- Checkpoint artifacts retain replayable side branches as well as the
active chain.
- The block downloader replans a body after its peer says it is
unavailable.
</details>

<details open><summary><h3>Diagram</h3></summary>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Checkpoint or snapshot activation] --> B[Witnessed snapshot file]
  B --> C[Worker seed slot]
  C --> D[Write live rows in bounded batches]
  D --> E[Check complete snapshot digest]
  E --> F[Commit live watermark]
  F --> G[Reconcile with active chain]
  H[Portable bundle] --> I[Check records against local blocks]
  I --> J[Import rows and commit transaction watermark]
  J --> G
  G --> K[Strict or covered-prefix queries]
```
</details>

<!-- greptile_confidence_score:4 -->

<sub>Reviews (4) · Last reviewed commit: ["Adapt merged sync tests to
branch
owners..."](3746075)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->

## Synchronization impact

(a) This PR does not touch an authoritative synchronization, validation,
or commit path. It changes index bundle export and restore caching and
paging, and index-side seed traversal cancellation. It consumes existing
chain views and does not alter scheduling, validation, or commit
ownership.

(b) No `SYNC-*` clause is affected.

(c) The smallest existing behavioral proof is `cargo test -p
bitcoin-rs-index --features fjall --test portable_bundle` (8 tests) and
`cargo test -p bitcoin-rs-index --lib portable` (25 tests). These
exercise export and restore against the current chain view and do not
cross a synchronization contract boundary.
metaphoric-dev added a commit that referenced this pull request Oct 28, 2026
Draft subsystem stack split from PR #1687.

Base: f024fc3
Tip: c8f3002
Full repository gate: native-gate-20261028T012000Z-868411
(scripts/ci-pr.sh all, exit 0).

Scope: overlay (Tor, I2P, SAM, SOCKS, addrman).
This is a verified stack tip. Do not rebase or reparent it
without owner approval.

No better-than-Core claim. No mainnet qualification.

See also: #1687






<!-- greptile_comment -->

<!-- greptile_summary -->




<h2><a
href="https://app.greptile.com/api/retrigger?id=89464541"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"
align="right"></picture></a><a
href="https://app.greptile.com/superpowers/github/gosuda/bitcoin-rs/-/pull/1694?utm_source=greptile_review&amp;utm_medium=github&amp;utm_campaign=view_in_greptile"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptileDark.svg?v=2"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"><img
alt="View in Greptile"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewInGreptile.svg?v=2"
align="right"></picture></a>Confidence Score: 5/5</h2>

<!-- greptile-impact-verdict --> The changes since the last review
appear safe to merge; both numbered findings are addressed.

<details><summary><h3>Summary</h3></summary>

This stack adds Tor, I2P, SOCKS, and typed peer addresses across
discovery, connections, sync, and RPC.

Since the last review:
- Tor and I2P peers can connect through configured overlay routes.
- Address books can store and gossip typed overlay addresses.
- Checkpoint recovery keeps eligible side-branch headers across
restarts.
- A peer's `notfound` reply releases only the block request it owns.
- Configured ZMQ `rawtx` subscribers receive accepted transaction
bodies.
- RPC transaction submission accepts the legacy `false` fee-limit
argument.
- Chain, mining, and build callers use the updated peer and checkpoint
types.

Both numbered findings are addressed. No new actionable issue was found
in these changes. Live overlay interoperability was not rerun.
</details>

<!-- greptile_confidence_score:5 -->

<sub>Reviews (3) · Last reviewed commit: ["Sync SAM key directory
through the
porta..."](a996a58)
· [Reviewed by
Greptile](https://www.greptile.com/?utm_source=greptile_review&utm_medium=github&utm_campaign=review_public&utm_content=gosuda/bitcoin-rs)</sub>

<!-- /greptile_comment -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants