github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/consensus/approvals/aggregated_signatures_test.go (about) 1 package approvals 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/utils/unittest" 10 ) 11 12 // TestAggregatedSignatures_NoChunks verifies that NewAggregatedSignatures 13 // errors when initialized with 0 chunks. This is compatible with Flow's 14 // architecture, because each block contains at least one chunk (the system chunk). 15 func TestAggregatedSignatures_NoChunks(t *testing.T) { 16 _, err := NewAggregatedSignatures(0) 17 require.Error(t, err) 18 } 19 20 // TestAggregatedSignatures_PutSignature tests putting signature with different indexes 21 func TestAggregatedSignatures_PutSignature(t *testing.T) { 22 // create NewAggregatedSignatures for block with chunk indices 0, 1, ... , 9 23 sigs, err := NewAggregatedSignatures(10) 24 require.NoError(t, err) 25 require.Empty(t, sigs.signatures) 26 27 // add signature for chunk with index 3 28 n, err := sigs.PutSignature(3, flow.AggregatedSignature{}) 29 require.NoError(t, err) 30 require.Equal(t, uint64(1), n) 31 require.Len(t, sigs.signatures, 1) 32 33 // attempt to add signature for chunk with index 10 should error 34 n, err = sigs.PutSignature(sigs.numberOfChunks, flow.AggregatedSignature{}) 35 require.Error(t, err) 36 require.Equal(t, uint64(1), n) 37 } 38 39 // TestAggregatedSignatures_Repeated_PutSignature tests that repeated calls to 40 // PutSignature for the same chunk index are no-ops except for the first one. 41 func TestAggregatedSignatures_Repeated_PutSignature(t *testing.T) { 42 // create NewAggregatedSignatures for block with chunk indices 0, 1, ... , 9 43 sigs, err := NewAggregatedSignatures(10) 44 require.NoError(t, err) 45 require.Empty(t, sigs.signatures) 46 47 // add signature for chunk with index 3 48 as1 := flow.AggregatedSignature{ 49 VerifierSignatures: unittest.SignaturesFixture(22), 50 SignerIDs: unittest.IdentifierListFixture(22), 51 } 52 n, err := sigs.PutSignature(3, as1) 53 require.NoError(t, err) 54 require.Equal(t, uint64(1), n) 55 56 // add _different_ sig for chunk index 3 (should be no-op) 57 as2 := flow.AggregatedSignature{ 58 VerifierSignatures: unittest.SignaturesFixture(2), 59 SignerIDs: unittest.IdentifierListFixture(2), 60 } 61 n, err = sigs.PutSignature(3, as2) 62 require.NoError(t, err) 63 require.Equal(t, uint64(1), n) 64 65 aggSigs := sigs.Collect() 66 for idx, s := range aggSigs { 67 if idx == 3 { 68 require.Equal(t, 22, s.CardinalitySignerSet()) 69 } else { 70 require.Equal(t, 0, s.CardinalitySignerSet()) 71 } 72 } 73 } 74 75 // TestAggregatedSignatures_Repeated_Signer tests that repeated calls to 76 // PutSignature for the same chunk index are no-ops except for the first one. 77 func TestAggregatedSignatures_Repeated_Signer(t *testing.T) { 78 // create NewAggregatedSignatures for block with chunk indices 0, 1, ... , 9 79 sigs, err := NewAggregatedSignatures(10) 80 require.NoError(t, err) 81 require.Empty(t, sigs.signatures) 82 83 // add signature for chunk with index 3 84 as1 := flow.AggregatedSignature{ 85 VerifierSignatures: unittest.SignaturesFixture(22), 86 SignerIDs: unittest.IdentifierListFixture(22), 87 } 88 n, err := sigs.PutSignature(3, as1) 89 require.NoError(t, err) 90 require.Equal(t, uint64(1), n) 91 92 // add _different_ sig for chunk index 3 (should be no-op) 93 as2 := flow.AggregatedSignature{ 94 VerifierSignatures: unittest.SignaturesFixture(2), 95 SignerIDs: unittest.IdentifierListFixture(2), 96 } 97 n, err = sigs.PutSignature(3, as2) 98 require.NoError(t, err) 99 require.Equal(t, uint64(1), n) 100 101 aggSigs := sigs.Collect() 102 for idx, s := range aggSigs { 103 if idx == 3 { 104 require.Equal(t, 22, s.CardinalitySignerSet()) 105 } else { 106 require.Equal(t, 0, s.CardinalitySignerSet()) 107 } 108 } 109 } 110 111 // TestAggregatedSignatures_PutSignature_Sequence tests PutSignature for a full sequence 112 func TestAggregatedSignatures_PutSignature_Sequence(t *testing.T) { 113 chunks := uint64(10) 114 sigs, err := NewAggregatedSignatures(chunks) 115 require.NoError(t, err) 116 117 for index := uint64(0); index < chunks; index++ { 118 n, err := sigs.PutSignature(index, flow.AggregatedSignature{}) 119 require.NoError(t, err) 120 require.Equal(t, n, index+1) 121 } 122 } 123 124 // TestAggregatedSignatures_Collect tests that collecting over full signatures and partial signatures behaves as expected 125 func TestAggregatedSignatures_Collect(t *testing.T) { 126 chunks := uint64(10) 127 sigs, err := NewAggregatedSignatures(chunks) 128 require.NoError(t, err) 129 sig := flow.AggregatedSignature{} 130 _, err = sigs.PutSignature(5, sig) 131 require.NoError(t, err) 132 133 // collecting over signatures with missing chunks results in empty array 134 require.Len(t, sigs.Collect(), int(chunks)) 135 for index := uint64(0); index < chunks; index++ { 136 _, err := sigs.PutSignature(index, sig) 137 require.NoError(t, err) 138 require.Len(t, sigs.Collect(), int(chunks)) 139 } 140 } 141 142 // TestAggregatedSignatures_HasSignature tests that after putting a signature we can get it 143 func TestAggregatedSignatures_HasSignature(t *testing.T) { 144 sigs, err := NewAggregatedSignatures(10) 145 require.NoError(t, err) 146 index := uint64(5) 147 _, err = sigs.PutSignature(index, flow.AggregatedSignature{}) 148 require.NoError(t, err) 149 require.True(t, sigs.HasSignature(index)) 150 require.False(t, sigs.HasSignature(0)) 151 } 152 153 // TestAggregatedSignatures_ChunksWithoutAggregatedSignature tests that we can retrieve all chunks with missing signatures 154 func TestAggregatedSignatures_ChunksWithoutAggregatedSignature(t *testing.T) { 155 numberOfChunks := uint64(10) 156 sigs, err := NewAggregatedSignatures(numberOfChunks) 157 require.NoError(t, err) 158 _, err = sigs.PutSignature(0, flow.AggregatedSignature{}) 159 require.NoError(t, err) 160 chunks := sigs.ChunksWithoutAggregatedSignature() 161 require.Len(t, chunks, int(numberOfChunks)-1) 162 163 expectedChunks := make([]uint64, 0, numberOfChunks) 164 for i := uint64(1); i < numberOfChunks; i++ { 165 expectedChunks = append(expectedChunks, i) 166 } 167 require.ElementsMatch(t, expectedChunks, chunks) 168 }