2019-06-28 13:11:27 -07:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
yaml "gopkg.in/yaml.v2"
|
|
|
|
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/supply/exported"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ exported.ModuleAccountI = (*ModuleAccount)(nil)
|
|
|
|
|
|
|
|
// ModuleAccount defines an account for modules that holds coins on a pool
|
|
|
|
type ModuleAccount struct {
|
|
|
|
*authtypes.BaseAccount
|
2019-07-06 12:42:06 -07:00
|
|
|
Name string `json:"name" yaml:"name"` // name of the module
|
|
|
|
Permissions []string `json:"permissions" yaml:"permissions"` // permissions of module account
|
2019-06-28 13:11:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewModuleAddress creates an AccAddress from the hash of the module's name
|
|
|
|
func NewModuleAddress(name string) sdk.AccAddress {
|
|
|
|
return sdk.AccAddress(crypto.AddressHash([]byte(name)))
|
|
|
|
}
|
|
|
|
|
2019-07-06 12:42:06 -07:00
|
|
|
func NewEmptyModuleAccount(name string, permissions ...string) *ModuleAccount {
|
2019-06-28 13:11:27 -07:00
|
|
|
moduleAddress := NewModuleAddress(name)
|
|
|
|
baseAcc := authtypes.NewBaseAccountWithAddress(moduleAddress)
|
|
|
|
|
2019-07-06 12:42:06 -07:00
|
|
|
if err := validatePermissions(permissions...); err != nil {
|
2019-06-28 13:11:27 -07:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ModuleAccount{
|
|
|
|
BaseAccount: &baseAcc,
|
|
|
|
Name: name,
|
2019-07-06 12:42:06 -07:00
|
|
|
Permissions: permissions,
|
2019-06-28 13:11:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewModuleAccount creates a new ModuleAccount instance
|
|
|
|
func NewModuleAccount(ba *authtypes.BaseAccount,
|
2019-07-06 12:42:06 -07:00
|
|
|
name string, permissions ...string) *ModuleAccount {
|
2019-06-28 13:11:27 -07:00
|
|
|
|
2019-07-06 12:42:06 -07:00
|
|
|
if err := validatePermissions(permissions...); err != nil {
|
2019-06-28 13:11:27 -07:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ModuleAccount{
|
|
|
|
BaseAccount: ba,
|
|
|
|
Name: name,
|
2019-07-06 12:42:06 -07:00
|
|
|
Permissions: permissions,
|
2019-06-28 13:11:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-06 12:42:06 -07:00
|
|
|
// AddPermissions adds the permissions to the module account's list of granted
|
|
|
|
// permissions.
|
|
|
|
func (ma *ModuleAccount) AddPermissions(permissions ...string) {
|
|
|
|
ma.Permissions = append(ma.Permissions, permissions...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemovePermission removes the permission from the list of granted permissions
|
|
|
|
// or returns an error if the permission is has not been granted.
|
|
|
|
func (ma *ModuleAccount) RemovePermission(permission string) error {
|
|
|
|
for i, perm := range ma.Permissions {
|
|
|
|
if perm == permission {
|
|
|
|
ma.Permissions = append(ma.Permissions[:i], ma.Permissions[i+1:]...)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fmt.Errorf("cannot remove non granted permission %s", permission)
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasPermission returns whether or not the module account has permission.
|
|
|
|
func (ma ModuleAccount) HasPermission(permission string) bool {
|
|
|
|
for _, perm := range ma.Permissions {
|
|
|
|
if perm == permission {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-06-28 13:11:27 -07:00
|
|
|
// GetName returns the the name of the holder's module
|
|
|
|
func (ma ModuleAccount) GetName() string {
|
|
|
|
return ma.Name
|
|
|
|
}
|
|
|
|
|
2019-07-06 12:42:06 -07:00
|
|
|
// GetPermissions returns permissions granted to the module account
|
|
|
|
func (ma ModuleAccount) GetPermissions() []string {
|
|
|
|
return ma.Permissions
|
2019-06-28 13:11:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetPubKey - Implements Account
|
|
|
|
func (ma ModuleAccount) SetPubKey(pubKey crypto.PubKey) error {
|
|
|
|
return fmt.Errorf("not supported for module accounts")
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSequence - Implements Account
|
|
|
|
func (ma ModuleAccount) SetSequence(seq uint64) error {
|
|
|
|
return fmt.Errorf("not supported for module accounts")
|
|
|
|
}
|
|
|
|
|
|
|
|
// String follows stringer interface
|
|
|
|
func (ma ModuleAccount) String() string {
|
|
|
|
b, err := yaml.Marshal(ma)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return string(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalYAML returns the YAML representation of a ModuleAccount.
|
|
|
|
func (ma ModuleAccount) MarshalYAML() (interface{}, error) {
|
|
|
|
bs, err := yaml.Marshal(struct {
|
|
|
|
Address sdk.AccAddress
|
|
|
|
Coins sdk.Coins
|
|
|
|
PubKey string
|
|
|
|
AccountNumber uint64
|
|
|
|
Sequence uint64
|
|
|
|
Name string
|
2019-07-06 12:42:06 -07:00
|
|
|
Permissions []string
|
2019-06-28 13:11:27 -07:00
|
|
|
}{
|
|
|
|
Address: ma.Address,
|
|
|
|
Coins: ma.Coins,
|
|
|
|
PubKey: "",
|
|
|
|
AccountNumber: ma.AccountNumber,
|
|
|
|
Sequence: ma.Sequence,
|
|
|
|
Name: ma.Name,
|
2019-07-06 12:42:06 -07:00
|
|
|
Permissions: ma.Permissions,
|
2019-06-28 13:11:27 -07:00
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(bs), nil
|
|
|
|
}
|