diff --git a/node/node.go b/node/node.go index aa6eb124d..47e3eee41 100644 --- a/node/node.go +++ b/node/node.go @@ -1,6 +1,7 @@ package node import ( + "bytes" "fmt" "math/rand" "net" @@ -10,6 +11,7 @@ import ( "strings" "time" + "github.com/tendermint/tendermint/binary" bc "github.com/tendermint/tendermint/blockchain" . "github.com/tendermint/tendermint/common" "github.com/tendermint/tendermint/consensus" @@ -42,6 +44,7 @@ type Node struct { consensusState *consensus.ConsensusState consensusReactor *consensus.ConsensusReactor privValidator *sm.PrivValidator + genDoc *sm.GenesisDoc } func NewNode() *Node { @@ -52,9 +55,24 @@ func NewNode() *Node { // Get State stateDB := dbm.GetDB("state") state := sm.LoadState(stateDB) + var genDoc *sm.GenesisDoc if state == nil { - state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) + genDoc, state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) state.Save() + // write the gendoc to db + buf, n, err := new(bytes.Buffer), new(int64), new(error) + binary.WriteJSON(genDoc, buf, n, err) + stateDB.Set(sm.GenDocKey, buf.Bytes()) + if *err != nil { + panic(Fmt("Unable to write gendoc to db: %v", err)) + } + } else { + genDocBytes := stateDB.Get(sm.GenDocKey) + err := new(error) + binary.ReadJSON(&genDoc, genDocBytes, err) + if *err != nil { + panic(Fmt("Unable to read gendoc from db: %v", err)) + } } // add the chainid to the global config config.Set("chain_id", state.ChainID) @@ -115,6 +133,7 @@ func NewNode() *Node { consensusState: consensusState, consensusReactor: consensusReactor, privValidator: privValidator, + genDoc: genDoc, } } @@ -184,6 +203,7 @@ func (n *Node) StartRPC() { core.SetMempoolReactor(n.mempoolReactor) core.SetSwitch(n.sw) core.SetPrivValidator(n.privValidator) + core.SetGenDoc(n.genDoc) listenAddr := config.GetString("rpc_laddr") mux := http.NewServeMux() diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 1a0bd6a7e..8dba8c35e 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -3,6 +3,7 @@ package types import ( "fmt" . "github.com/tendermint/tendermint/common" + "reflect" ) //------------------------------------------------------------------------------------------------ @@ -34,15 +35,26 @@ const ( AllSet PermFlag = (1 << 63) - 1 + (1 << 63) ) +// should have same ordering as above +type BasePermissionsString struct { + Root bool `json:"root,omitempty"` + Send bool `json:"send,omitempty"` + Call bool `json:"call,omitempty"` + CreateContract bool `json:"create_contract,omitempty"` + CreateAccount bool `json:"create_account,omitempty"` + Bond bool `json:"bond,omitempty"` + Name bool `json:"name,omitempty"` +} + //--------------------------------------------------------------------------------------------- // Base chain permissions struct type BasePermissions struct { // bit array with "has"/"doesn't have" for each permission - Perms PermFlag + Perms PermFlag `json:"perms"` // bit array with "set"/"not set" for each permission (not-set should fall back to global) - SetBit PermFlag + SetBit PermFlag `json:"set"` } func NewBasePermissions() *BasePermissions { @@ -85,6 +97,14 @@ func (p *BasePermissions) Unset(ty PermFlag) error { return nil } +// Check if the permission is set +func (p *BasePermissions) IsSet(ty PermFlag) bool { + if ty == 0 { + return false + } + return p.SetBit&ty > 0 +} + func (p *BasePermissions) Copy() *BasePermissions { if p == nil { return nil @@ -102,8 +122,8 @@ func (p *BasePermissions) String() string { //--------------------------------------------------------------------------------------------- type AccountPermissions struct { - Base *BasePermissions - Roles []string + Base *BasePermissions `json:"base"` + Roles []string `json:"roles"` } func NewAccountPermissions() *AccountPermissions { @@ -173,3 +193,95 @@ func NewDefaultAccountPermissions() *AccountPermissions { Roles: []string{}, } } + +//--------------------------------------------------------------------------------------------- +// Utilities to make bitmasks human readable + +func NewDefaultAccountPermissionsString() BasePermissionsString { + return BasePermissionsString{ + Root: false, + Bond: true, + Send: true, + Call: true, + Name: true, + CreateAccount: true, + CreateContract: true, + } +} + +func AccountPermissionsFromStrings(perms *BasePermissionsString, roles []string) (*AccountPermissions, error) { + base := NewBasePermissions() + permRv := reflect.ValueOf(perms) + for i := uint(0); i < uint(permRv.NumField()); i++ { + v := permRv.Field(int(i)).Bool() + base.Set(1< 0) { + t.Fatalf("Incorrect permission for send. Got %v, expected %v\n", perm, send1 > 0) + } +} + +func TestGenesisMakeState(t *testing.T) { + genDoc := GenesisDocFromJSON([]byte(g1)) + db := tdb.NewMemDB() + st := MakeGenesisState(db, genDoc) + acc := st.GetAccount(addr1) + v, _ := acc.Permissions.Base.Get(ptypes.Send) + if v != (send1 > 0) { + t.Fatalf("Incorrect permission for send. Got %v, expected %v\n", v, send1 > 0) + } +} diff --git a/state/permissions_test.go b/state/permissions_test.go index b9d3c7cbd..1ec99c47d 100644 --- a/state/permissions_test.go +++ b/state/permissions_test.go @@ -116,8 +116,8 @@ func newBaseGenDoc(globalPerm, accountPerm *ptypes.AccountPermissions) GenesisDo GenesisValidator{ PubKey: user[0].PubKey.(account.PubKeyEd25519), Amount: 10, - UnbondTo: []GenesisAccount{ - GenesisAccount{ + UnbondTo: []BasicAccount{ + BasicAccount{ Address: user[0].Address, }, }, diff --git a/state/test.go b/state/test.go index 7aced4809..a676498f7 100644 --- a/state/test.go +++ b/state/test.go @@ -89,7 +89,7 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numVa validators[i] = GenesisValidator{ PubKey: valInfo.PubKey, Amount: valInfo.FirstBondAmount, - UnbondTo: []GenesisAccount{ + UnbondTo: []BasicAccount{ { Address: valInfo.PubKey.Address(), Amount: valInfo.FirstBondAmount,