diff --git a/beacon-chain/forkchoice/doubly-linked-tree/proposer_boost_test.go b/beacon-chain/forkchoice/doubly-linked-tree/proposer_boost_test.go index e5bae806b6..c2322c01ab 100644 --- a/beacon-chain/forkchoice/doubly-linked-tree/proposer_boost_test.go +++ b/beacon-chain/forkchoice/doubly-linked-tree/proposer_boost_test.go @@ -51,7 +51,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -75,7 +75,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -101,7 +101,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -111,35 +111,37 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { require.NoError(t, err) assert.Equal(t, newRoot, headRoot, "Incorrect head for justified epoch at slot 3") - // Insert a second block at slot 3 into the tree and boost its score. + // Insert a second block at slot 4 into the tree and boost its score. // 0 // | // 1 // | // 2 // / \ - // 3 4 <- HEAD - slot = types.Slot(3) + // 3 | + // 4 <- HEAD + slot = types.Slot(4) newRoot = indexToHash(4) require.NoError(t, f.InsertOptimisticBlock( ctx, slot, newRoot, - headRoot, - params.BeaconConfig().ZeroHash, + indexToHash(2), + zeroHash, jEpoch, fEpoch, ), ) f.ProcessAttestation(ctx, []uint64{3}, newRoot, fEpoch) - clockSlot := types.Slot(3) + clockSlot := types.Slot(4) args := &forkchoicetypes.ProposerBoostRootArgs{ BlockRoot: newRoot, BlockSlot: slot, CurrentSlot: clockSlot, SecondsIntoSlot: 0, } + require.NoError(t, f.BoostProposerRoot(ctx, args)) headRoot, err = f.Head(ctx, jEpoch, zeroHash, balances, fEpoch) require.NoError(t, err) @@ -166,17 +168,27 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { // // In this case, we have a small fork: // - // (A: 54) -> (B: 44) -> (C: 34) + // (A: 54) -> (B: 44) -> (C: 10) // \_->(D: 24) // // So B has its own weight, 10, and the sum of both C and D. That's why we see weight 54 in the - // middle instead of the normal progression of (44 -> 34 -> 24). + // middle instead of the normal progression of (54 -> 44 -> 24). node1 := f.store.nodeByRoot[indexToHash(1)] require.Equal(t, node1.weight, uint64(54)) node2 := f.store.nodeByRoot[indexToHash(2)] require.Equal(t, node2.weight, uint64(44)) - node3 := f.store.nodeByRoot[indexToHash(4)] - require.Equal(t, node3.weight, uint64(24)) + node3 := f.store.nodeByRoot[indexToHash(3)] + require.Equal(t, node3.weight, uint64(10)) + node4 := f.store.nodeByRoot[indexToHash(4)] + require.Equal(t, node4.weight, uint64(24)) + + // Regression: process attestations for C, check that it + // becomes head, we need two attestations to have C.weight = 30 > 24 = D.weight + f.ProcessAttestation(ctx, []uint64{4, 5}, indexToHash(3), fEpoch) + headRoot, err = f.Head(ctx, jEpoch, zeroHash, balances, fEpoch) + require.NoError(t, err) + assert.Equal(t, indexToHash(3), headRoot, "Incorrect head for justified epoch at slot 4") + }) t.Run("vanilla ex ante attack", func(t *testing.T) { f := setup(jEpoch, fEpoch) diff --git a/beacon-chain/forkchoice/protoarray/proposer_boost_test.go b/beacon-chain/forkchoice/protoarray/proposer_boost_test.go index 3ddd394db6..006468ae96 100644 --- a/beacon-chain/forkchoice/protoarray/proposer_boost_test.go +++ b/beacon-chain/forkchoice/protoarray/proposer_boost_test.go @@ -51,7 +51,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -75,7 +75,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -101,7 +101,7 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { slot, newRoot, headRoot, - params.BeaconConfig().ZeroHash, + zeroHash, jEpoch, fEpoch, ), @@ -111,29 +111,30 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { require.NoError(t, err) assert.Equal(t, newRoot, headRoot, "Incorrect head for justified epoch at slot 3") - // Insert a second block at slot 3 into the tree and boost its score. + // Insert a second block at slot 4 into the tree and boost its score. // 0 // | // 1 // | // 2 // / \ - // 3 4 <- HEAD - slot = types.Slot(3) + // 3 | + // 4 <- HEAD + slot = types.Slot(4) newRoot = indexToHash(4) require.NoError(t, f.InsertOptimisticBlock( ctx, slot, newRoot, - headRoot, - params.BeaconConfig().ZeroHash, + indexToHash(2), + zeroHash, jEpoch, fEpoch, ), ) f.ProcessAttestation(ctx, []uint64{3}, newRoot, fEpoch) - clockSlot := types.Slot(3) + clockSlot := types.Slot(4) args := &forkchoicetypes.ProposerBoostRootArgs{ BlockRoot: newRoot, BlockSlot: slot, @@ -166,14 +167,22 @@ func TestForkChoice_BoostProposerRoot_PreventsExAnteAttack(t *testing.T) { // // In this case, we have a small fork: // - // (A: 54) -> (B: 44) -> (C: 24) - // \_->(D: 10) + // (A: 54) -> (B: 44) -> (C: 10) + // \_->(D: 24) // // So B has its own weight, 10, and the sum of both C and D. That's why we see weight 54 in the - // middle instead of the normal progression of (44 -> 34 -> 24). + // middle instead of the normal progression of (54 -> 44 -> 24). require.Equal(t, f.store.nodes[1].weight, uint64(54)) require.Equal(t, f.store.nodes[2].weight, uint64(44)) - require.Equal(t, f.store.nodes[3].weight, uint64(34)) + require.Equal(t, f.store.nodes[3].weight, uint64(10)) + require.Equal(t, f.store.nodes[4].weight, uint64(24)) + + // Regression: process attestations for C, check that it + // becomes head, we need two attestations to have C.weight = 30 > 24 = D.weight + f.ProcessAttestation(ctx, []uint64{4, 5}, indexToHash(3), fEpoch) + headRoot, err = f.Head(ctx, jEpoch, zeroHash, balances, fEpoch) + require.NoError(t, err) + assert.Equal(t, indexToHash(3), headRoot, "Incorrect head for justified epoch at slot 4") }) t.Run("vanilla ex ante attack", func(t *testing.T) { f := setup(jEpoch, fEpoch)