tendermint/state/genesis.go

179 lines
5.0 KiB
Go
Raw Normal View History

2014-10-22 17:20:44 -07:00
package state
import (
"io/ioutil"
2015-06-16 21:16:58 -07:00
"os"
2014-10-22 17:20:44 -07:00
"time"
2015-04-01 17:30:16 -07:00
"github.com/tendermint/tendermint/account"
"github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
dbm "github.com/tendermint/tendermint/db"
"github.com/tendermint/tendermint/merkle"
2015-05-15 21:48:04 -07:00
ptypes "github.com/tendermint/tendermint/permission/types"
2015-04-01 17:30:16 -07:00
"github.com/tendermint/tendermint/types"
2014-10-22 17:20:44 -07:00
)
2015-06-14 15:18:17 -07:00
//------------------------------------------------------------
// we store the gendoc in the db
var GenDocKey = []byte("GenDocKey")
//------------------------------------------------------------
// core types for a genesis definition
type BasicAccount struct {
Address []byte `json:"address"`
2015-07-07 14:17:20 -07:00
Amount int64 `json:"amount"`
2015-06-14 15:18:17 -07:00
}
type GenesisAccount struct {
2015-05-19 21:40:02 -07:00
Address []byte `json:"address"`
2015-07-07 14:17:20 -07:00
Amount int64 `json:"amount"`
2015-06-14 15:18:17 -07:00
Name string `json:"name"`
Permissions *ptypes.AccountPermissions `json:"permissions"`
}
type GenesisValidator struct {
2015-05-01 17:26:49 -07:00
PubKey account.PubKeyEd25519 `json:"pub_key"`
2015-07-07 14:17:20 -07:00
Amount int64 `json:"amount"`
2015-06-14 15:18:17 -07:00
Name string `json:"name"`
UnbondTo []BasicAccount `json:"unbond_to"`
}
2015-05-12 17:40:19 -07:00
type GenesisParams struct {
2015-05-19 21:40:02 -07:00
GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
2015-05-12 17:40:19 -07:00
}
2014-10-22 17:20:44 -07:00
type GenesisDoc struct {
2015-05-01 17:26:49 -07:00
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
2015-06-14 15:18:17 -07:00
Params *GenesisParams `json:"params"`
2015-05-01 17:26:49 -07:00
Accounts []GenesisAccount `json:"accounts"`
Validators []GenesisValidator `json:"validators"`
2014-10-22 17:20:44 -07:00
}
2015-06-14 15:18:17 -07:00
//------------------------------------------------------------
// Make genesis state from file
func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
var err error
binary.ReadJSONPtr(&genState, jsonBlob, &err)
2014-10-22 17:20:44 -07:00
if err != nil {
2015-06-16 21:16:58 -07:00
log.Error(Fmt("Couldn't read GenesisDoc: %v", err))
os.Exit(1)
2014-10-22 17:20:44 -07:00
}
return
}
2015-06-14 15:18:17 -07:00
func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*GenesisDoc, *State) {
2014-10-22 17:20:44 -07:00
jsonBlob, err := ioutil.ReadFile(genDocFile)
if err != nil {
2015-06-16 21:16:58 -07:00
log.Error(Fmt("Couldn't read GenesisDoc file: %v", err))
os.Exit(1)
2014-10-22 17:20:44 -07:00
}
genDoc := GenesisDocFromJSON(jsonBlob)
2015-06-14 15:18:17 -07:00
return genDoc, MakeGenesisState(db, genDoc)
2014-10-22 17:20:44 -07:00
}
func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
if len(genDoc.Validators) == 0 {
2014-12-29 18:09:06 -08:00
Exit(Fmt("The genesis file has no validators"))
2014-10-24 18:21:30 -07:00
}
if genDoc.GenesisTime.IsZero() {
genDoc.GenesisTime = time.Now()
2014-10-22 17:20:44 -07:00
}
// Make accounts state tree
accounts := merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
for _, genAcc := range genDoc.Accounts {
perm := ptypes.ZeroAccountPermissions
2015-05-12 17:40:19 -07:00
if genAcc.Permissions != nil {
perm = *genAcc.Permissions
2015-05-12 17:40:19 -07:00
}
acc := &account.Account{
2015-05-12 17:40:19 -07:00
Address: genAcc.Address,
PubKey: nil,
Sequence: 0,
Balance: genAcc.Amount,
Permissions: perm,
}
accounts.Set(acc.Address, acc)
2014-10-22 17:20:44 -07:00
}
2015-05-12 17:40:19 -07:00
// global permissions are saved as the 0 address
// so they are included in the accounts tree
globalPerms := ptypes.DefaultAccountPermissions
2015-05-12 17:40:19 -07:00
if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil {
globalPerms = *genDoc.Params.GlobalPermissions
2015-05-19 21:40:02 -07:00
// XXX: make sure the set bits are all true
// Without it the HasPermission() functions will fail
globalPerms.Base.SetBit = ptypes.AllPermFlags
2015-05-12 17:40:19 -07:00
}
2015-05-21 12:51:57 -07:00
2015-05-12 17:40:19 -07:00
permsAcc := &account.Account{
2015-05-15 21:48:04 -07:00
Address: ptypes.GlobalPermissionsAddress,
2015-05-12 17:40:19 -07:00
PubKey: nil,
Sequence: 0,
Balance: 1337,
Permissions: globalPerms,
}
accounts.Set(permsAcc.Address, permsAcc)
// Make validatorInfos state tree && validators slice
validatorInfos := merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db)
2014-12-17 01:37:13 -08:00
validators := make([]*Validator, len(genDoc.Validators))
for i, val := range genDoc.Validators {
pubKey := val.PubKey
address := pubKey.Address()
// Make ValidatorInfo
valInfo := &ValidatorInfo{
Address: address,
PubKey: pubKey,
UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)),
FirstBondHeight: 0,
FirstBondAmount: val.Amount,
}
for i, unbondTo := range val.UnbondTo {
valInfo.UnbondTo[i] = &types.TxOutput{
Address: unbondTo.Address,
Amount: unbondTo.Amount,
}
}
validatorInfos.Set(address, valInfo)
// Make validator
2014-12-17 01:37:13 -08:00
validators[i] = &Validator{
Address: address,
PubKey: pubKey,
VotingPower: val.Amount,
2014-12-17 01:37:13 -08:00
}
}
2015-05-22 13:53:10 -07:00
// Make namereg tree
nameReg := merkle.NewIAVLTree(binary.BasicCodec, NameRegCodec, 0, db)
2015-07-10 08:39:49 -07:00
// TODO: add names, contracts to genesis.json
2015-05-22 13:53:10 -07:00
2014-12-31 23:21:47 -08:00
// IAVLTrees must be persisted before copy operations.
accounts.Save()
validatorInfos.Save()
2015-05-22 13:53:10 -07:00
nameReg.Save()
2014-12-31 23:21:47 -08:00
2014-10-22 17:20:44 -07:00
return &State{
DB: db,
ChainID: genDoc.ChainID,
LastBlockHeight: 0,
LastBlockHash: nil,
LastBlockParts: types.PartSetHeader{},
LastBlockTime: genDoc.GenesisTime,
BondedValidators: NewValidatorSet(validators),
LastBondedValidators: NewValidatorSet(nil),
UnbondingValidators: NewValidatorSet(nil),
accounts: accounts,
validatorInfos: validatorInfos,
2015-05-22 13:53:10 -07:00
nameReg: nameReg,
2014-10-22 17:20:44 -07:00
}
}