Browse Source

names in gendoc, genesis_test

pull/102/head
Ethan Buchman 9 years ago
committed by Jae Kwon
parent
commit
3416004359
8 changed files with 261 additions and 34 deletions
  1. +21
    -1
      node/node.go
  2. +116
    -4
      permission/types/permissions.go
  3. +6
    -17
      rpc/core/net.go
  4. +5
    -0
      rpc/core/pipe.go
  5. +24
    -9
      state/genesis.go
  6. +86
    -0
      state/genesis_test.go
  7. +2
    -2
      state/permissions_test.go
  8. +1
    -1
      state/test.go

+ 21
- 1
node/node.go View File

@ -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()


+ 116
- 4
permission/types/permissions.go View File

@ -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<<i, v)
}
aP := &AccountPermissions{
Base: base,
Roles: make([]string, len(roles)),
}
copy(aP.Roles, roles)
return aP, nil
}
func AccountPermissionsToStrings(aP *AccountPermissions) (*BasePermissionsString, []string, error) {
perms := new(BasePermissionsString)
permsRv := reflect.ValueOf(perms).Elem()
for i := uint(0); i < NumBasePermissions; i++ {
pf := PermFlag(1 << i)
if aP.Base.IsSet(pf) {
// won't err if the bit is set
v, _ := aP.Base.Get(pf)
f := permsRv.Field(int(i))
f.SetBool(v)
}
}
roles := make([]string, len(aP.Roles))
copy(roles, aP.Roles)
return perms, roles, nil
}
func PermFlagToString(pf PermFlag) (perm string, err error) {
switch pf {
case Root:
perm = "root"
case Send:
perm = "send"
case Call:
perm = "call"
case CreateContract:
perm = "create_contract"
case CreateAccount:
perm = "create_account"
case Bond:
perm = "bond"
case Name:
perm = "name"
default:
err = fmt.Errorf("Unknown permission flag %b", pf)
}
return
}
func PermStringToFlag(perm string) (pf PermFlag, err error) {
switch perm {
case "root":
pf = Root
case "send":
pf = Send
case "call":
pf = Call
case "create_contract":
pf = CreateContract
case "create_account":
pf = CreateAccount
case "bond":
pf = Bond
case "name":
pf = Name
default:
err = fmt.Errorf("Unknown permission %s", perm)
}
return
}

+ 6
- 17
rpc/core/net.go View File

@ -1,9 +1,6 @@
package core
import (
"io/ioutil"
"github.com/tendermint/tendermint/binary"
dbm "github.com/tendermint/tendermint/db"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
sm "github.com/tendermint/tendermint/state"
@ -12,9 +9,14 @@ import (
//-----------------------------------------------------------------------------
// cache the genesis state
var genesisState *sm.State
func Status() (*ctypes.ResponseStatus, error) {
db := dbm.NewMemDB()
genesisState := sm.MakeGenesisStateFromFile(db, config.GetString("genesis_file"))
if genesisState == nil {
genesisState = sm.MakeGenesisState(db, genDoc)
}
genesisHash := genesisState.Hash()
latestHeight := blockStore.Height()
var (
@ -63,19 +65,6 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) {
//-----------------------------------------------------------------------------
// cache the genesis structure
var genDoc *sm.GenesisDoc
func Genesis() (*sm.GenesisDoc, error) {
if genDoc == nil {
b, err := ioutil.ReadFile(config.GetString("genesis_file"))
if err != nil {
return nil, err
}
binary.ReadJSON(&genDoc, b, &err)
if err != nil {
return nil, err
}
}
return genDoc, nil
}

+ 5
- 0
rpc/core/pipe.go View File

@ -14,6 +14,7 @@ var consensusReactor *consensus.ConsensusReactor
var mempoolReactor *mempl.MempoolReactor
var p2pSwitch *p2p.Switch
var privValidator *state.PrivValidator
var genDoc *state.GenesisDoc // cache the genesis structure
func SetBlockStore(bs *bc.BlockStore) {
blockStore = bs
@ -38,3 +39,7 @@ func SetSwitch(sw *p2p.Switch) {
func SetPrivValidator(pv *state.PrivValidator) {
privValidator = pv
}
func SetGenDoc(doc *state.GenesisDoc) {
genDoc = doc
}

+ 24
- 9
state/genesis.go View File

@ -14,33 +14,48 @@ import (
"github.com/tendermint/tendermint/types"
)
//------------------------------------------------------------
// we store the gendoc in the db
var GenDocKey = []byte("GenDocKey")
//------------------------------------------------------------
// core types for a genesis definition
type BasicAccount struct {
Address []byte `json:"address"`
Amount uint64 `json:"amount"`
}
type GenesisAccount struct {
Address []byte `json:"address"`
Amount uint64 `json:"amount"`
Permissions *ptypes.AccountPermissions `json:"global_permissions"` // pointer so optional
Name string `json:"name"`
Permissions *ptypes.AccountPermissions `json:"permissions"`
}
type GenesisValidator struct {
PubKey account.PubKeyEd25519 `json:"pub_key"`
Amount int64 `json:"amount"`
UnbondTo []GenesisAccount `json:"unbond_to"`
Amount uint64 `json:"amount"`
Name string `json:"name"`
UnbondTo []BasicAccount `json:"unbond_to"`
}
type GenesisParams struct {
// Default permissions for newly created accounts
GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
// TODO: other params we may want to tweak?
}
type GenesisDoc struct {
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
Params *GenesisParams `json:"params"` // pointer so optional
Params *GenesisParams `json:"params"`
Accounts []GenesisAccount `json:"accounts"`
Validators []GenesisValidator `json:"validators"`
}
//------------------------------------------------------------
// Make genesis state from file
func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
var err error
binary.ReadJSON(&genState, jsonBlob, &err)
@ -51,14 +66,14 @@ func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
return
}
func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) *State {
func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*GenesisDoc, *State) {
jsonBlob, err := ioutil.ReadFile(genDocFile)
if err != nil {
log.Error(Fmt("Couldn't read GenesisDoc file: %v", err))
os.Exit(1)
}
genDoc := GenesisDocFromJSON(jsonBlob)
return MakeGenesisState(db, genDoc)
return genDoc, MakeGenesisState(db, genDoc)
}
func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {


+ 86
- 0
state/genesis_test.go View File

@ -0,0 +1,86 @@
package state
import (
"bytes"
"encoding/hex"
"fmt"
"testing"
tdb "github.com/tendermint/tendermint/db"
ptypes "github.com/tendermint/tendermint/permission/types"
)
var chain_id = "lone_ranger"
var addr1, _ = hex.DecodeString("964B1493BBE3312278B7DEB94C39149F7899A345")
var send1, name1, call1 = 1, 1, 0
var perms, setbit = 66, 70
var accName = "me"
var roles1 = []string{"master", "universal-ruler"}
var amt1 uint64 = 1000000
var g1 = fmt.Sprintf(`
{
"chain_id":"%s",
"accounts": [
{
"address": "%X",
"amount": %d,
"name": "%s",
"permissions": {
"base": {
"perms": %d,
"set": %d
},
"roles": [
"%s",
"%s"
]
}
}
],
"validators": [
{
"amount": 100000000,
"pub_key": [1,"F6C79CF0CB9D66B677988BCB9B8EADD9A091CD465A60542A8AB85476256DBA92"],
"unbond_to": [
{
"address": "964B1493BBE3312278B7DEB94C39149F7899A345",
"amount": 10000000
}
]
}
]
}
`, chain_id, addr1, amt1, accName, perms, setbit, roles1[0], roles1[1])
func TestGenesisReadable(t *testing.T) {
genDoc := GenesisDocFromJSON([]byte(g1))
if genDoc.ChainID != chain_id {
t.Fatalf("Incorrect chain id. Got %d, expected %d\n", genDoc.ChainID, chain_id)
}
acc := genDoc.Accounts[0]
if bytes.Compare(acc.Address, addr1) != 0 {
t.Fatalf("Incorrect address for account. Got %X, expected %X\n", acc.Address, addr1)
}
if acc.Amount != amt1 {
t.Fatalf("Incorrect amount for account. Got %d, expected %d\n", acc.Amount, amt1)
}
if acc.Name != accName {
t.Fatalf("Incorrect name for account. Got %s, expected %s\n", acc.Name, accName)
}
perm, _ := acc.Permissions.Base.Get(ptypes.Send)
if perm != (send1 > 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)
}
}

+ 2
- 2
state/permissions_test.go View File

@ -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,
},
},


+ 1
- 1
state/test.go View File

@ -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,


Loading…
Cancel
Save