@@ -13,8 +13,8 @@ import (
1313 "github.com/onflow/flow-go/utils/unittest"
1414)
1515
16- // TestOperationPair is a pair of indexing operation and corresponding lock to be held during the operation.
17- // The name is an auxiliary identifier, for debugging only.
16+ // TestOperationPair is a pair of indexing operation and corresponding lock to be held during the operation.
17+ // The name is an auxiliary identifier, for debugging only.
1818type TestOperationPair struct {
1919 name string
2020 indexFunc func (lockctx.Proof , storage.ReaderBatchWriter , flow.Identifier , flow.Identifier ) error
@@ -83,10 +83,8 @@ func TestIndexAndLookupChild(t *testing.T) {
8383 }
8484}
8585
86- // if two blocks connect to the same parent, indexing the second block would have
87- // no effect, retrieving the child of the parent block will return the first block that
88- // was indexed.
89- func TestIndexTwiceAndRetrieve (t * testing.T ) {
86+ // indexing multiple children to the same parent should be retrievable
87+ func TestIndexWithMultiChildrenRetrieve (t * testing.T ) {
9088 for _ , opPair := range getTestOperationPairs () {
9189 t .Run (opPair .name , func (t * testing.T ) {
9290 dbtest .RunWithDB (t , func (t * testing.T , db storage.DB ) {
@@ -122,6 +120,46 @@ func TestIndexTwiceAndRetrieve(t *testing.T) {
122120 }
123121}
124122
123+ // Test indexing the same child with different parents should error
124+ func TestIndexAgainWithDifferentParentShouldError (t * testing.T ) {
125+ for _ , opPair := range getTestOperationPairs () {
126+ t .Run (opPair .name , func (t * testing.T ) {
127+ dbtest .RunWithDB (t , func (t * testing.T , db storage.DB ) {
128+ lockManager := storage .NewTestingLockManager ()
129+
130+ child := unittest .IdentifierFixture ()
131+ parent1 := unittest .IdentifierFixture ()
132+ parent2 := unittest .IdentifierFixture ()
133+
134+ // index with parent
135+ err := unittest .WithLock (t , lockManager , opPair .lockType , func (lctx lockctx.Context ) error {
136+ return db .WithReaderBatchWriter (func (rw storage.ReaderBatchWriter ) error {
137+ return opPair .indexFunc (lctx , rw , child , parent1 )
138+ })
139+ })
140+ require .NoError (t , err )
141+
142+ // index with a different parent
143+ err = unittest .WithLock (t , lockManager , opPair .lockType , func (lctx lockctx.Context ) error {
144+ return db .WithReaderBatchWriter (func (rw storage.ReaderBatchWriter ) error {
145+ return opPair .indexFunc (lctx , rw , child , parent2 )
146+ })
147+ })
148+ require .NoError (t , err )
149+
150+ var retrievedIDs flow.IdentifierList
151+ err = operation .RetrieveBlockChildren (db .Reader (), parent1 , & retrievedIDs )
152+ require .NoError (t , err )
153+
154+ require .ElementsMatch (t , flow.IdentifierList {child }, retrievedIDs )
155+
156+ err = operation .RetrieveBlockChildren (db .Reader (), parent2 , & retrievedIDs )
157+ require .ErrorIs (t , err , storage .ErrNotFound )
158+ })
159+ })
160+ }
161+ }
162+
125163// if parent is zero, then we don't index it
126164func TestIndexZeroParent (t * testing.T ) {
127165 for _ , opPair := range getTestOperationPairs () {
0 commit comments