Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/beacon-node/src/chain/forkChoice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ export function initializeForkChoiceFromUnfinalizedState(
};

const protoArray = ProtoArray.initialize(finalizedBlock, currentSlot);
protoArray.onBlock(justifiedBlock, currentSlot);
protoArray.onBlock(parentBlock, currentSlot);
protoArray.onBlock(headBlock, currentSlot);
protoArray.onBlock(justifiedBlock, currentSlot, null);
protoArray.onBlock(parentBlock, currentSlot, null);
protoArray.onBlock(headBlock, currentSlot, null);

logger?.verbose("Initialized protoArray successfully", {...logCtx, length: protoArray.length()});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ describe(`getAttestationsForBlock vc=${vc}`, () => {
builderIndex: null,
blockHashFromBid: null,
},
slot
slot,
null
);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/fork-choice/src/forkChoice/forkChoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ export class ForkChoice implements IForkChoice {
parentBlockHash: parentHashHex,
};

this.protoArray.onBlock(protoBlock, currentSlot);
this.protoArray.onBlock(protoBlock, currentSlot, this.proposerBoostRoot);

return protoBlock;
}
Expand Down Expand Up @@ -981,7 +981,8 @@ export class ForkChoice implements IForkChoice {
this.fcStore.currentSlot,
executionPayloadBlockHash,
executionPayloadNumber,
executionPayloadStateRoot
executionPayloadStateRoot,
this.proposerBoostRoot
);
}

Expand Down
33 changes: 18 additions & 15 deletions packages/fork-choice/src/protoArray/protoArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ export class ProtoArray {
// We are using the blockROot as the targetRoot, since it always lies on an epoch boundary
targetRoot: block.blockRoot,
} as ProtoBlock,
currentSlot
currentSlot,
null
);
return protoArray;
}
Expand Down Expand Up @@ -381,7 +382,7 @@ export class ProtoArray {
// If the node has a parent, try to update its best-child and best-descendant.
const parentIndex = node.parent;
if (parentIndex !== undefined) {
this.maybeUpdateBestChildAndDescendant(parentIndex, nodeIndex, currentSlot);
this.maybeUpdateBestChildAndDescendant(parentIndex, nodeIndex, currentSlot, proposerBoost?.root ?? null);
}
}
// Update the previous proposer boost
Expand All @@ -393,7 +394,7 @@ export class ProtoArray {
*
* It is only sane to supply an undefined parent for the genesis block
*/
onBlock(block: ProtoBlock, currentSlot: Slot): void {
onBlock(block: ProtoBlock, currentSlot: Slot, proposerBoostRoot: RootHex | null): void {
Comment thread
twoeths marked this conversation as resolved.
// If the block is already known, simply ignore it
if (this.hasBlock(block.blockRoot)) {
return;
Expand Down Expand Up @@ -465,15 +466,15 @@ export class ProtoArray {

// Update bestChild pointers
if (parentIndex !== undefined) {
this.maybeUpdateBestChildAndDescendant(parentIndex, pendingIndex, currentSlot);
this.maybeUpdateBestChildAndDescendant(parentIndex, pendingIndex, currentSlot, proposerBoostRoot);

if (pendingNode.executionStatus === ExecutionStatus.Valid) {
this.propagateValidExecutionStatusByIndex(parentIndex);
}
}

// Update bestChild for PENDING → EMPTY edge
this.maybeUpdateBestChildAndDescendant(pendingIndex, emptyIndex, currentSlot);
this.maybeUpdateBestChildAndDescendant(pendingIndex, emptyIndex, currentSlot, proposerBoostRoot);

// Initialize PTC votes for this block (all false initially)
// Spec: gloas/fork-choice.md#modified-on_block (line 645)
Expand All @@ -498,7 +499,7 @@ export class ProtoArray {
// If this node is valid, lets propagate the valid status up the chain
// and throw error if we counter invalid, as this breaks consensus
if (node.parent !== undefined) {
this.maybeUpdateBestChildAndDescendant(node.parent, nodeIndex, currentSlot);
this.maybeUpdateBestChildAndDescendant(node.parent, nodeIndex, currentSlot, proposerBoostRoot);

if (node.executionStatus === ExecutionStatus.Valid) {
this.propagateValidExecutionStatusByIndex(node.parent);
Expand All @@ -519,7 +520,8 @@ export class ProtoArray {
currentSlot: Slot,
executionPayloadBlockHash: RootHex,
executionPayloadNumber: number,
executionPayloadStateRoot: RootHex
executionPayloadStateRoot: RootHex,
proposerBoostRoot: RootHex | null
Comment thread
twoeths marked this conversation as resolved.
): void {
// First check if block exists
const variants = this.indices.get(blockRoot);
Expand Down Expand Up @@ -582,7 +584,7 @@ export class ProtoArray {
variants[PayloadStatus.FULL] = fullIndex;

// Update bestChild for PENDING node (may now prefer FULL over EMPTY)
this.maybeUpdateBestChildAndDescendant(pendingIndex, fullIndex, currentSlot);
this.maybeUpdateBestChildAndDescendant(pendingIndex, fullIndex, currentSlot, proposerBoostRoot);
}

/**
Expand Down Expand Up @@ -1183,7 +1185,12 @@ export class ProtoArray {
return isFromPreviousSlot || isFromCurrentSlot;
}

maybeUpdateBestChildAndDescendant(parentIndex: number, childIndex: number, currentSlot: Slot): void {
maybeUpdateBestChildAndDescendant(
parentIndex: number,
childIndex: number,
currentSlot: Slot,
proposerBoostRoot: RootHex | null
): void {
const childNode = this.nodes[childIndex];
if (childNode === undefined) {
throw new ProtoArrayError({
Expand Down Expand Up @@ -1278,13 +1285,9 @@ export class ProtoArray {
}

// Same weight and same root (or edge case), tie-breaker by payload status
const childTiebreaker = this.getPayloadStatusTiebreaker(
childNode,
currentSlot,
null // proposerBoostRoot
);
const childTiebreaker = this.getPayloadStatusTiebreaker(childNode, currentSlot, proposerBoostRoot);

const bestChildTiebreaker = this.getPayloadStatusTiebreaker(bestChildNode, currentSlot, null);
const bestChildTiebreaker = this.getPayloadStatusTiebreaker(bestChildNode, currentSlot, proposerBoostRoot);

if (childTiebreaker > bestChildTiebreaker) {
newChildAndDescendant = changeToChild;
Expand Down
2 changes: 1 addition & 1 deletion packages/fork-choice/test/perf/forkChoice/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function initializeForkChoice(opts: Opts): ForkChoice {
blockHashFromBid: null,
};

protoArr.onBlock(block, block.slot);
protoArr.onBlock(block, block.slot, null);
parentBlockRoot = blockRoot;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ describe("Forkchoice", () => {
for (let slot = genesisSlot + 1; slot <= tillSlot; slot++) {
if (!skippedSlots.includes(slot)) {
const block = getBlock(slot, skippedSlots);
protoArr.onBlock(block, block.slot);
protoArr.onBlock(block, block.slot, null);
}
}
};

it("getAllAncestorBlocks", () => {
// Add block that is a finalized descendant.
const block = getBlock(genesisSlot + 1);
protoArr.onBlock(block, block.slot);
protoArr.onBlock(block, block.slot, null);
const forkchoice = new ForkChoice(config, fcStore, protoArr, validatorCount, null);
const summaries = forkchoice.getAllAncestorBlocks(getBlockRoot(genesisSlot + 1));
// there are 2 blocks in protoArray but iterateAncestorBlocks should only return non-finalized blocks
Expand All @@ -174,7 +174,7 @@ describe("Forkchoice", () => {
...getBlock(genesisSlot + 10),
parentRoot: finalizedRoot, // Connect directly to genesis
};
protoArr.onBlock(forkBlock, forkBlock.slot);
protoArr.onBlock(forkBlock, forkBlock.slot, null);

const forkchoice = new ForkChoice(config, fcStore, protoArr, validatorCount, null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ describe("Forkchoice / GetProposerHead", () => {
expectedNotReorgedReason,
} of testCases) {
it(`${id}`, async () => {
protoArr.onBlock(parentBlock, parentBlock.slot);
protoArr.onBlock(headBlock, headBlock.slot);
protoArr.onBlock(parentBlock, parentBlock.slot, null);
protoArr.onBlock(headBlock, headBlock.slot, null);

const currentSlot = proposalSlot ?? headBlock.slot + 1;
const currentSecFromSlot = secFromSlot ?? 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ describe("Forkchoice / shouldOverrideForkChoiceUpdate", () => {
expectedNotReorgedReason,
} of testCases) {
it(id, async () => {
protoArr.onBlock(parentBlock, parentBlock.slot);
protoArr.onBlock(headBlock, headBlock.slot);
protoArr.onBlock(parentBlock, parentBlock.slot, null);
protoArr.onBlock(headBlock, headBlock.slot, null);

const secFromSlot = 0;
const currentSlot = blockSeenSlot ?? headBlock.slot;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ function setupForkChoice(): ProtoArray {
builderIndex: null,
blockHashFromBid: null,
},
block.slot
block.slot,
null
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ describe("getCommonAncestor", () => {
builderIndex: null,
blockHashFromBid: null,
},
block.slot
block.slot,
null
);
}

Expand Down
Loading
Loading