mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-20 06:54:41 +00:00
Refactoring genesis, including PubKey into TxInput
This commit is contained in:
+64
-14
@@ -1,6 +1,8 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
@@ -13,10 +15,21 @@ import (
|
||||
"github.com/tendermint/tendermint/merkle"
|
||||
)
|
||||
|
||||
type GenesisAccount struct {
|
||||
Address string
|
||||
Amount uint64
|
||||
}
|
||||
|
||||
type GenesisValidator struct {
|
||||
PubKey string
|
||||
Amount uint64
|
||||
UnbondTo []GenesisAccount
|
||||
}
|
||||
|
||||
type GenesisDoc struct {
|
||||
GenesisTime time.Time
|
||||
Accounts []*Account
|
||||
Validators []*ValidatorInfo
|
||||
Accounts []GenesisAccount
|
||||
Validators []GenesisValidator
|
||||
}
|
||||
|
||||
func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
|
||||
@@ -38,7 +51,7 @@ func MakeGenesisStateFromFile(db db_.DB, genDocFile string) *State {
|
||||
|
||||
func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
||||
if len(genDoc.Validators) == 0 {
|
||||
panic("Must have some validators")
|
||||
Exitf("The genesis file has no validators")
|
||||
}
|
||||
|
||||
if genDoc.GenesisTime.IsZero() {
|
||||
@@ -48,22 +61,59 @@ func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
||||
// Make accounts state tree
|
||||
accounts := merkle.NewIAVLTree(BasicCodec, AccountCodec, defaultAccountsCacheCapacity, db)
|
||||
for _, acc := range genDoc.Accounts {
|
||||
accounts.Set(acc.Address, acc)
|
||||
address, err := base64.StdEncoding.DecodeString(acc.Address)
|
||||
if err != nil {
|
||||
Exitf("Invalid account address: %v", acc.Address)
|
||||
}
|
||||
account := &Account{
|
||||
Address: address,
|
||||
PubKey: PubKeyNil{},
|
||||
Sequence: 0,
|
||||
Balance: acc.Amount,
|
||||
}
|
||||
accounts.Set(address, account)
|
||||
}
|
||||
|
||||
// Make validatorInfos state tree
|
||||
// Make validatorInfos state tree && validators slice
|
||||
validatorInfos := merkle.NewIAVLTree(BasicCodec, ValidatorInfoCodec, 0, db)
|
||||
for _, valInfo := range genDoc.Validators {
|
||||
validatorInfos.Set(valInfo.Address, valInfo)
|
||||
}
|
||||
|
||||
// Make validators
|
||||
validators := make([]*Validator, len(genDoc.Validators))
|
||||
for i, valInfo := range genDoc.Validators {
|
||||
for i, val := range genDoc.Validators {
|
||||
pubKeyBytes, err := base64.StdEncoding.DecodeString(val.PubKey)
|
||||
if err != nil {
|
||||
Exitf("Invalid validator pubkey: %v", val.PubKey)
|
||||
}
|
||||
pubKey := ReadBinary(PubKeyEd25519{},
|
||||
bytes.NewBuffer(pubKeyBytes), new(int64), &err).(PubKeyEd25519)
|
||||
if err != nil {
|
||||
Exitf("Invalid validator pubkey: %v", val.PubKey)
|
||||
}
|
||||
address := pubKey.Address()
|
||||
|
||||
// Make ValidatorInfo
|
||||
valInfo := &ValidatorInfo{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
UnbondTo: make([]*TxOutput, len(val.UnbondTo)),
|
||||
FirstBondHeight: 0,
|
||||
FirstBondAmount: val.Amount,
|
||||
}
|
||||
for i, unbondTo := range val.UnbondTo {
|
||||
address, err := base64.StdEncoding.DecodeString(unbondTo.Address)
|
||||
if err != nil {
|
||||
Exitf("Invalid unbond-to address: %v", unbondTo.Address)
|
||||
}
|
||||
valInfo.UnbondTo[i] = &TxOutput{
|
||||
Address: address,
|
||||
Amount: unbondTo.Amount,
|
||||
}
|
||||
}
|
||||
validatorInfos.Set(address, valInfo)
|
||||
|
||||
// Make validator
|
||||
validators[i] = &Validator{
|
||||
Address: valInfo.Address,
|
||||
PubKey: valInfo.PubKey,
|
||||
VotingPower: valInfo.FirstBondAmount,
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
VotingPower: val.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -126,6 +126,14 @@ func (privVal *PrivValidator) Save() {
|
||||
}
|
||||
|
||||
func (privVal *PrivValidator) save() {
|
||||
jsonBytes := privVal.JSONBytes()
|
||||
err := ioutil.WriteFile(privVal.filename, jsonBytes, 0700)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (privVal *PrivValidator) JSONBytes() []byte {
|
||||
privValJSON := PrivValidatorJSON{
|
||||
Address: base64.StdEncoding.EncodeToString(privVal.Address),
|
||||
PubKey: base64.StdEncoding.EncodeToString(BinaryBytes(privVal.PubKey)),
|
||||
@@ -134,14 +142,11 @@ func (privVal *PrivValidator) save() {
|
||||
LastRound: privVal.LastRound,
|
||||
LastStep: privVal.LastStep,
|
||||
}
|
||||
privValJSONBytes, err := json.Marshal(privValJSON)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = ioutil.WriteFile(privVal.filename, privValJSONBytes, 0700)
|
||||
privValJSONBytes, err := json.MarshalIndent(privValJSON, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return privValJSONBytes
|
||||
}
|
||||
|
||||
// TODO: test
|
||||
|
||||
+23
-1
@@ -108,6 +108,9 @@ func (s *State) Copy() *State {
|
||||
}
|
||||
}
|
||||
|
||||
// The accounts from the TxInputs must either already have
|
||||
// account.PubKey.(type) != PubKeyNil, (it must be known),
|
||||
// or it must be specified in the TxInput. But not both.
|
||||
func (s *State) GetOrMakeAccounts(ins []*TxInput, outs []*TxOutput) (map[string]*Account, error) {
|
||||
accounts := map[string]*Account{}
|
||||
for _, in := range ins {
|
||||
@@ -119,6 +122,20 @@ func (s *State) GetOrMakeAccounts(ins []*TxInput, outs []*TxOutput) (map[string]
|
||||
if account == nil {
|
||||
return nil, ErrTxInvalidAddress
|
||||
}
|
||||
// PubKey should be present in either "account" or "in"
|
||||
if _, isNil := account.PubKey.(PubKeyNil); isNil {
|
||||
if _, isNil := in.PubKey.(PubKeyNil); isNil {
|
||||
return nil, ErrTxUnknownPubKey
|
||||
}
|
||||
if !bytes.Equal(in.PubKey.Address(), account.Address) {
|
||||
return nil, ErrTxInvalidPubKey
|
||||
}
|
||||
account.PubKey = in.PubKey
|
||||
} else {
|
||||
if _, isNil := in.PubKey.(PubKeyNil); !isNil {
|
||||
return nil, ErrTxRedeclaredPubKey
|
||||
}
|
||||
}
|
||||
accounts[string(in.Address)] = account
|
||||
}
|
||||
for _, out := range outs {
|
||||
@@ -129,7 +146,12 @@ func (s *State) GetOrMakeAccounts(ins []*TxInput, outs []*TxOutput) (map[string]
|
||||
account := s.GetAccount(out.Address)
|
||||
// output account may be nil (new)
|
||||
if account == nil {
|
||||
account = NewAccount(NewPubKeyUnknown(out.Address))
|
||||
account = &Account{
|
||||
Address: out.Address,
|
||||
PubKey: PubKeyNil{},
|
||||
Sequence: 0,
|
||||
Balance: 0,
|
||||
}
|
||||
}
|
||||
accounts[string(out.Address)] = account
|
||||
}
|
||||
|
||||
+25
-8
@@ -2,9 +2,11 @@ package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"sort"
|
||||
|
||||
. "github.com/tendermint/tendermint/account"
|
||||
. "github.com/tendermint/tendermint/binary"
|
||||
. "github.com/tendermint/tendermint/block"
|
||||
. "github.com/tendermint/tendermint/common"
|
||||
db_ "github.com/tendermint/tendermint/db"
|
||||
@@ -24,9 +26,12 @@ func Tempfile(prefix string) (*os.File, string) {
|
||||
|
||||
func RandAccount(randBalance bool, minBalance uint64) (*Account, *PrivAccount) {
|
||||
privAccount := GenPrivAccount()
|
||||
account := NewAccount(privAccount.PubKey)
|
||||
account.Sequence = RandUint()
|
||||
account.Balance = minBalance
|
||||
account := &Account{
|
||||
Address: privAccount.PubKey.Address(),
|
||||
PubKey: privAccount.PubKey,
|
||||
Sequence: RandUint(),
|
||||
Balance: minBalance,
|
||||
}
|
||||
if randBalance {
|
||||
account.Balance += uint64(RandUint32())
|
||||
}
|
||||
@@ -53,20 +58,32 @@ func RandValidator(randBonded bool, minBonded uint64) (*ValidatorInfo, *PrivVali
|
||||
return valInfo, privVal
|
||||
}
|
||||
|
||||
// The first numValidators accounts are validators.
|
||||
func RandGenesisState(numAccounts int, randBalance bool, minBalance uint64, numValidators int, randBonded bool, minBonded uint64) (*State, []*PrivAccount, []*PrivValidator) {
|
||||
db := db_.NewMemDB()
|
||||
accounts := make([]*Account, numAccounts)
|
||||
accounts := make([]GenesisAccount, numAccounts)
|
||||
privAccounts := make([]*PrivAccount, numAccounts)
|
||||
for i := 0; i < numAccounts; i++ {
|
||||
account, privAccount := RandAccount(randBalance, minBalance)
|
||||
accounts[i], privAccounts[i] = account, privAccount
|
||||
accounts[i] = GenesisAccount{
|
||||
Address: base64.StdEncoding.EncodeToString(account.Address),
|
||||
Amount: account.Balance,
|
||||
}
|
||||
privAccounts[i] = privAccount
|
||||
}
|
||||
validators := make([]*ValidatorInfo, numValidators)
|
||||
validators := make([]GenesisValidator, numValidators)
|
||||
privValidators := make([]*PrivValidator, numValidators)
|
||||
for i := 0; i < numValidators; i++ {
|
||||
valInfo, privVal := RandValidator(randBonded, minBonded)
|
||||
validators[i] = valInfo
|
||||
validators[i] = GenesisValidator{
|
||||
PubKey: base64.StdEncoding.EncodeToString(BinaryBytes(valInfo.PubKey)),
|
||||
Amount: valInfo.FirstBondAmount,
|
||||
UnbondTo: []GenesisAccount{
|
||||
{
|
||||
Address: base64.StdEncoding.EncodeToString(valInfo.PubKey.Address()),
|
||||
Amount: valInfo.FirstBondAmount,
|
||||
},
|
||||
},
|
||||
}
|
||||
privValidators[i] = privVal
|
||||
}
|
||||
sort.Sort(PrivValidatorsByAddress(privValidators))
|
||||
|
||||
Reference in New Issue
Block a user