@lodestar/beacon-node 1.40.0-dev.1c71f4299a → 1.40.0-dev.2ae7375100
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 +7 -7
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +10 -2
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +9 -8
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +7 -3
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +3 -1
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +5 -3
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +2 -2
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -2
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +4 -2
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +2 -2
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +9 -6
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +36 -18
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/attestationError.d.ts +14 -1
- package/lib/chain/errors/attestationError.d.ts.map +1 -1
- package/lib/chain/errors/attestationError.js +8 -0
- package/lib/chain/errors/attestationError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
- package/lib/chain/errors/executionPayloadBid.js +15 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
- package/lib/chain/errors/index.d.ts +3 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +3 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/payloadAttestation.d.ts +34 -0
- package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
- package/lib/chain/errors/payloadAttestation.js +13 -0
- package/lib/chain/errors/payloadAttestation.js.map +1 -0
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +18 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +7 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
- package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
- package/lib/chain/opPools/index.d.ts +2 -0
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +2 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
- package/lib/chain/opPools/payloadAttestationPool.js +109 -0
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
- package/lib/chain/prepareNextSlot.js +6 -4
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +5 -3
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +3 -8
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -1
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +1 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +2 -16
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +5 -7
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +7 -17
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +3 -1
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +3 -1
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +5 -0
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/seenCache/seenGossipBlockInput.js +1 -1
- package/lib/chain/validation/aggregateAndProof.js +35 -14
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts +2 -2
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +27 -8
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
- package/lib/chain/validation/blobSidecar.js +3 -3
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +5 -4
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +3 -3
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
- package/lib/chain/validation/executionPayloadBid.js +104 -0
- package/lib/chain/validation/executionPayloadBid.js.map +1 -0
- package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
- package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
- package/lib/chain/validation/payloadAttestationMessage.js +72 -0
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
- package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.js +1 -1
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +7 -4
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/db/repositories/checkpointState.js +0 -1
- package/lib/db/repositories/checkpointState.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +20 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +40 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +20 -2
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +3 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +38 -2
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +77 -1
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +20 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +34 -0
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +16 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +3 -0
- package/lib/network/processor/index.js.map +1 -1
- package/lib/sync/backfill/backfill.js +2 -2
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +1 -2
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +2 -2
- package/lib/sync/backfill/verify.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +9 -7
- package/src/api/impl/lodestar/index.ts +12 -3
- package/src/api/impl/validator/index.ts +12 -11
- package/src/chain/ColumnReconstructionTracker.ts +8 -4
- package/src/chain/blocks/verifyBlock.ts +0 -1
- package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
- package/src/chain/bls/multithread/index.ts +7 -4
- package/src/chain/bls/multithread/jobItem.ts +7 -3
- package/src/chain/bls/singleThread.ts +5 -3
- package/src/chain/bls/utils.ts +15 -7
- package/src/chain/chain.ts +39 -26
- package/src/chain/errors/attestationError.ts +11 -1
- package/src/chain/errors/executionPayloadBid.ts +35 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
- package/src/chain/errors/index.ts +3 -0
- package/src/chain/errors/payloadAttestation.ts +25 -0
- package/src/chain/forkChoice/index.ts +19 -0
- package/src/chain/interface.ts +16 -1
- package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
- package/src/chain/opPools/index.ts +2 -0
- package/src/chain/opPools/payloadAttestationPool.ts +157 -0
- package/src/chain/prepareNextSlot.ts +6 -6
- package/src/chain/produceBlock/produceBlockBody.ts +7 -5
- package/src/chain/regen/interface.ts +2 -12
- package/src/chain/regen/queued.ts +3 -23
- package/src/chain/regen/regen.ts +10 -25
- package/src/chain/seenCache/index.ts +3 -1
- package/src/chain/seenCache/seenAttesters.ts +5 -0
- package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
- package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
- package/src/chain/seenCache/seenGossipBlockInput.ts +1 -1
- package/src/chain/validation/aggregateAndProof.ts +36 -14
- package/src/chain/validation/attestation.ts +33 -16
- package/src/chain/validation/attesterSlashing.ts +1 -6
- package/src/chain/validation/blobSidecar.ts +2 -7
- package/src/chain/validation/block.ts +5 -4
- package/src/chain/validation/dataColumnSidecar.ts +2 -7
- package/src/chain/validation/executionPayloadBid.ts +141 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
- package/src/chain/validation/payloadAttestationMessage.ts +109 -0
- package/src/chain/validation/proposerSlashing.ts +1 -6
- package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
- package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
- package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
- package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
- package/src/chain/validation/syncCommittee.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/chain/validatorMonitor.ts +10 -5
- package/src/db/repositories/checkpointState.ts +1 -1
- package/src/metrics/metrics/lodestar.ts +40 -0
- package/src/network/gossip/interface.ts +17 -0
- package/src/network/gossip/scoringParameters.ts +44 -2
- package/src/network/gossip/topic.ts +21 -0
- package/src/network/processor/gossipHandlers.ts +48 -0
- package/src/network/processor/gossipQueues/index.ts +16 -0
- package/src/network/processor/index.ts +3 -0
- package/src/sync/backfill/backfill.ts +2 -2
- package/src/sync/backfill/verify.ts +2 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {ForkName, isForkPostDeneb} from "@lodestar/params";
|
|
2
|
+
import {ForkName, isForkPostBellatrix, isForkPostDeneb, isForkPostGloas} from "@lodestar/params";
|
|
3
3
|
import {
|
|
4
4
|
computeEpochAtSlot,
|
|
5
5
|
computeStartSlotAtEpoch,
|
|
@@ -111,7 +111,7 @@ export async function validateGossipBlock(
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer -- i.e. validate that len(body.signed_beacon_block.message.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
|
|
114
|
-
if (isForkPostDeneb(fork)) {
|
|
114
|
+
if (isForkPostDeneb(fork) && !isForkPostGloas(fork)) {
|
|
115
115
|
const blobKzgCommitmentsLen = (block as deneb.BeaconBlock).body.blobKzgCommitments.length;
|
|
116
116
|
const maxBlobsPerBlock = config.getMaxBlobsPerBlock(computeEpochAtSlot(blockSlot));
|
|
117
117
|
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
@@ -128,6 +128,7 @@ export async function validateGossipBlock(
|
|
|
128
128
|
// this is something we should change this in the future to make the code airtight to the spec.
|
|
129
129
|
// [IGNORE] The block's parent (defined by block.parent_root) has been seen (via both gossip and non-gossip sources) (a client MAY queue blocks for processing once the parent block is retrieved).
|
|
130
130
|
// [REJECT] The block's parent (defined by block.parent_root) passes validation.
|
|
131
|
+
// TODO GLOAS: post-gloas, we check the validity of bid's parent payload, not the entire beacon block
|
|
131
132
|
const blockState = await chain.regen
|
|
132
133
|
.getPreState(block, {dontTransferCache: true}, RegenCaller.validateGossipBlock)
|
|
133
134
|
.catch(() => {
|
|
@@ -140,7 +141,7 @@ export async function validateGossipBlock(
|
|
|
140
141
|
// Extra conditions for merge fork blocks
|
|
141
142
|
// [REJECT] The block's execution payload timestamp is correct with respect to the slot
|
|
142
143
|
// -- i.e. execution_payload.timestamp == compute_timestamp_at_slot(state, block.slot).
|
|
143
|
-
if (fork
|
|
144
|
+
if (isForkPostBellatrix(fork) && !isForkPostGloas(fork)) {
|
|
144
145
|
if (!isExecutionBlockBodyType(block.body)) throw Error("Not merge block type");
|
|
145
146
|
const executionPayload = block.body.executionPayload;
|
|
146
147
|
if (isExecutionStateType(blockState) && isExecutionEnabled(blockState, block)) {
|
|
@@ -157,7 +158,7 @@ export async function validateGossipBlock(
|
|
|
157
158
|
|
|
158
159
|
// [REJECT] The proposer signature, signed_beacon_block.signature, is valid with respect to the proposer_index pubkey.
|
|
159
160
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRoot, signedBlock.signature)) {
|
|
160
|
-
const signatureSet = getBlockProposerSignatureSet(chain.config,
|
|
161
|
+
const signatureSet = getBlockProposerSignatureSet(chain.config, signedBlock);
|
|
161
162
|
// Don't batch so verification is not delayed
|
|
162
163
|
if (!(await chain.bls.verifySignatureSets([signatureSet], {verifyOnMainThread: true}))) {
|
|
163
164
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
@@ -106,7 +106,7 @@ export async function validateGossipDataColumnSidecar(
|
|
|
106
106
|
// this is something we should change this in the future to make the code airtight to the spec.
|
|
107
107
|
// 7) [REJECT] The sidecar's block's parent passes validation.
|
|
108
108
|
const blockState = await chain.regen
|
|
109
|
-
.getBlockSlotState(
|
|
109
|
+
.getBlockSlotState(parentBlock, blockHeader.slot, {dontTransferCache: true}, RegenCaller.validateGossipDataColumn)
|
|
110
110
|
.catch(() => {
|
|
111
111
|
throw new DataColumnSidecarGossipError(GossipAction.IGNORE, {
|
|
112
112
|
code: DataColumnSidecarErrorCode.PARENT_UNKNOWN,
|
|
@@ -136,7 +136,6 @@ export async function validateGossipDataColumnSidecar(
|
|
|
136
136
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockHeader.slot, blockRootHex, signature)) {
|
|
137
137
|
const signatureSet = getBlockHeaderProposerSignatureSetByParentStateSlot(
|
|
138
138
|
chain.config,
|
|
139
|
-
chain.index2pubkey,
|
|
140
139
|
blockState.slot,
|
|
141
140
|
dataColumnSidecar.signedBlockHeader
|
|
142
141
|
);
|
|
@@ -337,11 +336,7 @@ export async function validateBlockDataColumnSidecars(
|
|
|
337
336
|
const slot = firstSidecarSignedBlockHeader.message.slot;
|
|
338
337
|
const signature = firstSidecarSignedBlockHeader.signature;
|
|
339
338
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(slot, rootHex, signature)) {
|
|
340
|
-
const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(
|
|
341
|
-
chain.config,
|
|
342
|
-
chain.index2pubkey,
|
|
343
|
-
firstSidecarSignedBlockHeader
|
|
344
|
-
);
|
|
339
|
+
const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(chain.config, firstSidecarSignedBlockHeader);
|
|
345
340
|
|
|
346
341
|
if (
|
|
347
342
|
!(await chain.bls.verifySignatureSets([signatureSet], {
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {PublicKey} from "@chainsafe/blst";
|
|
2
|
+
import {
|
|
3
|
+
CachedBeaconStateGloas,
|
|
4
|
+
canBuilderCoverBid,
|
|
5
|
+
createSingleSignatureSetFromComponents,
|
|
6
|
+
getExecutionPayloadBidSigningRoot,
|
|
7
|
+
isActiveBuilder,
|
|
8
|
+
} from "@lodestar/state-transition";
|
|
9
|
+
import {gloas} from "@lodestar/types";
|
|
10
|
+
import {toRootHex} from "@lodestar/utils";
|
|
11
|
+
import {ExecutionPayloadBidError, ExecutionPayloadBidErrorCode, GossipAction} from "../errors/index.js";
|
|
12
|
+
import {IBeaconChain} from "../index.js";
|
|
13
|
+
import {RegenCaller} from "../regen/index.js";
|
|
14
|
+
|
|
15
|
+
export async function validateApiExecutionPayloadBid(
|
|
16
|
+
chain: IBeaconChain,
|
|
17
|
+
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
18
|
+
): Promise<void> {
|
|
19
|
+
return validateExecutionPayloadBid(chain, signedExecutionPayloadBid);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function validateGossipExecutionPayloadBid(
|
|
23
|
+
chain: IBeaconChain,
|
|
24
|
+
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
return validateExecutionPayloadBid(chain, signedExecutionPayloadBid);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function validateExecutionPayloadBid(
|
|
30
|
+
chain: IBeaconChain,
|
|
31
|
+
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
32
|
+
): Promise<void> {
|
|
33
|
+
const bid = signedExecutionPayloadBid.message;
|
|
34
|
+
const parentBlockRootHex = toRootHex(bid.parentBlockRoot);
|
|
35
|
+
const parentBlockHashHex = toRootHex(bid.parentBlockHash);
|
|
36
|
+
const state = (await chain.getHeadStateAtCurrentEpoch(
|
|
37
|
+
RegenCaller.validateGossipExecutionPayloadBid
|
|
38
|
+
)) as CachedBeaconStateGloas;
|
|
39
|
+
|
|
40
|
+
// [IGNORE] `bid.slot` is the current slot or the next slot.
|
|
41
|
+
const currentSlot = chain.clock.currentSlot;
|
|
42
|
+
if (bid.slot !== currentSlot && bid.slot !== currentSlot + 1) {
|
|
43
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
44
|
+
code: ExecutionPayloadBidErrorCode.INVALID_SLOT,
|
|
45
|
+
builderIndex: bid.builderIndex,
|
|
46
|
+
slot: bid.slot,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// [IGNORE] the `SignedProposerPreferences` where `preferences.proposal_slot`
|
|
51
|
+
// is equal to `bid.slot` has been seen.
|
|
52
|
+
// TODO GLOAS: Implement this along with proposer preference
|
|
53
|
+
|
|
54
|
+
// [REJECT] `bid.builder_index` is a valid/active builder index -- i.e.
|
|
55
|
+
// `is_active_builder(state, bid.builder_index)` returns `True`.
|
|
56
|
+
const builder = state.builders.getReadonly(bid.builderIndex);
|
|
57
|
+
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
58
|
+
throw new ExecutionPayloadBidError(GossipAction.REJECT, {
|
|
59
|
+
code: ExecutionPayloadBidErrorCode.BUILDER_NOT_ELIGIBLE,
|
|
60
|
+
builderIndex: bid.builderIndex,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// [REJECT] `bid.execution_payment` is zero.
|
|
65
|
+
if (bid.executionPayment !== 0) {
|
|
66
|
+
throw new ExecutionPayloadBidError(GossipAction.REJECT, {
|
|
67
|
+
code: ExecutionPayloadBidErrorCode.NON_ZERO_EXECUTION_PAYMENT,
|
|
68
|
+
builderIndex: bid.builderIndex,
|
|
69
|
+
executionPayment: bid.executionPayment,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// [REJECT] `bid.fee_recipient` matches the `fee_recipient` from the proposer's
|
|
74
|
+
// `SignedProposerPreferences` associated with `bid.slot`.
|
|
75
|
+
// [REJECT] `bid.gas_limit` matches the `gas_limit` from the proposer's
|
|
76
|
+
// `SignedProposerPreferences` associated with `bid.slot`.
|
|
77
|
+
// TODO GLOAS: Implement this along with proposer preference
|
|
78
|
+
|
|
79
|
+
// [IGNORE] this is the first signed bid seen with a valid signature from the given builder for this slot.
|
|
80
|
+
if (chain.seenExecutionPayloadBids.isKnown(bid.slot, bid.builderIndex)) {
|
|
81
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
82
|
+
code: ExecutionPayloadBidErrorCode.BID_ALREADY_KNOWN,
|
|
83
|
+
builderIndex: bid.builderIndex,
|
|
84
|
+
slot: bid.slot,
|
|
85
|
+
parentBlockRoot: parentBlockRootHex,
|
|
86
|
+
parentBlockHash: parentBlockHashHex,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// [IGNORE] this bid is the highest value bid seen for the corresponding slot
|
|
91
|
+
// and the given parent block hash.
|
|
92
|
+
const bestBid = chain.executionPayloadBidPool.getBestBid(parentBlockRootHex, parentBlockHashHex, bid.slot);
|
|
93
|
+
if (bestBid !== null && bestBid.value >= bid.value) {
|
|
94
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
95
|
+
code: ExecutionPayloadBidErrorCode.BID_TOO_LOW,
|
|
96
|
+
bidValue: bid.value,
|
|
97
|
+
currentHighestBid: bestBid.value,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// [IGNORE] `bid.value` is less or equal than the builder's excess balance --
|
|
101
|
+
// i.e. `can_builder_cover_bid(state, builder_index, amount)` returns `True`.
|
|
102
|
+
if (!canBuilderCoverBid(state, bid.builderIndex, bid.value)) {
|
|
103
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
104
|
+
code: ExecutionPayloadBidErrorCode.BID_TOO_HIGH,
|
|
105
|
+
bidValue: bid.value,
|
|
106
|
+
builderBalance: builder.balance,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// [IGNORE] `bid.parent_block_hash` is the block hash of a known execution
|
|
111
|
+
// payload in fork choice.
|
|
112
|
+
// TODO GLOAS: implement this
|
|
113
|
+
|
|
114
|
+
// [IGNORE] `bid.parent_block_root` is the hash tree root of a known beacon
|
|
115
|
+
// block in fork choice.
|
|
116
|
+
const block = chain.forkChoice.getBlock(bid.parentBlockRoot);
|
|
117
|
+
if (block === null) {
|
|
118
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
119
|
+
code: ExecutionPayloadBidErrorCode.UNKNOWN_BLOCK_ROOT,
|
|
120
|
+
parentBlockRoot: parentBlockRootHex,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// [REJECT] `signed_execution_payload_bid.signature` is valid with respect to the `bid.builder_index`.
|
|
125
|
+
const signatureSet = createSingleSignatureSetFromComponents(
|
|
126
|
+
PublicKey.fromBytes(builder.pubkey),
|
|
127
|
+
getExecutionPayloadBidSigningRoot(chain.config, state.slot, bid),
|
|
128
|
+
signedExecutionPayloadBid.signature
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
|
|
132
|
+
throw new ExecutionPayloadBidError(GossipAction.REJECT, {
|
|
133
|
+
code: ExecutionPayloadBidErrorCode.INVALID_SIGNATURE,
|
|
134
|
+
builderIndex: bid.builderIndex,
|
|
135
|
+
slot: bid.slot,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Valid
|
|
140
|
+
chain.seenExecutionPayloadBids.add(bid.slot, bid.builderIndex);
|
|
141
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {PublicKey} from "@chainsafe/blst";
|
|
2
|
+
import {
|
|
3
|
+
CachedBeaconStateGloas,
|
|
4
|
+
computeStartSlotAtEpoch,
|
|
5
|
+
createSingleSignatureSetFromComponents,
|
|
6
|
+
getExecutionPayloadEnvelopeSigningRoot,
|
|
7
|
+
} from "@lodestar/state-transition";
|
|
8
|
+
import {gloas} from "@lodestar/types";
|
|
9
|
+
import {toRootHex} from "@lodestar/utils";
|
|
10
|
+
import {ExecutionPayloadEnvelopeError, ExecutionPayloadEnvelopeErrorCode, GossipAction} from "../errors/index.js";
|
|
11
|
+
import {IBeaconChain} from "../index.js";
|
|
12
|
+
|
|
13
|
+
export async function validateApiExecutionPayloadEnvelope(
|
|
14
|
+
chain: IBeaconChain,
|
|
15
|
+
executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
return validateExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function validateGossipExecutionPayloadEnvelope(
|
|
21
|
+
chain: IBeaconChain,
|
|
22
|
+
executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
23
|
+
): Promise<void> {
|
|
24
|
+
return validateExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function validateExecutionPayloadEnvelope(
|
|
28
|
+
chain: IBeaconChain,
|
|
29
|
+
executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
30
|
+
): Promise<void> {
|
|
31
|
+
const envelope = executionPayloadEnvelope.message;
|
|
32
|
+
const {payload} = envelope;
|
|
33
|
+
const blockRootHex = toRootHex(envelope.beaconBlockRoot);
|
|
34
|
+
|
|
35
|
+
// [IGNORE] The envelope's block root `envelope.block_root` has been seen (via
|
|
36
|
+
// gossip or non-gossip sources) (a client MAY queue payload for processing once
|
|
37
|
+
// the block is retrieved).
|
|
38
|
+
// TODO GLOAS: Need to review this
|
|
39
|
+
const block = chain.forkChoice.getBlock(envelope.beaconBlockRoot);
|
|
40
|
+
if (block === null) {
|
|
41
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
42
|
+
code: ExecutionPayloadEnvelopeErrorCode.BLOCK_ROOT_UNKNOWN,
|
|
43
|
+
blockRoot: blockRootHex,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// [IGNORE] The node has not seen another valid
|
|
48
|
+
// `SignedExecutionPayloadEnvelope` for this block root from this builder.
|
|
49
|
+
if (chain.seenExecutionPayloadEnvelopes.isKnown(blockRootHex)) {
|
|
50
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
51
|
+
code: ExecutionPayloadEnvelopeErrorCode.ENVELOPE_ALREADY_KNOWN,
|
|
52
|
+
blockRoot: blockRootHex,
|
|
53
|
+
slot: envelope.slot,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// [IGNORE] The envelope is from a slot greater than or equal to the latest finalized slot -- i.e. validate that `envelope.slot >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)`
|
|
58
|
+
const finalizedCheckpoint = chain.forkChoice.getFinalizedCheckpoint();
|
|
59
|
+
const finalizedSlot = computeStartSlotAtEpoch(finalizedCheckpoint.epoch);
|
|
60
|
+
if (envelope.slot < finalizedSlot) {
|
|
61
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
62
|
+
code: ExecutionPayloadEnvelopeErrorCode.BELONG_TO_FINALIZED_BLOCK,
|
|
63
|
+
envelopeSlot: envelope.slot,
|
|
64
|
+
finalizedSlot,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// [REJECT] `block` passes validation.
|
|
69
|
+
// TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
|
|
70
|
+
// it is possible that the block didn't pass the validation
|
|
71
|
+
|
|
72
|
+
// [REJECT] `block.slot` equals `envelope.slot`.
|
|
73
|
+
if (block.slot !== envelope.slot) {
|
|
74
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
75
|
+
code: ExecutionPayloadEnvelopeErrorCode.SLOT_MISMATCH,
|
|
76
|
+
envelopeSlot: envelope.slot,
|
|
77
|
+
blockSlot: block.slot,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (block.builderIndex === undefined || block.blockHashHex === undefined) {
|
|
82
|
+
// This indicates this block is a pre-gloas block which is wrong
|
|
83
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
84
|
+
code: ExecutionPayloadEnvelopeErrorCode.CACHE_FAIL,
|
|
85
|
+
blockRoot: blockRootHex,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// [REJECT] `envelope.builder_index == bid.builder_index`
|
|
90
|
+
if (envelope.builderIndex !== block.builderIndex) {
|
|
91
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
92
|
+
code: ExecutionPayloadEnvelopeErrorCode.BUILDER_INDEX_MISMATCH,
|
|
93
|
+
envelopeBuilderIndex: envelope.builderIndex,
|
|
94
|
+
bidBuilderIndex: block.builderIndex,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// [REJECT] `payload.block_hash == bid.block_hash`
|
|
99
|
+
if (toRootHex(payload.blockHash) !== block.blockHashHex) {
|
|
100
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
101
|
+
code: ExecutionPayloadEnvelopeErrorCode.BLOCK_HASH_MISMATCH,
|
|
102
|
+
envelopeBlockHash: toRootHex(payload.blockHash),
|
|
103
|
+
bidBlockHash: block.blockHashHex,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// [REJECT] `signed_execution_payload_envelope.signature` is valid with respect to the builder's public key.
|
|
108
|
+
const state = chain.getHeadState() as CachedBeaconStateGloas;
|
|
109
|
+
const signatureSet = createSingleSignatureSetFromComponents(
|
|
110
|
+
PublicKey.fromBytes(state.builders.getReadonly(envelope.builderIndex).pubkey),
|
|
111
|
+
getExecutionPayloadEnvelopeSigningRoot(chain.config, envelope),
|
|
112
|
+
executionPayloadEnvelope.signature
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
|
|
116
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
117
|
+
code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
chain.seenExecutionPayloadEnvelopes.add(blockRootHex, envelope.slot);
|
|
122
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CachedBeaconStateGloas,
|
|
3
|
+
computeEpochAtSlot,
|
|
4
|
+
createSingleSignatureSetFromComponents,
|
|
5
|
+
getPayloadAttestationDataSigningRoot,
|
|
6
|
+
} from "@lodestar/state-transition";
|
|
7
|
+
import {RootHex, gloas, ssz} from "@lodestar/types";
|
|
8
|
+
import {toRootHex} from "@lodestar/utils";
|
|
9
|
+
import {GossipAction, PayloadAttestationError, PayloadAttestationErrorCode} from "../errors/index.js";
|
|
10
|
+
import {IBeaconChain} from "../index.js";
|
|
11
|
+
|
|
12
|
+
export type PayloadAttestationValidationResult = {
|
|
13
|
+
attDataRootHex: RootHex;
|
|
14
|
+
validatorCommitteeIndex: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export async function validateApiPayloadAttestationMessage(
|
|
18
|
+
chain: IBeaconChain,
|
|
19
|
+
payloadAttestationMessage: gloas.PayloadAttestationMessage
|
|
20
|
+
): Promise<PayloadAttestationValidationResult> {
|
|
21
|
+
return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function validateGossipPayloadAttestationMessage(
|
|
25
|
+
chain: IBeaconChain,
|
|
26
|
+
payloadAttestationMessage: gloas.PayloadAttestationMessage
|
|
27
|
+
): Promise<PayloadAttestationValidationResult> {
|
|
28
|
+
return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function validatePayloadAttestationMessage(
|
|
32
|
+
chain: IBeaconChain,
|
|
33
|
+
payloadAttestationMessage: gloas.PayloadAttestationMessage
|
|
34
|
+
): Promise<PayloadAttestationValidationResult> {
|
|
35
|
+
const {data, validatorIndex} = payloadAttestationMessage;
|
|
36
|
+
const epoch = computeEpochAtSlot(data.slot);
|
|
37
|
+
|
|
38
|
+
// [IGNORE] The message's slot is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. `data.slot == current_slot`.
|
|
39
|
+
if (!chain.clock.isCurrentSlotGivenGossipDisparity(data.slot)) {
|
|
40
|
+
throw new PayloadAttestationError(GossipAction.IGNORE, {
|
|
41
|
+
code: PayloadAttestationErrorCode.NOT_CURRENT_SLOT,
|
|
42
|
+
currentSlot: chain.clock.currentSlot,
|
|
43
|
+
slot: data.slot,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// [IGNORE] The `payload_attestation_message` is the first valid message received
|
|
48
|
+
// from the validator with index `payload_attestation_message.validator_index`.
|
|
49
|
+
// A single validator can participate PTC at most once per epoch
|
|
50
|
+
if (chain.seenPayloadAttesters.isKnown(epoch, validatorIndex)) {
|
|
51
|
+
throw new PayloadAttestationError(GossipAction.IGNORE, {
|
|
52
|
+
code: PayloadAttestationErrorCode.PAYLOAD_ATTESTATION_ALREADY_KNOWN,
|
|
53
|
+
validatorIndex,
|
|
54
|
+
slot: data.slot,
|
|
55
|
+
blockRoot: toRootHex(data.beaconBlockRoot),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// [IGNORE] The message's block `data.beacon_block_root` has been seen (via
|
|
60
|
+
// gossip or non-gossip sources) (a client MAY queue attestation for processing
|
|
61
|
+
// once the block is retrieved. Note a client might want to request payload after).
|
|
62
|
+
const block = chain.forkChoice.getBlock(data.beaconBlockRoot);
|
|
63
|
+
if (block === null) {
|
|
64
|
+
throw new PayloadAttestationError(GossipAction.IGNORE, {
|
|
65
|
+
code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT,
|
|
66
|
+
blockRoot: toRootHex(data.beaconBlockRoot),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const state = chain.getHeadState() as CachedBeaconStateGloas;
|
|
71
|
+
|
|
72
|
+
// [REJECT] The message's block `data.beacon_block_root` passes validation.
|
|
73
|
+
// TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
|
|
74
|
+
// it is possible that the block didn't pass the validation
|
|
75
|
+
|
|
76
|
+
// [REJECT] The message's validator index is within the payload committee in
|
|
77
|
+
// `get_ptc(state, data.slot)`. The `state` is the head state corresponding to
|
|
78
|
+
// processing the block up to the current slot as determined by the fork choice.
|
|
79
|
+
const ptc = state.epochCtx.getPayloadTimelinessCommittee(data.slot);
|
|
80
|
+
const validatorCommitteeIndex = ptc.indexOf(validatorIndex);
|
|
81
|
+
|
|
82
|
+
if (validatorCommitteeIndex === -1) {
|
|
83
|
+
throw new PayloadAttestationError(GossipAction.REJECT, {
|
|
84
|
+
code: PayloadAttestationErrorCode.INVALID_ATTESTER,
|
|
85
|
+
attesterIndex: validatorIndex,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// [REJECT] `payload_attestation_message.signature` is valid with respect to the validator's public key.
|
|
90
|
+
const signatureSet = createSingleSignatureSetFromComponents(
|
|
91
|
+
chain.index2pubkey[validatorIndex],
|
|
92
|
+
getPayloadAttestationDataSigningRoot(chain.config, state.slot, data),
|
|
93
|
+
payloadAttestationMessage.signature
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
|
|
97
|
+
throw new PayloadAttestationError(GossipAction.REJECT, {
|
|
98
|
+
code: PayloadAttestationErrorCode.INVALID_SIGNATURE,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Valid
|
|
103
|
+
chain.seenPayloadAttesters.add(epoch, validatorIndex);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
attDataRootHex: toRootHex(ssz.gloas.PayloadAttestationData.hashTreeRoot(data)),
|
|
107
|
+
validatorCommitteeIndex,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -45,12 +45,7 @@ async function validateProposerSlashing(
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const signatureSets = getProposerSlashingSignatureSets(
|
|
49
|
-
chain.config,
|
|
50
|
-
chain.index2pubkey,
|
|
51
|
-
state.slot,
|
|
52
|
-
proposerSlashing
|
|
53
|
-
);
|
|
48
|
+
const signatureSets = getProposerSlashingSignatureSets(chain.config, state.slot, proposerSlashing);
|
|
54
49
|
if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
|
|
55
50
|
throw new ProposerSlashingError(GossipAction.REJECT, {
|
|
56
51
|
code: ProposerSlashingErrorCode.INVALID,
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {PublicKey} from "@chainsafe/blst";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {DOMAIN_AGGREGATE_AND_PROOF, ForkSeq} from "@lodestar/params";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
computeSigningRoot,
|
|
7
|
-
computeStartSlotAtEpoch,
|
|
8
|
-
createSingleSignatureSetFromComponents,
|
|
9
|
-
} from "@lodestar/state-transition";
|
|
10
|
-
import {Epoch, SignedAggregateAndProof, ssz} from "@lodestar/types";
|
|
3
|
+
import {ISignatureSet, SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
4
|
+
import {Epoch, SignedAggregateAndProof, ValidatorIndex, ssz} from "@lodestar/types";
|
|
11
5
|
|
|
12
6
|
export function getAggregateAndProofSigningRoot(
|
|
13
7
|
config: BeaconConfig,
|
|
@@ -27,12 +21,13 @@ export function getAggregateAndProofSigningRoot(
|
|
|
27
21
|
export function getAggregateAndProofSignatureSet(
|
|
28
22
|
config: BeaconConfig,
|
|
29
23
|
epoch: Epoch,
|
|
30
|
-
|
|
24
|
+
aggregatorIndex: ValidatorIndex,
|
|
31
25
|
aggregateAndProof: SignedAggregateAndProof
|
|
32
26
|
): ISignatureSet {
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
aggregateAndProof
|
|
37
|
-
|
|
27
|
+
return {
|
|
28
|
+
type: SignatureSetType.indexed,
|
|
29
|
+
index: aggregatorIndex,
|
|
30
|
+
signingRoot: getAggregateAndProofSigningRoot(config, epoch, aggregateAndProof),
|
|
31
|
+
signature: aggregateAndProof.signature,
|
|
32
|
+
};
|
|
38
33
|
}
|
|
@@ -3,7 +3,6 @@ import {DOMAIN_CONTRIBUTION_AND_PROOF} from "@lodestar/params";
|
|
|
3
3
|
import {
|
|
4
4
|
CachedBeaconStateAllForks,
|
|
5
5
|
ISignatureSet,
|
|
6
|
-
Index2PubkeyCache,
|
|
7
6
|
SignatureSetType,
|
|
8
7
|
computeSigningRoot,
|
|
9
8
|
} from "@lodestar/state-transition";
|
|
@@ -11,7 +10,6 @@ import {altair, ssz} from "@lodestar/types";
|
|
|
11
10
|
|
|
12
11
|
export function getContributionAndProofSignatureSet(
|
|
13
12
|
config: BeaconConfig,
|
|
14
|
-
index2pubkey: Index2PubkeyCache,
|
|
15
13
|
state: CachedBeaconStateAllForks,
|
|
16
14
|
signedContributionAndProof: altair.SignedContributionAndProof
|
|
17
15
|
): ISignatureSet {
|
|
@@ -22,8 +20,8 @@ export function getContributionAndProofSignatureSet(
|
|
|
22
20
|
);
|
|
23
21
|
const signingData = signedContributionAndProof.message;
|
|
24
22
|
return {
|
|
25
|
-
type: SignatureSetType.
|
|
26
|
-
|
|
23
|
+
type: SignatureSetType.indexed,
|
|
24
|
+
index: signedContributionAndProof.message.aggregatorIndex,
|
|
27
25
|
signingRoot: computeSigningRoot(ssz.altair.ContributionAndProof, signingData, domain),
|
|
28
26
|
signature: signedContributionAndProof.signature,
|
|
29
27
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {PublicKey} from "@chainsafe/blst";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {DOMAIN_SELECTION_PROOF} from "@lodestar/params";
|
|
4
|
-
import {ISignatureSet,
|
|
5
|
-
import {Slot, phase0, ssz} from "@lodestar/types";
|
|
3
|
+
import {ISignatureSet, SignatureSetType, computeSigningRoot} from "@lodestar/state-transition";
|
|
4
|
+
import {Slot, ValidatorIndex, phase0, ssz} from "@lodestar/types";
|
|
6
5
|
|
|
7
6
|
export function getSelectionProofSigningRoot(config: BeaconConfig, slot: Slot): Uint8Array {
|
|
8
7
|
// previously, we call `const selectionProofDomain = config.getDomain(state.slot, DOMAIN_SELECTION_PROOF, slot)`
|
|
@@ -16,12 +15,13 @@ export function getSelectionProofSigningRoot(config: BeaconConfig, slot: Slot):
|
|
|
16
15
|
export function getSelectionProofSignatureSet(
|
|
17
16
|
config: BeaconConfig,
|
|
18
17
|
slot: Slot,
|
|
19
|
-
|
|
18
|
+
aggregatorIndex: ValidatorIndex,
|
|
20
19
|
aggregateAndProof: phase0.SignedAggregateAndProof
|
|
21
20
|
): ISignatureSet {
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
return {
|
|
22
|
+
type: SignatureSetType.indexed,
|
|
23
|
+
index: aggregatorIndex,
|
|
24
|
+
signingRoot: getSelectionProofSigningRoot(config, slot),
|
|
25
|
+
signature: aggregateAndProof.message.selectionProof,
|
|
26
|
+
};
|
|
27
27
|
}
|
|
@@ -3,7 +3,6 @@ import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
|
|
|
3
3
|
import {
|
|
4
4
|
CachedBeaconStateAllForks,
|
|
5
5
|
ISignatureSet,
|
|
6
|
-
Index2PubkeyCache,
|
|
7
6
|
SignatureSetType,
|
|
8
7
|
computeSigningRoot,
|
|
9
8
|
} from "@lodestar/state-transition";
|
|
@@ -11,15 +10,14 @@ import {altair, ssz} from "@lodestar/types";
|
|
|
11
10
|
|
|
12
11
|
export function getSyncCommitteeSignatureSet(
|
|
13
12
|
config: BeaconConfig,
|
|
14
|
-
index2pubkey: Index2PubkeyCache,
|
|
15
13
|
state: CachedBeaconStateAllForks,
|
|
16
14
|
syncCommittee: altair.SyncCommitteeMessage
|
|
17
15
|
): ISignatureSet {
|
|
18
16
|
const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, syncCommittee.slot);
|
|
19
17
|
|
|
20
18
|
return {
|
|
21
|
-
type: SignatureSetType.
|
|
22
|
-
|
|
19
|
+
type: SignatureSetType.indexed,
|
|
20
|
+
index: syncCommittee.validatorIndex,
|
|
23
21
|
signingRoot: computeSigningRoot(ssz.Root, syncCommittee.beaconBlockRoot, domain),
|
|
24
22
|
signature: syncCommittee.signature,
|
|
25
23
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PublicKey} from "@chainsafe/blst";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
|
|
4
3
|
import {CachedBeaconStateAltair, ISignatureSet, SignatureSetType, computeSigningRoot} from "@lodestar/state-transition";
|
|
@@ -8,12 +7,12 @@ export function getSyncCommitteeContributionSignatureSet(
|
|
|
8
7
|
config: BeaconConfig,
|
|
9
8
|
state: CachedBeaconStateAltair,
|
|
10
9
|
contribution: altair.SyncCommitteeContribution,
|
|
11
|
-
|
|
10
|
+
participantIndices: number[]
|
|
12
11
|
): ISignatureSet {
|
|
13
12
|
const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, contribution.slot);
|
|
14
13
|
return {
|
|
15
14
|
type: SignatureSetType.aggregate,
|
|
16
|
-
|
|
15
|
+
indices: participantIndices,
|
|
17
16
|
signingRoot: computeSigningRoot(ssz.Root, contribution.beaconBlockRoot, domain),
|
|
18
17
|
signature: contribution.signature,
|
|
19
18
|
};
|
|
@@ -3,7 +3,6 @@ import {DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF} from "@lodestar/params";
|
|
|
3
3
|
import {
|
|
4
4
|
CachedBeaconStateAllForks,
|
|
5
5
|
ISignatureSet,
|
|
6
|
-
Index2PubkeyCache,
|
|
7
6
|
SignatureSetType,
|
|
8
7
|
computeSigningRoot,
|
|
9
8
|
} from "@lodestar/state-transition";
|
|
@@ -11,7 +10,6 @@ import {altair, ssz} from "@lodestar/types";
|
|
|
11
10
|
|
|
12
11
|
export function getSyncCommitteeSelectionProofSignatureSet(
|
|
13
12
|
config: BeaconConfig,
|
|
14
|
-
index2pubkey: Index2PubkeyCache,
|
|
15
13
|
state: CachedBeaconStateAllForks,
|
|
16
14
|
contributionAndProof: altair.ContributionAndProof
|
|
17
15
|
): ISignatureSet {
|
|
@@ -22,8 +20,8 @@ export function getSyncCommitteeSelectionProofSignatureSet(
|
|
|
22
20
|
subcommitteeIndex: contributionAndProof.contribution.subcommitteeIndex,
|
|
23
21
|
};
|
|
24
22
|
return {
|
|
25
|
-
type: SignatureSetType.
|
|
26
|
-
|
|
23
|
+
type: SignatureSetType.indexed,
|
|
24
|
+
index: contributionAndProof.aggregatorIndex,
|
|
27
25
|
signingRoot: computeSigningRoot(ssz.altair.SyncAggregatorSelectionData, signingData, domain),
|
|
28
26
|
signature: contributionAndProof.selectionProof,
|
|
29
27
|
};
|
|
@@ -89,7 +89,7 @@ async function validateSyncCommitteeSigOnly(
|
|
|
89
89
|
syncCommittee: altair.SyncCommitteeMessage,
|
|
90
90
|
prioritizeBls = false
|
|
91
91
|
): Promise<void> {
|
|
92
|
-
const signatureSet = getSyncCommitteeSignatureSet(chain.config,
|
|
92
|
+
const signatureSet = getSyncCommitteeSignatureSet(chain.config, headState, syncCommittee);
|
|
93
93
|
if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
|
|
94
94
|
throw new SyncCommitteeError(GossipAction.REJECT, {
|
|
95
95
|
code: SyncCommitteeErrorCode.INVALID_SIGNATURE,
|