/
genesis_account.go
151 lines (129 loc) · 5.04 KB
/
genesis_account.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
145
146
147
148
149
150
151
package types
import (
"errors"
"fmt"
"strings"
sdk "github.com/BITCOIVA/Bitcoiva-sdk/types"
"github.com/BITCOIVA/Bitcoiva-sdk/x/auth"
authexported "github.com/BITCOIVA/Bitcoiva-sdk/x/auth/exported"
"github.com/BITCOIVA/Bitcoiva-sdk/x/supply"
supplyexported "github.com/BITCOIVA/Bitcoiva-sdk/x/supply/exported"
)
// GenesisAccount is a struct for account initialization used exclusively during genesis
type GenesisAccount struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
Sequence uint64 `json:"sequence_number" yaml:"sequence_number"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
// vesting account fields
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // total vesting coins upon initialization
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // delegated vested coins at time of delegation
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // delegated vesting coins at time of delegation
StartTime int64 `json:"start_time" yaml:"start_time"` // vesting start time (UNIX Epoch time)
EndTime int64 `json:"end_time" yaml:"end_time"` // vesting end time (UNIX Epoch time)
// module account fields
ModuleName string `json:"module_name" yaml:"module_name"` // name of the module account
ModulePermissions []string `json:"module_permissions" yaml:"module_permissions"` // permissions of module account
}
// Validate checks for errors on the vesting and module account parameters
func (ga GenesisAccount) Validate() error {
if !ga.OriginalVesting.IsZero() {
if ga.OriginalVesting.IsAnyGT(ga.Coins) {
return errors.New("vesting amount cannot be greater than total amount")
}
if ga.StartTime >= ga.EndTime {
return errors.New("vesting start-time cannot be before end-time")
}
}
// don't allow blank (i.e just whitespaces) on the module name
if ga.ModuleName != "" && strings.TrimSpace(ga.ModuleName) == "" {
return errors.New("module account name cannot be blank")
}
return nil
}
// NewGenesisAccountRaw creates a new GenesisAccount object
func NewGenesisAccountRaw(address sdk.AccAddress, coins,
vestingAmount sdk.Coins, vestingStartTime, vestingEndTime int64,
module string, permissions ...string) GenesisAccount {
return GenesisAccount{
Address: address,
Coins: coins,
Sequence: 0,
AccountNumber: 0, // ignored set by the account keeper during InitGenesis
OriginalVesting: vestingAmount,
DelegatedFree: sdk.Coins{}, // ignored
DelegatedVesting: sdk.Coins{}, // ignored
StartTime: vestingStartTime,
EndTime: vestingEndTime,
ModuleName: module,
ModulePermissions: permissions,
}
}
// NewGenesisAccount creates a GenesisAccount instance from a BaseAccount.
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
return GenesisAccount{
Address: acc.Address,
Coins: acc.Coins,
AccountNumber: acc.AccountNumber,
Sequence: acc.Sequence,
}
}
// NewGenesisAccountI creates a GenesisAccount instance from an Account interface.
func NewGenesisAccountI(acc authexported.Account) (GenesisAccount, error) {
gacc := GenesisAccount{
Address: acc.GetAddress(),
Coins: acc.GetCoins(),
AccountNumber: acc.GetAccountNumber(),
Sequence: acc.GetSequence(),
}
if err := gacc.Validate(); err != nil {
return gacc, err
}
switch acc := acc.(type) {
case authexported.VestingAccount:
gacc.OriginalVesting = acc.GetOriginalVesting()
gacc.DelegatedFree = acc.GetDelegatedFree()
gacc.DelegatedVesting = acc.GetDelegatedVesting()
gacc.StartTime = acc.GetStartTime()
gacc.EndTime = acc.GetEndTime()
case supplyexported.ModuleAccountI:
gacc.ModuleName = acc.GetName()
gacc.ModulePermissions = acc.GetPermissions()
}
return gacc, nil
}
// ToAccount converts a GenesisAccount to an Account interface
func (ga *GenesisAccount) ToAccount() auth.Account {
bacc := auth.NewBaseAccount(ga.Address, ga.Coins.Sort(), nil, ga.AccountNumber, ga.Sequence)
// vesting accounts
if !ga.OriginalVesting.IsZero() {
baseVestingAcc := auth.NewBaseVestingAccount(
bacc, ga.OriginalVesting, ga.DelegatedFree,
ga.DelegatedVesting, ga.EndTime,
)
switch {
case ga.StartTime != 0 && ga.EndTime != 0:
return auth.NewContinuousVestingAccountRaw(baseVestingAcc, ga.StartTime)
case ga.EndTime != 0:
return auth.NewDelayedVestingAccountRaw(baseVestingAcc)
default:
panic(fmt.Sprintf("invalid genesis vesting account: %+v", ga))
}
}
// module accounts
if ga.ModuleName != "" {
return supply.NewModuleAccount(bacc, ga.ModuleName, ga.ModulePermissions...)
}
return bacc
}
//___________________________________
type GenesisAccounts []GenesisAccount
// genesis accounts contain an address
func (gaccs GenesisAccounts) Contains(acc sdk.AccAddress) bool {
for _, gacc := range gaccs {
if gacc.Address.Equals(acc) {
return true
}
}
return false
}