mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-04 15:17:02 +00:00
state save/load test.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"github.com/op/go-logging"
|
||||
)
|
||||
|
||||
var log = logging.MustGetLogger("state")
|
||||
|
||||
func init() {
|
||||
logging.SetFormatter(logging.MustStringFormatter("[%{level:.1s}] %{message}"))
|
||||
}
|
||||
|
||||
func SetStatesLogger(l *logging.Logger) {
|
||||
log = l
|
||||
}
|
||||
+22
-2
@@ -13,7 +13,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrStateInvalidSequenceNumber = errors.New("Error State invalid sequence number")
|
||||
ErrStateInvalidSequenceNumber = errors.New("Error State invalid sequence number")
|
||||
ErrStateInvalidValidationStateHash = errors.New("Error State invalid ValidationStateHash")
|
||||
ErrStateInvalidAccountStateHash = errors.New("Error State invalid AccountStateHash")
|
||||
|
||||
stateKey = []byte("stateKey")
|
||||
)
|
||||
@@ -33,6 +35,7 @@ func (abc accountBalanceCodec) Read(accBalBytes []byte) (interface{}, error) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// TODO: make it unsafe, remove mtx, and export fields?
|
||||
type State struct {
|
||||
mtx sync.Mutex
|
||||
db DB
|
||||
@@ -175,7 +178,17 @@ func (s *State) AppendBlock(b *Block) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Increment validator AccumPowers
|
||||
s.validators.IncrementAccum()
|
||||
|
||||
// State hashes should match
|
||||
if !bytes.Equal(s.validators.Hash(), b.ValidationStateHash) {
|
||||
return ErrStateInvalidValidationStateHash
|
||||
}
|
||||
if !bytes.Equal(s.accountBalances.Tree.Hash(), b.AccountStateHash) {
|
||||
return ErrStateInvalidAccountStateHash
|
||||
}
|
||||
|
||||
s.height = b.Height
|
||||
s.blockHash = b.Hash()
|
||||
return nil
|
||||
@@ -193,13 +206,20 @@ func (s *State) CommitTime() time.Time {
|
||||
return s.commitTime
|
||||
}
|
||||
|
||||
// The returned ValidatorSet gets mutated upon s.Commit*().
|
||||
// The returned ValidatorSet gets mutated upon s.ExecTx() and s.AppendBlock().
|
||||
// Caller should copy the returned set before mutating.
|
||||
func (s *State) Validators() *ValidatorSet {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
return s.validators
|
||||
}
|
||||
|
||||
func (s *State) BlockHash() []byte {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
return s.blockHash
|
||||
}
|
||||
|
||||
func (s *State) AccountBalance(accountId uint64) *AccountBalance {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
+33
-4
@@ -1,9 +1,12 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
. "github.com/tendermint/tendermint/blocks"
|
||||
. "github.com/tendermint/tendermint/common"
|
||||
. "github.com/tendermint/tendermint/config"
|
||||
. "github.com/tendermint/tendermint/db"
|
||||
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -38,9 +41,27 @@ func TestGenesisSaveLoad(t *testing.T) {
|
||||
|
||||
// Generate a state, save & load it.
|
||||
s0 := randGenesisState(10, 5)
|
||||
// Mutate the state to append one block.
|
||||
block := &Block{Data: Data{Txs: []Tx{}}}
|
||||
s0.AppendBlock(block)
|
||||
// Figure out what the next state hashes should be.
|
||||
s0ValsCopy := s0.Validators().Copy()
|
||||
s0ValsCopy.IncrementAccum()
|
||||
nextValidationStateHash := s0ValsCopy.Hash()
|
||||
nextAccountStateHash := s0.accountBalances.Tree.Hash()
|
||||
// Mutate the state to append one empty block.
|
||||
block := &Block{
|
||||
Header: Header{
|
||||
Network: Config.Network,
|
||||
Height: 1,
|
||||
ValidationStateHash: nextValidationStateHash,
|
||||
AccountStateHash: nextAccountStateHash,
|
||||
},
|
||||
Data: Data{
|
||||
Txs: []Tx{},
|
||||
},
|
||||
}
|
||||
err := s0.AppendBlock(block)
|
||||
if err != nil {
|
||||
t.Error("Error appending initial block:", err)
|
||||
}
|
||||
|
||||
// Save s0, load s1.
|
||||
commitTime := time.Now()
|
||||
@@ -53,7 +74,15 @@ func TestGenesisSaveLoad(t *testing.T) {
|
||||
t.Error("CommitTime was not the same")
|
||||
}
|
||||
// Compare height & blockHash
|
||||
// XXX
|
||||
if s0.Height() != 1 {
|
||||
t.Error("s0 Height should be 1, got", s0.Height())
|
||||
}
|
||||
if s0.Height() != s1.Height() {
|
||||
t.Error("Height mismatch")
|
||||
}
|
||||
if !bytes.Equal(s0.BlockHash(), s1.BlockHash()) {
|
||||
t.Error("BlockHash mismatch")
|
||||
}
|
||||
// Compare Validators
|
||||
s0Vals := s0.Validators()
|
||||
s1Vals := s1.Validators()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
. "github.com/tendermint/tendermint/binary"
|
||||
. "github.com/tendermint/tendermint/common"
|
||||
"github.com/tendermint/tendermint/merkle"
|
||||
)
|
||||
|
||||
// Holds state for a Validator at a given height+round.
|
||||
@@ -155,3 +156,17 @@ func (vset *ValidatorSet) GetProposer() (proposer *Validator) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Should uniquely determine the state of the ValidatorSet.
|
||||
func (vset *ValidatorSet) Hash() []byte {
|
||||
ids := []uint64{}
|
||||
for id, _ := range vset.validators {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
UInt64Slice(ids).Sort()
|
||||
sortedValidators := make([]Binary, len(ids))
|
||||
for i, id := range ids {
|
||||
sortedValidators[i] = vset.validators[id]
|
||||
}
|
||||
return merkle.HashFromBinaries(sortedValidators)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user