diff --git a/app/app.go b/app/app.go index 8ed6825fd..191ad30fd 100644 --- a/app/app.go +++ b/app/app.go @@ -330,7 +330,9 @@ func NewBabylonApp( epochingKeeper.SetMsgServiceRouter(app.BaseApp.MsgServiceRouter()) app.EpochingKeeper = epochingKeeper - app.BTCLightClientKeeper = *btclightclientkeeper.NewKeeper(appCodec, keys[btclightclienttypes.StoreKey], keys[btclightclienttypes.MemStoreKey], app.GetSubspace(btclightclienttypes.ModuleName)) + btclightclientKeeper := *btclightclientkeeper.NewKeeper(appCodec, keys[btclightclienttypes.StoreKey], keys[btclightclienttypes.MemStoreKey], app.GetSubspace(btclightclienttypes.ModuleName)) + btclightclientKeeper.SetHooks(btclightclienttypes.NewMultiBTCLightClientHooks()) + app.BTCLightClientKeeper = btclightclientKeeper // TODO for now use mocks, as soon as Checkpoining and lightClient will have correct interfaces // change to correct implementations diff --git a/proto/babylon/btclightclient/btclightclient.proto b/proto/babylon/btclightclient/btclightclient.proto index b8883a9f7..e9487396a 100644 --- a/proto/babylon/btclightclient/btclightclient.proto +++ b/proto/babylon/btclightclient/btclightclient.proto @@ -14,12 +14,13 @@ message BaseBTCHeader { uint64 height = 2; } -message HeaderInfo { +message BTCHeaderInfo { bytes header = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; bytes hash = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + uint64 height = 3; } diff --git a/proto/babylon/btclightclient/event.proto b/proto/babylon/btclightclient/event.proto new file mode 100644 index 000000000..4a4fb9e74 --- /dev/null +++ b/proto/babylon/btclightclient/event.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package babylon.btclightclient.v1; + +import "gogoproto/gogo.proto"; +import "babylon/btclightclient/btclightclient.proto"; + +option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; + +// The header included in the event is the block in the history +// of the current mainchain to which we are rolling back to. +// In other words, there is one rollback event emitted per re-org, to the +// greatest common ancestor of the old and the new fork. +message EventBTCRollBack { + BTCHeaderInfo header = 1; +} + +// EventBTCRollForward is emitted on Msg/InsertHeader +// The header included in the event is the one the main chain is extended with. +// In the event of a reorg, each block on the new fork that comes after +// the greatest common ancestor will have a corresponding roll forward event. +message EventBTCRollForward { + BTCHeaderInfo header = 1; +} diff --git a/proto/babylon/btclightclient/query.proto b/proto/babylon/btclightclient/query.proto index 8d1203092..dc28a6307 100644 --- a/proto/babylon/btclightclient/query.proto +++ b/proto/babylon/btclightclient/query.proto @@ -75,7 +75,7 @@ message QueryMainChainRequest { // QueryMainChainResponse is response type for the Query/MainChain RPC method. message QueryMainChainResponse { - repeated HeaderInfo headers = 1; + repeated BTCHeaderInfo headers = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/x/btclightclient/keeper/grpc_query.go b/x/btclightclient/keeper/grpc_query.go index ea5bcf303..17706794a 100644 --- a/x/btclightclient/keeper/grpc_query.go +++ b/x/btclightclient/keeper/grpc_query.go @@ -67,6 +67,11 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) } // If a starting key has not been set, then the first header is the tip prevHeader := k.HeadersState(sdkCtx).GetTip() + prevHeaderHash := prevHeader.BlockHash() + prevHeaderHeight, err := k.HeadersState(sdkCtx).GetHeaderHeight(&prevHeaderHash) + if err != nil { + panic("Maintained header does not have a height") + } // Otherwise, retrieve the header from the key if len(req.Pagination.Key) != 0 { headerHash, err := bbl.NewBTCHeaderHashBytesFromBytes(req.Pagination.Key) @@ -82,8 +87,9 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) return &types.QueryMainChainResponse{}, nil } - var headers []*types.HeaderInfo - headerInfo := types.NewHeaderInfo(prevHeader) + var headers []*types.BTCHeaderInfo + currentHeight := prevHeaderHeight + headerInfo := types.NewBTCHeaderInfo(prevHeader, prevHeaderHeight) headers = append(headers, headerInfo) store := prefix.NewStore(k.HeadersState(sdkCtx).headers, types.HeadersObjectPrefix) @@ -94,8 +100,9 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) btcdHeader := blockHeaderFromStoredBytes(value) // If the previous block extends this block, then this block is part of the main chain if prevHeader.PrevBlock.String() == btcdHeader.BlockHash().String() { + currentHeight -= 1 prevHeader = btcdHeader - headers = append(headers, types.NewHeaderInfo(btcdHeader)) + headers = append(headers, types.NewBTCHeaderInfo(btcdHeader, currentHeight)) } } return true, nil diff --git a/x/btclightclient/keeper/hooks.go b/x/btclightclient/keeper/hooks.go new file mode 100644 index 000000000..502e6244c --- /dev/null +++ b/x/btclightclient/keeper/hooks.go @@ -0,0 +1,23 @@ +package keeper + +import ( + "github.com/babylonchain/babylon/x/btclightclient/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Implements BTCLightClientHooks interface +var _ types.BTCLightClientHooks = Keeper{} + +// AfterBTCRollBack - call hook if registered +func (k Keeper) AfterBTCRollBack(ctx sdk.Context, headerInfo *types.BTCHeaderInfo) { + if k.hooks != nil { + k.hooks.AfterBTCRollBack(ctx, headerInfo) + } +} + +// AfterBTCRollForward - call hook if registered +func (k Keeper) AfterBTCRollForward(ctx sdk.Context, headerInfo *types.BTCHeaderInfo) { + if k.hooks != nil { + k.hooks.AfterBTCRollBack(ctx, headerInfo) + } +} diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index 1d11d18bf..638032435 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -17,6 +17,7 @@ type ( cdc codec.BinaryCodec storeKey sdk.StoreKey memKey sdk.StoreKey + hooks types.BTCLightClientHooks paramstore paramtypes.Subspace } ) @@ -37,6 +38,7 @@ func NewKeeper( cdc: cdc, storeKey: storeKey, memKey: memKey, + hooks: nil, paramstore: ps, } } @@ -45,6 +47,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } +// SetHooks sets the btclightclient hooks +func (k *Keeper) SetHooks(bh types.BTCLightClientHooks) *Keeper { + if k.hooks != nil { + panic("cannot set btclightclient hooks twice") + } + k.hooks = bh + + return k +} + // InsertHeader inserts a btcd header into the header state func (k Keeper) InsertHeader(ctx sdk.Context, header *wire.BlockHeader) error { headerHash := header.BlockHash() @@ -58,7 +70,7 @@ func (k Keeper) InsertHeader(ctx sdk.Context, header *wire.BlockHeader) error { return types.ErrHeaderParentDoesNotExist.Wrap("parent for provided hash is not maintained") } - height, err := k.HeadersState(ctx).GetHeaderHeight(&header.PrevBlock) + parentHeight, err := k.HeadersState(ctx).GetHeaderHeight(&header.PrevBlock) if err != nil { // Height should always exist if the previous checks have passed panic("Height for parent is not maintained") @@ -73,7 +85,77 @@ func (k Keeper) InsertHeader(ctx sdk.Context, header *wire.BlockHeader) error { headerWork := types.CalcWork(header) cumulativeWork := types.CumulativeWork(headerWork, parentWork) + previousTip := k.HeadersState(ctx).GetTip() // Create the header - k.HeadersState(ctx).CreateHeader(header, height+1, cumulativeWork) + k.HeadersState(ctx).CreateHeader(header, parentHeight+1, cumulativeWork) + + // Get the new tip + currentTip := k.HeadersState(ctx).GetTip() + + // Variable maintaining the headers that have been added to the main chain + var addedToMainChain []*wire.BlockHeader + + // The tip has changed, we need to send events + if !sameBlock(currentTip, previousTip) { + if !sameBlock(currentTip, header) { + panic("The tip was updated but with a different header than the one provided") + } + tipHeight := parentHeight + 1 + // Get the highest common ancestor between the new tip and the old tip + // There are two cases: + // 1. The new tip extends the old tip + // - The highest common ancestor is the old tip + // - No need to send a roll-back event + // 2. There has been a chain re-org + // - Need to send a roll-back event + var hca *wire.BlockHeader + var hcaHeight uint64 + if isParent(currentTip, previousTip) { + hca = previousTip + hcaHeight = parentHeight + } else { + hca := k.HeadersState(ctx).GetHighestCommonAncestor(previousTip, currentTip) + hcaHash := hca.BlockHash() + hcaHeight, err = k.HeadersState(ctx).GetHeaderHeight(&hcaHash) + if err != nil { + panic("Height for maintained header not available in storage") + } + // chain re-org: trigger a roll-back event to the highest common ancestor + k.triggerRollBack(ctx, hca, hcaHeight) + } + // Find the newly added headers to the main chain + addedToMainChain = k.HeadersState(ctx).GetInOrderAncestorsUntil(currentTip, hca) + // Iterate through the added headers and trigger a roll-forward event + for idx, added := range addedToMainChain { + // tipHeight + 1 - len(addedToMainChain) -> height of the highest common ancestor + addedHeight := tipHeight - uint64(len(addedToMainChain)) + 1 + uint64(idx) + k.triggerRollForward(ctx, added, addedHeight) + } + } + return nil } + +// BlockHeight returns the height of the provided header +func (k Keeper) BlockHeight(ctx sdk.Context, header *wire.BlockHeader) (uint64, error) { + headerHash := header.BlockHash() + return k.HeadersState(ctx).GetHeaderHeight(&headerHash) +} + +// HeaderKDeep returns true if a header is at least k-deep on the main chain +func (k Keeper) HeaderKDeep(ctx sdk.Context, header *wire.BlockHeader, depth uint64) bool { + // TODO: optimize to not traverse the entire mainchain by storing the height along with the header + mainchain := k.HeadersState(ctx).GetMainChain() + if depth > uint64(len(mainchain)) { + return false + } + // k-deep -> k headers built on top of the BTC header + // Discard the first `depth` headers + kDeepMainChain := mainchain[depth:] + for _, mainChainHeader := range kDeepMainChain { + if sameBlock(header, mainChainHeader) { + return true + } + } + return false +} diff --git a/x/btclightclient/keeper/state.go b/x/btclightclient/keeper/state.go index 53277bac2..8910058f8 100644 --- a/x/btclightclient/keeper/state.go +++ b/x/btclightclient/keeper/state.go @@ -173,21 +173,16 @@ func (s HeadersState) GetHeadersByHeight(height uint64, f func(*wire.BlockHeader // GetDescendingHeaders returns a collection of descending headers according to their height func (s HeadersState) GetDescendingHeaders() []*wire.BlockHeader { - // Get the prefix store for the (height, hash) -> header collection - store := prefix.NewStore(s.headers, types.HeadersObjectPrefix) - // Iterate it in reverse in order to get highest heights first - // TODO: need to verify this assumption - iter := store.ReverseIterator(nil, nil) - defer iter.Close() - var headers []*wire.BlockHeader - for ; iter.Valid(); iter.Next() { - headers = append(headers, blockHeaderFromStoredBytes(iter.Value())) - } + s.iterateReverseHeaders(func(header *wire.BlockHeader) bool { + headers = append(headers, header) + return false + }) return headers } // GetMainChain returns the current canonical chain as a collection of block headers +// starting from the tip and ending on the base header func (s HeadersState) GetMainChain() []*wire.BlockHeader { // If there is no tip, there is no base header if !s.TipExists() { @@ -215,6 +210,87 @@ func (s HeadersState) GetMainChain() []*wire.BlockHeader { return chain } +// GetHighestCommonAncestor traverses the ancestors of both headers +// to identify the common ancestor with the highest height +func (s HeadersState) GetHighestCommonAncestor(header1 *wire.BlockHeader, header2 *wire.BlockHeader) *wire.BlockHeader { + // The algorithm works as follows: + // 1. Initialize a hashmap hash -> bool denoting whether the hash + // of an ancestor of either header1 or header2 has been encountered + // 2. Maintain ancestor1 and ancestor2 as variables that point + // to the current ancestor hash of the header1 and header2 parameters + // 3. Whenever a node is encountered with a hash that is equal to ancestor{1,2}, + // update the ancestor{1,2} variables. + // 4. If ancestor1 or ancestor2 is set to the hash table, + // then that's the hash of the earliest ancestor + // 5. Using the hash of the heighest ancestor wait until we get the header bytes + // in order to avoid an extra access. + if isParent(header1, header2) { + return header2 + } + if isParent(header2, header1) { + return header1 + } + ancestor1 := header1.BlockHash() + ancestor2 := header2.BlockHash() + var encountered map[string]bool + encountered[ancestor1.String()] = true + encountered[ancestor2.String()] = true + var found *chainhash.Hash = nil + + var resHeader *wire.BlockHeader = nil + + s.iterateReverseHeaders(func(btcdHeader *wire.BlockHeader) bool { + // During iteration, we will encounter an ancestor for which its header hash + // has been set on the hash map. + // However, we do not have the entry yet, so we set the found flag to that hash + // and when we encounter it during iteration we return it. + if found != nil && sameHash(*found, btcdHeader.BlockHash()) { + resHeader = btcdHeader + return true + } else { + if ancestor1 == btcdHeader.BlockHash() { + ancestor1 = btcdHeader.PrevBlock + if encountered[ancestor1.String()] { + found = &ancestor1 + } + encountered[ancestor1.String()] = true + } + if ancestor2 == btcdHeader.BlockHash() { + ancestor2 = btcdHeader.PrevBlock + if encountered[ancestor2.String()] { + found = &ancestor2 + } + encountered[ancestor2.String()] = true + } + } + return false + }) + return resHeader +} + +// GetInOrderAncestorsUntil returns the list of nodes starting from the child and ending with the block *before* the `ancestor`. +func (s HeadersState) GetInOrderAncestorsUntil(child *wire.BlockHeader, ancestor *wire.BlockHeader) []*wire.BlockHeader { + currentHeader := child + + var ancestors []*wire.BlockHeader + ancestors = append(ancestors, child) + if isParent(child, ancestor) { + return ancestors + } + s.iterateReverseHeaders(func(header *wire.BlockHeader) bool { + if header.BlockHash() == ancestor.BlockHash() { + return true + } + if header.BlockHash().String() == currentHeader.PrevBlock.String() { + currentHeader = header + ancestors = append(ancestors, header) + } + return false + }) + + return ancestors +} + // HeaderExists Check whether a hash is maintained in storage func (s HeadersState) HeaderExists(hash *chainhash.Hash) bool { // Get the prefix store for the hash->height collection @@ -235,7 +311,7 @@ func (s HeadersState) TipExists() bool { return s.tip.Has(tipKey) } -// updateLongestChain checks whether the tip should be updated and acts accordingly +// updateLongestChain checks whether the tip should be updated and returns true if it does func (s HeadersState) updateLongestChain(header *wire.BlockHeader, cumulativeWork *big.Int) { // If there is no existing tip, then the header is set as the tip if !s.TipExists() { @@ -259,3 +335,20 @@ func (s HeadersState) updateLongestChain(header *wire.BlockHeader, cumulativeWor s.CreateTip(header) } } + +func (s HeadersState) iterateReverseHeaders(fn func(*wire.BlockHeader) bool) { + // Get the prefix store for the (height, hash) -> header collection + store := prefix.NewStore(s.headers, types.HeadersObjectPrefix) + // Iterate it in reverse in order to get highest heights first + // TODO: need to verify this assumption + iter := store.ReverseIterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + btcdHeader := blockHeaderFromStoredBytes(iter.Value()) + stop := fn(btcdHeader) + if stop { + break + } + } +} diff --git a/x/btclightclient/keeper/triggers.go b/x/btclightclient/keeper/triggers.go new file mode 100644 index 000000000..de058c87d --- /dev/null +++ b/x/btclightclient/keeper/triggers.go @@ -0,0 +1,23 @@ +package keeper + +import ( + "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/btcsuite/btcd/wire" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) triggerRollBack(ctx sdk.Context, header *wire.BlockHeader, height uint64) { + headerInfo := types.NewBTCHeaderInfo(header, height) + // Trigger AfterBTCRollBack hook + k.AfterBTCRollBack(ctx, headerInfo) + // Emit BTCRollBack event + ctx.EventManager().EmitTypedEvent(&types.EventBTCRollBack{Header: headerInfo}) +} + +func (k Keeper) triggerRollForward(ctx sdk.Context, header *wire.BlockHeader, height uint64) { + headerInfo := types.NewBTCHeaderInfo(header, height) + // Trigger AfterBTCRollForward hook + k.AfterBTCRollForward(ctx, headerInfo) + // Emit BTCRollForward event + ctx.EventManager().EmitTypedEvent(&types.EventBTCRollForward{Header: headerInfo}) +} diff --git a/x/btclightclient/keeper/utils.go b/x/btclightclient/keeper/utils.go index 3c1b1035b..37b5175a5 100644 --- a/x/btclightclient/keeper/utils.go +++ b/x/btclightclient/keeper/utils.go @@ -2,6 +2,7 @@ package keeper import ( bbl "github.com/babylonchain/babylon/types" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" ) @@ -14,3 +15,15 @@ func blockHeaderFromStoredBytes(bz []byte) *wire.BlockHeader { // Convert the BTCHeaderBytes object into a *wire.BlockHeader object return headerBytes.ToBlockHeader() } + +func isParent(child *wire.BlockHeader, parent *wire.BlockHeader) bool { + return sameHash(child.PrevBlock, parent.BlockHash()) +} + +func sameBlock(header1 *wire.BlockHeader, header2 *wire.BlockHeader) bool { + return sameHash(header1.BlockHash(), header2.BlockHash()) +} + +func sameHash(hash1 chainhash.Hash, hash2 chainhash.Hash) bool { + return hash1.String() == hash2.String() +} diff --git a/x/btclightclient/types/header_info.go b/x/btclightclient/types/btc_header_info.go similarity index 73% rename from x/btclightclient/types/header_info.go rename to x/btclightclient/types/btc_header_info.go index 5d1a5d25b..10d926ff0 100644 --- a/x/btclightclient/types/header_info.go +++ b/x/btclightclient/types/btc_header_info.go @@ -5,14 +5,15 @@ import ( "github.com/btcsuite/btcd/wire" ) -func NewHeaderInfo(header *wire.BlockHeader) *HeaderInfo { +func NewBTCHeaderInfo(header *wire.BlockHeader, height uint64) *BTCHeaderInfo { headerHashCh := header.BlockHash() currentHeaderBytes := bbl.NewBTCHeaderBytesFromBlockHeader(header) headerHash := bbl.NewBTCHeaderHashBytesFromChainhash(&headerHashCh) - return &HeaderInfo{ + return &BTCHeaderInfo{ Header: ¤tHeaderBytes, Hash: &headerHash, + Height: height, } } diff --git a/x/btclightclient/types/header_info_test.go b/x/btclightclient/types/btc_header_info_test.go similarity index 90% rename from x/btclightclient/types/header_info_test.go rename to x/btclightclient/types/btc_header_info_test.go index d61071ae5..9400e15f2 100644 --- a/x/btclightclient/types/header_info_test.go +++ b/x/btclightclient/types/btc_header_info_test.go @@ -19,10 +19,11 @@ func FuzzNewHeaderInfo(f *testing.F) { btcdHeader.Timestamp.Unix(), btcdHeader.PrevBlock.String(), btcdHeader.MerkleRoot.String(), + uint64(42), int64(17)) f.Fuzz(func(t *testing.T, version int32, bits uint32, nonce uint32, - timeInt int64, prevBlockStr string, merkleRootStr string, seed int64) { + timeInt int64, prevBlockStr string, merkleRootStr string, height uint64, seed int64) { // If either of the hash strings is not of appropriate length // or not valid hex, generate a random hex randomly @@ -32,7 +33,7 @@ func FuzzNewHeaderInfo(f *testing.F) { // Get the expected header bytes expectedHeaderBytes := bbl.NewBTCHeaderBytesFromBlockHeader(header) - headerInfo := types.NewHeaderInfo(header) + headerInfo := types.NewBTCHeaderInfo(header, height) if headerInfo == nil { t.Errorf("returned object is nil") } diff --git a/x/btclightclient/types/btclightclient.pb.go b/x/btclightclient/types/btclightclient.pb.go index 29a2d7609..48f3b0718 100644 --- a/x/btclightclient/types/btclightclient.pb.go +++ b/x/btclightclient/types/btclightclient.pb.go @@ -71,23 +71,24 @@ func (m *BaseBTCHeader) GetHeight() uint64 { return 0 } -type HeaderInfo struct { +type BTCHeaderInfo struct { Header *github_com_babylonchain_babylon_types.BTCHeaderBytes `protobuf:"bytes,1,opt,name=header,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderBytes" json:"header,omitempty"` Hash *github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,2,opt,name=hash,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` + Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` } -func (m *HeaderInfo) Reset() { *m = HeaderInfo{} } -func (m *HeaderInfo) String() string { return proto.CompactTextString(m) } -func (*HeaderInfo) ProtoMessage() {} -func (*HeaderInfo) Descriptor() ([]byte, []int) { +func (m *BTCHeaderInfo) Reset() { *m = BTCHeaderInfo{} } +func (m *BTCHeaderInfo) String() string { return proto.CompactTextString(m) } +func (*BTCHeaderInfo) ProtoMessage() {} +func (*BTCHeaderInfo) Descriptor() ([]byte, []int) { return fileDescriptor_3313d955a6cadef2, []int{1} } -func (m *HeaderInfo) XXX_Unmarshal(b []byte) error { +func (m *BTCHeaderInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *HeaderInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *BTCHeaderInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_HeaderInfo.Marshal(b, m, deterministic) + return xxx_messageInfo_BTCHeaderInfo.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -97,21 +98,28 @@ func (m *HeaderInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *HeaderInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_HeaderInfo.Merge(m, src) +func (m *BTCHeaderInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCHeaderInfo.Merge(m, src) } -func (m *HeaderInfo) XXX_Size() int { +func (m *BTCHeaderInfo) XXX_Size() int { return m.Size() } -func (m *HeaderInfo) XXX_DiscardUnknown() { - xxx_messageInfo_HeaderInfo.DiscardUnknown(m) +func (m *BTCHeaderInfo) XXX_DiscardUnknown() { + xxx_messageInfo_BTCHeaderInfo.DiscardUnknown(m) } -var xxx_messageInfo_HeaderInfo proto.InternalMessageInfo +var xxx_messageInfo_BTCHeaderInfo proto.InternalMessageInfo + +func (m *BTCHeaderInfo) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} func init() { proto.RegisterType((*BaseBTCHeader)(nil), "babylon.btclightclient.v1.BaseBTCHeader") - proto.RegisterType((*HeaderInfo)(nil), "babylon.btclightclient.v1.HeaderInfo") + proto.RegisterType((*BTCHeaderInfo)(nil), "babylon.btclightclient.v1.BTCHeaderInfo") } func init() { @@ -119,7 +127,7 @@ func init() { } var fileDescriptor_3313d955a6cadef2 = []byte{ - // 247 bytes of a gzipped FileDescriptorProto + // 253 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0x68, 0x5c, 0xbd, 0x82, 0xa2, 0xfc, 0x92, 0x7c, 0x21, 0x49, 0xa8, 0x62, 0x3d, 0x34, 0xd9, 0x32, @@ -129,13 +137,13 @@ var fileDescriptor_3313d955a6cadef2 = []byte{ 0xde, 0x24, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x6a, 0x41, 0x72, 0x46, 0x62, 0x66, 0x1e, 0x8c, 0xa3, 0x5f, 0x52, 0x59, 0x90, 0x5a, 0xac, 0x07, 0x37, 0xc4, 0xa9, 0xb2, 0x24, 0xb5, 0x38, 0x08, 0x6a, 0x8e, 0x90, 0x18, 0xc8, 0x44, 0x90, 0x5b, 0x24, 0x98, 0x14, - 0x18, 0x35, 0x58, 0x82, 0xa0, 0x3c, 0xa5, 0x0d, 0x8c, 0x5c, 0x5c, 0x10, 0xf5, 0x9e, 0x79, 0x69, - 0xf9, 0x34, 0xb0, 0x38, 0x80, 0x8b, 0x25, 0x23, 0xb1, 0x38, 0x03, 0x6c, 0x2d, 0x8f, 0x93, 0xcd, - 0xad, 0x7b, 0xf2, 0x16, 0x24, 0x9a, 0xe7, 0x91, 0x58, 0x9c, 0x01, 0x31, 0x13, 0x6c, 0x92, 0x53, - 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, - 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x99, 0x11, 0x32, 0xb9, 0x02, - 0x3d, 0xfe, 0xc0, 0x56, 0x25, 0xb1, 0x81, 0xa3, 0xc1, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x30, - 0xbb, 0x6f, 0xf3, 0xe6, 0x01, 0x00, 0x00, + 0x18, 0x35, 0x58, 0x82, 0xa0, 0x3c, 0xa5, 0xd3, 0x8c, 0x5c, 0xbc, 0x70, 0x2d, 0x9e, 0x79, 0x69, + 0xf9, 0x34, 0xb0, 0x3b, 0x80, 0x8b, 0x25, 0x23, 0xb1, 0x38, 0x03, 0x6c, 0x33, 0x8f, 0x93, 0xcd, + 0xad, 0x7b, 0xf2, 0x16, 0x24, 0x9a, 0xe7, 0x91, 0x58, 0x9c, 0x01, 0x31, 0x13, 0x6c, 0x12, 0x92, + 0x6f, 0x98, 0x91, 0x7d, 0xe3, 0x14, 0x70, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, + 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, + 0x51, 0x66, 0x84, 0x6c, 0xac, 0x40, 0x8f, 0x5a, 0xb0, 0x13, 0x92, 0xd8, 0xc0, 0x31, 0x64, 0x0c, + 0x08, 0x00, 0x00, 0xff, 0xff, 0x73, 0x01, 0xff, 0x5f, 0x01, 0x02, 0x00, 0x00, } func (m *BaseBTCHeader) Marshal() (dAtA []byte, err error) { @@ -178,7 +186,7 @@ func (m *BaseBTCHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *HeaderInfo) Marshal() (dAtA []byte, err error) { +func (m *BTCHeaderInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -188,16 +196,21 @@ func (m *HeaderInfo) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *HeaderInfo) MarshalTo(dAtA []byte) (int, error) { +func (m *BTCHeaderInfo) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *HeaderInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *BTCHeaderInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l + if m.Height != 0 { + i = encodeVarintBtclightclient(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x18 + } if m.Hash != nil { { size := m.Hash.Size() @@ -252,7 +265,7 @@ func (m *BaseBTCHeader) Size() (n int) { return n } -func (m *HeaderInfo) Size() (n int) { +func (m *BTCHeaderInfo) Size() (n int) { if m == nil { return 0 } @@ -266,6 +279,9 @@ func (m *HeaderInfo) Size() (n int) { l = m.Hash.Size() n += 1 + l + sovBtclightclient(uint64(l)) } + if m.Height != 0 { + n += 1 + sovBtclightclient(uint64(m.Height)) + } return n } @@ -379,7 +395,7 @@ func (m *BaseBTCHeader) Unmarshal(dAtA []byte) error { } return nil } -func (m *HeaderInfo) Unmarshal(dAtA []byte) error { +func (m *BTCHeaderInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -402,10 +418,10 @@ func (m *HeaderInfo) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HeaderInfo: wiretype end group for non-group") + return fmt.Errorf("proto: BTCHeaderInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HeaderInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BTCHeaderInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -478,6 +494,25 @@ func (m *HeaderInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtclightclient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipBtclightclient(dAtA[iNdEx:]) diff --git a/x/btclightclient/types/event.pb.go b/x/btclightclient/types/event.pb.go new file mode 100644 index 000000000..46f732761 --- /dev/null +++ b/x/btclightclient/types/event.pb.go @@ -0,0 +1,511 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: babylon/btclightclient/event.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// EventBTCRollBack is emitted on Msg/InsertHeader +type EventBTCRollBack struct { + Header *BTCHeaderInfo `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` +} + +func (m *EventBTCRollBack) Reset() { *m = EventBTCRollBack{} } +func (m *EventBTCRollBack) String() string { return proto.CompactTextString(m) } +func (*EventBTCRollBack) ProtoMessage() {} +func (*EventBTCRollBack) Descriptor() ([]byte, []int) { + return fileDescriptor_dbeb7d7d6407e7ec, []int{0} +} +func (m *EventBTCRollBack) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventBTCRollBack) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventBTCRollBack.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventBTCRollBack) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventBTCRollBack.Merge(m, src) +} +func (m *EventBTCRollBack) XXX_Size() int { + return m.Size() +} +func (m *EventBTCRollBack) XXX_DiscardUnknown() { + xxx_messageInfo_EventBTCRollBack.DiscardUnknown(m) +} + +var xxx_messageInfo_EventBTCRollBack proto.InternalMessageInfo + +func (m *EventBTCRollBack) GetHeader() *BTCHeaderInfo { + if m != nil { + return m.Header + } + return nil +} + +// EventBTCRollForward is emitted on Msg/InsertHeader +type EventBTCRollForward struct { + Header *BTCHeaderInfo `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` +} + +func (m *EventBTCRollForward) Reset() { *m = EventBTCRollForward{} } +func (m *EventBTCRollForward) String() string { return proto.CompactTextString(m) } +func (*EventBTCRollForward) ProtoMessage() {} +func (*EventBTCRollForward) Descriptor() ([]byte, []int) { + return fileDescriptor_dbeb7d7d6407e7ec, []int{1} +} +func (m *EventBTCRollForward) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventBTCRollForward) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventBTCRollForward.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventBTCRollForward) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventBTCRollForward.Merge(m, src) +} +func (m *EventBTCRollForward) XXX_Size() int { + return m.Size() +} +func (m *EventBTCRollForward) XXX_DiscardUnknown() { + xxx_messageInfo_EventBTCRollForward.DiscardUnknown(m) +} + +var xxx_messageInfo_EventBTCRollForward proto.InternalMessageInfo + +func (m *EventBTCRollForward) GetHeader() *BTCHeaderInfo { + if m != nil { + return m.Header + } + return nil +} + +func init() { + proto.RegisterType((*EventBTCRollBack)(nil), "babylon.btclightclient.v1.EventBTCRollBack") + proto.RegisterType((*EventBTCRollForward)(nil), "babylon.btclightclient.v1.EventBTCRollForward") +} + +func init() { + proto.RegisterFile("babylon/btclightclient/event.proto", fileDescriptor_dbeb7d7d6407e7ec) +} + +var fileDescriptor_dbeb7d7d6407e7ec = []byte{ + // 223 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0x4a, 0x4c, 0xaa, + 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, + 0xfa, 0xa9, 0x65, 0xa9, 0x79, 0x25, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x92, 0x50, 0x35, + 0x7a, 0xa8, 0x6a, 0xf4, 0xca, 0x0c, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xaa, 0xf4, 0x41, + 0x2c, 0x88, 0x06, 0x29, 0x6d, 0x1c, 0x86, 0xa2, 0xe9, 0x07, 0x2b, 0x56, 0x0a, 0xe1, 0x12, 0x70, + 0x05, 0x59, 0xe6, 0x14, 0xe2, 0x1c, 0x94, 0x9f, 0x93, 0xe3, 0x94, 0x98, 0x9c, 0x2d, 0xe4, 0xc0, + 0xc5, 0x96, 0x91, 0x9a, 0x98, 0x92, 0x5a, 0x24, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xa1, + 0x87, 0xd3, 0x09, 0x7a, 0x4e, 0x21, 0xce, 0x1e, 0x60, 0xb5, 0x9e, 0x79, 0x69, 0xf9, 0x41, 0x50, + 0x7d, 0x4a, 0xe1, 0x5c, 0xc2, 0xc8, 0xa6, 0xba, 0xe5, 0x17, 0x95, 0x27, 0x16, 0xa5, 0x50, 0x6e, + 0xb0, 0x53, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, + 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x99, 0xa5, 0x67, + 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x4d, 0x4d, 0xce, 0x48, 0xcc, 0xcc, + 0x83, 0x71, 0xf4, 0x2b, 0xd0, 0xc3, 0xa3, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0x1c, 0x0e, + 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xad, 0x58, 0xdc, 0x8b, 0x01, 0x00, 0x00, +} + +func (m *EventBTCRollBack) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventBTCRollBack) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventBTCRollBack) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Header != nil { + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventBTCRollForward) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventBTCRollForward) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventBTCRollForward) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Header != nil { + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintEvent(dAtA []byte, offset int, v uint64) int { + offset -= sovEvent(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *EventBTCRollBack) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovEvent(uint64(l)) + } + return n +} + +func (m *EventBTCRollForward) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovEvent(uint64(l)) + } + return n +} + +func sovEvent(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEvent(x uint64) (n int) { + return sovEvent(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EventBTCRollBack) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventBTCRollBack: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventBTCRollBack: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &BTCHeaderInfo{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventBTCRollForward) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventBTCRollForward: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventBTCRollForward: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &BTCHeaderInfo{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEvent(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEvent + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEvent + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEvent + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEvent = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEvent = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEvent = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/btclightclient/types/expected_keepers.go b/x/btclightclient/types/expected_keepers.go index 6aa6e9778..8a6b9b437 100644 --- a/x/btclightclient/types/expected_keepers.go +++ b/x/btclightclient/types/expected_keepers.go @@ -16,3 +16,8 @@ type BankKeeper interface { SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins // Methods imported from bank should be defined here } + +type BTCLightClientHooks interface { + AfterBTCRollBack(ctx sdk.Context, headerInfo *BTCHeaderInfo) // Must be called after the chain is rolled back + AfterBTCRollForward(ctx sdk.Context, headerInfo *BTCHeaderInfo) // Must be called after the chain is rolled forward +} diff --git a/x/btclightclient/types/hooks.go b/x/btclightclient/types/hooks.go new file mode 100644 index 000000000..c703b0315 --- /dev/null +++ b/x/btclightclient/types/hooks.go @@ -0,0 +1,25 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ BTCLightClientHooks = &MultiBTCLightClientHooks{} + +type MultiBTCLightClientHooks []BTCLightClientHooks + +func NewMultiBTCLightClientHooks(hooks ...BTCLightClientHooks) MultiBTCLightClientHooks { + return hooks +} + +func (h MultiBTCLightClientHooks) AfterBTCRollBack(ctx sdk.Context, headerInfo *BTCHeaderInfo) { + for i := range h { + h[i].AfterBTCRollBack(ctx, headerInfo) + } +} + +func (h MultiBTCLightClientHooks) AfterBTCRollForward(ctx sdk.Context, headerInfo *BTCHeaderInfo) { + for i := range h { + h[i].AfterBTCRollForward(ctx, headerInfo) + } +} diff --git a/x/btclightclient/types/query.pb.go b/x/btclightclient/types/query.pb.go index ec933fcc1..5ba211ec7 100644 --- a/x/btclightclient/types/query.pb.go +++ b/x/btclightclient/types/query.pb.go @@ -338,7 +338,7 @@ func (m *QueryMainChainRequest) GetPagination() *query.PageRequest { // QueryMainChainResponse is response type for the Query/MainChain RPC method. type QueryMainChainResponse struct { - Headers []*HeaderInfo `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` + Headers []*BTCHeaderInfo `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -375,7 +375,7 @@ func (m *QueryMainChainResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryMainChainResponse proto.InternalMessageInfo -func (m *QueryMainChainResponse) GetHeaders() []*HeaderInfo { +func (m *QueryMainChainResponse) GetHeaders() []*BTCHeaderInfo { if m != nil { return m.Headers } @@ -405,45 +405,45 @@ func init() { } var fileDescriptor_6293be71fb7ba6c4 = []byte{ - // 602 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x6f, 0xd3, 0x3c, - 0x18, 0xc7, 0xeb, 0xbd, 0x7d, 0x4b, 0xf1, 0x38, 0x99, 0x82, 0x46, 0x84, 0xb2, 0x2d, 0x65, 0x63, - 0x30, 0xb0, 0x69, 0x27, 0x21, 0x0e, 0x48, 0x48, 0xad, 0x04, 0xe3, 0x80, 0x54, 0xa2, 0x89, 0x03, - 0x42, 0x42, 0x4e, 0x31, 0x49, 0xa4, 0xd6, 0xce, 0x1a, 0xb7, 0xa2, 0x57, 0x3e, 0x01, 0x82, 0x1b, - 0x07, 0x0e, 0x7c, 0x06, 0x3e, 0xc4, 0x8e, 0x93, 0xb8, 0x20, 0x0e, 0x13, 0x6a, 0xb9, 0xf3, 0x15, - 0x50, 0x6c, 0xa7, 0x90, 0xa0, 0x36, 0x45, 0xec, 0x52, 0xd5, 0xce, 0xf3, 0x3c, 0xff, 0x9f, 0x1f, - 0xff, 0x1f, 0x43, 0xc7, 0xa3, 0xde, 0xb8, 0x27, 0x38, 0xf1, 0x64, 0xb7, 0x17, 0xfa, 0x41, 0xf2, - 0xcb, 0xb8, 0x24, 0x87, 0x43, 0x36, 0x18, 0xe3, 0x68, 0x20, 0xa4, 0x40, 0x97, 0x4c, 0x0c, 0xce, - 0xc6, 0xe0, 0x51, 0xc3, 0xaa, 0xf9, 0xc2, 0x17, 0x2a, 0x8a, 0x24, 0xff, 0x74, 0x82, 0x75, 0xd9, - 0x17, 0xc2, 0xef, 0x31, 0x42, 0xa3, 0x90, 0x50, 0xce, 0x85, 0xa4, 0x32, 0x14, 0x3c, 0x36, 0x5f, - 0xaf, 0x77, 0x45, 0xdc, 0x17, 0x31, 0xf1, 0x68, 0xcc, 0xb4, 0x0e, 0x19, 0x35, 0x3c, 0x26, 0x69, - 0x83, 0x44, 0xd4, 0x0f, 0xb9, 0x0a, 0x36, 0xb1, 0xf5, 0x39, 0x78, 0x11, 0x1d, 0xd0, 0x7e, 0x5a, - 0x70, 0x77, 0x4e, 0x50, 0x0e, 0x57, 0x05, 0x3b, 0x35, 0x88, 0x1e, 0x27, 0x9a, 0x1d, 0x55, 0xc1, - 0x65, 0x87, 0x43, 0x16, 0x4b, 0xe7, 0x09, 0x3c, 0x9f, 0xd9, 0x8d, 0x23, 0xc1, 0x63, 0x86, 0xee, - 0xc1, 0x8a, 0x56, 0x5a, 0x03, 0x1b, 0x60, 0x67, 0xb5, 0xb9, 0x89, 0xe7, 0xb6, 0x02, 0xeb, 0xd4, - 0x56, 0xf9, 0xe8, 0x64, 0xbd, 0xe4, 0x9a, 0x34, 0xe7, 0x99, 0x51, 0xdb, 0xa7, 0x71, 0xc0, 0x52, - 0x35, 0x74, 0x1f, 0xc2, 0x5f, 0x27, 0x35, 0xa5, 0xb7, 0xb1, 0x6e, 0x0b, 0x4e, 0xda, 0x82, 0x75, - 0xfb, 0x4d, 0x5b, 0x70, 0x87, 0xfa, 0xcc, 0xe4, 0xba, 0xbf, 0x65, 0x3a, 0x9f, 0x80, 0xc1, 0x4e, - 0xcb, 0x1b, 0xec, 0x03, 0x58, 0x09, 0xd4, 0xce, 0x1a, 0xd8, 0xf8, 0x6f, 0xe7, 0x5c, 0xeb, 0xee, - 0xd7, 0x93, 0xf5, 0x3b, 0x7e, 0x28, 0x83, 0xa1, 0x87, 0xbb, 0xa2, 0x4f, 0xcc, 0x21, 0xba, 0x01, - 0x0d, 0x79, 0xba, 0x20, 0x72, 0x1c, 0xb1, 0x18, 0xb7, 0x0e, 0xda, 0xfb, 0x8c, 0xbe, 0x60, 0x83, - 0xa4, 0x64, 0x6b, 0x2c, 0x59, 0xec, 0x9a, 0x5a, 0xe8, 0x41, 0x86, 0x7a, 0x45, 0x51, 0x5f, 0x2d, - 0xa4, 0xd6, 0x48, 0x19, 0xec, 0x00, 0xd6, 0x14, 0x75, 0x5b, 0x70, 0x49, 0x43, 0x3e, 0x6b, 0x4b, - 0x07, 0x96, 0x13, 0x29, 0xd5, 0x90, 0x7f, 0x85, 0x56, 0x95, 0x9c, 0x3d, 0x78, 0x21, 0xa7, 0x64, - 0x3a, 0x64, 0xc1, 0x6a, 0xd7, 0xec, 0x29, 0xb9, 0xaa, 0x3b, 0x5b, 0x3b, 0xcf, 0x4d, 0xd2, 0x23, - 0x1a, 0xf2, 0x76, 0xa2, 0x76, 0xda, 0xd7, 0xf6, 0x11, 0xc0, 0x8b, 0x79, 0x85, 0x99, 0xe1, 0xce, - 0x04, 0xea, 0x24, 0xfa, 0xea, 0x56, 0x9b, 0x5b, 0x0b, 0x1c, 0xa7, 0xcf, 0xfc, 0x90, 0xbf, 0x14, - 0x6e, 0x9a, 0x75, 0x6a, 0x97, 0xd4, 0xfc, 0x51, 0x86, 0xff, 0x2b, 0x48, 0xf4, 0x16, 0xc0, 0x8a, - 0x36, 0x37, 0xba, 0xb9, 0x80, 0xe6, 0xcf, 0xa9, 0xb2, 0xf0, 0xb2, 0xe1, 0x5a, 0xdf, 0xb9, 0xf6, - 0xfa, 0xf3, 0xf7, 0x77, 0x2b, 0x75, 0xb4, 0x49, 0xe6, 0x4c, 0xf4, 0xa8, 0x61, 0x26, 0x5f, 0x41, - 0x69, 0xd7, 0x17, 0x43, 0x65, 0x86, 0xaf, 0x18, 0x2a, 0x3b, 0x4c, 0x4b, 0x41, 0x99, 0x09, 0x79, - 0x0f, 0x60, 0x35, 0xb5, 0x1a, 0x22, 0x45, 0x3a, 0x39, 0xfb, 0x5b, 0xb7, 0x96, 0x4f, 0x30, 0x68, - 0xbb, 0x0a, 0x6d, 0x0b, 0xd5, 0x17, 0xa0, 0xa5, 0xb6, 0x46, 0x1f, 0x00, 0x3c, 0x3b, 0x33, 0x1c, - 0x2a, 0x14, 0xcb, 0xbb, 0xdf, 0x6a, 0xfc, 0x45, 0x86, 0xe1, 0xbb, 0xa1, 0xf8, 0xb6, 0xd1, 0x95, - 0x05, 0x7c, 0x7d, 0x1a, 0xea, 0x99, 0x6e, 0x75, 0x8e, 0x26, 0x36, 0x38, 0x9e, 0xd8, 0xe0, 0xdb, - 0xc4, 0x06, 0x6f, 0xa6, 0x76, 0xe9, 0x78, 0x6a, 0x97, 0xbe, 0x4c, 0xed, 0xd2, 0xd3, 0xdb, 0x45, - 0xcf, 0xc0, 0xab, 0x7c, 0x61, 0xf5, 0x2e, 0x78, 0x15, 0xf5, 0xe4, 0xef, 0xfd, 0x0c, 0x00, 0x00, - 0xff, 0xff, 0x52, 0x94, 0xb8, 0xb6, 0xe5, 0x06, 0x00, 0x00, + // 601 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0xeb, 0x31, 0xca, 0xf0, 0x38, 0x99, 0x81, 0x46, 0x84, 0xb2, 0x2d, 0x85, 0x51, 0x18, + 0xd8, 0xb4, 0x93, 0x10, 0x07, 0x24, 0xa4, 0x54, 0x82, 0x71, 0x40, 0x2a, 0xd1, 0xc4, 0x01, 0x21, + 0x21, 0xa7, 0x98, 0x24, 0x52, 0x6b, 0x67, 0x8d, 0x5b, 0xd1, 0x2b, 0x9f, 0x00, 0xc1, 0x8d, 0x03, + 0x37, 0xbe, 0x01, 0x1f, 0x62, 0xc7, 0x49, 0x5c, 0x10, 0x87, 0x09, 0xb5, 0xdc, 0xf9, 0x0a, 0x28, + 0xb6, 0x53, 0x48, 0x50, 0x9b, 0x22, 0x76, 0xa9, 0x6a, 0xe7, 0xbd, 0xf7, 0xff, 0xf9, 0xf9, 0xfd, + 0x0d, 0x1d, 0x9f, 0xfa, 0xa3, 0xae, 0xe0, 0xc4, 0x97, 0x9d, 0x6e, 0x14, 0x84, 0xe9, 0x2f, 0xe3, + 0x92, 0x1c, 0x0c, 0x58, 0x7f, 0x84, 0xe3, 0xbe, 0x90, 0x02, 0x5d, 0x32, 0x31, 0x38, 0x1f, 0x83, + 0x87, 0x0d, 0x6b, 0x2d, 0x10, 0x81, 0x50, 0x51, 0x24, 0xfd, 0xa7, 0x13, 0xac, 0xcb, 0x81, 0x10, + 0x41, 0x97, 0x11, 0x1a, 0x47, 0x84, 0x72, 0x2e, 0x24, 0x95, 0x91, 0xe0, 0x89, 0xf9, 0x7a, 0xa3, + 0x23, 0x92, 0x9e, 0x48, 0x88, 0x4f, 0x13, 0xa6, 0x75, 0xc8, 0xb0, 0xe1, 0x33, 0x49, 0x1b, 0x24, + 0xa6, 0x41, 0xc4, 0x55, 0xb0, 0x89, 0xad, 0xcd, 0xc0, 0x8b, 0x69, 0x9f, 0xf6, 0xb2, 0x82, 0x3b, + 0x33, 0x82, 0x0a, 0xb8, 0x2a, 0xd8, 0x59, 0x83, 0xe8, 0x49, 0xaa, 0xd9, 0x56, 0x15, 0x3c, 0x76, + 0x30, 0x60, 0x89, 0x74, 0x9e, 0xc2, 0xf3, 0xb9, 0xdd, 0x24, 0x16, 0x3c, 0x61, 0xe8, 0x3e, 0xac, + 0x6a, 0xa5, 0x75, 0xb0, 0x09, 0xea, 0xab, 0xcd, 0x2d, 0x3c, 0xb3, 0x15, 0x58, 0xa7, 0xba, 0xcb, + 0x87, 0xc7, 0x1b, 0x15, 0xcf, 0xa4, 0x39, 0xcf, 0x8d, 0xda, 0x1e, 0x4d, 0x42, 0x96, 0xa9, 0xa1, + 0x07, 0x10, 0xfe, 0x3e, 0xa9, 0x29, 0xbd, 0x8d, 0x75, 0x5b, 0x70, 0xda, 0x16, 0xac, 0xdb, 0x6f, + 0xda, 0x82, 0xdb, 0x34, 0x60, 0x26, 0xd7, 0xfb, 0x23, 0xd3, 0xf9, 0x0c, 0x0c, 0x76, 0x56, 0xde, + 0x60, 0xef, 0xc3, 0x6a, 0xa8, 0x76, 0xd6, 0xc1, 0xe6, 0xa9, 0xfa, 0x39, 0xf7, 0xde, 0xb7, 0xe3, + 0x8d, 0xbb, 0x41, 0x24, 0xc3, 0x81, 0x8f, 0x3b, 0xa2, 0x47, 0xcc, 0x21, 0x3a, 0x21, 0x8d, 0x78, + 0xb6, 0x20, 0x72, 0x14, 0xb3, 0x04, 0xbb, 0xfb, 0xad, 0x3d, 0x46, 0x5f, 0xb2, 0x7e, 0x5a, 0xd2, + 0x1d, 0x49, 0x96, 0x78, 0xa6, 0x16, 0x7a, 0x98, 0xa3, 0x5e, 0x52, 0xd4, 0xd7, 0x4a, 0xa9, 0x35, + 0x52, 0x0e, 0x3b, 0x84, 0x6b, 0x8a, 0xba, 0x25, 0xb8, 0xa4, 0x11, 0x9f, 0xb6, 0xa5, 0x0d, 0x97, + 0x53, 0x29, 0xd5, 0x90, 0xff, 0x85, 0x56, 0x95, 0x9c, 0x5d, 0x78, 0xa1, 0xa0, 0x64, 0x3a, 0x64, + 0xc1, 0x95, 0x8e, 0xd9, 0x53, 0x72, 0x2b, 0xde, 0x74, 0xed, 0xbc, 0x30, 0x49, 0x8f, 0x69, 0xc4, + 0x5b, 0xa9, 0xda, 0x49, 0x5f, 0xdb, 0x27, 0x00, 0x2f, 0x16, 0x15, 0x0c, 0x97, 0x0b, 0xcf, 0x84, + 0xea, 0x24, 0xfa, 0xea, 0x56, 0x9b, 0xf5, 0x39, 0x13, 0x37, 0x3d, 0xf6, 0x23, 0xfe, 0x4a, 0x78, + 0x59, 0xe2, 0x89, 0xdd, 0x53, 0xf3, 0xe7, 0x32, 0x3c, 0xad, 0x38, 0xd1, 0x3b, 0x00, 0xab, 0x7a, + 0xbe, 0xd1, 0xad, 0x39, 0x40, 0x7f, 0x1b, 0xcb, 0xc2, 0x8b, 0x86, 0x6b, 0x7d, 0xe7, 0xfa, 0x9b, + 0x2f, 0x3f, 0xde, 0x2f, 0xd5, 0xd0, 0x16, 0x99, 0x61, 0xea, 0x61, 0xc3, 0x98, 0x5f, 0x41, 0xe9, + 0xc1, 0x2f, 0x87, 0xca, 0xf9, 0xaf, 0x1c, 0x2a, 0xef, 0xa7, 0x85, 0xa0, 0x8c, 0x49, 0x3e, 0x00, + 0xb8, 0x92, 0x4d, 0x1b, 0x22, 0x65, 0x3a, 0x05, 0x07, 0x58, 0xb7, 0x17, 0x4f, 0x30, 0x68, 0x3b, + 0x0a, 0xed, 0x2a, 0xaa, 0xcd, 0x41, 0xcb, 0x26, 0x1b, 0x7d, 0x04, 0xf0, 0xec, 0x74, 0xe6, 0x50, + 0xa9, 0x58, 0xd1, 0x00, 0x56, 0xe3, 0x1f, 0x32, 0x0c, 0xdf, 0x4d, 0xc5, 0xb7, 0x8d, 0xae, 0xcc, + 0xe1, 0xeb, 0xd1, 0x48, 0xdb, 0xda, 0x6d, 0x1f, 0x8e, 0x6d, 0x70, 0x34, 0xb6, 0xc1, 0xf7, 0xb1, + 0x0d, 0xde, 0x4e, 0xec, 0xca, 0xd1, 0xc4, 0xae, 0x7c, 0x9d, 0xd8, 0x95, 0x67, 0x77, 0xca, 0x5e, + 0x82, 0xd7, 0xc5, 0xc2, 0xea, 0x69, 0xf0, 0xab, 0xea, 0xd5, 0xdf, 0xfd, 0x15, 0x00, 0x00, 0xff, + 0xff, 0x06, 0x17, 0x60, 0x3b, 0xe8, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1699,7 +1699,7 @@ func (m *QueryMainChainResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Headers = append(m.Headers, &HeaderInfo{}) + m.Headers = append(m.Headers, &BTCHeaderInfo{}) if err := m.Headers[len(m.Headers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err }