forked from babylonlabs-io/babylon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfork_indexer.go
58 lines (53 loc) · 1.98 KB
/
fork_indexer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package keeper
import (
"bytes"
"context"
"github.com/cosmos/cosmos-sdk/runtime"
sdkerrors "cosmossdk.io/errors"
"cosmossdk.io/store/prefix"
"github.com/babylonlabs-io/babylon/x/zoneconcierge/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// GetForks returns a list of forked headers at a given height
func (k Keeper) GetForks(ctx context.Context, chainID string, height uint64) *types.Forks {
store := k.forkStore(ctx, chainID)
heightBytes := sdk.Uint64ToBigEndian(height)
// if no fork at the moment, create an empty struct
if !store.Has(heightBytes) {
return &types.Forks{
Headers: []*types.IndexedHeader{},
}
}
forksBytes := store.Get(heightBytes)
var forks types.Forks
k.cdc.MustUnmarshal(forksBytes, &forks)
return &forks
}
// insertForkHeader inserts a forked header to the list of forked headers at the same height
func (k Keeper) insertForkHeader(ctx context.Context, chainID string, header *types.IndexedHeader) error {
if header == nil {
return sdkerrors.Wrapf(types.ErrInvalidHeader, "header is nil")
}
store := k.forkStore(ctx, chainID)
forks := k.GetForks(ctx, chainID, header.Height) // if no fork at the height, forks will be an empty struct rather than nil
// if the header is already in forks, discard this header and return directly
for _, h := range forks.Headers {
if bytes.Equal(h.Hash, header.Hash) {
return nil
}
}
forks.Headers = append(forks.Headers, header)
forksBytes := k.cdc.MustMarshal(forks)
store.Set(sdk.Uint64ToBigEndian(header.Height), forksBytes)
return nil
}
// forkStore stores the forks for each CZ
// prefix: ForkKey || chainID
// key: height that this fork starts from
// value: a list of IndexedHeader, representing each header in the fork
func (k Keeper) forkStore(ctx context.Context, chainID string) prefix.Store {
storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
forkStore := prefix.NewStore(storeAdapter, types.ForkKey)
chainIDBytes := []byte(chainID)
return prefix.NewStore(forkStore, chainIDBytes)
}