Start specifying the roles module

This commit is contained in:
Ethan Frey 2017-07-10 13:50:11 +02:00
parent af9169f629
commit 9eb3c3c7de
6 changed files with 187 additions and 8 deletions

View File

@ -2,20 +2,20 @@
package coin package coin
import ( import (
rawerr "errors" "fmt"
abci "github.com/tendermint/abci/types" abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/errors" "github.com/tendermint/basecoin/errors"
) )
var ( var (
errNoAccount = rawerr.New("No such account") errNoAccount = fmt.Errorf("No such account")
errInsufficientFunds = rawerr.New("Insufficient Funds") errInsufficientFunds = fmt.Errorf("Insufficient Funds")
errNoInputs = rawerr.New("No Input Coins") errNoInputs = fmt.Errorf("No Input Coins")
errNoOutputs = rawerr.New("No Output Coins") errNoOutputs = fmt.Errorf("No Output Coins")
errInvalidAddress = rawerr.New("Invalid Address") errInvalidAddress = fmt.Errorf("Invalid Address")
errInvalidCoins = rawerr.New("Invalid Coins") errInvalidCoins = fmt.Errorf("Invalid Coins")
errInvalidSequence = rawerr.New("Invalid Sequence") errInvalidSequence = fmt.Errorf("Invalid Sequence")
) )
var ( var (

60
modules/roles/error.go Normal file
View File

@ -0,0 +1,60 @@
//nolint
package roles
import (
"fmt"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/errors"
)
var (
errNoRole = fmt.Errorf("No such role")
errRoleExists = fmt.Errorf("Role already exists")
errNotMember = fmt.Errorf("Not a member")
errInsufficientSigs = fmt.Errorf("Not enough signatures")
errNoMembers = fmt.Errorf("No members specified")
errTooManyMembers = fmt.Errorf("Too many members specified")
)
func ErrNoRole() errors.TMError {
return errors.WithCode(errNoRole, abci.CodeType_Unauthorized)
}
func IsNoRoleErr(err error) bool {
return errors.IsSameError(errNoRole, err)
}
func ErrRoleExists() errors.TMError {
return errors.WithCode(errRoleExists, abci.CodeType_Unauthorized)
}
func IsRoleExistsErr(err error) bool {
return errors.IsSameError(errRoleExists, err)
}
func ErrNotMember() errors.TMError {
return errors.WithCode(errNotMember, abci.CodeType_Unauthorized)
}
func IsNotMemberErr(err error) bool {
return errors.IsSameError(errNotMember, err)
}
func ErrInsufficientSigs() errors.TMError {
return errors.WithCode(errInsufficientSigs, abci.CodeType_Unauthorized)
}
func IsInsufficientSigsErr(err error) bool {
return errors.IsSameError(errInsufficientSigs, err)
}
func ErrNoMembers() errors.TMError {
return errors.WithCode(errNoMembers, abci.CodeType_Unauthorized)
}
func IsNoMembersErr(err error) bool {
return errors.IsSameError(errNoMembers, err)
}
func ErrTooManyMembers() errors.TMError {
return errors.WithCode(errTooManyMembers, abci.CodeType_Unauthorized)
}
func IsTooManyMembersErr(err error) bool {
return errors.IsSameError(errTooManyMembers, err)
}

4
modules/roles/handler.go Normal file
View File

@ -0,0 +1,4 @@
package roles
//NameRole - name space of the roles module
const NameRole = "role"

View File

@ -0,0 +1 @@
package roles

44
modules/roles/store.go Normal file
View File

@ -0,0 +1,44 @@
package roles
import (
"fmt"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/state"
wire "github.com/tendermint/go-wire"
)
// Role - structure to hold permissioning
type Role struct {
MinSigs uint32 `json:"min_sigs"`
Signers []basecoin.Actor `json:"signers"`
}
// MakeKey creates the lookup key for a role
func MakeKey(role []byte) []byte {
prefix := []byte(NameRole + "/")
return append(prefix, role...)
}
func loadRole(store state.KVStore, key []byte) (role Role, err error) {
data := store.Get(key)
if len(data) == 0 {
return role, ErrNoRole()
}
err = wire.ReadBinaryBytes(data, &role)
if err != nil {
msg := fmt.Sprintf("Error reading role %X", key)
return role, errors.ErrInternal(msg)
}
return role, nil
}
func createRole(store state.KVStore, key []byte, role Role) error {
if _, err := loadRole(store, key); !IsNoRoleErr(err) {
return ErrRoleExists()
}
bin := wire.BinaryBytes(role)
store.Set(key, bin)
return nil // real stores can return error...
}

70
modules/roles/tx.go Normal file
View File

@ -0,0 +1,70 @@
package roles
import (
"github.com/tendermint/go-wire/data"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
)
// AssumeRoleTx is a layered tx that can wrap your normal tx to give it
// the authority to use a given role.
type AssumeRoleTx struct {
Role data.Bytes `json:"role"`
Tx basecoin.Tx `json:"tx"`
}
// NewAssumeRoleTx creates a new wrapper to add a role to a tx execution
func NewAssumeRoleTx(role []byte, tx basecoin.Tx) basecoin.Tx {
return AssumeRoleTx{Role: role, Tx: tx}.Wrap()
}
// ValidateBasic - validate nothing is empty
func (tx AssumeRoleTx) ValidateBasic() error {
if len(tx.Role) == 0 {
return ErrNoRole()
}
if tx.Tx.Empty() {
return errors.ErrUnknownTxType(tx.Tx)
}
return nil
}
// Wrap - used to satisfy TxInner
func (tx AssumeRoleTx) Wrap() basecoin.Tx {
return basecoin.Tx{tx}
}
// CreateRoleTx is used to construct a new role
//
// TODO: add ability to update signers on a role... but that adds a lot
// more complexity to the permissions
type CreateRoleTx struct {
Role data.Bytes `json:"role"`
MinSigs uint32 `json:"min_sigs"`
Signers []basecoin.Actor `json:"signers"`
}
// NewCreateRoleTx creates a new role, which we can later use
func NewCreateRoleTx(role []byte, minSigs uint32, signers []basecoin.Actor) basecoin.Tx {
return CreateRoleTx{Role: role, MinSigs: minSigs, Signers: signers}.Wrap()
}
// ValidateBasic - validate nothing is empty
func (tx CreateRoleTx) ValidateBasic() error {
if len(tx.Role) == 0 {
return ErrNoRole()
}
if tx.MinSigs == 0 {
return ErrNoMembers()
}
if len(tx.Signers) == 0 {
return ErrNoMembers()
}
return nil
}
// Wrap - used to satisfy TxInner
func (tx CreateRoleTx) Wrap() basecoin.Tx {
return basecoin.Tx{tx}
}