permission/types pkg, Base and Roles

This commit is contained in:
Ethan Buchman
2015-07-07 14:07:56 -07:00
committed by Jae Kwon
parent 94f21ad012
commit 87ed1f5fda
9 changed files with 286 additions and 67 deletions
+28 -16
View File
@@ -178,7 +178,7 @@ func getOrMakeOutputs(state AccountGetter, accounts map[string]*account.Account,
PubKey: nil,
Sequence: 0,
Balance: 0,
Permissions: state.GetAccount(ptypes.GlobalPermissionsAddress).Permissions,
Permissions: ptypes.NewAccountPermissions(),
}
}
accounts[string(out.Address)] = acc
@@ -307,7 +307,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
}
// ensure all inputs have send permissions
if !hasSendPermission(accounts) {
if !hasSendPermission(blockCache, accounts) {
return fmt.Errorf("At least one input lacks permission for SendTx")
}
@@ -364,11 +364,11 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
createAccount := len(tx.Address) == 0
if createAccount {
if !hasCreatePermission(inAcc) {
if !hasCreatePermission(blockCache, inAcc) {
return fmt.Errorf("Account %X does not have Create permission", tx.Input.Address)
}
} else {
if !hasCallPermission(inAcc) {
if !hasCallPermission(blockCache, inAcc) {
return fmt.Errorf("Account %X does not have Call permission", tx.Input.Address)
}
}
@@ -465,7 +465,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
// we need to bind a copy of the accounts tree (from the txCache)
// so the gendoug can make a native call to create accounts and update
// permissions
setupDoug(vmach, txCache, _s)
// setupDoug(vmach, txCache, _s)
}
ret, err := vmach.Call(caller, callee, code, tx.Data, value, &gas)
@@ -636,7 +636,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
return err
}
if !hasBondPermission(accounts) {
if !hasBondPermission(blockCache, accounts) {
return fmt.Errorf("At least one input lacks permission to bond")
}
@@ -790,38 +790,49 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
//---------------------------------------------------------------
// TODO: for debug log the failed accounts
func hasSendPermission(accs map[string]*account.Account) bool {
// Get permission on an account or fall back to global value
func HasPermission(state AccountGetter, acc *account.Account, perm ptypes.PermFlag) bool {
v, err := acc.Permissions.Base.Get(perm)
fmt.Printf("has permission? %x %v %b %v %v\n", acc.Address, acc.Permissions, perm, v, err)
if _, ok := err.(ptypes.ErrValueNotSet); ok {
return HasPermission(state, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
}
return v
}
func hasSendPermission(state AccountGetter, accs map[string]*account.Account) bool {
for _, acc := range accs {
if !acc.Permissions.Send {
if !HasPermission(state, acc, ptypes.Send) {
return false
}
}
return true
}
func hasCallPermission(acc *account.Account) bool {
if !acc.Permissions.Call {
func hasCallPermission(state AccountGetter, acc *account.Account) bool {
if !HasPermission(state, acc, ptypes.Call) {
return false
}
return true
}
func hasCreatePermission(acc *account.Account) bool {
if !acc.Permissions.Create {
func hasCreatePermission(state AccountGetter, acc *account.Account) bool {
if !HasPermission(state, acc, ptypes.Create) {
return false
}
return true
}
func hasBondPermission(accs map[string]*account.Account) bool {
func hasBondPermission(state AccountGetter, accs map[string]*account.Account) bool {
for _, acc := range accs {
if !acc.Permissions.Bond {
if !HasPermission(state, acc, ptypes.Bond) {
return false
}
}
return true
}
/*
// permission management functions
// get/set closures which bind the txCache (for modifying an accounts permissions)
// add/rm closures which bind txCache & state (for creating/removing permissions on *all* accounts - expensive!)
@@ -841,7 +852,7 @@ func setupDoug(vmach *vm.VM, txCache *TxCache, _s *State) {
}
stAcc := toStateAccount(vmAcc)
permN := uint(Uint64FromWord256(permNum))
perm, err := stAcc.Permissions.Get(permN)
perm, err := stAcc.Permissions.Base.Get(permN)
if err != nil {
return nil, err
}
@@ -870,7 +881,7 @@ func setupDoug(vmach *vm.VM, txCache *TxCache, _s *State) {
stAcc := toStateAccount(vmAcc)
permN := uint(Uint64FromWord256(permNum))
permV := !perm.IsZero()
if err = stAcc.Permissions.Set(permN, permV); err != nil {
if err = stAcc.Permissions.Base.Set(permN, permV); err != nil {
return nil, err
}
vmAcc = toVMAccount(stAcc)
@@ -942,3 +953,4 @@ func setupDoug(vmach *vm.VM, txCache *TxCache, _s *State) {
// must be called or else functions not accessible
vmach.EnableDoug()
}
*/
+8 -8
View File
@@ -15,9 +15,9 @@ import (
)
type GenesisAccount struct {
Address []byte `json:"address"`
Amount uint64 `json:"amount"`
Permissions *ptypes.Permissions `json:"global_permissions"` // pointer so optional
Address []byte `json:"address"`
Amount uint64 `json:"amount"`
Permissions *ptypes.AccountPermissions `json:"global_permissions"` // pointer so optional
}
type GenesisValidator struct {
@@ -28,7 +28,7 @@ type GenesisValidator struct {
type GenesisParams struct {
// Default permissions for newly created accounts
GlobalPermissions *ptypes.Permissions `json:"global_permissions"`
GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
// TODO: other params we may want to tweak?
}
@@ -73,8 +73,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
// Make accounts state tree
accounts := merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
for _, genAcc := range genDoc.Accounts {
perm_ := account.DefaultPermissions
perm := &perm_
perm := ptypes.NewDefaultAccountPermissions()
if genAcc.Permissions != nil {
perm = genAcc.Permissions
}
@@ -90,10 +89,11 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
// global permissions are saved as the 0 address
// so they are included in the accounts tree
globalPerms_ := account.DefaultPermissions
globalPerms := &globalPerms_
globalPerms := ptypes.NewDefaultAccountPermissions()
if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil {
globalPerms = genDoc.Params.GlobalPermissions
// XXX: make sure the set bits are all true
globalPerms.Base.SetBit = ptypes.AllSet
}
permsAcc := &account.Account{
Address: ptypes.GlobalPermissionsAddress,
+19 -25
View File
@@ -62,29 +62,23 @@ func makeUsers(n int) []*account.PrivAccount {
}
var (
PermsAllFalse = ptypes.Permissions{
Send: false,
Call: false,
Create: false,
Bond: false,
}
PermsAllFalse = ptypes.NewAccountPermissions()
)
func newBaseGenDoc(globalPerm, accountPerm ptypes.Permissions) GenesisDoc {
func newBaseGenDoc(globalPerm, accountPerm *ptypes.AccountPermissions) GenesisDoc {
genAccounts := []GenesisAccount{}
for _, u := range user[:5] {
accPerm := accountPerm
genAccounts = append(genAccounts, GenesisAccount{
Address: u.Address,
Amount: 1000000,
Permissions: &accPerm,
Permissions: accountPerm.Copy(),
})
}
return GenesisDoc{
GenesisTime: time.Now(),
Params: &GenesisParams{
GlobalPermissions: &globalPerm,
GlobalPermissions: globalPerm,
},
Accounts: genAccounts,
Validators: []GenesisValidator{
@@ -104,9 +98,9 @@ func newBaseGenDoc(globalPerm, accountPerm ptypes.Permissions) GenesisDoc {
func TestSendFails(t *testing.T) {
stateDB := dbm.GetDB("state")
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
genDoc.Accounts[1].Permissions.Send = true
genDoc.Accounts[2].Permissions.Call = true
genDoc.Accounts[3].Permissions.Create = true
genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
genDoc.Accounts[3].Permissions.Base.Set(ptypes.Create, true)
st := MakeGenesisState(stateDB, &genDoc)
blockCache := NewBlockCache(st)
@@ -156,9 +150,9 @@ func TestSendFails(t *testing.T) {
func TestCallFails(t *testing.T) {
stateDB := dbm.GetDB("state")
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
genDoc.Accounts[1].Permissions.Send = true
genDoc.Accounts[2].Permissions.Call = true
genDoc.Accounts[3].Permissions.Create = true
genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
genDoc.Accounts[3].Permissions.Base.Set(ptypes.Create, true)
st := MakeGenesisState(stateDB, &genDoc)
blockCache := NewBlockCache(st)
@@ -226,7 +220,7 @@ func TestCallFails(t *testing.T) {
func TestSendPermission(t *testing.T) {
stateDB := dbm.GetDB("state")
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
genDoc.Accounts[0].Permissions.Send = true // give the 0 account permission
genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
st := MakeGenesisState(stateDB, &genDoc)
blockCache := NewBlockCache(st)
@@ -275,7 +269,7 @@ func callContractCode(contractAddr []byte) []byte {
func TestCallPermission(t *testing.T) {
stateDB := dbm.GetDB("state")
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
genDoc.Accounts[0].Permissions.Call = true // give the 0 account permission
genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
st := MakeGenesisState(stateDB, &genDoc)
blockCache := NewBlockCache(st)
@@ -291,7 +285,7 @@ func TestCallPermission(t *testing.T) {
Code: []byte{0x60},
Sequence: 0,
StorageRoot: Zero256.Bytes(),
Permissions: ptypes.NilPermissions.Copy(),
Permissions: ptypes.NewAccountPermissions(),
}
st.UpdateAccount(simpleAcc)
@@ -315,7 +309,7 @@ func TestCallPermission(t *testing.T) {
Code: contractCode,
Sequence: 0,
StorageRoot: Zero256.Bytes(),
Permissions: ptypes.NilPermissions.Copy(),
Permissions: ptypes.NewAccountPermissions(),
}
blockCache.UpdateAccount(caller1Acc)
@@ -334,7 +328,7 @@ func TestCallPermission(t *testing.T) {
fmt.Println("##### CALL TO SIMPLE CONTRACT (PASS)")
// A single input, having the permission, and the contract has permission
caller1Acc.Permissions.Call = true
caller1Acc.Permissions.Base.Set(ptypes.Call, true)
blockCache.UpdateAccount(caller1Acc)
tx, _ = NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100)
SignCallTx(tx, user[0])
@@ -359,10 +353,10 @@ func TestCallPermission(t *testing.T) {
Code: contractCode2,
Sequence: 0,
StorageRoot: Zero256.Bytes(),
Permissions: ptypes.NilPermissions.Copy(),
Permissions: ptypes.NewAccountPermissions(),
}
caller1Acc.Permissions.Call = false
caller2Acc.Permissions.Call = true
caller1Acc.Permissions.Base.Set(ptypes.Call, false)
caller2Acc.Permissions.Base.Set(ptypes.Call, true)
blockCache.UpdateAccount(caller1Acc)
blockCache.UpdateAccount(caller2Acc)
@@ -381,7 +375,7 @@ func TestCallPermission(t *testing.T) {
// both caller1 and caller2 have permission
fmt.Println("##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)")
caller1Acc.Permissions.Call = true
caller1Acc.Permissions.Base.Set(ptypes.Call, true)
blockCache.UpdateAccount(caller1Acc)
tx, _ = NewCallTx(blockCache, user[0].PubKey, caller2ContractAddr, nil, 100, 10000, 100)
+9 -4
View File
@@ -7,6 +7,7 @@ import (
"github.com/tendermint/tendermint/account"
. "github.com/tendermint/tendermint/common"
dbm "github.com/tendermint/tendermint/db"
ptypes "github.com/tendermint/tendermint/permission/types"
"github.com/tendermint/tendermint/types"
"io/ioutil"
@@ -24,13 +25,13 @@ func Tempfile(prefix string) (*os.File, string) {
func RandAccount(randBalance bool, minBalance int64) (*account.Account, *account.PrivAccount) {
privAccount := account.GenPrivAccount()
perms := account.DefaultPermissions
perms := ptypes.NewDefaultAccountPermissions()
acc := &account.Account{
Address: privAccount.PubKey.Address(),
PubKey: privAccount.PubKey,
Sequence: RandInt(),
Balance: minBalance,
Permissions: &perms,
Permissions: perms,
}
if randBalance {
acc.Balance += int64(RandUint32())
@@ -75,8 +76,9 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numVa
for i := 0; i < numAccounts; i++ {
account, privAccount := RandAccount(randBalance, minBalance)
accounts[i] = GenesisAccount{
Address: account.Address,
Amount: account.Balance,
Address: account.Address,
Amount: account.Balance,
Permissions: ptypes.NewDefaultAccountPermissions(),
}
privAccounts[i] = privAccount
}
@@ -102,6 +104,9 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numVa
ChainID: "tendermint_test",
Accounts: accounts,
Validators: validators,
Params: &GenesisParams{
GlobalPermissions: ptypes.NewDefaultAccountPermissions(),
},
})
s0.Save()
return s0, privAccounts, privValidators