Search Apps Documentation Source Content File Folder Download Copy Actions Download

misbehaviour.gno

2.36 Kb · 73 lines
 1package tendermint
 2
 3import (
 4	"gno.land/p/aib/ibc/lightclient"
 5	"gno.land/p/nt/ufmt/v0"
 6)
 7
 8// Misbehaviour is a wrapper over two conflicting Headers
 9// that implements Misbehaviour interface expected by ICS-02
10type Misbehaviour struct {
11	Header1 *MsgHeader
12	Header2 *MsgHeader
13}
14
15// Implements lightclient.ClientMessage
16func (Misbehaviour) ClientType() string {
17	return lightclient.Tendermint
18}
19
20// Implements lightclient.ClientMessage
21func (m Misbehaviour) ValidateBasic() error {
22	if m.Header1 == nil {
23		return ufmt.Errorf("misbehaviour Header1 cannot be nil")
24	}
25	if m.Header2 == nil {
26		return ufmt.Errorf("misbehaviour Header2 cannot be nil")
27	}
28	if m.Header1.TrustedHeight.RevisionHeight == 0 {
29		return ufmt.Errorf("misbehaviour Header1 cannot have zero revision height")
30	}
31	if m.Header2.TrustedHeight.RevisionHeight == 0 {
32		return ufmt.Errorf("misbehaviour Header2 cannot have zero revision height")
33	}
34	if m.Header1.TrustedValidators == nil {
35		return ufmt.Errorf("trusted validator set in Header1 cannot be empty")
36	}
37	if m.Header2.TrustedValidators == nil {
38		return ufmt.Errorf("trusted validator set in Header2 cannot be empty")
39	}
40	if m.Header1.Header.ChainID != m.Header2.Header.ChainID {
41		return ufmt.Errorf("headers must have identical chainIDs")
42	}
43
44	// ValidateBasic on both validators
45	if err := m.Header1.ValidateBasic(); err != nil {
46		return ufmt.Errorf("header 1 failed validation: %v", err)
47	}
48	if err := m.Header2.ValidateBasic(); err != nil {
49		return ufmt.Errorf("header 2 failed validation: %v", err)
50	}
51	// Ensure that Height1 is greater than or equal to Height2
52	if m.Header1.GetHeight().LT(m.Header2.GetHeight()) {
53		return ufmt.Errorf("Header1 height is less than Header2 height (%s < %s)", m.Header1.GetHeight(), m.Header2.GetHeight())
54	}
55
56	if err := validateCommit(m.Header1); err != nil {
57		return ufmt.Errorf("invalid header1 commit: %v", err)
58	}
59	if err := validateCommit(m.Header2); err != nil {
60		return ufmt.Errorf("invalid header2 commit: %v", err)
61	}
62	return nil
63}
64
65// validateCommit checks if the given commit is a valid commit from the
66// passed-in MsgHeader.
67func validateCommit(msg *MsgHeader) error {
68	votingPowerNeeded := msg.ValidatorSet.TotalVotingPower * 2 / 3
69	if err := verifyCommit(msg.Header.ChainID, msg.ValidatorSet, msg.Commit, votingPowerNeeded, true); err != nil {
70		return ufmt.Errorf("validator set did not commit to header: %v", err)
71	}
72	return nil
73}