-
Notifications
You must be signed in to change notification settings - Fork 368
/
genesis.go
106 lines (91 loc) · 2.93 KB
/
genesis.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package types
import (
"bytes"
"fmt"
)
// DefaultNextProposalID is the starting poiint for proposal IDs.
const DefaultNextProposalID uint64 = 1
// GenesisState is state that must be provided at chain genesis.
type GenesisState struct {
NextProposalID uint64 `json:"next_proposal_id" yaml:"next_proposal_id"`
Committees []Committee `json:"committees" yaml:"committees"`
Proposals []Proposal `json:"proposals" yaml:"proposals"`
Votes []Vote `json:"votes" yaml:"votes"`
}
// NewGenesisState returns a new genesis state object for the module.
func NewGenesisState(nextProposalID uint64, committees []Committee, proposals []Proposal, votes []Vote) GenesisState {
return GenesisState{
NextProposalID: nextProposalID,
Committees: committees,
Proposals: proposals,
Votes: votes,
}
}
// DefaultGenesisState returns the default genesis state for the module.
func DefaultGenesisState() GenesisState {
return NewGenesisState(
DefaultNextProposalID,
[]Committee{},
[]Proposal{},
[]Vote{},
)
}
// Equal checks whether two gov GenesisState structs are equivalent
func (data GenesisState) Equal(data2 GenesisState) bool {
b1 := ModuleCdc.MustMarshalBinaryBare(data)
b2 := ModuleCdc.MustMarshalBinaryBare(data2)
return bytes.Equal(b1, b2)
}
// IsEmpty returns true if a GenesisState is empty
func (data GenesisState) IsEmpty() bool {
return data.Equal(GenesisState{})
}
// Validate performs basic validation of genesis data.
func (gs GenesisState) Validate() error {
// validate committees
committeeMap := make(map[uint64]bool, len(gs.Committees))
for _, com := range gs.Committees {
// check there are no duplicate IDs
if _, ok := committeeMap[com.ID]; ok {
return fmt.Errorf("duplicate committee ID found in genesis state; id: %d", com.ID)
}
committeeMap[com.ID] = true
// validate committee
if err := com.Validate(); err != nil {
return err
}
}
// validate proposals
proposalMap := make(map[uint64]bool, len(gs.Proposals))
for _, p := range gs.Proposals {
// check there are no duplicate IDs
if _, ok := proposalMap[p.ID]; ok {
return fmt.Errorf("duplicate proposal ID found in genesis state; id: %d", p.ID)
}
proposalMap[p.ID] = true
// validate next proposal ID
if p.ID >= gs.NextProposalID {
return fmt.Errorf("NextProposalID is not greater than all proposal IDs; id: %d", p.ID)
}
// check committee exists
if !committeeMap[p.CommitteeID] {
return fmt.Errorf("proposal refers to non existent committee; proposal: %+v", p)
}
// validate pubProposal
if err := p.PubProposal.ValidateBasic(); err != nil {
return fmt.Errorf("proposal %d invalid: %w", p.ID, err)
}
}
// validate votes
for _, v := range gs.Votes {
// validate committee
if err := v.Validate(); err != nil {
return err
}
// check proposal exists
if !proposalMap[v.ProposalID] {
return fmt.Errorf("vote refers to non existent proposal; vote: %+v", v)
}
}
return nil
}