github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/badger/validity_test.go (about) 1 package badger 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/onflow/flow-go/model/flow" 9 "github.com/onflow/flow-go/state/protocol" 10 "github.com/onflow/flow-go/state/protocol/mock" 11 "github.com/onflow/flow-go/utils/unittest" 12 ) 13 14 var participants = unittest.IdentityListFixture(20, unittest.WithAllRoles()) 15 16 // TestEntityExpirySnapshotValidation tests that we perform correct sanity checks when 17 // bootstrapping consensus nodes and access nodes we expect that we only bootstrap snapshots 18 // with sufficient history. 19 func TestEntityExpirySnapshotValidation(t *testing.T) { 20 t.Run("spork-root-snapshot", func(t *testing.T) { 21 rootSnapshot := unittest.RootSnapshotFixture(participants) 22 err := ValidRootSnapshotContainsEntityExpiryRange(rootSnapshot) 23 require.NoError(t, err) 24 }) 25 t.Run("not-enough-history", func(t *testing.T) { 26 rootSnapshot := unittest.RootSnapshotFixture(participants) 27 rootSnapshot.Encodable().Head.Height += 10 // advance height to be not spork root snapshot 28 err := ValidRootSnapshotContainsEntityExpiryRange(rootSnapshot) 29 require.Error(t, err) 30 }) 31 t.Run("enough-history-spork-just-started", func(t *testing.T) { 32 rootSnapshot := unittest.RootSnapshotFixture(participants) 33 // advance height to be not spork root snapshot, but still lower than transaction expiry 34 rootSnapshot.Encodable().Head.Height += flow.DefaultTransactionExpiry / 2 35 // add blocks to sealing segment 36 rootSnapshot.Encodable().SealingSegment.ExtraBlocks = unittest.BlockFixtures(int(flow.DefaultTransactionExpiry / 2)) 37 err := ValidRootSnapshotContainsEntityExpiryRange(rootSnapshot) 38 require.NoError(t, err) 39 }) 40 t.Run("enough-history-long-spork", func(t *testing.T) { 41 rootSnapshot := unittest.RootSnapshotFixture(participants) 42 // advance height to be not spork root snapshot 43 rootSnapshot.Encodable().Head.Height += flow.DefaultTransactionExpiry * 2 44 // add blocks to sealing segment 45 rootSnapshot.Encodable().SealingSegment.ExtraBlocks = unittest.BlockFixtures(int(flow.DefaultTransactionExpiry) - 1) 46 err := ValidRootSnapshotContainsEntityExpiryRange(rootSnapshot) 47 require.NoError(t, err) 48 }) 49 t.Run("more-history-than-needed", func(t *testing.T) { 50 rootSnapshot := unittest.RootSnapshotFixture(participants) 51 // advance height to be not spork root snapshot 52 rootSnapshot.Encodable().Head.Height += flow.DefaultTransactionExpiry * 2 53 // add blocks to sealing segment 54 rootSnapshot.Encodable().SealingSegment.ExtraBlocks = unittest.BlockFixtures(flow.DefaultTransactionExpiry * 2) 55 err := ValidRootSnapshotContainsEntityExpiryRange(rootSnapshot) 56 require.NoError(t, err) 57 }) 58 } 59 60 func TestValidateVersionBeacon(t *testing.T) { 61 t.Run("no version beacon is ok", func(t *testing.T) { 62 snap := new(mock.Snapshot) 63 64 snap.On("VersionBeacon").Return(nil, nil) 65 66 err := validateVersionBeacon(snap) 67 require.NoError(t, err) 68 }) 69 t.Run("valid version beacon is ok", func(t *testing.T) { 70 snap := new(mock.Snapshot) 71 block := unittest.BlockFixture() 72 block.Header.Height = 100 73 74 vb := &flow.SealedVersionBeacon{ 75 VersionBeacon: &flow.VersionBeacon{ 76 VersionBoundaries: []flow.VersionBoundary{ 77 { 78 BlockHeight: 1000, 79 Version: "1.0.0", 80 }, 81 }, 82 Sequence: 50, 83 }, 84 SealHeight: uint64(37), 85 } 86 87 snap.On("Head").Return(block.Header, nil) 88 snap.On("VersionBeacon").Return(vb, nil) 89 90 err := validateVersionBeacon(snap) 91 require.NoError(t, err) 92 }) 93 t.Run("height must be below highest block", func(t *testing.T) { 94 snap := new(mock.Snapshot) 95 block := unittest.BlockFixture() 96 block.Header.Height = 12 97 98 vb := &flow.SealedVersionBeacon{ 99 VersionBeacon: &flow.VersionBeacon{ 100 VersionBoundaries: []flow.VersionBoundary{ 101 { 102 BlockHeight: 1000, 103 Version: "1.0.0", 104 }, 105 }, 106 Sequence: 50, 107 }, 108 SealHeight: uint64(37), 109 } 110 111 snap.On("Head").Return(block.Header, nil) 112 snap.On("VersionBeacon").Return(vb, nil) 113 114 err := validateVersionBeacon(snap) 115 require.Error(t, err) 116 require.True(t, protocol.IsInvalidServiceEventError(err)) 117 }) 118 t.Run("version beacon must be valid", func(t *testing.T) { 119 snap := new(mock.Snapshot) 120 block := unittest.BlockFixture() 121 block.Header.Height = 12 122 123 vb := &flow.SealedVersionBeacon{ 124 VersionBeacon: &flow.VersionBeacon{ 125 VersionBoundaries: []flow.VersionBoundary{ 126 { 127 BlockHeight: 0, 128 Version: "asdf", // invalid semver - hence will be considered invalid 129 }, 130 }, 131 Sequence: 50, 132 }, 133 SealHeight: uint64(1), 134 } 135 136 snap.On("Head").Return(block.Header, nil) 137 snap.On("VersionBeacon").Return(vb, nil) 138 139 err := validateVersionBeacon(snap) 140 require.Error(t, err) 141 require.True(t, protocol.IsInvalidServiceEventError(err)) 142 }) 143 }