@optimystic/db-p2p 0.24.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{readme.md → README.md} +688 -668
- package/dist/src/cluster/block-transfer-service.d.ts +133 -10
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +155 -9
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +67 -7
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +127 -24
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/certified-claims.d.ts +170 -0
- package/dist/src/cluster/certified-claims.d.ts.map +1 -0
- package/dist/src/cluster/certified-claims.js +200 -0
- package/dist/src/cluster/certified-claims.js.map +1 -0
- package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
- package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
- package/dist/src/cluster/client-signature-verifier.js +33 -0
- package/dist/src/cluster/client-signature-verifier.js.map +1 -0
- package/dist/src/cluster/cluster-policy.d.ts +9 -3
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js +111 -27
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +140 -11
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +485 -29
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.d.ts +134 -0
- package/dist/src/cluster/commit-proof.d.ts.map +1 -0
- package/dist/src/cluster/commit-proof.js +263 -0
- package/dist/src/cluster/commit-proof.js.map +1 -0
- package/dist/src/cluster/quorum-restore.d.ts +95 -8
- package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
- package/dist/src/cluster/quorum-restore.js +113 -14
- package/dist/src/cluster/quorum-restore.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +207 -5
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/reconcile-block.d.ts +27 -7
- package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
- package/dist/src/cluster/reconcile-block.js +179 -38
- package/dist/src/cluster/reconcile-block.js.map +1 -1
- package/dist/src/cluster/service.d.ts +21 -4
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +28 -17
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +8 -2
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +7 -7
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -7
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +7 -6
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +14 -41
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/dispute/cascade.d.ts +7 -8
- package/dist/src/dispute/cascade.d.ts.map +1 -1
- package/dist/src/dispute/cascade.js +24 -7
- package/dist/src/dispute/cascade.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +5 -0
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +13 -3
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +33 -15
- package/dist/src/dispute/invalidation.d.ts.map +1 -1
- package/dist/src/dispute/invalidation.js +127 -34
- package/dist/src/dispute/invalidation.js.map +1 -1
- package/dist/src/dispute/service.d.ts.map +1 -1
- package/dist/src/dispute/service.js +2 -1
- package/dist/src/dispute/service.js.map +1 -1
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +78 -6
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +136 -57
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +38 -7
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +150 -62
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/logger.d.ts +2 -2
- package/dist/src/logger.js +2 -2
- package/dist/src/network/open-protocol-stream.d.ts +56 -0
- package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
- package/dist/src/network/open-protocol-stream.js +60 -0
- package/dist/src/network/open-protocol-stream.js.map +1 -0
- package/dist/src/network/register-protocol-handler.d.ts +66 -0
- package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
- package/dist/src/network/register-protocol-handler.js +51 -0
- package/dist/src/network/register-protocol-handler.js.map +1 -0
- package/dist/src/peer-address-book.d.ts +128 -1
- package/dist/src/peer-address-book.d.ts.map +1 -1
- package/dist/src/peer-address-book.js +198 -15
- package/dist/src/peer-address-book.js.map +1 -1
- package/dist/src/pend-validation.d.ts +65 -0
- package/dist/src/pend-validation.d.ts.map +1 -0
- package/dist/src/pend-validation.js +69 -0
- package/dist/src/pend-validation.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
- package/dist/src/reactivity/notify-transport.js +2 -1
- package/dist/src/reactivity/notify-transport.js.map +1 -1
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
- package/dist/src/reactivity/push-state-gossip.js +2 -1
- package/dist/src/reactivity/push-state-gossip.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +32 -6
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +44 -10
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +181 -25
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +650 -62
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/served-repo-proxy.d.ts +30 -0
- package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
- package/dist/src/repo/served-repo-proxy.js +50 -0
- package/dist/src/repo/served-repo-proxy.js.map +1 -0
- package/dist/src/repo/service.d.ts +22 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +25 -13
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/reputation/types.d.ts +3 -1
- package/dist/src/reputation/types.d.ts.map +1 -1
- package/dist/src/reputation/types.js +3 -1
- package/dist/src/reputation/types.js.map +1 -1
- package/dist/src/rn.d.ts +24 -2
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +33 -4
- package/dist/src/rn.js.map +1 -1
- package/dist/src/routing/libp2p-known-peers.d.ts.map +1 -1
- package/dist/src/routing/libp2p-known-peers.js +5 -0
- package/dist/src/routing/libp2p-known-peers.js.map +1 -1
- package/dist/src/storage/block-archive.d.ts +153 -0
- package/dist/src/storage/block-archive.d.ts.map +1 -0
- package/dist/src/storage/block-archive.js +194 -0
- package/dist/src/storage/block-archive.js.map +1 -0
- package/dist/src/storage/block-latch.d.ts +92 -0
- package/dist/src/storage/block-latch.d.ts.map +1 -0
- package/dist/src/storage/block-latch.js +132 -0
- package/dist/src/storage/block-latch.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +169 -12
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +415 -152
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/cached-raw-storage.d.ts +5 -1
- package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/cached-raw-storage.js +16 -1
- package/dist/src/storage/cached-raw-storage.js.map +1 -1
- package/dist/src/storage/cached-store-driver.d.ts +14 -4
- package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
- package/dist/src/storage/cached-store-driver.js +39 -5
- package/dist/src/storage/cached-store-driver.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +70 -19
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js +21 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/i-raw-storage.d.ts +38 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.d.ts +14 -8
- package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.js +29 -9
- package/dist/src/storage/kv-raw-storage.js.map +1 -1
- package/dist/src/storage/memory-store-driver.d.ts +4 -1
- package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
- package/dist/src/storage/memory-store-driver.js +22 -2
- package/dist/src/storage/memory-store-driver.js.map +1 -1
- package/dist/src/storage/raw-store-codec.js +2 -2
- package/dist/src/storage/raw-store-driver.d.ts +44 -3
- package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.d.ts +60 -3
- package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.js +68 -4
- package/dist/src/storage/shared-cache-pool.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +204 -26
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +422 -119
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/store-identity.d.ts +21 -0
- package/dist/src/storage/store-identity.d.ts.map +1 -0
- package/dist/src/storage/store-identity.js +33 -0
- package/dist/src/storage/store-identity.js.map +1 -0
- package/dist/src/storage/struct.d.ts +15 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/storage/with-read-cache.d.ts +92 -0
- package/dist/src/storage/with-read-cache.d.ts.map +1 -0
- package/dist/src/storage/with-read-cache.js +132 -0
- package/dist/src/storage/with-read-cache.js.map +1 -0
- package/dist/src/sync/service.d.ts +13 -3
- package/dist/src/sync/service.d.ts.map +1 -1
- package/dist/src/sync/service.js +7 -30
- package/dist/src/sync/service.js.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +75 -2
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +193 -81
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
- package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
- package/dist/src/testing/raw-storage-conformance.js +97 -2
- package/dist/src/testing/raw-storage-conformance.js.map +1 -1
- package/package.json +5 -6
- package/src/cluster/block-transfer-service.ts +528 -312
- package/src/cluster/block-transfer.ts +547 -424
- package/src/cluster/certified-claims.ts +319 -0
- package/src/cluster/client-signature-verifier.ts +34 -0
- package/src/cluster/cluster-policy.ts +294 -203
- package/src/cluster/cluster-repo.ts +2501 -2034
- package/src/cluster/commit-proof.ts +344 -0
- package/src/cluster/quorum-restore.ts +348 -223
- package/src/cluster/rebalance-monitor.ts +539 -254
- package/src/cluster/reconcile-block.ts +404 -203
- package/src/cluster/service.ts +308 -293
- package/src/cluster/spread-on-churn.ts +352 -346
- package/src/cohort-topic/host.ts +8 -7
- package/src/cohort-topic/stream-util.ts +14 -43
- package/src/dispute/cascade.ts +31 -15
- package/src/dispute/dispute-service.ts +706 -696
- package/src/dispute/invalidation.ts +162 -52
- package/src/dispute/service.ts +126 -125
- package/src/index.ts +7 -0
- package/src/libp2p-key-network.ts +142 -58
- package/src/libp2p-node-base.ts +1793 -1675
- package/src/logger.ts +27 -27
- package/src/network/open-protocol-stream.ts +87 -0
- package/src/network/register-protocol-handler.ts +85 -0
- package/src/peer-address-book.ts +360 -149
- package/src/pend-validation.ts +89 -0
- package/src/reactivity/notify-transport.ts +145 -144
- package/src/reactivity/push-state-gossip.ts +292 -291
- package/src/repo/cluster-coordinator.ts +65 -11
- package/src/repo/coordinator-repo.ts +729 -71
- package/src/repo/served-repo-proxy.ts +55 -0
- package/src/repo/service.ts +332 -313
- package/src/reputation/types.ts +3 -1
- package/src/rn.ts +34 -4
- package/src/routing/libp2p-known-peers.ts +31 -26
- package/src/storage/block-archive.ts +242 -0
- package/src/storage/block-latch.ts +144 -0
- package/src/storage/block-storage.ts +787 -498
- package/src/storage/cached-raw-storage.ts +21 -1
- package/src/storage/cached-store-driver.ts +898 -859
- package/src/storage/i-block-storage.ts +172 -116
- package/src/storage/i-raw-storage.ts +40 -0
- package/src/storage/kv-raw-storage.ts +34 -9
- package/src/storage/memory-store-driver.ts +26 -2
- package/src/storage/raw-store-codec.ts +42 -42
- package/src/storage/raw-store-driver.ts +45 -3
- package/src/storage/shared-cache-pool.ts +516 -452
- package/src/storage/storage-repo.ts +1421 -1014
- package/src/storage/store-identity.ts +41 -0
- package/src/storage/struct.ts +52 -34
- package/src/storage/with-read-cache.ts +182 -0
- package/src/sync/service.ts +178 -198
- package/src/testing/cohort-topic-mesh-harness.ts +673 -673
- package/src/testing/mesh-harness.ts +524 -344
- package/src/testing/raw-storage-conformance.ts +114 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Startable } from '@libp2p/interface';
|
|
2
|
-
import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, IBlock, BlockId } from '@optimystic/db-core';
|
|
2
|
+
import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, GetBlockResult, IBlock, BlockId } from '@optimystic/db-core';
|
|
3
3
|
import { ProtocolClient } from '../protocol-client.js';
|
|
4
4
|
import { type InboundStreamAuthorizationInit } from '../inbound-authorization.js';
|
|
5
|
+
import type { BlockCommitProof } from './commit-proof.js';
|
|
6
|
+
import { type ArchiveServingRepo } from '../storage/block-archive.js';
|
|
5
7
|
export declare const buildBlockTransferProtocol: (protocolPrefix?: string) => string;
|
|
6
8
|
/** Request to transfer blocks */
|
|
7
9
|
export interface BlockTransferRequest {
|
|
@@ -22,7 +24,76 @@ export interface BlockTransferRequest {
|
|
|
22
24
|
rev: number;
|
|
23
25
|
actionId: ActionId;
|
|
24
26
|
}>;
|
|
27
|
+
/**
|
|
28
|
+
* For push: the cohort's commit proof for each block's revision. Verified against the pushed
|
|
29
|
+
* bytes AND against the declared {@link blockMeta} before anything is persisted — one
|
|
30
|
+
* `certifyContent` call covers the signatures and thresholds, the claim matching the declared
|
|
31
|
+
* `(rev, actionId)`, and the declared digest matching the pushed bytes.
|
|
32
|
+
*
|
|
33
|
+
* Optional on the wire so an un-upgraded sender still parses; whether a proof-less push is
|
|
34
|
+
* ACCEPTED is the receiver's `requirePushCertificate` decision (default: reject).
|
|
35
|
+
*/
|
|
36
|
+
blockProofs?: Record<string, BlockCommitProof>;
|
|
25
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The `blockMeta` a pusher sends alongside one block: the source's own `state.latest`, so the
|
|
40
|
+
* replica lands at the source's `(rev, actionId)` rather than a fabricated one. That match is what
|
|
41
|
+
* later lets the replica CORROBORATE the source in a read-repair quorum vote — a fabricated action
|
|
42
|
+
* id never matches the source's claim, so the vote sees one claimant, not two.
|
|
43
|
+
*
|
|
44
|
+
* `undefined` when the source repo reports no `latest`; the receiver then falls back to its
|
|
45
|
+
* deterministic rev-1 replica (see `IBlockStorage.saveReplica`).
|
|
46
|
+
*
|
|
47
|
+
* Every push path (rebalance confirm/push, spread-on-churn) builds it here so the wire shape stays
|
|
48
|
+
* defined in one place alongside {@link BlockTransferRequest.blockMeta}.
|
|
49
|
+
*
|
|
50
|
+
* The caller must read the block UNPINNED (no `BlockGets.context`). `state.latest` is the newest
|
|
51
|
+
* revision the source holds, while `block` is the revision `materialized` names; those agree only
|
|
52
|
+
* for an unpinned read. Pairing pinned (older) content with `latest` would label content with a
|
|
53
|
+
* revision it is not — so the pairing is guarded below and drops the meta rather than lying.
|
|
54
|
+
*
|
|
55
|
+
* Dropping, rather than labelling the older content with its own (now known) `materialized`
|
|
56
|
+
* revision, is deliberate: a push is "here is my latest replica" — the receiver lands it as its
|
|
57
|
+
* replica and the source's `latest` is what the cohort corroborates — and no push path reads
|
|
58
|
+
* pinned, so a mismatch here is a caller bug, not a historical serve. A repair fetch of an older
|
|
59
|
+
* revision is a different wire (`serveBlockArchive`), and that one DOES label from `materialized`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function sourceBlockMeta(blockId: BlockId, result: Pick<GetBlockResult, 'state' | 'materialized'> | undefined): Record<string, ActionRev> | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Everything a push carries ABOUT the blocks it pushes, as one value: the source's revision
|
|
64
|
+
* metadata and the cohort commit proof for that same revision. One parameter rather than two so a
|
|
65
|
+
* caller cannot attach a proof for one revision beside metadata for another — the two are built
|
|
66
|
+
* together by {@link sourceBlockCertification} from a single unpinned read, or not at all.
|
|
67
|
+
*/
|
|
68
|
+
export type PushCertification = {
|
|
69
|
+
blockMeta?: Record<string, ActionRev>;
|
|
70
|
+
blockProofs?: Record<string, BlockCommitProof>;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Build a push's {@link PushCertification} for ONE block from a single unpinned read: the
|
|
74
|
+
* {@link sourceBlockMeta} for the source's `state.latest`, plus the locally-retained
|
|
75
|
+
* {@link BlockCommitProof} for exactly that revision.
|
|
76
|
+
*
|
|
77
|
+
* The proof comes from {@link servableProof} — the same accessor that decides what a peer attaches
|
|
78
|
+
* to a served repair archive — so a push and a repair fetch can never disagree about which proof
|
|
79
|
+
* pairs with which revision. It fails closed on every unhappy path (repo with no proof accessor, a
|
|
80
|
+
* throwing lookup, a stored proof whose message names a different `(blockId, rev, actionId)`), so a
|
|
81
|
+
* mis-paired artifact is never pushed.
|
|
82
|
+
*
|
|
83
|
+
* **A proof is never attached without its meta.** Without the declared `(rev, actionId)` a receiver
|
|
84
|
+
* has no claim to verify the proof against, and it rejects the block (see
|
|
85
|
+
* `BlockTransferService.handlePush`).
|
|
86
|
+
*
|
|
87
|
+
* **Meta IS still attached when no proof exists.** That is the pre-proof push, unchanged: a
|
|
88
|
+
* receiver running the default `requirePushCertificate: true` rejects it either way, and one
|
|
89
|
+
* migrating with the flag `false` needs the meta to land the replica at the source's revision
|
|
90
|
+
* instead of a fabricated rev 1. Dropping the meta alongside the missing proof would regress the
|
|
91
|
+
* legacy path without making the strict path any stricter.
|
|
92
|
+
*
|
|
93
|
+
* Like `sourceBlockMeta`, the caller must have read the block UNPINNED, so `block`, the meta and
|
|
94
|
+
* the proof all describe the same revision.
|
|
95
|
+
*/
|
|
96
|
+
export declare function sourceBlockCertification(repo: ArchiveServingRepo, blockId: BlockId, result: Pick<GetBlockResult, 'state' | 'materialized'> | undefined): Promise<PushCertification>;
|
|
26
97
|
/** Response with block data */
|
|
27
98
|
export interface BlockTransferResponse {
|
|
28
99
|
/** Blocks successfully transferred: blockId → base64-encoded data */
|
|
@@ -42,11 +113,36 @@ export interface IBlockReplicaStore extends IRepo {
|
|
|
42
113
|
* Seeds metadata if absent, advances `latest` monotonically, and makes the block
|
|
43
114
|
* durably servable via `get`. Idempotent for a fixed `(rev, actionId)`; a no-op
|
|
44
115
|
* (still durable) when an equal-or-newer revision is already present.
|
|
116
|
+
*
|
|
117
|
+
* `verifiedProof` MUST already have been verified against these exact bytes and this exact
|
|
118
|
+
* `source` (`certifyContent` — the digest check is what binds a proof to the content). It is
|
|
119
|
+
* retained so the receiver can re-prove onward what it just verified, instead of becoming a
|
|
120
|
+
* holder that can only corroborate.
|
|
45
121
|
*/
|
|
46
|
-
saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev): Promise<void>;
|
|
122
|
+
saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev, verifiedProof?: BlockCommitProof): Promise<void>;
|
|
47
123
|
}
|
|
48
124
|
export interface BlockTransferServiceInit extends InboundStreamAuthorizationInit {
|
|
49
125
|
protocolPrefix?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Reject a pushed block that carries no verifying commit proof. Default `true`.
|
|
128
|
+
* A deployment holding pre-proof data sets this `false` during migration.
|
|
129
|
+
*
|
|
130
|
+
* **Why the strict default.** `handlePush` persists what a peer hands it, and
|
|
131
|
+
* `saveReplicatedBlock` advances `latest` monotonically — so an uncertified push makes the
|
|
132
|
+
* pusher's bytes this node's authoritative revision, after which this node *corroborates* the
|
|
133
|
+
* pusher in a later read-repair vote. That is how a peer manufactures its own corroborators.
|
|
134
|
+
*
|
|
135
|
+
* The failure mode of `true` is that legacy blocks stop gaining new holders via push — visible
|
|
136
|
+
* in a `push:reject-uncertified` log line, and those blocks stay readable while two or more
|
|
137
|
+
* holders remain. The failure mode of `false` is silent acceptance of forged content. Pre-proof
|
|
138
|
+
* blocks can never be certified (the signatures no longer exist), but any block written again
|
|
139
|
+
* under the current code gets a proof, so only cold, never-updated blocks stay uncertified.
|
|
140
|
+
*
|
|
141
|
+
* With the flag `false` an uncertified push falls back to the pre-proof behaviour, logged as
|
|
142
|
+
* `push:accept-uncertified`. A push carrying a proof that FAILS verification is rejected
|
|
143
|
+
* regardless of the flag — that is not a legacy block, it is a bad one.
|
|
144
|
+
*/
|
|
145
|
+
requirePushCertificate?: boolean;
|
|
50
146
|
}
|
|
51
147
|
export interface BlockTransferServiceComponents {
|
|
52
148
|
registrar: {
|
|
@@ -54,6 +150,20 @@ export interface BlockTransferServiceComponents {
|
|
|
54
150
|
unhandle: (...args: any[]) => Promise<void>;
|
|
55
151
|
};
|
|
56
152
|
repo: IBlockReplicaStore;
|
|
153
|
+
/**
|
|
154
|
+
* The cohort's configured super-majority fraction, used to verify a pushed block's commit proof.
|
|
155
|
+
*
|
|
156
|
+
* REQUIRED rather than defaulted: the node factory must hand this down from the single resolved
|
|
157
|
+
* `consensusConfig` every other consensus consumer reads (`libp2p-node-base.ts`, which already
|
|
158
|
+
* fail-fast asserts member/coordinator coupling on exactly this value). A local default here
|
|
159
|
+
* would be a third copy that silently disagrees with a deployment that tuned the threshold.
|
|
160
|
+
*
|
|
161
|
+
* The simple-majority half of {@link ProofThresholds} is deliberately NOT threaded: it must
|
|
162
|
+
* mirror what members actually enforce (`count > total / 2`), not the configured 0.51 — see
|
|
163
|
+
* `proofThresholds` in `certified-claims.ts`, the one helper every proof-verifying path builds
|
|
164
|
+
* its thresholds with.
|
|
165
|
+
*/
|
|
166
|
+
superMajorityThreshold: number;
|
|
57
167
|
/**
|
|
58
168
|
* Optional libp2p component logger. Supplied by the node factory so authorization denials
|
|
59
169
|
* land on the same `logger.forComponent(...).error` sink as the repo/cluster/sync services;
|
|
@@ -78,6 +188,10 @@ export declare class BlockTransferService implements Startable {
|
|
|
78
188
|
private readonly registrar;
|
|
79
189
|
/** Optional embedder authorization gate; `undefined` (the default) means no check runs. */
|
|
80
190
|
private readonly authorization;
|
|
191
|
+
/** Built once from the node's configured super-majority — see {@link BlockTransferServiceComponents.superMajorityThreshold}. */
|
|
192
|
+
private readonly proofThresholds;
|
|
193
|
+
/** See {@link BlockTransferServiceInit.requirePushCertificate}. */
|
|
194
|
+
private readonly requirePushCertificate;
|
|
81
195
|
constructor(components: BlockTransferServiceComponents, init?: BlockTransferServiceInit);
|
|
82
196
|
start(): Promise<void>;
|
|
83
197
|
stop(): Promise<void>;
|
|
@@ -86,8 +200,18 @@ export declare class BlockTransferService implements Startable {
|
|
|
86
200
|
/**
|
|
87
201
|
* Persist pushed blocks into local storage so the new owner holds a durable
|
|
88
202
|
* replica after churn. A block is reported `accepted` only if it was both
|
|
89
|
-
* received (parseable) AND successfully persisted; a parse or persist failure
|
|
203
|
+
* received (parseable) AND successfully persisted; a parse, certification or persist failure
|
|
90
204
|
* surfaces it as `missing` so the sender does not falsely treat it as replicated.
|
|
205
|
+
*
|
|
206
|
+
* **Certification.** A pushed block is content this node will serve — and, because
|
|
207
|
+
* `saveReplicatedBlock` advances `latest`, content it will later CORROBORATE in a read-repair
|
|
208
|
+
* vote. So by default the pusher must show the cohort's commit proof for the revision it
|
|
209
|
+
* declares, verified here against both the declared `(rev, actionId)` and the pushed bytes. See
|
|
210
|
+
* {@link BlockTransferServiceInit.requirePushCertificate} for the migration flag and its
|
|
211
|
+
* rationale.
|
|
212
|
+
*
|
|
213
|
+
* Decisions are strictly PER BLOCK: in a multi-block push a block that verifies is accepted
|
|
214
|
+
* beside one that does not. `handlePull` is unaffected — it serves this node's own storage.
|
|
91
215
|
*/
|
|
92
216
|
private handlePush;
|
|
93
217
|
}
|
|
@@ -115,9 +239,11 @@ export declare class BlockTransferClient extends ProtocolClient {
|
|
|
115
239
|
/**
|
|
116
240
|
* Push blocks to the remote peer.
|
|
117
241
|
*
|
|
118
|
-
* @param
|
|
119
|
-
*
|
|
120
|
-
*
|
|
242
|
+
* @param certification What this push claims about the blocks — the source's revision metadata
|
|
243
|
+
* and the cohort commit proof for that same revision, built as one unit by
|
|
244
|
+
* {@link sourceBlockCertification}. Without a proof the receiver rejects the block under its
|
|
245
|
+
* default `requirePushCertificate: true`; without metadata it replicates at a deterministic
|
|
246
|
+
* rev-1 (and rejects any proof, which then covers nothing).
|
|
121
247
|
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
122
248
|
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
123
249
|
* bounds waiting for the reply once connected (so a peer that connects but goes
|
|
@@ -125,10 +251,7 @@ export declare class BlockTransferClient extends ProtocolClient {
|
|
|
125
251
|
* cancels the whole request. Omitting all of them preserves the previous
|
|
126
252
|
* uncapped behavior.
|
|
127
253
|
*/
|
|
128
|
-
pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'],
|
|
129
|
-
rev: number;
|
|
130
|
-
actionId: ActionId;
|
|
131
|
-
}>, options?: {
|
|
254
|
+
pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'], certification?: PushCertification, options?: {
|
|
132
255
|
signal?: AbortSignal;
|
|
133
256
|
dialTimeoutMs?: number;
|
|
134
257
|
responseTimeoutMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAU,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,11 +6,85 @@ import { ProtocolClient } from '../protocol-client.js';
|
|
|
6
6
|
import { MAX_BLOCK_MESSAGE_BYTES } from '../protocol-limits.js';
|
|
7
7
|
import { createLogger } from '../logger.js';
|
|
8
8
|
import { createInboundStreamAuthorization } from '../inbound-authorization.js';
|
|
9
|
+
import { certifyContent, proofThresholds } from './certified-claims.js';
|
|
10
|
+
import { servableProof } from '../storage/block-archive.js';
|
|
11
|
+
import { registerProtocolHandler } from '../network/register-protocol-handler.js';
|
|
9
12
|
const log = createLogger('block-transfer-service');
|
|
10
13
|
/** Protocol path */
|
|
11
14
|
const BLOCK_TRANSFER_PREFIX = '/db-p2p/block-transfer/';
|
|
12
15
|
const BLOCK_TRANSFER_VERSION = '1.0.0';
|
|
13
16
|
export const buildBlockTransferProtocol = (protocolPrefix = '') => `${protocolPrefix}${BLOCK_TRANSFER_PREFIX}${BLOCK_TRANSFER_VERSION}`;
|
|
17
|
+
/**
|
|
18
|
+
* The `blockMeta` a pusher sends alongside one block: the source's own `state.latest`, so the
|
|
19
|
+
* replica lands at the source's `(rev, actionId)` rather than a fabricated one. That match is what
|
|
20
|
+
* later lets the replica CORROBORATE the source in a read-repair quorum vote — a fabricated action
|
|
21
|
+
* id never matches the source's claim, so the vote sees one claimant, not two.
|
|
22
|
+
*
|
|
23
|
+
* `undefined` when the source repo reports no `latest`; the receiver then falls back to its
|
|
24
|
+
* deterministic rev-1 replica (see `IBlockStorage.saveReplica`).
|
|
25
|
+
*
|
|
26
|
+
* Every push path (rebalance confirm/push, spread-on-churn) builds it here so the wire shape stays
|
|
27
|
+
* defined in one place alongside {@link BlockTransferRequest.blockMeta}.
|
|
28
|
+
*
|
|
29
|
+
* The caller must read the block UNPINNED (no `BlockGets.context`). `state.latest` is the newest
|
|
30
|
+
* revision the source holds, while `block` is the revision `materialized` names; those agree only
|
|
31
|
+
* for an unpinned read. Pairing pinned (older) content with `latest` would label content with a
|
|
32
|
+
* revision it is not — so the pairing is guarded below and drops the meta rather than lying.
|
|
33
|
+
*
|
|
34
|
+
* Dropping, rather than labelling the older content with its own (now known) `materialized`
|
|
35
|
+
* revision, is deliberate: a push is "here is my latest replica" — the receiver lands it as its
|
|
36
|
+
* replica and the source's `latest` is what the cohort corroborates — and no push path reads
|
|
37
|
+
* pinned, so a mismatch here is a caller bug, not a historical serve. A repair fetch of an older
|
|
38
|
+
* revision is a different wire (`serveBlockArchive`), and that one DOES label from `materialized`.
|
|
39
|
+
*/
|
|
40
|
+
export function sourceBlockMeta(blockId, result) {
|
|
41
|
+
const latest = result?.state?.latest;
|
|
42
|
+
if (!latest)
|
|
43
|
+
return undefined;
|
|
44
|
+
const materialized = result?.materialized;
|
|
45
|
+
if (materialized !== undefined && materialized.rev !== latest.rev) {
|
|
46
|
+
log('meta:skip block=%s materialized=%d latest=%d (pinned read — refusing to mislabel content)', blockId, materialized.rev, latest.rev);
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return { [blockId]: { rev: latest.rev, actionId: latest.actionId } };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a push's {@link PushCertification} for ONE block from a single unpinned read: the
|
|
53
|
+
* {@link sourceBlockMeta} for the source's `state.latest`, plus the locally-retained
|
|
54
|
+
* {@link BlockCommitProof} for exactly that revision.
|
|
55
|
+
*
|
|
56
|
+
* The proof comes from {@link servableProof} — the same accessor that decides what a peer attaches
|
|
57
|
+
* to a served repair archive — so a push and a repair fetch can never disagree about which proof
|
|
58
|
+
* pairs with which revision. It fails closed on every unhappy path (repo with no proof accessor, a
|
|
59
|
+
* throwing lookup, a stored proof whose message names a different `(blockId, rev, actionId)`), so a
|
|
60
|
+
* mis-paired artifact is never pushed.
|
|
61
|
+
*
|
|
62
|
+
* **A proof is never attached without its meta.** Without the declared `(rev, actionId)` a receiver
|
|
63
|
+
* has no claim to verify the proof against, and it rejects the block (see
|
|
64
|
+
* `BlockTransferService.handlePush`).
|
|
65
|
+
*
|
|
66
|
+
* **Meta IS still attached when no proof exists.** That is the pre-proof push, unchanged: a
|
|
67
|
+
* receiver running the default `requirePushCertificate: true` rejects it either way, and one
|
|
68
|
+
* migrating with the flag `false` needs the meta to land the replica at the source's revision
|
|
69
|
+
* instead of a fabricated rev 1. Dropping the meta alongside the missing proof would regress the
|
|
70
|
+
* legacy path without making the strict path any stricter.
|
|
71
|
+
*
|
|
72
|
+
* Like `sourceBlockMeta`, the caller must have read the block UNPINNED, so `block`, the meta and
|
|
73
|
+
* the proof all describe the same revision.
|
|
74
|
+
*/
|
|
75
|
+
export async function sourceBlockCertification(repo, blockId, result) {
|
|
76
|
+
const blockMeta = sourceBlockMeta(blockId, result);
|
|
77
|
+
if (!blockMeta) {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
const latest = result.state.latest;
|
|
81
|
+
const proof = await servableProof(repo, blockId, latest);
|
|
82
|
+
if (!proof) {
|
|
83
|
+
log('cert:no-local-proof block=%s rev=%d (pushing uncertified)', blockId, latest.rev);
|
|
84
|
+
return { blockMeta };
|
|
85
|
+
}
|
|
86
|
+
return { blockMeta, blockProofs: { [blockId]: proof } };
|
|
87
|
+
}
|
|
14
88
|
/**
|
|
15
89
|
* Libp2p service that handles incoming block transfer requests.
|
|
16
90
|
*
|
|
@@ -24,17 +98,23 @@ export class BlockTransferService {
|
|
|
24
98
|
registrar;
|
|
25
99
|
/** Optional embedder authorization gate; `undefined` (the default) means no check runs. */
|
|
26
100
|
authorization;
|
|
101
|
+
/** Built once from the node's configured super-majority — see {@link BlockTransferServiceComponents.superMajorityThreshold}. */
|
|
102
|
+
proofThresholds;
|
|
103
|
+
/** See {@link BlockTransferServiceInit.requirePushCertificate}. */
|
|
104
|
+
requirePushCertificate;
|
|
27
105
|
constructor(components, init = {}) {
|
|
28
106
|
this.protocol = buildBlockTransferProtocol(init.protocolPrefix ?? '');
|
|
29
107
|
this.repo = components.repo;
|
|
30
108
|
this.registrar = components.registrar;
|
|
109
|
+
this.proofThresholds = proofThresholds(components.superMajorityThreshold);
|
|
110
|
+
this.requirePushCertificate = init.requirePushCertificate ?? true;
|
|
31
111
|
const componentLog = components.logger?.forComponent('db-p2p:block-transfer');
|
|
32
112
|
this.authorization = createInboundStreamAuthorization(init, this.protocol, componentLog ? (msg, ...args) => componentLog.error(msg, ...args) : (msg, ...args) => log(msg, ...args));
|
|
33
113
|
}
|
|
34
114
|
async start() {
|
|
35
115
|
if (this.running)
|
|
36
116
|
return;
|
|
37
|
-
await this.registrar
|
|
117
|
+
await registerProtocolHandler(this.registrar, this.protocol, async (data, connection) => {
|
|
38
118
|
// libp2p invokes the stream handler with the Stream as the FIRST positional argument
|
|
39
119
|
// (see cluster/repo/dispute services, which all use `(stream, connection)`). The block-
|
|
40
120
|
// transfer handler previously read `data.stream`, which is `undefined` for the positional
|
|
@@ -118,8 +198,18 @@ export class BlockTransferService {
|
|
|
118
198
|
/**
|
|
119
199
|
* Persist pushed blocks into local storage so the new owner holds a durable
|
|
120
200
|
* replica after churn. A block is reported `accepted` only if it was both
|
|
121
|
-
* received (parseable) AND successfully persisted; a parse or persist failure
|
|
201
|
+
* received (parseable) AND successfully persisted; a parse, certification or persist failure
|
|
122
202
|
* surfaces it as `missing` so the sender does not falsely treat it as replicated.
|
|
203
|
+
*
|
|
204
|
+
* **Certification.** A pushed block is content this node will serve — and, because
|
|
205
|
+
* `saveReplicatedBlock` advances `latest`, content it will later CORROBORATE in a read-repair
|
|
206
|
+
* vote. So by default the pusher must show the cohort's commit proof for the revision it
|
|
207
|
+
* declares, verified here against both the declared `(rev, actionId)` and the pushed bytes. See
|
|
208
|
+
* {@link BlockTransferServiceInit.requirePushCertificate} for the migration flag and its
|
|
209
|
+
* rationale.
|
|
210
|
+
*
|
|
211
|
+
* Decisions are strictly PER BLOCK: in a multi-block push a block that verifies is accepted
|
|
212
|
+
* beside one that does not. `handlePull` is unaffected — it serves this node's own storage.
|
|
123
213
|
*/
|
|
124
214
|
async handlePush(request) {
|
|
125
215
|
const blocks = {};
|
|
@@ -150,10 +240,60 @@ export class BlockTransferService {
|
|
|
150
240
|
missing.push(blockId);
|
|
151
241
|
continue;
|
|
152
242
|
}
|
|
243
|
+
// Certify BEFORE persisting: `saveReplicatedBlock` advances `latest`, so anything that
|
|
244
|
+
// reaches it becomes this node's authoritative revision.
|
|
245
|
+
const source = request.blockMeta?.[blockId];
|
|
246
|
+
const proof = request.blockProofs?.[blockId];
|
|
247
|
+
let verifiedProof;
|
|
248
|
+
if (proof !== undefined) {
|
|
249
|
+
if (!source) {
|
|
250
|
+
// No declared `(rev, actionId)` means no claim to verify the proof against, and
|
|
251
|
+
// `saveReplica` would fabricate a rev-1 replica the proof does not cover.
|
|
252
|
+
log('push:reject-uncertified block=%s reason=proof-without-meta', blockId);
|
|
253
|
+
missing.push(blockId);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// One call covers the signatures and thresholds, the claim matching the declared
|
|
257
|
+
// `(rev, actionId)`, and the declared digest matching these exact bytes. Routed through
|
|
258
|
+
// `certifyContent` rather than the raw verifier so the wire-facing signer cap
|
|
259
|
+
// (MAX_PROOF_SIGNERS) the verifier requires of its callers is applied before any
|
|
260
|
+
// signature work — this input comes from an unauthenticated peer.
|
|
261
|
+
//
|
|
262
|
+
// NOTE: no `ProofAnchoring` is threaded here, unlike the other two proof-verifying
|
|
263
|
+
// paths (`ReconcileBlockDeps.anchoring`, `CoordinatorRepo`'s). Nothing wires anchoring
|
|
264
|
+
// in production today, so all three behave identically; when
|
|
265
|
+
// `feat-cluster-membership-threshold-cert-anchoring` lands, this call needs the same
|
|
266
|
+
// optional dep or the push path becomes the one place the unanchored residual is
|
|
267
|
+
// neither compared nor surfaced.
|
|
268
|
+
//
|
|
269
|
+
// NOTE: verification cost per REQUEST is unbounded in a way per-proof caps do not
|
|
270
|
+
// cover — one inbound push frame is capped at MAX_BLOCK_MESSAGE_BYTES (8 MiB, not the
|
|
271
|
+
// 1 MiB control cap `MAX_PROOF_SIGNERS`' note reasons about) and may carry one proof
|
|
272
|
+
// per block id. Each proof is bounded (≤ 256 signers), but their number is the
|
|
273
|
+
// sender's choice. Acceptable today because the pre-proof path already did per-block
|
|
274
|
+
// parse + disk write on the same frame; if inbound push CPU ever shows up in a
|
|
275
|
+
// profile, bound the per-request proof count (or total proof bytes) here.
|
|
276
|
+
const verdict = await certifyContent(proof, { blockId, rev: source.rev, actionId: source.actionId }, block, this.proofThresholds);
|
|
277
|
+
if (!verdict.contentCertified) {
|
|
278
|
+
log('push:reject-uncertified block=%s rev=%d reason=%s', blockId, source.rev, verdict.failure);
|
|
279
|
+
missing.push(blockId);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
verifiedProof = proof;
|
|
283
|
+
}
|
|
284
|
+
else if (this.requirePushCertificate) {
|
|
285
|
+
// The documented migration case: an un-upgraded sender, or a block committed before
|
|
286
|
+
// proofs existed. Diagnosable by this line alone.
|
|
287
|
+
log('push:reject-uncertified block=%s rev=%s reason=no-proof', blockId, source?.rev);
|
|
288
|
+
missing.push(blockId);
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
log('push:accept-uncertified block=%s rev=%s (requirePushCertificate disabled)', blockId, source?.rev);
|
|
293
|
+
}
|
|
153
294
|
// Persist locally. Only a received-AND-persisted block is reported accepted.
|
|
154
295
|
try {
|
|
155
|
-
|
|
156
|
-
await this.repo.saveReplicatedBlock(blockId, block, source);
|
|
296
|
+
await this.repo.saveReplicatedBlock(blockId, block, source, verifiedProof);
|
|
157
297
|
blocks[blockId] = data;
|
|
158
298
|
}
|
|
159
299
|
catch (error) {
|
|
@@ -191,9 +331,11 @@ export class BlockTransferClient extends ProtocolClient {
|
|
|
191
331
|
/**
|
|
192
332
|
* Push blocks to the remote peer.
|
|
193
333
|
*
|
|
194
|
-
* @param
|
|
195
|
-
*
|
|
196
|
-
*
|
|
334
|
+
* @param certification What this push claims about the blocks — the source's revision metadata
|
|
335
|
+
* and the cohort commit proof for that same revision, built as one unit by
|
|
336
|
+
* {@link sourceBlockCertification}. Without a proof the receiver rejects the block under its
|
|
337
|
+
* default `requirePushCertificate: true`; without metadata it replicates at a deterministic
|
|
338
|
+
* rev-1 (and rejects any proof, which then covers nothing).
|
|
197
339
|
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
198
340
|
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
199
341
|
* bounds waiting for the reply once connected (so a peer that connects but goes
|
|
@@ -201,12 +343,16 @@ export class BlockTransferClient extends ProtocolClient {
|
|
|
201
343
|
* cancels the whole request. Omitting all of them preserves the previous
|
|
202
344
|
* uncapped behavior.
|
|
203
345
|
*/
|
|
204
|
-
async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance',
|
|
346
|
+
async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance', certification, options) {
|
|
205
347
|
const blockData = {};
|
|
206
348
|
for (let i = 0; i < blockIds.length; i++) {
|
|
207
349
|
blockData[blockIds[i]] = Buffer.from(blockDataBuffers[i]).toString('base64');
|
|
208
350
|
}
|
|
209
|
-
const request = {
|
|
351
|
+
const request = {
|
|
352
|
+
type: 'push', blockIds, reason, blockData,
|
|
353
|
+
...(certification?.blockMeta ? { blockMeta: certification.blockMeta } : {}),
|
|
354
|
+
...(certification?.blockProofs ? { blockProofs: certification.blockProofs } : {})
|
|
355
|
+
};
|
|
210
356
|
return await this.processMessage(request, this.protocol, { ...options, maxDataLength: MAX_BLOCK_MESSAGE_BYTES });
|
|
211
357
|
}
|
|
212
358
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IPeerNetwork } from '@optimystic/db-core';
|
|
2
2
|
import type { PartitionDetector } from './partition-detector.js';
|
|
3
3
|
import type { RestorationCoordinator } from '../storage/restoration-coordinator.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { ProofRetainingRepo } from '../storage/block-archive.js';
|
|
5
|
+
import type { GrowthOutcome, RebalanceEvent } from './rebalance-monitor.js';
|
|
5
6
|
export interface BlockTransferConfig {
|
|
6
7
|
/** Max concurrent transfers. Default: 4 */
|
|
7
8
|
maxConcurrency?: number;
|
|
@@ -26,6 +27,22 @@ export interface RebalanceReactionResult {
|
|
|
26
27
|
released: string[];
|
|
27
28
|
/** Lost blocks whose replication could not be confirmed — keep serving, retry later. */
|
|
28
29
|
retained: string[];
|
|
30
|
+
/** Grown blocks confirmed pushed to every newly co-responsible peer (capped by the floor). */
|
|
31
|
+
replicated: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Grown blocks that could not be confirmed on the new peers this pass. Nothing is released off
|
|
34
|
+
* this list — the node keeps the block either way. The retry lives in the monitor: the caller
|
|
35
|
+
* feeds each block's {@link GrowthOutcome} (in `growth`) back via
|
|
36
|
+
* `RebalanceMonitor.recordGrowthOutcome`, so an unconfirmed peer stays out of the seen set and
|
|
37
|
+
* the next check re-detects it.
|
|
38
|
+
*/
|
|
39
|
+
underReplicated: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Per-block feedback for the growth arm, keyed by block id. A block reported `grown` that the
|
|
42
|
+
* reaction had NO information about (its confirm was deduped against one already in flight) has
|
|
43
|
+
* no entry — the monitor must leave that block's state untouched.
|
|
44
|
+
*/
|
|
45
|
+
growth: Map<string, GrowthOutcome>;
|
|
29
46
|
}
|
|
30
47
|
/**
|
|
31
48
|
* Coordinates block transfers in response to rebalance events.
|
|
@@ -37,6 +54,13 @@ export interface RebalanceReactionResult {
|
|
|
37
54
|
* via the BlockTransfer protocol.
|
|
38
55
|
*/
|
|
39
56
|
export declare class BlockTransferCoordinator {
|
|
57
|
+
/**
|
|
58
|
+
* The node's OWN store, proof accessor REQUIRED (not the optional `ArchiveServingRepo`
|
|
59
|
+
* shape): every push this class makes is certified out of it, and a repo without the
|
|
60
|
+
* accessor would make `sourceBlockCertification` return meta-only for every block — so
|
|
61
|
+
* every push would be refused by a receiver running the default `requirePushCertificate`,
|
|
62
|
+
* silently and with no type error. Same reasoning as `createServedRepoProxy`'s.
|
|
63
|
+
*/
|
|
40
64
|
private readonly repo;
|
|
41
65
|
private readonly peerNetwork;
|
|
42
66
|
private readonly restorationCoordinator;
|
|
@@ -49,7 +73,15 @@ export declare class BlockTransferCoordinator {
|
|
|
49
73
|
private inFlight;
|
|
50
74
|
private concurrency;
|
|
51
75
|
private readonly waitQueue;
|
|
52
|
-
constructor(
|
|
76
|
+
constructor(
|
|
77
|
+
/**
|
|
78
|
+
* The node's OWN store, proof accessor REQUIRED (not the optional `ArchiveServingRepo`
|
|
79
|
+
* shape): every push this class makes is certified out of it, and a repo without the
|
|
80
|
+
* accessor would make `sourceBlockCertification` return meta-only for every block — so
|
|
81
|
+
* every push would be refused by a receiver running the default `requirePushCertificate`,
|
|
82
|
+
* silently and with no type error. Same reasoning as `createServedRepoProxy`'s.
|
|
83
|
+
*/
|
|
84
|
+
repo: ProofRetainingRepo, peerNetwork: IPeerNetwork, restorationCoordinator: RestorationCoordinator, partitionDetector: PartitionDetector, protocolPrefix?: string, config?: BlockTransferConfig);
|
|
53
85
|
/**
|
|
54
86
|
* Pull blocks that this node has gained responsibility for.
|
|
55
87
|
* Uses RestorationCoordinator to discover holders and fetch block data.
|
|
@@ -76,6 +108,27 @@ export declare class BlockTransferCoordinator {
|
|
|
76
108
|
* hole (`docs/arachnode-ring-handoff.md` § Why the current code violates it #2).
|
|
77
109
|
*/
|
|
78
110
|
handleRebalanceEvent(event: RebalanceEvent): Promise<RebalanceReactionResult>;
|
|
111
|
+
/**
|
|
112
|
+
* Push each GROWN block (still owned; new peers became co-responsible) to its newly
|
|
113
|
+
* co-responsible peers, reusing {@link executeConfirm} per block. The per-block floor is
|
|
114
|
+
* `min(event floor, new-peer count)`: passing the raw event floor would be wrong when fewer new
|
|
115
|
+
* peers exist than the floor — `executeConfirm` could then never reach the floor and would burn
|
|
116
|
+
* `maxRetries` re-pushing peers that already accepted. Nothing is released off this path (the
|
|
117
|
+
* node KEEPS the block either way); the confirmed/unconfirmed split is reporting only. The
|
|
118
|
+
* in-flight `confirm:<id>` key dedups against a concurrent lost-confirm for the same block —
|
|
119
|
+
* such a block gets NO `growth` entry (no information), so the monitor leaves it untouched.
|
|
120
|
+
* `enablePush` deliberately does not gate this (same rationale as the NOTE in
|
|
121
|
+
* {@link confirmReplicated}); the growth arm as a whole is gated by the `rebalance.enabled`
|
|
122
|
+
* wiring in `libp2p-node-base`.
|
|
123
|
+
*
|
|
124
|
+
* Per-block {@link GrowthOutcome} rules:
|
|
125
|
+
* - floor met → all reported peers satisfied, complete. Deliberately includes peers
|
|
126
|
+
* `executeConfirm` skipped once the floor was reached — the block is adequately replicated,
|
|
127
|
+
* and re-pushing the remainder on every check forever would be a live loop.
|
|
128
|
+
* - no local data → all reported peers satisfied, complete (nothing to replicate; see NOTE).
|
|
129
|
+
* - otherwise → only the peers that actually confirmed, incomplete (retried by the monitor).
|
|
130
|
+
*/
|
|
131
|
+
private replicateGrown;
|
|
79
132
|
/**
|
|
80
133
|
* Confirm each block is replicated to at least `floor` qualifying owners — the gate the ring-shift
|
|
81
134
|
* handoff (Phase B) and the rebalance release both open before a block may stop being served.
|
|
@@ -99,10 +152,17 @@ export declare class BlockTransferCoordinator {
|
|
|
99
152
|
private executePull;
|
|
100
153
|
private executePush;
|
|
101
154
|
/**
|
|
102
|
-
* Confirm one block replicated to ≥ `floor` distinct qualifying owners. Reads the local block once
|
|
103
|
-
* pushes to each candidate owner (stopping once the floor is reached), and counts
|
|
104
|
-
* that report holding it (not `missing`). Retries the whole round up to
|
|
105
|
-
*
|
|
155
|
+
* Confirm one block replicated to ≥ `floor` distinct qualifying owners. Reads the local block once
|
|
156
|
+
* per attempt, pushes to each candidate owner (stopping once the floor is reached), and counts
|
|
157
|
+
* distinct owners that report holding it (not `missing`). Retries the whole round up to
|
|
158
|
+
* `maxRetries` before giving up.
|
|
159
|
+
*
|
|
160
|
+
* Returns `null` when a confirm for this block is already in flight (no information — the caller
|
|
161
|
+
* must not record anything for it). Otherwise: `confirmed` iff the floor was met; `confirmedPeers`
|
|
162
|
+
* is the union of owners that confirmed across every attempt (a peer that accepted a push holds a
|
|
163
|
+
* replica even if a later round missed it — the floor decision itself stays per-round, unchanged);
|
|
164
|
+
* `noLocalData` marks the nothing-local-to-push case. The lost-block release path uses only
|
|
165
|
+
* `confirmed`; the growth arm consumes the other two.
|
|
106
166
|
*/
|
|
107
167
|
private executeConfirm;
|
|
108
168
|
private acquireSemaphore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-transfer.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"block-transfer.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer.ts"],"names":[],"mappings":"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"}
|