@lodestar/beacon-node 1.40.0-dev.737da5eee3 → 1.40.0-dev.787d0f5eee
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/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +2 -8
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +0 -28
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +1 -36
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +0 -8
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +2 -1
- package/lib/chain/chain.js.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts +0 -19
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +0 -71
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/options.d.ts +0 -6
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js.map +1 -1
- package/lib/network/processor/gossipHandlers.js +1 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +12 -22
- package/src/chain/blocks/blockInput/blockInput.ts +2 -45
- package/src/chain/blocks/writeBlockInputToDb.ts +0 -9
- package/src/chain/chain.ts +2 -1
- package/src/network/gossip/gossipsub.ts +1 -86
- package/src/network/options.ts +0 -6
- package/src/network/processor/gossipHandlers.ts +1 -1
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.40.0-dev.
|
|
14
|
+
"version": "1.40.0-dev.787d0f5eee",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -134,18 +134,18 @@
|
|
|
134
134
|
"@libp2p/peer-id": "^5.1.0",
|
|
135
135
|
"@libp2p/prometheus-metrics": "^4.3.15",
|
|
136
136
|
"@libp2p/tcp": "^10.1.8",
|
|
137
|
-
"@lodestar/api": "^1.40.0-dev.
|
|
138
|
-
"@lodestar/config": "^1.40.0-dev.
|
|
139
|
-
"@lodestar/db": "^1.40.0-dev.
|
|
140
|
-
"@lodestar/fork-choice": "^1.40.0-dev.
|
|
141
|
-
"@lodestar/light-client": "^1.40.0-dev.
|
|
142
|
-
"@lodestar/logger": "^1.40.0-dev.
|
|
143
|
-
"@lodestar/params": "^1.40.0-dev.
|
|
144
|
-
"@lodestar/reqresp": "^1.40.0-dev.
|
|
145
|
-
"@lodestar/state-transition": "^1.40.0-dev.
|
|
146
|
-
"@lodestar/types": "^1.40.0-dev.
|
|
147
|
-
"@lodestar/utils": "^1.40.0-dev.
|
|
148
|
-
"@lodestar/validator": "^1.40.0-dev.
|
|
137
|
+
"@lodestar/api": "^1.40.0-dev.787d0f5eee",
|
|
138
|
+
"@lodestar/config": "^1.40.0-dev.787d0f5eee",
|
|
139
|
+
"@lodestar/db": "^1.40.0-dev.787d0f5eee",
|
|
140
|
+
"@lodestar/fork-choice": "^1.40.0-dev.787d0f5eee",
|
|
141
|
+
"@lodestar/light-client": "^1.40.0-dev.787d0f5eee",
|
|
142
|
+
"@lodestar/logger": "^1.40.0-dev.787d0f5eee",
|
|
143
|
+
"@lodestar/params": "^1.40.0-dev.787d0f5eee",
|
|
144
|
+
"@lodestar/reqresp": "^1.40.0-dev.787d0f5eee",
|
|
145
|
+
"@lodestar/state-transition": "^1.40.0-dev.787d0f5eee",
|
|
146
|
+
"@lodestar/types": "^1.40.0-dev.787d0f5eee",
|
|
147
|
+
"@lodestar/utils": "^1.40.0-dev.787d0f5eee",
|
|
148
|
+
"@lodestar/validator": "^1.40.0-dev.787d0f5eee",
|
|
149
149
|
"@multiformats/multiaddr": "^12.1.3",
|
|
150
150
|
"datastore-core": "^10.0.2",
|
|
151
151
|
"datastore-fs": "^10.0.6",
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"@chainsafe/swap-or-not-shuffle": "^1.2.1",
|
|
170
170
|
"@libp2p/interface-internal": "^2.3.18",
|
|
171
171
|
"@libp2p/logger": "^5.1.21",
|
|
172
|
-
"@lodestar/spec-test-util": "^1.40.0-dev.
|
|
172
|
+
"@lodestar/spec-test-util": "^1.40.0-dev.787d0f5eee",
|
|
173
173
|
"@types/js-yaml": "^4.0.5",
|
|
174
174
|
"@types/qs": "^6.9.7",
|
|
175
175
|
"@types/tmp": "^0.2.3",
|
|
@@ -188,5 +188,5 @@
|
|
|
188
188
|
"beacon",
|
|
189
189
|
"blockchain"
|
|
190
190
|
],
|
|
191
|
-
"gitHead": "
|
|
191
|
+
"gitHead": "652021e4737c3fcce4b03f730fef446fb1883061"
|
|
192
192
|
}
|
|
@@ -133,31 +133,21 @@ export function getBeaconBlockApi({
|
|
|
133
133
|
|
|
134
134
|
if (isBlockInputColumns(blockForImport)) {
|
|
135
135
|
for (const dataColumnSidecar of dataColumnSidecars) {
|
|
136
|
-
blockForImport.addColumn(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
},
|
|
143
|
-
// In multi-BN setups (DVT, fallback), the same block may be published to multiple nodes.
|
|
144
|
-
// Data columns may arrive via gossip from another node before the API publish completes,
|
|
145
|
-
// so we allow duplicates here instead of throwing an error.
|
|
146
|
-
{throwOnDuplicateAdd: false}
|
|
147
|
-
);
|
|
136
|
+
blockForImport.addColumn({
|
|
137
|
+
blockRootHex: blockRoot,
|
|
138
|
+
columnSidecar: dataColumnSidecar,
|
|
139
|
+
source: BlockInputSource.api,
|
|
140
|
+
seenTimestampSec,
|
|
141
|
+
});
|
|
148
142
|
}
|
|
149
143
|
} else if (isBlockInputBlobs(blockForImport)) {
|
|
150
144
|
for (const blobSidecar of blobSidecars) {
|
|
151
|
-
blockForImport.addBlob(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
// Same as above for columns
|
|
159
|
-
{throwOnDuplicateAdd: false}
|
|
160
|
-
);
|
|
145
|
+
blockForImport.addBlob({
|
|
146
|
+
blockRootHex: blockRoot,
|
|
147
|
+
blobSidecar,
|
|
148
|
+
source: BlockInputSource.api,
|
|
149
|
+
seenTimestampSec,
|
|
150
|
+
});
|
|
161
151
|
}
|
|
162
152
|
}
|
|
163
153
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas
|
|
1
|
+
import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas} from "@lodestar/params";
|
|
2
2
|
import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
3
3
|
import {fromHex, prettyBytes, toRootHex, withTimeout} from "@lodestar/utils";
|
|
4
4
|
import {VersionedHashes} from "../../../execution/index.js";
|
|
@@ -561,7 +561,6 @@ type BlockInputColumnsState =
|
|
|
561
561
|
| {
|
|
562
562
|
hasBlock: true;
|
|
563
563
|
hasAllData: true;
|
|
564
|
-
hasComputedAllData: boolean;
|
|
565
564
|
versionedHashes: VersionedHashes;
|
|
566
565
|
block: SignedBeaconBlock<ForkColumnsDA>;
|
|
567
566
|
source: SourceMeta;
|
|
@@ -570,7 +569,6 @@ type BlockInputColumnsState =
|
|
|
570
569
|
| {
|
|
571
570
|
hasBlock: true;
|
|
572
571
|
hasAllData: false;
|
|
573
|
-
hasComputedAllData: false;
|
|
574
572
|
versionedHashes: VersionedHashes;
|
|
575
573
|
block: SignedBeaconBlock<ForkColumnsDA>;
|
|
576
574
|
source: SourceMeta;
|
|
@@ -578,13 +576,11 @@ type BlockInputColumnsState =
|
|
|
578
576
|
| {
|
|
579
577
|
hasBlock: false;
|
|
580
578
|
hasAllData: true;
|
|
581
|
-
hasComputedAllData: boolean;
|
|
582
579
|
versionedHashes: VersionedHashes;
|
|
583
580
|
}
|
|
584
581
|
| {
|
|
585
582
|
hasBlock: false;
|
|
586
583
|
hasAllData: false;
|
|
587
|
-
hasComputedAllData: false;
|
|
588
584
|
versionedHashes: VersionedHashes;
|
|
589
585
|
};
|
|
590
586
|
/**
|
|
@@ -602,12 +598,6 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
602
598
|
private columnsCache = new Map<ColumnIndex, ColumnWithSource>();
|
|
603
599
|
private readonly sampledColumns: ColumnIndex[];
|
|
604
600
|
private readonly custodyColumns: ColumnIndex[];
|
|
605
|
-
/**
|
|
606
|
-
* This promise resolves when all sampled columns are available
|
|
607
|
-
*
|
|
608
|
-
* This is different from `dataPromise` which resolves when all data is available or could become available (e.g. through reconstruction)
|
|
609
|
-
*/
|
|
610
|
-
protected computedDataPromise = createPromise<fulu.DataColumnSidecars>();
|
|
611
601
|
|
|
612
602
|
private constructor(
|
|
613
603
|
init: BlockInputInit,
|
|
@@ -636,7 +626,6 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
636
626
|
const state = {
|
|
637
627
|
hasBlock: true,
|
|
638
628
|
hasAllData,
|
|
639
|
-
hasComputedAllData: hasAllData,
|
|
640
629
|
versionedHashes: props.block.message.body.blobKzgCommitments.map(kzgCommitmentToVersionedHash),
|
|
641
630
|
block: props.block,
|
|
642
631
|
source: {
|
|
@@ -660,7 +649,6 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
660
649
|
blockInput.blockPromise.resolve(props.block);
|
|
661
650
|
if (hasAllData) {
|
|
662
651
|
blockInput.dataPromise.resolve([]);
|
|
663
|
-
blockInput.computedDataPromise.resolve([]);
|
|
664
652
|
}
|
|
665
653
|
return blockInput;
|
|
666
654
|
}
|
|
@@ -673,7 +661,6 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
673
661
|
const state: BlockInputColumnsState = {
|
|
674
662
|
hasBlock: false,
|
|
675
663
|
hasAllData,
|
|
676
|
-
hasComputedAllData: hasAllData as false,
|
|
677
664
|
versionedHashes: props.columnSidecar.kzgCommitments.map(kzgCommitmentToVersionedHash),
|
|
678
665
|
};
|
|
679
666
|
const init: BlockInputInit = {
|
|
@@ -687,7 +674,6 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
687
674
|
const blockInput = new BlockInputColumns(init, state, props.sampledColumns, props.custodyColumns);
|
|
688
675
|
if (hasAllData) {
|
|
689
676
|
blockInput.dataPromise.resolve([]);
|
|
690
|
-
blockInput.computedDataPromise.resolve([]);
|
|
691
677
|
}
|
|
692
678
|
return blockInput;
|
|
693
679
|
}
|
|
@@ -736,14 +722,11 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
736
722
|
const hasAllData =
|
|
737
723
|
(props.block.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments.length === 0 ||
|
|
738
724
|
this.state.hasAllData;
|
|
739
|
-
const hasComputedAllData =
|
|
740
|
-
props.block.message.body.blobKzgCommitments.length === 0 || this.state.hasComputedAllData;
|
|
741
725
|
|
|
742
726
|
this.state = {
|
|
743
727
|
...this.state,
|
|
744
728
|
hasBlock: true,
|
|
745
729
|
hasAllData,
|
|
746
|
-
hasComputedAllData,
|
|
747
730
|
block: props.block,
|
|
748
731
|
source: {
|
|
749
732
|
source: props.source,
|
|
@@ -791,32 +774,17 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
791
774
|
this.columnsCache.set(columnSidecar.index, {columnSidecar, source, seenTimestampSec, peerIdStr});
|
|
792
775
|
|
|
793
776
|
const sampledColumns = this.getSampledColumns();
|
|
794
|
-
const hasAllData =
|
|
795
|
-
// already hasAllData
|
|
796
|
-
this.state.hasAllData ||
|
|
797
|
-
// has all sampled columns
|
|
798
|
-
sampledColumns.length === this.sampledColumns.length ||
|
|
799
|
-
// has enough columns to reconstruct the rest
|
|
800
|
-
this.columnsCache.size >= NUMBER_OF_COLUMNS / 2;
|
|
801
|
-
|
|
802
|
-
const hasComputedAllData =
|
|
803
|
-
// has all sampled columns
|
|
804
|
-
sampledColumns.length === this.sampledColumns.length;
|
|
777
|
+
const hasAllData = this.state.hasAllData || sampledColumns.length === this.sampledColumns.length;
|
|
805
778
|
|
|
806
779
|
this.state = {
|
|
807
780
|
...this.state,
|
|
808
781
|
hasAllData: hasAllData || this.state.hasAllData,
|
|
809
|
-
hasComputedAllData: hasComputedAllData || this.state.hasComputedAllData,
|
|
810
782
|
timeCompleteSec: hasAllData ? seenTimestampSec : undefined,
|
|
811
783
|
} as BlockInputColumnsState;
|
|
812
784
|
|
|
813
785
|
if (hasAllData && sampledColumns !== null) {
|
|
814
786
|
this.dataPromise.resolve(sampledColumns);
|
|
815
787
|
}
|
|
816
|
-
|
|
817
|
-
if (hasComputedAllData && sampledColumns !== null) {
|
|
818
|
-
this.computedDataPromise.resolve(sampledColumns);
|
|
819
|
-
}
|
|
820
788
|
}
|
|
821
789
|
|
|
822
790
|
hasColumn(columnIndex: number): boolean {
|
|
@@ -891,15 +859,4 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
891
859
|
versionedHashes: this.state.versionedHashes,
|
|
892
860
|
};
|
|
893
861
|
}
|
|
894
|
-
|
|
895
|
-
hasComputedAllData(): boolean {
|
|
896
|
-
return this.state.hasComputedAllData;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecars> {
|
|
900
|
-
if (!this.state.hasComputedAllData) {
|
|
901
|
-
return withTimeout(() => this.computedDataPromise.promise, timeout, signal);
|
|
902
|
-
}
|
|
903
|
-
return Promise.resolve(this.getSampledColumns());
|
|
904
|
-
}
|
|
905
862
|
}
|
|
@@ -44,15 +44,6 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInputs: IBloc
|
|
|
44
44
|
|
|
45
45
|
// NOTE: Old data is pruned on archive
|
|
46
46
|
if (isBlockInputColumns(blockInput)) {
|
|
47
|
-
if (!blockInput.hasComputedAllData()) {
|
|
48
|
-
// Supernodes may only have a subset of the data columns by the time the block begins to be imported
|
|
49
|
-
// because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
|
|
50
|
-
// Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
|
|
51
|
-
await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
|
|
52
|
-
this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
47
|
const {custodyColumns} = this.custodyConfig;
|
|
57
48
|
const blobsLen = (block.message as fulu.BeaconBlock).body.blobKzgCommitments.length;
|
|
58
49
|
let dataColumnsLen: number;
|
package/src/chain/chain.ts
CHANGED
|
@@ -340,8 +340,9 @@ export class BeaconChain implements IBeaconChain {
|
|
|
340
340
|
const blockStateCache = new FIFOBlockStateCache(this.opts, {metrics});
|
|
341
341
|
this.bufferPool = new BufferPool(anchorState.type.tree_serializedSize(anchorState.node), metrics);
|
|
342
342
|
|
|
343
|
+
let checkpointStateCache: CheckpointStateCache;
|
|
343
344
|
this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
|
|
344
|
-
|
|
345
|
+
checkpointStateCache = new PersistentCheckpointStateCache(
|
|
345
346
|
{
|
|
346
347
|
config,
|
|
347
348
|
metrics,
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {peerIdFromString} from "@libp2p/peer-id";
|
|
2
|
-
import {multiaddr} from "@multiformats/multiaddr";
|
|
3
|
-
import {ENR} from "@chainsafe/enr";
|
|
4
1
|
import {GossipSub, GossipsubEvents} from "@chainsafe/libp2p-gossipsub";
|
|
5
2
|
import {MetricsRegister, TopicLabel, TopicStrToLabel} from "@chainsafe/libp2p-gossipsub/metrics";
|
|
6
3
|
import {PeerScoreParams} from "@chainsafe/libp2p-gossipsub/score";
|
|
7
|
-
import {
|
|
4
|
+
import {SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
|
|
8
5
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
9
6
|
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
10
7
|
import {SubnetID} from "@lodestar/types";
|
|
@@ -58,12 +55,6 @@ export type Eth2GossipsubOpts = {
|
|
|
58
55
|
disableFloodPublish?: boolean;
|
|
59
56
|
skipParamsLog?: boolean;
|
|
60
57
|
disableLightClientServer?: boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
|
|
63
|
-
* Supports multiaddr strings with peer ID (e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...")
|
|
64
|
-
* or ENR strings (e.g., "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...")
|
|
65
|
-
*/
|
|
66
|
-
directPeers?: string[];
|
|
67
58
|
};
|
|
68
59
|
|
|
69
60
|
export type ForkBoundaryLabel = string;
|
|
@@ -106,9 +97,6 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
106
97
|
);
|
|
107
98
|
}
|
|
108
99
|
|
|
109
|
-
// Parse direct peers from multiaddr strings to AddrInfo objects
|
|
110
|
-
const directPeers = parseDirectPeers(opts.directPeers ?? [], logger);
|
|
111
|
-
|
|
112
100
|
// Gossipsub parameters defined here:
|
|
113
101
|
// https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
|
|
114
102
|
super(modules.libp2p.services.components, {
|
|
@@ -118,7 +106,6 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
118
106
|
Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
|
|
119
107
|
Dhi: gossipsubDHigh ?? GOSSIP_D_HIGH,
|
|
120
108
|
Dlazy: 6,
|
|
121
|
-
directPeers,
|
|
122
109
|
heartbeatInterval: GOSSIPSUB_HEARTBEAT_INTERVAL,
|
|
123
110
|
fanoutTTL: 60 * 1000,
|
|
124
111
|
mcacheLength: 6,
|
|
@@ -394,75 +381,3 @@ function getForkBoundaryLabel(boundary: ForkBoundary): ForkBoundaryLabel {
|
|
|
394
381
|
|
|
395
382
|
return label;
|
|
396
383
|
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Parse direct peer strings into AddrInfo objects for GossipSub.
|
|
400
|
-
* Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
|
|
401
|
-
*
|
|
402
|
-
* Supported formats:
|
|
403
|
-
* - Multiaddr with peer ID: `/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...`
|
|
404
|
-
* - ENR: `enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...`
|
|
405
|
-
*
|
|
406
|
-
* For multiaddrs, the string must contain a /p2p/ component with the peer ID.
|
|
407
|
-
* For ENRs, the TCP multiaddr and peer ID are extracted from the encoded record.
|
|
408
|
-
*/
|
|
409
|
-
export function parseDirectPeers(directPeerStrs: string[], logger: Logger): AddrInfo[] {
|
|
410
|
-
const directPeers: AddrInfo[] = [];
|
|
411
|
-
|
|
412
|
-
for (const peerStr of directPeerStrs) {
|
|
413
|
-
// Check if this is an ENR (starts with "enr:")
|
|
414
|
-
if (peerStr.startsWith("enr:")) {
|
|
415
|
-
try {
|
|
416
|
-
const enr = ENR.decodeTxt(peerStr);
|
|
417
|
-
const peerId = enr.peerId;
|
|
418
|
-
|
|
419
|
-
// Get TCP multiaddr from ENR
|
|
420
|
-
const multiaddrTCP = enr.getLocationMultiaddr("tcp");
|
|
421
|
-
if (!multiaddrTCP) {
|
|
422
|
-
logger.warn("ENR does not contain TCP multiaddr", {enr: peerStr});
|
|
423
|
-
continue;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
directPeers.push({
|
|
427
|
-
id: peerId,
|
|
428
|
-
addrs: [multiaddrTCP],
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
logger.info("Added direct peer from ENR", {peerId: peerId.toString(), addr: multiaddrTCP.toString()});
|
|
432
|
-
} catch (e) {
|
|
433
|
-
logger.warn("Failed to parse direct peer ENR", {enr: peerStr}, e as Error);
|
|
434
|
-
}
|
|
435
|
-
} else {
|
|
436
|
-
// Parse as multiaddr
|
|
437
|
-
try {
|
|
438
|
-
const ma = multiaddr(peerStr);
|
|
439
|
-
|
|
440
|
-
const peerIdStr = ma.getPeerId();
|
|
441
|
-
if (!peerIdStr) {
|
|
442
|
-
logger.warn("Direct peer multiaddr must contain /p2p/ component with peer ID", {multiaddr: peerStr});
|
|
443
|
-
continue;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
try {
|
|
447
|
-
const peerId = peerIdFromString(peerIdStr);
|
|
448
|
-
|
|
449
|
-
// Get the address without the /p2p/ component
|
|
450
|
-
const addr = ma.decapsulate("/p2p/" + peerIdStr);
|
|
451
|
-
|
|
452
|
-
directPeers.push({
|
|
453
|
-
id: peerId,
|
|
454
|
-
addrs: [addr],
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
logger.info("Added direct peer", {peerId: peerIdStr, addr: addr.toString()});
|
|
458
|
-
} catch (e) {
|
|
459
|
-
logger.warn("Invalid peer ID in direct peer multiaddr", {multiaddr: peerStr, peerId: peerIdStr}, e as Error);
|
|
460
|
-
}
|
|
461
|
-
} catch (e) {
|
|
462
|
-
logger.warn("Failed to parse direct peer multiaddr", {multiaddr: peerStr}, e as Error);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
return directPeers;
|
|
468
|
-
}
|
package/src/network/options.ts
CHANGED
|
@@ -15,12 +15,6 @@ export interface NetworkOptions
|
|
|
15
15
|
Omit<Eth2GossipsubOpts, "disableLightClientServer"> {
|
|
16
16
|
localMultiaddrs: string[];
|
|
17
17
|
bootMultiaddrs?: string[];
|
|
18
|
-
/**
|
|
19
|
-
* Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
|
|
20
|
-
* Format: multiaddr strings with peer ID, e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7..."
|
|
21
|
-
* Both peers must configure each other as direct peers for the feature to work properly.
|
|
22
|
-
*/
|
|
23
|
-
directPeers?: string[];
|
|
24
18
|
subscribeAllSubnets?: boolean;
|
|
25
19
|
mdns?: boolean;
|
|
26
20
|
connectToDiscv5Bootnodes?: boolean;
|
|
@@ -579,7 +579,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
579
579
|
break;
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
-
if (!blockInput.
|
|
582
|
+
if (!blockInput.hasAllData()) {
|
|
583
583
|
// immediately attempt fetch of data columns from execution engine
|
|
584
584
|
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
585
585
|
// if we've received at least half of the columns, trigger reconstruction of the rest
|