client_state.gno
3.95 Kb · 143 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
13type ClientState struct {
14 ChainID string
15 TrustingPeriod uint64
16 UnbondingPeriod uint64
17 MaxClockDrift uint64
18 FrozenHeight types.Height
19 LatestHeight types.Height
20 ContractAddress types.H256
21}
22
23func NewClientState(
24 chainID string,
25 trustingPeriod,
26 unbondingPeriod 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 UnbondingPeriod: unbondingPeriod,
36 MaxClockDrift: maxClockDrift,
37 FrozenHeight: frozenHeight,
38 LatestHeight: latestHeight,
39 ContractAddress: contractAddress,
40 }
41}
42
43// ClientType is tendermint.
44func (ClientState) ClientType() string {
45 return ClientType
46}
47
48// GetChainID returns the chain-id
49func (cs *ClientState) GetChainID() string {
50 return cs.ChainID
51}
52
53func (cs *ClientState) GetTrustingPeriod() uint64 {
54 return cs.TrustingPeriod
55}
56
57func (cs *ClientState) GetUnbondingPeriod() uint64 {
58 return cs.UnbondingPeriod
59}
60
61func (cs *ClientState) GetMaxClockDrift() uint64 {
62 return cs.MaxClockDrift
63}
64
65// GetLatestHeight returns latest block height.
66func (cs *ClientState) GetLatestHeight() types.Height {
67 return cs.LatestHeight
68}
69
70func (cs *ClientState) GetFrozenRevisionHeight() uint64 {
71 return cs.FrozenHeight.RevisionHeight
72}
73
74// GetLatestRevisionHeight returns latest block height.
75func (cs *ClientState) GetLatestRevisionHeight() uint64 {
76 return cs.LatestHeight.RevisionHeight
77}
78
79func (cs *ClientState) GetContractAddress() types.H256 {
80 return cs.ContractAddress
81}
82
83// IsExpired returns whether or not the client has passed the trusting period since the last
84// update (in which case no headers are considered valid).
85func (cs *ClientState) IsExpired(latestTimestamp, now uint64) bool {
86 return isClientExpiredAt(latestTimestamp, cs.TrustingPeriod, now)
87}
88
89// Validate performs a basic validation of the client state fields.
90func (cs *ClientState) Validate() error {
91 if strings.TrimSpace(cs.ChainID) == "" {
92 return errorWithDetails(ErrInvalidChainID, "chain id cannot be empty string")
93 }
94
95 // NOTE: the value of tmtypes.MaxChainIDLen may change in the future.
96 // If this occurs, the code here must account for potential difference
97 // between the tendermint version being run by the counterparty chain
98 // and the tendermint version used by this light client.
99 // https://github.com/cosmos/ibc-go/issues/177
100 if len(cs.ChainID) > MaxChainIDLen {
101 return errorWithDetails(
102 ErrInvalidChainID,
103 ufmt.Sprintf("chainID is too long; got: %d, max: %d", len(cs.ChainID), MaxChainIDLen),
104 )
105 }
106
107 if cs.TrustingPeriod <= 0 {
108 return errorWithDetails(ErrInvalidTrustingPeriod, "trusting period must be greater than zero")
109 }
110
111 if cs.UnbondingPeriod <= 0 {
112 return errorWithDetails(ErrInvalidUnbondingPeriod, "unbonding period must be greater than zero")
113 }
114
115 if cs.MaxClockDrift <= 0 {
116 return errorWithDetails(ErrInvalidMaxClockDrift, "max clock drift must be greater than zero")
117 }
118
119 if cs.GetLatestRevisionHeight() == 0 {
120 return errorWithDetails(ErrInvalidHeaderHeight, "cometbls client's latest height cannot be zero")
121 }
122
123 if cs.TrustingPeriod >= cs.UnbondingPeriod {
124 return errorWithDetails(
125 ErrInvalidTrustingPeriod,
126 ufmt.Sprintf("trusting period (%d) should be < unbonding period (%d)", cs.TrustingPeriod, cs.UnbondingPeriod),
127 )
128 }
129
130 return nil
131}
132
133// ZeroCustomFields returns a ClientState that is a copy of the current ClientState
134// with all client customizable fields zeroed out
135func (cs *ClientState) ZeroCustomFields() *ClientState {
136 // copy over all chain-specified fields
137 // and leave custom fields empty
138 return &ClientState{
139 ChainID: cs.ChainID,
140 UnbondingPeriod: cs.UnbondingPeriod,
141 LatestHeight: cs.LatestHeight,
142 }
143}