-
-
Notifications
You must be signed in to change notification settings - Fork 456
feat: only give proposer boost to canonical proposer #9313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,13 +116,23 @@ export async function importBlock( | |
| } | ||
| executionStatus = parentBlock.executionStatus; | ||
| } | ||
|
|
||
| let expectedProposerIndex: number | null = null; | ||
| const headState = this.getHeadState(); | ||
| if (headState.epoch === blockEpoch) { | ||
| expectedProposerIndex = headState.currentProposers[blockSlot % SLOTS_PER_EPOCH]; | ||
| } else if (headState.epoch + 1 === blockEpoch) { | ||
| expectedProposerIndex = headState.nextProposers[blockSlot % SLOTS_PER_EPOCH]; | ||
| } | ||
|
Comment on lines
+120
to
+126
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for determining the expected proposer index from the head state is duplicated in |
||
|
|
||
| const blockSummary = this.forkChoice.onBlock( | ||
| block.message, | ||
| postState, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| expectedProposerIndex | ||
| ); | ||
|
|
||
| // This adds the state necessary to process the next block | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,15 +106,17 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| targetBlock.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| orphanedBlock.message, | ||
| orphanedState, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| orphanedBlock.message.proposerIndex | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems misleading because this requires an "expected proposer index" in terms of head view, may pass null instead? |
||
| ); | ||
| let head = forkChoice.getHead(); | ||
| expect(head.slot).toBe(orphanedBlock.message.slot); | ||
|
|
@@ -124,7 +126,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| parentBlock.message.proposerIndex | ||
| ); | ||
| // tie break condition causes head to be orphaned block (based on hex root comparison) | ||
| head = forkChoice.getHead(); | ||
|
|
@@ -135,7 +138,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| childBlock.message.proposerIndex | ||
| ); | ||
| head = forkChoice.getHead(); | ||
| // without vote, head gets stuck at orphaned block | ||
|
|
@@ -195,19 +199,75 @@ describe("LodestarForkChoice", () => { | |
| const currentSlot = 128; | ||
| forkChoice.updateTime(currentSlot); | ||
|
|
||
| forkChoice.onBlock(block08.message, state08, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock(block12.message, state12, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock(block16.message, state16, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock(block20.message, state20, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock(block24.message, state24, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock(block28.message, state28, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock( | ||
| block08.message, | ||
| state08, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block08.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| block12.message, | ||
| state12, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block12.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| block16.message, | ||
| state16, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block16.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| block20.message, | ||
| state20, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block20.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| block24.message, | ||
| state24, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block24.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| block28.message, | ||
| state28, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block28.message.proposerIndex | ||
| ); | ||
| expect(forkChoice.getAllAncestorBlocks(hashBlock(block16.message), PayloadStatus.FULL)).toHaveLength(4); | ||
| expect(forkChoice.getAllAncestorBlocks(hashBlock(block24.message), PayloadStatus.FULL)).toHaveLength(6); | ||
| expect(forkChoice.getBlockHexDefaultStatus(hashBlock(block08.message))).not.toBeNull(); | ||
| expect(forkChoice.getBlockHexDefaultStatus(hashBlock(block12.message))).not.toBeNull(); | ||
| expect(forkChoice.hasBlockHex(hashBlock(block08.message))).toBe(true); | ||
| expect(forkChoice.hasBlockHex(hashBlock(block12.message))).toBe(true); | ||
| forkChoice.onBlock(block32.message, state32, blockDelaySec, currentSlot, executionStatus, dataAvailabilityStatus); | ||
| forkChoice.onBlock( | ||
| block32.message, | ||
| state32, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus, | ||
| block32.message.proposerIndex | ||
| ); | ||
| forkChoice.prune(hashBlock(block16.message)); | ||
| expect(forkChoice.getAllAncestorBlocks(hashBlock(block16.message), PayloadStatus.FULL).length).toBeWithMessage( | ||
| 1, | ||
|
|
@@ -243,31 +303,35 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| targetBlock.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| orphanedBlock.message, | ||
| orphanedState, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| orphanedBlock.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| parentBlock.message, | ||
| parentState, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| parentBlock.message.proposerIndex | ||
| ); | ||
| forkChoice.onBlock( | ||
| childBlock.message, | ||
| childState, | ||
| blockDelaySec, | ||
| currentSlot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| childBlock.message.proposerIndex | ||
| ); | ||
| const childBlockRoot = toHexString(ssz.phase0.BeaconBlock.hashTreeRoot(childBlock.message)); | ||
| // the old way to get non canonical blocks | ||
|
|
@@ -314,7 +378,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| blockW.message.slot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| blockW.message.proposerIndex | ||
| ); | ||
|
|
||
| // X | ||
|
|
@@ -326,7 +391,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| blockX.message.slot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| blockX.message.proposerIndex | ||
| ); | ||
|
|
||
| // Y, same epoch to X | ||
|
|
@@ -338,7 +404,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| blockY.message.slot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| blockY.message.proposerIndex | ||
| ); | ||
|
|
||
| // Y and Z are candidates for new head, make more attestations on Y | ||
|
|
@@ -379,7 +446,8 @@ describe("LodestarForkChoice", () => { | |
| blockDelaySec, | ||
| blockZ.message.slot, | ||
| executionStatus, | ||
| dataAvailabilityStatus | ||
| dataAvailabilityStatus, | ||
| blockZ.message.proposerIndex | ||
| ); | ||
|
|
||
| const head = forkChoice.updateHead(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we also have
BeaconStateView.getBeaconProposer()but it only query from current epochlooks like a good chance to clean that up
ideally we should be able to have this logic once