mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-23 09:41:38 +00:00
names in gendoc, genesis_test
This commit is contained in:
22
node/node.go
22
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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
state/genesis_test.go
Normal file
86
state/genesis_test.go
Normal 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)
|
||||
}
|
||||
}
|
@ -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,
|
||||
},
|
||||
},
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user