github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/forkchoice/protoarray/ffg_update_test.go (about)

     1  package protoarray
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  	"github.com/prysmaticlabs/prysm/shared/params"
     9  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    10  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    11  )
    12  
    13  func TestFFGUpdates_OneBranch(t *testing.T) {
    14  	balances := []uint64{1, 1}
    15  	f := setup(0, 0)
    16  
    17  	// The head should always start at the finalized block.
    18  	r, err := f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
    19  	require.NoError(t, err)
    20  	assert.Equal(t, params.BeaconConfig().ZeroHash, r, "Incorrect head with genesis")
    21  
    22  	// Define the following tree:
    23  	//            0 <- justified: 0, finalized: 0
    24  	//            |
    25  	//            1 <- justified: 0, finalized: 0
    26  	//            |
    27  	//            2 <- justified: 1, finalized: 0
    28  	//            |
    29  	//            3 <- justified: 2, finalized: 1
    30  	require.NoError(t, f.ProcessBlock(context.Background(), 1, indexToHash(1), params.BeaconConfig().ZeroHash, [32]byte{}, 0, 0))
    31  	require.NoError(t, f.ProcessBlock(context.Background(), 2, indexToHash(2), indexToHash(1), [32]byte{}, 1, 0))
    32  	require.NoError(t, f.ProcessBlock(context.Background(), 3, indexToHash(3), indexToHash(2), [32]byte{}, 2, 1))
    33  
    34  	// With starting justified epoch at 0, the head should be 3:
    35  	//            0 <- start
    36  	//            |
    37  	//            1
    38  	//            |
    39  	//            2
    40  	//            |
    41  	//            3 <- head
    42  	r, err = f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
    43  	require.NoError(t, err)
    44  	assert.Equal(t, indexToHash(3), r, "Incorrect head for with justified epoch at 0")
    45  
    46  	// With starting justified epoch at 1, the head should be 2:
    47  	//            0
    48  	//            |
    49  	//            1 <- start
    50  	//            |
    51  	//            2 <- head
    52  	//            |
    53  	//            3
    54  	r, err = f.Head(context.Background(), 1, indexToHash(2), balances, 0)
    55  	require.NoError(t, err)
    56  	assert.Equal(t, indexToHash(2), r, "Incorrect head with justified epoch at 1")
    57  
    58  	// With starting justified epoch at 2, the head should be 3:
    59  	//            0
    60  	//            |
    61  	//            1
    62  	//            |
    63  	//            2 <- start
    64  	//            |
    65  	//            3 <- head
    66  	r, err = f.Head(context.Background(), 2, indexToHash(3), balances, 1)
    67  	require.NoError(t, err)
    68  	assert.Equal(t, indexToHash(3), r, "Incorrect head with justified epoch at 2")
    69  }
    70  
    71  func TestFFGUpdates_TwoBranches(t *testing.T) {
    72  	balances := []uint64{1, 1}
    73  	f := setup(0, 0)
    74  
    75  	r, err := f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
    76  	require.NoError(t, err)
    77  	assert.Equal(t, params.BeaconConfig().ZeroHash, r, "Incorrect head with genesis")
    78  
    79  	// Define the following tree:
    80  	//                                0
    81  	//                               / \
    82  	//  justified: 0, finalized: 0 -> 1   2 <- justified: 0, finalized: 0
    83  	//                              |   |
    84  	//  justified: 1, finalized: 0 -> 3   4 <- justified: 0, finalized: 0
    85  	//                              |   |
    86  	//  justified: 1, finalized: 0 -> 5   6 <- justified: 0, finalized: 0
    87  	//                              |   |
    88  	//  justified: 1, finalized: 0 -> 7   8 <- justified: 1, finalized: 0
    89  	//                              |   |
    90  	//  justified: 2, finalized: 0 -> 9  10 <- justified: 2, finalized: 0
    91  	// Left branch.
    92  	require.NoError(t, f.ProcessBlock(context.Background(), 1, indexToHash(1), params.BeaconConfig().ZeroHash, [32]byte{}, 0, 0))
    93  	require.NoError(t, f.ProcessBlock(context.Background(), 2, indexToHash(3), indexToHash(1), [32]byte{}, 1, 0))
    94  	require.NoError(t, f.ProcessBlock(context.Background(), 3, indexToHash(5), indexToHash(3), [32]byte{}, 1, 0))
    95  	require.NoError(t, f.ProcessBlock(context.Background(), 4, indexToHash(7), indexToHash(5), [32]byte{}, 1, 0))
    96  	require.NoError(t, f.ProcessBlock(context.Background(), 4, indexToHash(9), indexToHash(7), [32]byte{}, 2, 0))
    97  	// Right branch.
    98  	require.NoError(t, f.ProcessBlock(context.Background(), 1, indexToHash(2), params.BeaconConfig().ZeroHash, [32]byte{}, 0, 0))
    99  	require.NoError(t, f.ProcessBlock(context.Background(), 2, indexToHash(4), indexToHash(2), [32]byte{}, 0, 0))
   100  	require.NoError(t, f.ProcessBlock(context.Background(), 3, indexToHash(6), indexToHash(4), [32]byte{}, 0, 0))
   101  	require.NoError(t, f.ProcessBlock(context.Background(), 4, indexToHash(8), indexToHash(6), [32]byte{}, 1, 0))
   102  	require.NoError(t, f.ProcessBlock(context.Background(), 4, indexToHash(10), indexToHash(8), [32]byte{}, 2, 0))
   103  
   104  	// With start at 0, the head should be 10:
   105  	//           0  <-- start
   106  	//          / \
   107  	//         1   2
   108  	//         |   |
   109  	//         3   4
   110  	//         |   |
   111  	//         5   6
   112  	//         |   |
   113  	//         7   8
   114  	//         |   |
   115  	//         9  10 <-- head
   116  	r, err = f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
   117  	require.NoError(t, err)
   118  	assert.Equal(t, indexToHash(10), r, "Incorrect head with justified epoch at 0")
   119  
   120  	// Add a vote to 1:
   121  	//                 0
   122  	//                / \
   123  	//    +1 vote -> 1   2
   124  	//               |   |
   125  	//               3   4
   126  	//               |   |
   127  	//               5   6
   128  	//               |   |
   129  	//               7   8
   130  	//               |   |
   131  	//               9  10
   132  	f.ProcessAttestation(context.Background(), []uint64{0}, indexToHash(1), 0)
   133  
   134  	// With the additional vote to the left branch, the head should be 9:
   135  	//           0  <-- start
   136  	//          / \
   137  	//         1   2
   138  	//         |   |
   139  	//         3   4
   140  	//         |   |
   141  	//         5   6
   142  	//         |   |
   143  	//         7   8
   144  	//         |   |
   145  	// head -> 9  10
   146  	r, err = f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
   147  	require.NoError(t, err)
   148  	assert.Equal(t, indexToHash(9), r, "Incorrect head with justified epoch at 0")
   149  
   150  	// Add a vote to 2:
   151  	//                 0
   152  	//                / \
   153  	//               1   2 <- +1 vote
   154  	//               |   |
   155  	//               3   4
   156  	//               |   |
   157  	//               5   6
   158  	//               |   |
   159  	//               7   8
   160  	//               |   |
   161  	//               9  10
   162  	f.ProcessAttestation(context.Background(), []uint64{1}, indexToHash(2), 0)
   163  
   164  	// With the additional vote to the right branch, the head should be 10:
   165  	//           0  <-- start
   166  	//          / \
   167  	//         1   2
   168  	//         |   |
   169  	//         3   4
   170  	//         |   |
   171  	//         5   6
   172  	//         |   |
   173  	//         7   8
   174  	//         |   |
   175  	//         9  10 <-- head
   176  	r, err = f.Head(context.Background(), 0, params.BeaconConfig().ZeroHash, balances, 0)
   177  	require.NoError(t, err)
   178  	assert.Equal(t, indexToHash(10), r, "Incorrect head with justified epoch at 0")
   179  
   180  	r, err = f.Head(context.Background(), 1, indexToHash(1), balances, 0)
   181  	require.NoError(t, err)
   182  	assert.Equal(t, indexToHash(7), r, "Incorrect head with justified epoch at 0")
   183  }
   184  
   185  func setup(justifiedEpoch, finalizedEpoch types.Epoch) *ForkChoice {
   186  	f := New(0, 0, params.BeaconConfig().ZeroHash)
   187  	f.store.nodesIndices[params.BeaconConfig().ZeroHash] = 0
   188  	f.store.nodes = append(f.store.nodes, &Node{
   189  		slot:           0,
   190  		root:           params.BeaconConfig().ZeroHash,
   191  		parent:         NonExistentNode,
   192  		justifiedEpoch: justifiedEpoch,
   193  		finalizedEpoch: finalizedEpoch,
   194  		bestChild:      NonExistentNode,
   195  		bestDescendant: NonExistentNode,
   196  		weight:         0,
   197  	})
   198  
   199  	return f
   200  }