client_state.gno
3.85 Kb · 130 lines
1package cometbls
2
3import (
4 "strings"
5
6 "gno.land/p/nt/ufmt/v0"
7 "gno.land/p/onbloc/ibc/union/types"
8)
9
10// https://github.com/cometbft/cometbft/blob/6b567cd510acb6d729869db8621ae93ac79247cf/types/genesis.go#L18-L21
11const MaxChainIDLen int = 50
12
13// Union reference (no UnbondingPeriod field):
14// https://github.com/unionlabs/union/blob/0ceb6f830211d752b7c099e4630e2c95d3c179d1/lib/cometbls-light-client-types/src/client_state.rs#L13-L31
15type ClientState struct {
16 ChainID string
17 TrustingPeriod uint64
18 MaxClockDrift uint64
19 FrozenHeight types.Height
20 LatestHeight types.Height
21 ContractAddress types.H256
22}
23
24func NewClientState(
25 chainID string,
26 trustingPeriod uint64,
27 maxClockDrift uint64,
28 frozenHeight types.Height,
29 latestHeight types.Height,
30 contractAddress types.H256,
31) *ClientState {
32 return &ClientState{
33 ChainID: chainID,
34 TrustingPeriod: trustingPeriod,
35 MaxClockDrift: maxClockDrift,
36 FrozenHeight: frozenHeight,
37 LatestHeight: latestHeight,
38 ContractAddress: contractAddress,
39 }
40}
41
42// ClientType is tendermint.
43func (ClientState) ClientType() string {
44 return ClientType
45}
46
47// GetChainID returns the chain-id
48func (cs *ClientState) GetChainID() string {
49 return cs.ChainID
50}
51
52func (cs *ClientState) GetTrustingPeriod() uint64 {
53 return cs.TrustingPeriod
54}
55
56func (cs *ClientState) GetMaxClockDrift() uint64 {
57 return cs.MaxClockDrift
58}
59
60// GetLatestHeight returns latest block height.
61func (cs *ClientState) GetLatestHeight() types.Height {
62 return cs.LatestHeight
63}
64
65func (cs *ClientState) GetFrozenRevisionHeight() uint64 {
66 return cs.FrozenHeight.RevisionHeight
67}
68
69// GetLatestRevisionHeight returns latest block height.
70func (cs *ClientState) GetLatestRevisionHeight() uint64 {
71 return cs.LatestHeight.RevisionHeight
72}
73
74func (cs *ClientState) GetContractAddress() types.H256 {
75 return cs.ContractAddress
76}
77
78// IsExpired returns whether or not the client has passed the trusting period since the last
79// update (in which case no headers are considered valid).
80func (cs *ClientState) IsExpired(latestTimestamp, now uint64) bool {
81 return isClientExpiredAt(latestTimestamp, cs.TrustingPeriod, now)
82}
83
84// Validate performs a basic validation of the client state fields.
85func (cs *ClientState) Validate() error {
86 if strings.TrimSpace(cs.ChainID) == "" {
87 return errorWithDetails(ErrInvalidChainID, "chain id cannot be empty string")
88 }
89
90 // NOTE: the value of tmtypes.MaxChainIDLen may change in the future.
91 // If this occurs, the code here must account for potential difference
92 // between the tendermint version being run by the counterparty chain
93 // and the tendermint version used by this light client.
94 // https://github.com/cosmos/ibc-go/issues/177
95 if len(cs.ChainID) > MaxChainIDLen {
96 return errorWithDetails(
97 ErrInvalidChainID,
98 ufmt.Sprintf("chainID is too long; got: %d, max: %d", len(cs.ChainID), MaxChainIDLen),
99 )
100 }
101
102 if cs.TrustingPeriod <= 0 {
103 return errorWithDetails(ErrInvalidTrustingPeriod, "trusting period must be greater than zero")
104 }
105
106 // No upper bound on TrustingPeriod: Union doesn't check it either (see
107 // VerifyCreation), relying on gating CreateClient to the relayer role.
108 // https://github.com/unionlabs/union/blob/8cff0ff34f6baa4cdb1e4650a08985dd05de0c5a/cosmwasm/deployer/src/main.rs#L1786-L1830
109
110 if cs.MaxClockDrift <= 0 {
111 return errorWithDetails(ErrInvalidMaxClockDrift, "max clock drift must be greater than zero")
112 }
113
114 if cs.GetLatestRevisionHeight() == 0 {
115 return errorWithDetails(ErrInvalidHeaderHeight, "cometbls client's latest height cannot be zero")
116 }
117
118 return nil
119}
120
121// ZeroCustomFields returns a ClientState that is a copy of the current ClientState
122// with all client customizable fields zeroed out
123func (cs *ClientState) ZeroCustomFields() *ClientState {
124 // copy over all chain-specified fields
125 // and leave custom fields empty
126 return &ClientState{
127 ChainID: cs.ChainID,
128 LatestHeight: cs.LatestHeight,
129 }
130}