-
Notifications
You must be signed in to change notification settings - Fork 45
/
genesis.go
135 lines (114 loc) · 3.76 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package types
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec/types"
)
// NewGenesisState returns a new genesis state instance
func NewGenesisState(subspaces []SubspaceDataEntry, reasons []Reason, reports []Report, params Params) *GenesisState {
return &GenesisState{
SubspacesData: subspaces,
Reasons: reasons,
Reports: reports,
Params: params,
}
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (data GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error {
for _, report := range data.Reports {
err := report.UnpackInterfaces(unpacker)
if err != nil {
return err
}
}
return nil
}
// DefaultGenesisState returns a DefaultGenesisState
func DefaultGenesisState() *GenesisState {
return NewGenesisState(nil, nil, nil, DefaultParams())
}
// ValidateGenesis validates the given genesis state and returns an error if something is invalid
func ValidateGenesis(data *GenesisState) error {
for _, subspaceData := range data.SubspacesData {
if containsDuplicatedSubspacesData(data.SubspacesData, subspaceData) {
return fmt.Errorf("duplicated subspace entry for subspace id %d", subspaceData.SubspaceID)
}
err := subspaceData.Validate()
if err != nil {
return fmt.Errorf("invalid subspace data: %s", err)
}
}
for _, reason := range data.Reasons {
if containsDuplicatedReason(data.Reasons, reason) {
return fmt.Errorf("duplicate reason: subspace id %d, reason id %d", reason.SubspaceID, reason.ID)
}
err := reason.Validate()
if err != nil {
return fmt.Errorf("invalid reason: %s", err)
}
}
for _, report := range data.Reports {
if containsDuplicatedReport(data.Reports, report) {
return fmt.Errorf("duplicated report: subspace id %d, report id %d", report.SubspaceID, report.ID)
}
err := report.Validate()
if err != nil {
return fmt.Errorf("invalid report: %s", err)
}
}
return data.Params.Validate()
}
// containsDuplicatedSubspacesData tells whether the given subspaces data slice
// contains a duplicated entry for the same subspace id as the one given
func containsDuplicatedSubspacesData(subspaces []SubspaceDataEntry, data SubspaceDataEntry) bool {
var count = 0
for _, entry := range subspaces {
if entry.SubspaceID == data.SubspaceID {
count++
}
}
return count > 1
}
// containsDuplicatedReason tells whether the given reasons slice contains
// a duplicated reason based on the same subspace id and reason id of the given one
func containsDuplicatedReason(reasons []Reason, reason Reason) bool {
var count = 0
for _, r := range reasons {
if r.SubspaceID == reason.SubspaceID && r.ID == reason.ID {
count++
}
}
return count > 1
}
// containsDuplicatedReport tells whether the given reports slice contains
// a duplicated report based on the same subspace id and report id of the given one
func containsDuplicatedReport(reports []Report, report Report) bool {
var count = 0
for _, r := range reports {
if r.SubspaceID == report.SubspaceID && r.ID == report.ID {
count++
}
}
return count > 1
}
// --------------------------------------------------------------------------------------------------------------------
// NewSubspacesDataEntry returns a new SubspaceDataEntry instance
func NewSubspacesDataEntry(subspaceID uint64, reasonID uint32, reportID uint64) SubspaceDataEntry {
return SubspaceDataEntry{
SubspaceID: subspaceID,
ReportID: reportID,
ReasonID: reasonID,
}
}
// Validate implements fmt.Validator
func (data SubspaceDataEntry) Validate() error {
if data.SubspaceID == 0 {
return fmt.Errorf("invalid subspace id: %d", data.SubspaceID)
}
if data.ReasonID == 0 {
return fmt.Errorf("invalid reason id: %d", data.ReasonID)
}
if data.ReportID == 0 {
return fmt.Errorf("invalid report id: %d", data.ReportID)
}
return nil
}