-
Notifications
You must be signed in to change notification settings - Fork 3.5k
/
genesis.go
144 lines (117 loc) · 3.9 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
136
137
138
139
140
141
142
143
144
package types
import (
"encoding/json"
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Validate performs basic validation of supply genesis data returning an
// error for any failed validation criteria.
func (gs GenesisState) Validate() error {
if len(gs.Params.SendEnabled) > 0 && len(gs.SendEnabled) > 0 {
return errors.New("send_enabled defined in both the send_enabled field and in params (deprecated)")
}
if err := gs.Params.Validate(); err != nil {
return err
}
seenSendEnabled := make(map[string]bool)
seenBalances := make(map[string]bool)
seenMetadatas := make(map[string]bool)
totalSupply := sdk.Coins{}
for _, p := range gs.GetAllSendEnabled() {
if _, exists := seenSendEnabled[p.Denom]; exists {
return fmt.Errorf("duplicate send enabled found: '%s'", p.Denom)
}
if err := p.Validate(); err != nil {
return err
}
seenSendEnabled[p.Denom] = true
}
for _, balance := range gs.Balances {
if seenBalances[balance.Address] {
return fmt.Errorf("duplicate balance for address %s", balance.Address)
}
if err := balance.Validate(); err != nil {
return err
}
seenBalances[balance.Address] = true
totalSupply = totalSupply.Add(balance.Coins...)
}
for _, metadata := range gs.DenomMetadata {
if seenMetadatas[metadata.Base] {
return fmt.Errorf("duplicate client metadata for denom %s", metadata.Base)
}
if err := metadata.Validate(); err != nil {
return err
}
seenMetadatas[metadata.Base] = true
}
if !gs.Supply.Empty() {
// NOTE: this errors if supply for any given coin is zero
err := gs.Supply.Validate()
if err != nil {
return err
}
if !gs.Supply.IsEqual(totalSupply) {
return fmt.Errorf("genesis supply is incorrect, expected %v, got %v", gs.Supply, totalSupply)
}
}
return nil
}
// NewGenesisState creates a new genesis state.
func NewGenesisState(params Params, balances []Balance, supply sdk.Coins, denomMetaData []Metadata, sendEnabled []SendEnabled) *GenesisState {
rv := &GenesisState{
Params: params,
Balances: balances,
Supply: supply,
DenomMetadata: denomMetaData,
SendEnabled: sendEnabled,
}
rv.MigrateSendEnabled()
return rv
}
// DefaultGenesisState returns a default bank module genesis state.
func DefaultGenesisState() *GenesisState {
return NewGenesisState(DefaultParams(), []Balance{}, sdk.Coins{}, []Metadata{}, []SendEnabled{})
}
// GetGenesisStateFromAppState returns x/bank GenesisState given raw application
// genesis state.
func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *GenesisState {
var genesisState GenesisState
if appState[ModuleName] != nil {
cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState)
}
return &genesisState
}
// MigrateSendEnabled moves the SendEnabled info from Params into the
// GenesisState.SendEnabled field and removes them from Params. If the
// Params.SendEnabled slice is empty, this is a noop.
//
// If the main SendEnabled slice already has entries, the Params.SendEnabled
// entries are added. In case of the same demon in both, preference is given to
// the existing (main GenesisState field) entry.
func (g *GenesisState) MigrateSendEnabled() {
g.SendEnabled = g.GetAllSendEnabled()
g.Params.SendEnabled = nil
}
// GetAllSendEnabled returns all the SendEnabled entries from both the SendEnabled
// field and the Params. If a denom has an entry in both, the entry in the
// SendEnabled field takes precedence over one in Params.
func (g GenesisState) GetAllSendEnabled() []SendEnabled {
if len(g.Params.SendEnabled) == 0 {
return g.SendEnabled
}
rv := make([]SendEnabled, len(g.SendEnabled))
knownSendEnabled := map[string]bool{}
for i, se := range g.SendEnabled {
rv[i] = se
knownSendEnabled[se.Denom] = true
}
for _, se := range g.Params.SendEnabled {
if _, known := knownSendEnabled[se.Denom]; !known {
rv = append(rv, *se)
}
}
return rv
}