From dc3ad962ef992962c815477a37766dc71a1c690b Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Mon, 25 Jul 2022 12:40:37 +0300 Subject: [PATCH 1/4] Refactor expected keepers --- testutil/datagen/btc_header_tree.go | 14 ++-- x/btclightclient/keeper/keeper.go | 55 +++++++++++--- x/btclightclient/keeper/keeper_test.go | 100 +++++++++++++++++++++++-- x/btclightclient/keeper/state.go | 62 ++++++--------- x/btclightclient/keeper/state_test.go | 38 +++++++++- x/btclightclient/types/errors.go | 1 + 6 files changed, 207 insertions(+), 63 deletions(-) diff --git a/testutil/datagen/btc_header_tree.go b/testutil/datagen/btc_header_tree.go index 24f8cfe6a..5650c04d4 100644 --- a/testutil/datagen/btc_header_tree.go +++ b/testutil/datagen/btc_header_tree.go @@ -38,7 +38,7 @@ func (t *BTCHeaderTree) Contains(node *blctypes.BTCHeaderInfo) bool { // GetRoot returns the root of the tree -- i.e. the node without an existing parent func (t *BTCHeaderTree) GetRoot() *blctypes.BTCHeaderInfo { for _, header := range t.headers { - if t.getParent(header) == nil { + if t.GetParent(header) == nil { return header } } @@ -154,7 +154,7 @@ func (t *BTCHeaderTree) getNodeAncestryUpToUtil(ancestry *[]*blctypes.BTCHeaderI return } *ancestry = append(*ancestry, node) - parent := t.getParent(node) + parent := t.GetParent(node) if parent != nil { t.getNodeAncestryUpToUtil(ancestry, parent, upTo) } @@ -176,9 +176,9 @@ func (t *BTCHeaderTree) GetNodeAncestry(node *blctypes.BTCHeaderInfo) []*blctype return t.GetNodeAncestryUpTo(node, nil) } -// GetRandomAncestor retrieves the ancestry list and returns an ancestor from it. +// RandomAncestor retrieves the ancestry list and returns an ancestor from it. // Can include the node itself. -func (t *BTCHeaderTree) GetRandomAncestor(node *blctypes.BTCHeaderInfo) *blctypes.BTCHeaderInfo { +func (t *BTCHeaderTree) RandomAncestor(node *blctypes.BTCHeaderInfo) *blctypes.BTCHeaderInfo { ancestry := t.GetNodeAncestry(node) idx := RandomInt(len(ancestry)) return ancestry[idx] @@ -192,7 +192,7 @@ func (t *BTCHeaderTree) IsOnNodeChain(node *blctypes.BTCHeaderInfo, ancestor *bl } ancestryUpTo := t.GetNodeAncestryUpTo(node, ancestor) lastElement := ancestryUpTo[len(ancestryUpTo)-1] - parent := t.getParent(lastElement) + parent := t.GetParent(lastElement) if parent != nil && parent.Eq(ancestor) { return true } @@ -244,8 +244,8 @@ func (t *BTCHeaderTree) Size() int { return len(t.headers) } -// getParent returns the parent of the node, or nil if it doesn't exist -func (t *BTCHeaderTree) getParent(node *blctypes.BTCHeaderInfo) *blctypes.BTCHeaderInfo { +// GetParent returns the parent of the node, or nil if it doesn't exist +func (t *BTCHeaderTree) GetParent(node *blctypes.BTCHeaderInfo) *blctypes.BTCHeaderInfo { if header, ok := t.headers[node.Header.ParentHash().String()]; ok { return header } diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index 4a88a6bf0..aebc3bbdb 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -142,21 +142,20 @@ func (k Keeper) InsertHeader(ctx sdk.Context, header *bbl.BTCHeaderBytes) error } // BlockHeight returns the height of the provided header -func (k Keeper) BlockHeight(ctx sdk.Context, header *bbl.BTCHeaderBytes) (uint64, error) { - if header == nil { +func (k Keeper) BlockHeight(ctx sdk.Context, headerHash *bbl.BTCHeaderHashBytes) (uint64, error) { + if headerHash == nil { return 0, types.ErrEmptyMessage } - headerHash := header.Hash() return k.headersState(ctx).GetHeaderHeight(headerHash) } // MainChainDepth returns the depth of the header in the main chain or -1 if it does not exist in it -func (k Keeper) MainChainDepth(ctx sdk.Context, headerBytes *bbl.BTCHeaderBytes) (int64, error) { - if headerBytes == nil { +func (k Keeper) MainChainDepth(ctx sdk.Context, headerHashBytes *bbl.BTCHeaderHashBytes) (int64, error) { + if headerHashBytes == nil { return -1, types.ErrEmptyMessage } // Retrieve the header. If it does not exist, return an error - headerInfo, err := k.headersState(ctx).GetHeaderByHash(headerBytes.Hash()) + headerInfo, err := k.headersState(ctx).GetHeaderByHash(headerHashBytes) if err != nil { return -1, err } @@ -185,11 +184,11 @@ func (k Keeper) MainChainDepth(ctx sdk.Context, headerBytes *bbl.BTCHeaderBytes) } // IsHeaderKDeep returns true if a header is at least k-deep on the main chain -func (k Keeper) IsHeaderKDeep(ctx sdk.Context, headerBytes *bbl.BTCHeaderBytes, depth uint64) (bool, error) { - if headerBytes == nil { +func (k Keeper) IsHeaderKDeep(ctx sdk.Context, headerHashBytes *bbl.BTCHeaderHashBytes, depth uint64) (bool, error) { + if headerHashBytes == nil { return false, types.ErrEmptyMessage } - mainchainDepth, err := k.MainChainDepth(ctx, headerBytes) + mainchainDepth, err := k.MainChainDepth(ctx, headerHashBytes) if err != nil { return false, err } @@ -198,6 +197,42 @@ func (k Keeper) IsHeaderKDeep(ctx sdk.Context, headerBytes *bbl.BTCHeaderBytes, return false, nil } // return true if the provided depth is more than equal the mainchain depth - //panic(fmt.Sprintf("%d %d", depth, mainchainDepth)) return depth >= uint64(mainchainDepth), nil } + +// IsAncestor returns true/false depending on whether `parent` is an ancestor of `child`. +// Returns false if the parent and the child are the same header. +func (k Keeper) IsAncestor(ctx sdk.Context, parentHashBytes *bbl.BTCHeaderHashBytes, childHashBytes *bbl.BTCHeaderHashBytes) (bool, error) { + // nil checks + if parentHashBytes == nil || childHashBytes == nil { + return false, types.ErrEmptyMessage + } + // Retrieve parent and child header + parentHeader, err := k.headersState(ctx).GetHeaderByHash(parentHashBytes) + if err != nil { + return false, types.ErrHeaderDoesNotExist.Wrapf("parent does not exist") + } + childHeader, err := k.headersState(ctx).GetHeaderByHash(childHashBytes) + if err != nil { + return false, types.ErrHeaderDoesNotExist.Wrapf("child does not exist") + } + + // If the height of the child is less than the parent, then the input is invalid + if childHeader.Height < parentHeader.Height { + return false, types.ErrInvalidAncestor.Wrapf("ancestor height is larger than descendant height") + } + + // If they have the same height, then the result is false + if childHeader.Height == parentHeader.Height { + return false, nil + } + + // Retrieve the ancestry + ancestry := k.headersState(ctx).GetHeaderAncestryUpTo(childHeader, childHeader.Height-parentHeader.Height) + // If it is empty, return false + if len(ancestry) == 0 { + return false, nil + } + // Return whether the last element of the ancestry is equal to the parent + return ancestry[len(ancestry)-1].Eq(parentHeader), nil +} diff --git a/x/btclightclient/keeper/keeper_test.go b/x/btclightclient/keeper/keeper_test.go index 29bee7c7a..31bcbf8d1 100644 --- a/x/btclightclient/keeper/keeper_test.go +++ b/x/btclightclient/keeper/keeper_test.go @@ -42,7 +42,7 @@ func FuzzKeeperIsHeaderKDeep(f *testing.F) { // Test header not existing nonExistentHeader := datagen.GenRandomBTCHeaderBytes(nil, nil) - isDeep, err = blcKeeper.IsHeaderKDeep(ctx, &nonExistentHeader, depth) + isDeep, err = blcKeeper.IsHeaderKDeep(ctx, nonExistentHeader.Hash(), depth) if err == nil { t.Errorf("Non existent header led to nil error") } @@ -62,7 +62,7 @@ func FuzzKeeperIsHeaderKDeep(f *testing.F) { mainchain := tree.GetMainChain() // Select a random depth based on the main-chain length randDepth := uint64(rand.Int63n(int64(len(mainchain)))) - isDeep, err = blcKeeper.IsHeaderKDeep(ctx, header.Header, randDepth) + isDeep, err = blcKeeper.IsHeaderKDeep(ctx, header.Hash, randDepth) // Identify whether the function should return true or false headerDepth := tip.Height - header.Height // If the random depth that we chose is more than the headerDepth, then it should return true @@ -76,7 +76,7 @@ func FuzzKeeperIsHeaderKDeep(f *testing.F) { } else { // The depth provided does not matter, we should always get false. randDepth := rand.Uint64() - isDeep, err = blcKeeper.IsHeaderKDeep(ctx, header.Header, randDepth) + isDeep, err = blcKeeper.IsHeaderKDeep(ctx, header.Hash, randDepth) if err != nil { t.Errorf("Existent header led to a non-nil error %s", err) } @@ -117,7 +117,7 @@ func FuzzKeeperMainChainDepth(f *testing.F) { // Test header not existing nonExistentHeader := datagen.GenRandomBTCHeaderBytes(nil, nil) - depth, err = blcKeeper.MainChainDepth(ctx, &nonExistentHeader) + depth, err = blcKeeper.MainChainDepth(ctx, nonExistentHeader.Hash()) if err == nil { t.Errorf("Non existent header led to nil error") } @@ -134,7 +134,7 @@ func FuzzKeeperMainChainDepth(f *testing.F) { // Otherwise, the result should always be -1 tip := tree.GetTip() // Get the depth - depth, err = blcKeeper.MainChainDepth(ctx, header.Header) + depth, err = blcKeeper.MainChainDepth(ctx, header.Hash) if err != nil { t.Errorf("Existent and header led to error") } @@ -182,7 +182,7 @@ func FuzzKeeperBlockHeight(f *testing.F) { // Test header not existing nonExistentHeader := datagen.GenRandomBTCHeaderBytes(nil, nil) - height, err = blcKeeper.BlockHeight(ctx, &nonExistentHeader) + height, err = blcKeeper.BlockHeight(ctx, nonExistentHeader.Hash()) if err == nil { t.Errorf("Non existent header led to nil error") } @@ -192,7 +192,7 @@ func FuzzKeeperBlockHeight(f *testing.F) { tree := genRandomTree(blcKeeper, ctx, 1, 10) header := tree.RandomNode() - height, err = blcKeeper.BlockHeight(ctx, header.Header) + height, err = blcKeeper.BlockHeight(ctx, header.Hash) if err != nil { t.Errorf("Existent header led to an error") } @@ -202,6 +202,92 @@ func FuzzKeeperBlockHeight(f *testing.F) { }) } +func FuzzKeeperIsAncestor(f *testing.F) { + /* + Checks: + 1. If the child hash or the parent hash are nil, an error is returned + 2. If the child has a lower height than the parent, an error is returned + 3. If the child and the parent are the same, false is returned + 4. If the parent is an ancestor of child then `true` is returned. + + Data generation: + - Generate a random tree of headers and insert it into storage. + - Select a random header and select a random descendant and a random ancestor to test (2-4). + */ + datagen.AddRandomSeedsToFuzzer(f, 100) + f.Fuzz(func(t *testing.T, seed int64) { + rand.Seed(seed) + blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + + nonExistentParent := datagen.GenRandomBTCHeaderInfo() + nonExistentChild := datagen.GenRandomBTCHeaderInfo() + + // nil inputs test + isAncestor, err := blcKeeper.IsAncestor(ctx, nil, nil) + if err == nil { + t.Errorf("Nil input led to nil error") + } + if isAncestor { + t.Errorf("Nil input led to true result") + } + isAncestor, err = blcKeeper.IsAncestor(ctx, nonExistentParent.Hash, nil) + if err == nil { + t.Errorf("Nil input led to nil error") + } + if isAncestor { + t.Errorf("Nil input led to true result") + } + isAncestor, err = blcKeeper.IsAncestor(ctx, nil, nonExistentChild.Hash) + if err == nil { + t.Errorf("Nil input led to nil error") + } + if isAncestor { + t.Errorf("Nil input led to true result") + } + + // non-existent test + isAncestor, err = blcKeeper.IsAncestor(ctx, nonExistentParent.Hash, nonExistentChild.Hash) + if err == nil { + t.Errorf("Non existent headers led to nil error") + } + if isAncestor { + t.Errorf("Non existent headers led to true result") + } + + // Generate random tree of headers + tree := genRandomTree(blcKeeper, ctx, 1, 10) + header := tree.RandomNode() + ancestor := tree.RandomNode() + + if ancestor.Eq(header) { + // Same headers test + isAncestor, err = blcKeeper.IsAncestor(ctx, ancestor.Hash, header.Hash) + if err != nil { + t.Errorf("Valid input led to an error") + } + if isAncestor { + t.Errorf("Same header input led to true result") + } + } else if ancestor.Height > header.Height { // Descendant test + isAncestor, err = blcKeeper.IsAncestor(ctx, ancestor.Hash, header.Hash) + if err == nil { + t.Errorf("Providing a descendant as a parent led to a nil error") + } + if isAncestor { + t.Errorf("Providing a descendant as a parent led to a true result") + } + } else { // Ancestor test + isAncestor, err = blcKeeper.IsAncestor(ctx, ancestor.Hash, header.Hash) + if err != nil { + t.Errorf("Valid input led to an error") + } + if isAncestor != tree.IsOnNodeChain(header, ancestor) { // The result should be whether it is an ancestor or not + t.Errorf("Got invalid ancestry result. Expected %t, got %t", tree.IsOnNodeChain(header, ancestor), isAncestor) + } + } + }) +} + func FuzzKeeperInsertHeader(f *testing.F) { /* Checks: diff --git a/x/btclightclient/keeper/state.go b/x/btclightclient/keeper/state.go index ce842d996..a835f26b2 100644 --- a/x/btclightclient/keeper/state.go +++ b/x/btclightclient/keeper/state.go @@ -170,12 +170,12 @@ func (s headersState) HeadersByHeight(height uint64, f func(*types.BTCHeaderInfo } // getDescendingHeadersUpTo returns a collection of descending headers according to their height -func (s headersState) getDescendingHeadersUpTo(tipHeight uint64, depth uint64) []*types.BTCHeaderInfo { +func (s headersState) getDescendingHeadersUpTo(startHeight uint64, depth uint64) []*types.BTCHeaderInfo { var headers []*types.BTCHeaderInfo s.iterateReverseHeaders(func(header *types.BTCHeaderInfo) bool { // Use `depth+1` because we want to first gather all the headers // with a depth of `depth`. - if tipHeight-header.Height == depth+1 { + if startHeight-header.Height == depth+1 { return true } headers = append(headers, header) @@ -184,15 +184,9 @@ func (s headersState) getDescendingHeadersUpTo(tipHeight uint64, depth uint64) [ return headers } -// GetMainChainUpTo returns the current canonical chain as a collection of block headers -// starting from the tip and ending on the header that has a depth distance from it. -func (s headersState) GetMainChainUpTo(depth uint64) []*types.BTCHeaderInfo { - // If there is no tip, there is no base header - if !s.TipExists() { - return nil - } - currentHeader := s.GetTip() - +// GetHeaderAncestryUpTo returns a list of headers starting from the header parameter and leading to +// the header that has a `depth` distance from it. +func (s headersState) GetHeaderAncestryUpTo(currentHeader *types.BTCHeaderInfo, depth uint64) []*types.BTCHeaderInfo { // Retrieve a collection of headers in descending height order // Use depth+1 since we want all headers at the depth height. headers := s.getDescendingHeadersUpTo(currentHeader.Height, depth) @@ -214,6 +208,16 @@ func (s headersState) GetMainChainUpTo(depth uint64) []*types.BTCHeaderInfo { return chain } +// GetMainChainUpTo returns the current canonical chain as a collection of block headers +// starting from the tip and ending on the header that has a depth distance from it. +func (s headersState) GetMainChainUpTo(depth uint64) []*types.BTCHeaderInfo { + // If there is no tip, there is no base header + if !s.TipExists() { + return nil + } + return s.GetHeaderAncestryUpTo(s.GetTip(), depth) +} + // GetMainChain retrieves the main chain as a collection of block headers starting from the tip // and ending on the base BTC header. func (s headersState) GetMainChain() []*types.BTCHeaderInfo { @@ -294,38 +298,20 @@ func (s headersState) GetInOrderAncestorsUntil(descendant *types.BTCHeaderInfo, return []*types.BTCHeaderInfo{} } - currentHeader := descendant - - var ancestors []*types.BTCHeaderInfo - ancestors = append(ancestors, descendant) if descendant.HasParent(ancestor) { - return ancestors + return []*types.BTCHeaderInfo{descendant} } - found := false - s.iterateReverseHeaders(func(header *types.BTCHeaderInfo) bool { - if header.Eq(ancestor) { - found = true - return true - } - if currentHeader.HasParent(header) { - currentHeader = header - ancestors = append(ancestors, header) - } - // Abandon the iteration if the height of the current header is lower - // than the height of the provided ancestor - if currentHeader.Height < ancestor.Height { - return true - } - return false - }) - - // If the header was not found, discard the ancestors list - if !found { - ancestors = []*types.BTCHeaderInfo{} + ancestors := s.GetHeaderAncestryUpTo(descendant, descendant.Height-ancestor.Height) + if !ancestors[len(ancestors)-1].Eq(ancestor) { + // `ancestor` is not an ancestor of `descendant`, return an empty list + return []*types.BTCHeaderInfo{} } - // Reverse the array + // Discard the last element of the ancestry which corresponds to `ancestor` + ancestors = ancestors[:len(ancestors)-1] + + // Reverse the ancestry for i, j := 0, len(ancestors)-1; i < j; i, j = i+1, j-1 { ancestors[i], ancestors[j] = ancestors[j], ancestors[i] } diff --git a/x/btclightclient/keeper/state_test.go b/x/btclightclient/keeper/state_test.go index 2db38d8ba..b25910384 100644 --- a/x/btclightclient/keeper/state_test.go +++ b/x/btclightclient/keeper/state_test.go @@ -507,7 +507,7 @@ func FuzzHeadersStateGetInOrderAncestorsUntil(f *testing.F) { // Get a random header from the tree descendant := tree.RandomNode() // Get a random ancestor from it - ancestor := tree.GetRandomAncestor(descendant) + ancestor := tree.RandomAncestor(descendant) // Get the ancestry of the descendant. // It is in reverse order from the one that GetInOrderAncestorsUntil returns, since it starts with the descendant. expectedAncestorsReverse := tree.GetNodeAncestryUpTo(descendant, ancestor) @@ -524,3 +524,39 @@ func FuzzHeadersStateGetInOrderAncestorsUntil(f *testing.F) { } }) } + +func FuzzHeadersStateGetHeaderAncestryUpTo(f *testing.F) { + /* + Checks: + 1. All the ancestors up to the depth are in the returned list. + 2. The ancestors start from the parameter and lead to the ancestor. + + Data generation: + - Generate a random tree of headers and store it. + - Select a random header which will serve as the `header` parameter. + - Select a random depth in the range of [0, header.Height-baseHeader.Height] + */ + datagen.AddRandomSeedsToFuzzer(f, 100) + f.Fuzz(func(t *testing.T, seed int64) { + rand.Seed(seed) + blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + tree := genRandomTree(blcKeeper, ctx, 1, 10) + + descendant := tree.RandomNode() + ancestor := tree.RandomAncestor(descendant) + + ancestors := blcKeeper.HeadersState(ctx).GetHeaderAncestryUpTo(descendant, descendant.Height-ancestor.Height) + // Use the parent of the ancestor since UpTo does not include the ancestor in the result + expectedAncestors := tree.GetNodeAncestryUpTo(descendant, tree.GetParent(ancestor)) + + if len(ancestors) != len(expectedAncestors) { + t.Errorf("Got different ancestor list sizes. Expected %d, got %d", len(expectedAncestors), len(ancestors)) + } + + for i := 0; i < len(ancestors); i++ { + if !ancestors[i].Eq(expectedAncestors[i]) { + t.Errorf("Ancestors do not match. Expected %s, got %s", expectedAncestors[i].Hash, ancestors[i].Hash) + } + } + }) +} diff --git a/x/btclightclient/types/errors.go b/x/btclightclient/types/errors.go index 60788390e..ee4c0e7f4 100644 --- a/x/btclightclient/types/errors.go +++ b/x/btclightclient/types/errors.go @@ -13,4 +13,5 @@ var ( ErrHeaderParentDoesNotExist = sdkerrors.Register(ModuleName, 1102, "header parent does not exist") ErrInvalidDifficulty = sdkerrors.Register(ModuleName, 1103, "invalid difficulty bits") ErrEmptyMessage = sdkerrors.Register(ModuleName, 1104, "empty message provided") + ErrInvalidAncestor = sdkerrors.Register(ModuleName, 1105, "invalid ancestor provided") ) From 053a41258cdf522a6256974a5eee6f1d756d5b5d Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Tue, 26 Jul 2022 10:44:29 +0300 Subject: [PATCH 2/4] minor --- x/btclightclient/keeper/keeper.go | 9 ++------- x/btclightclient/keeper/keeper_test.go | 4 ++-- x/btclightclient/types/errors.go | 1 - 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index aebc3bbdb..018b94f82 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -217,13 +217,8 @@ func (k Keeper) IsAncestor(ctx sdk.Context, parentHashBytes *bbl.BTCHeaderHashBy return false, types.ErrHeaderDoesNotExist.Wrapf("child does not exist") } - // If the height of the child is less than the parent, then the input is invalid - if childHeader.Height < parentHeader.Height { - return false, types.ErrInvalidAncestor.Wrapf("ancestor height is larger than descendant height") - } - - // If they have the same height, then the result is false - if childHeader.Height == parentHeader.Height { + // If the height of the child is equal or less than the parent, then the input is invalid + if childHeader.Height <= parentHeader.Height { return false, nil } diff --git a/x/btclightclient/keeper/keeper_test.go b/x/btclightclient/keeper/keeper_test.go index 31bcbf8d1..972561843 100644 --- a/x/btclightclient/keeper/keeper_test.go +++ b/x/btclightclient/keeper/keeper_test.go @@ -270,8 +270,8 @@ func FuzzKeeperIsAncestor(f *testing.F) { } } else if ancestor.Height > header.Height { // Descendant test isAncestor, err = blcKeeper.IsAncestor(ctx, ancestor.Hash, header.Hash) - if err == nil { - t.Errorf("Providing a descendant as a parent led to a nil error") + if err != nil { + t.Errorf("Providing a descendant as a parent led to a non-nil error") } if isAncestor { t.Errorf("Providing a descendant as a parent led to a true result") diff --git a/x/btclightclient/types/errors.go b/x/btclightclient/types/errors.go index ee4c0e7f4..60788390e 100644 --- a/x/btclightclient/types/errors.go +++ b/x/btclightclient/types/errors.go @@ -13,5 +13,4 @@ var ( ErrHeaderParentDoesNotExist = sdkerrors.Register(ModuleName, 1102, "header parent does not exist") ErrInvalidDifficulty = sdkerrors.Register(ModuleName, 1103, "invalid difficulty bits") ErrEmptyMessage = sdkerrors.Register(ModuleName, 1104, "empty message provided") - ErrInvalidAncestor = sdkerrors.Register(ModuleName, 1105, "invalid ancestor provided") ) From 59f3528c79292ea4510272270ecdac22fb6fb76d Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Tue, 26 Jul 2022 10:53:40 +0300 Subject: [PATCH 3/4] minor --- x/btclightclient/keeper/keeper_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/btclightclient/keeper/keeper_test.go b/x/btclightclient/keeper/keeper_test.go index 972561843..891ea79ab 100644 --- a/x/btclightclient/keeper/keeper_test.go +++ b/x/btclightclient/keeper/keeper_test.go @@ -268,7 +268,7 @@ func FuzzKeeperIsAncestor(f *testing.F) { if isAncestor { t.Errorf("Same header input led to true result") } - } else if ancestor.Height > header.Height { // Descendant test + } else if ancestor.Height >= header.Height { // Descendant test isAncestor, err = blcKeeper.IsAncestor(ctx, ancestor.Hash, header.Hash) if err != nil { t.Errorf("Providing a descendant as a parent led to a non-nil error") From c58833e1207ca5be6263508e3b4c48044bd77ebb Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Tue, 26 Jul 2022 10:56:41 +0300 Subject: [PATCH 4/4] Tests fix --- types/btc_header_hash_bytes_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/types/btc_header_hash_bytes_test.go b/types/btc_header_hash_bytes_test.go index 27a06a3c6..116798162 100644 --- a/types/btc_header_hash_bytes_test.go +++ b/types/btc_header_hash_bytes_test.go @@ -90,7 +90,8 @@ func FuzzBTCHeaderHashBytesHexOps(f *testing.F) { if datagen.OneInN(10) { if datagen.OneInN(2) { // 1/4 times generate an invalid hash size - hex = datagen.GenRandomHexStr(datagen.RandomInt(types.BTCHeaderHashLen * 20)) + bzSz := datagen.RandomIntOtherThan(types.BTCHeaderHashLen, types.BTCHeaderHashLen*20) + hex = datagen.GenRandomHexStr(bzSz) } else { // 1/4 times generate an invalid hex hex = string(datagen.GenRandomByteArray(types.BTCHeaderHashLen * 2)) @@ -135,7 +136,8 @@ func FuzzBTCHeaderHashBytesJSONOps(f *testing.F) { if datagen.OneInN(10) { if datagen.OneInN(2) { // 1/4 times generate an invalid hash size - hex = datagen.GenRandomHexStr(datagen.RandomInt(types.BTCHeaderHashLen * 20)) + bzSz := datagen.RandomIntOtherThan(types.BTCHeaderHashLen, types.BTCHeaderHashLen*20) + hex = datagen.GenRandomHexStr(bzSz) } else { // 1/4 times generate an invalid hex hex = string(datagen.GenRandomByteArray(types.BTCHeaderHashLen * 2))