mirror of
https://github.com/tendermint/tendermint.git
synced 2025-12-23 06:15:19 +00:00
state: proto migration (#4972)
## Description the second part of state proto migration Closes: #XXX
This commit is contained in:
@@ -6,13 +6,9 @@ import (
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
//"strconv"
|
||||
//"strings"
|
||||
"time"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
//auto "github.com/tendermint/tendermint/libs/autofile"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/clist"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -64,7 +65,7 @@ func (emptyEvidencePool) Header(int64) *types.Header { return nil }
|
||||
// Useful because we don't want to call Commit() twice for the same block on
|
||||
// the real app.
|
||||
|
||||
func newMockProxyApp(appHash []byte, abciResponses *sm.ABCIResponses) proxy.AppConnConsensus {
|
||||
func newMockProxyApp(appHash []byte, abciResponses *tmstate.ABCIResponses) proxy.AppConnConsensus {
|
||||
clientCreator := proxy.NewLocalClientCreator(&mockProxyApp{
|
||||
appHash: appHash,
|
||||
abciResponses: abciResponses,
|
||||
@@ -82,7 +83,7 @@ type mockProxyApp struct {
|
||||
|
||||
appHash []byte
|
||||
txCount int
|
||||
abciResponses *sm.ABCIResponses
|
||||
abciResponses *tmstate.ABCIResponses
|
||||
}
|
||||
|
||||
func (mock *mockProxyApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -176,6 +177,7 @@ LOOP:
|
||||
csWal, err := cs.OpenWAL(walFile)
|
||||
require.NoError(t, err)
|
||||
crashingWal.next = csWal
|
||||
|
||||
// reset the message counter
|
||||
crashingWal.msgIndex = 1
|
||||
cs.wal = crashingWal
|
||||
@@ -577,13 +579,13 @@ func TestMockProxyApp(t *testing.T) {
|
||||
txIndex := 0
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
abciResWithEmptyDeliverTx := new(sm.ABCIResponses)
|
||||
abciResWithEmptyDeliverTx := new(tmstate.ABCIResponses)
|
||||
abciResWithEmptyDeliverTx.DeliverTxs = make([]*abci.ResponseDeliverTx, 0)
|
||||
abciResWithEmptyDeliverTx.DeliverTxs = append(abciResWithEmptyDeliverTx.DeliverTxs, &abci.ResponseDeliverTx{})
|
||||
|
||||
// called when saveABCIResponses:
|
||||
bytes := cdc.MustMarshalBinaryBare(abciResWithEmptyDeliverTx)
|
||||
loadedAbciRes := new(sm.ABCIResponses)
|
||||
loadedAbciRes := new(tmstate.ABCIResponses)
|
||||
|
||||
// this also happens sm.LoadABCIResponses
|
||||
err := cdc.UnmarshalBinaryBare(bytes, loadedAbciRes)
|
||||
@@ -591,7 +593,7 @@ func TestMockProxyApp(t *testing.T) {
|
||||
|
||||
mock := newMockProxyApp([]byte("mock_hash"), loadedAbciRes)
|
||||
|
||||
abciRes := new(sm.ABCIResponses)
|
||||
abciRes := new(tmstate.ABCIResponses)
|
||||
abciRes.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs))
|
||||
// Execute transactions and get hash.
|
||||
proxyCb := func(req *abci.Request, res *abci.Response) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -283,19 +284,21 @@ func TestRecoverPendingEvidence(t *testing.T) {
|
||||
|
||||
func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
|
||||
stateDB := dbm.NewMemDB()
|
||||
pk := ed25519.GenPrivKey().PubKey()
|
||||
|
||||
// create validator set and state
|
||||
validator := &types.Validator{Address: valAddr, VotingPower: 100, PubKey: pk}
|
||||
valSet := &types.ValidatorSet{
|
||||
Validators: []*types.Validator{
|
||||
{Address: valAddr, VotingPower: 0},
|
||||
},
|
||||
Validators: []*types.Validator{validator},
|
||||
Proposer: validator,
|
||||
}
|
||||
|
||||
state := sm.State{
|
||||
LastBlockHeight: height,
|
||||
LastBlockTime: tmtime.Now(),
|
||||
LastValidators: valSet,
|
||||
Validators: valSet,
|
||||
NextValidators: valSet.CopyIncrementProposerPriority(1),
|
||||
LastValidators: valSet,
|
||||
LastHeightValidatorsChanged: 1,
|
||||
ConsensusParams: tmproto.ConsensusParams{
|
||||
Block: tmproto.BlockParams{
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -69,7 +70,7 @@ func TestBlockchainInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockResults(t *testing.T) {
|
||||
results := &sm.ABCIResponses{
|
||||
results := &tmstate.ABCIResponses{
|
||||
DeliverTxs: []*abci.ResponseDeliverTx{
|
||||
{Code: 0, Data: []byte{0x01}, Log: "ok"},
|
||||
{Code: 0, Data: []byte{0x02}, Log: "ok"},
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/fail"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -252,11 +253,13 @@ func execBlockOnProxyApp(
|
||||
proxyAppConn proxy.AppConnConsensus,
|
||||
block *types.Block,
|
||||
stateDB dbm.DB,
|
||||
) (*ABCIResponses, error) {
|
||||
) (*tmstate.ABCIResponses, error) {
|
||||
var validTxs, invalidTxs = 0, 0
|
||||
|
||||
txIndex := 0
|
||||
abciResponses := NewABCIResponses(block)
|
||||
abciResponses := new(tmstate.ABCIResponses)
|
||||
dtxs := make([]*abci.ResponseDeliverTx, len(block.Txs))
|
||||
abciResponses.DeliverTxs = dtxs
|
||||
|
||||
// Execute transactions and get hash.
|
||||
proxyCb := func(req *abci.Request, res *abci.Response) {
|
||||
@@ -391,7 +394,7 @@ func updateState(
|
||||
state State,
|
||||
blockID types.BlockID,
|
||||
header *types.Header,
|
||||
abciResponses *ABCIResponses,
|
||||
abciResponses *tmstate.ABCIResponses,
|
||||
validatorUpdates []*types.Validator,
|
||||
) (State, error) {
|
||||
|
||||
@@ -444,7 +447,7 @@ func updateState(
|
||||
LastHeightValidatorsChanged: lastHeightValsChanged,
|
||||
ConsensusParams: nextParams,
|
||||
LastHeightConsensusParamsChanged: lastHeightParamsChanged,
|
||||
LastResultsHash: abciResponses.ResultsHash(),
|
||||
LastResultsHash: ABCIResponsesResultsHash(*abciResponses),
|
||||
AppHash: nil,
|
||||
}, nil
|
||||
}
|
||||
@@ -456,7 +459,7 @@ func fireEvents(
|
||||
logger log.Logger,
|
||||
eventBus types.BlockEventPublisher,
|
||||
block *types.Block,
|
||||
abciResponses *ABCIResponses,
|
||||
abciResponses *tmstate.ABCIResponses,
|
||||
validatorUpdates []*types.Validator,
|
||||
) {
|
||||
eventBus.PublishEventNewBlock(types.EventDataNewBlock{
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@@ -27,7 +28,7 @@ func UpdateState(
|
||||
state State,
|
||||
blockID types.BlockID,
|
||||
header *types.Header,
|
||||
abciResponses *ABCIResponses,
|
||||
abciResponses *tmstate.ABCIResponses,
|
||||
validatorUpdates []*types.Validator,
|
||||
) (State, error) {
|
||||
return updateState(state, blockID, header, abciResponses, validatorUpdates)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -121,6 +122,7 @@ func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValida
|
||||
s.LastValidators = s.Validators.Copy()
|
||||
sm.SaveState(stateDB, s)
|
||||
}
|
||||
|
||||
return s, stateDB, privVals
|
||||
}
|
||||
|
||||
@@ -166,13 +168,12 @@ func makeConsensusParams(
|
||||
func makeHeaderPartsResponsesValPubKeyChange(
|
||||
state sm.State,
|
||||
pubkey crypto.PubKey,
|
||||
) (types.Header, types.BlockID, *sm.ABCIResponses) {
|
||||
) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
|
||||
// If the pubkey is new, remove the old and add the new.
|
||||
_, val := state.NextValidators.GetByIndex(0)
|
||||
if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
|
||||
@@ -190,10 +191,10 @@ func makeHeaderPartsResponsesValPubKeyChange(
|
||||
func makeHeaderPartsResponsesValPowerChange(
|
||||
state sm.State,
|
||||
power int64,
|
||||
) (types.Header, types.BlockID, *sm.ABCIResponses) {
|
||||
) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
|
||||
@@ -213,10 +214,10 @@ func makeHeaderPartsResponsesValPowerChange(
|
||||
func makeHeaderPartsResponsesParams(
|
||||
state sm.State,
|
||||
params tmproto.ConsensusParams,
|
||||
) (types.Header, types.BlockID, *sm.ABCIResponses) {
|
||||
) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(¶ms)},
|
||||
}
|
||||
return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses
|
||||
|
||||
124
state/state.go
124
state/state.go
@@ -2,10 +2,14 @@ package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
tmversion "github.com/tendermint/tendermint/proto/version"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -20,20 +24,11 @@ var (
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Version is for versioning the State.
|
||||
// It holds the Block and App version needed for making blocks,
|
||||
// and the software version to support upgrades to the format of
|
||||
// the State as stored on disk.
|
||||
type Version struct {
|
||||
Consensus tmversion.Consensus
|
||||
Software string
|
||||
}
|
||||
|
||||
// InitStateVersion sets the Consensus.Block and Software versions,
|
||||
// but leaves the Consensus.App version blank.
|
||||
// The Consensus.App version will be set during the Handshake, once
|
||||
// we hear from the app what protocol version it is running.
|
||||
var InitStateVersion = Version{
|
||||
var InitStateVersion = tmstate.Version{
|
||||
Consensus: tmversion.Consensus{
|
||||
Block: version.BlockProtocol,
|
||||
App: 0,
|
||||
@@ -51,7 +46,7 @@ var InitStateVersion = Version{
|
||||
// Instead, use state.Copy() or state.NextState(...).
|
||||
// NOTE: not goroutine-safe.
|
||||
type State struct {
|
||||
Version Version
|
||||
Version tmstate.Version
|
||||
|
||||
// immutable
|
||||
ChainID string
|
||||
@@ -86,6 +81,7 @@ type State struct {
|
||||
|
||||
// Copy makes a copy of the State for mutating.
|
||||
func (state State) Copy() State {
|
||||
|
||||
return State{
|
||||
Version: state.Version,
|
||||
ChainID: state.ChainID,
|
||||
@@ -114,9 +110,18 @@ func (state State) Equals(state2 State) bool {
|
||||
return bytes.Equal(sbz, s2bz)
|
||||
}
|
||||
|
||||
// Bytes serializes the State using go-amino.
|
||||
// Bytes serializes the State using protobuf.
|
||||
// It panics if either casting to protobuf or serialization fails.
|
||||
func (state State) Bytes() []byte {
|
||||
return cdc.MustMarshalBinaryBare(state)
|
||||
sm, err := state.ToProto()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bz, err := proto.Marshal(sm)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return bz
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the State is equal to the empty State.
|
||||
@@ -124,6 +129,99 @@ func (state State) IsEmpty() bool {
|
||||
return state.Validators == nil // XXX can't compare to Empty
|
||||
}
|
||||
|
||||
//ToProto takes the local state type and returns the equivalent proto type
|
||||
func (state *State) ToProto() (*tmstate.State, error) {
|
||||
if state == nil {
|
||||
return nil, errors.New("state is nil")
|
||||
}
|
||||
|
||||
sm := new(tmstate.State)
|
||||
|
||||
sm.Version = state.Version
|
||||
sm.ChainID = state.ChainID
|
||||
sm.LastBlockHeight = state.LastBlockHeight
|
||||
|
||||
sm.LastBlockID = state.LastBlockID.ToProto()
|
||||
sm.LastBlockTime = state.LastBlockTime
|
||||
vals, err := state.Validators.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sm.Validators = vals
|
||||
|
||||
nVals, err := state.NextValidators.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sm.NextValidators = nVals
|
||||
|
||||
if state.LastBlockHeight >= 1 { // At Block 1 LastValidators is nil
|
||||
lVals, err := state.LastValidators.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sm.LastValidators = lVals
|
||||
}
|
||||
|
||||
sm.LastHeightValidatorsChanged = state.LastHeightValidatorsChanged
|
||||
sm.ConsensusParams = state.ConsensusParams
|
||||
sm.LastHeightConsensusParamsChanged = state.LastHeightConsensusParamsChanged
|
||||
sm.LastResultsHash = state.LastResultsHash
|
||||
sm.AppHash = state.AppHash
|
||||
|
||||
return sm, nil
|
||||
}
|
||||
|
||||
// StateFromProto takes a state proto message & returns the local state type
|
||||
func StateFromProto(pb *tmstate.State) (*State, error) { //nolint:golint
|
||||
if pb == nil {
|
||||
return nil, errors.New("nil State")
|
||||
}
|
||||
|
||||
state := new(State)
|
||||
|
||||
state.Version = pb.Version
|
||||
state.ChainID = pb.ChainID
|
||||
|
||||
bi, err := types.BlockIDFromProto(&pb.LastBlockID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.LastBlockID = *bi
|
||||
state.LastBlockHeight = pb.LastBlockHeight
|
||||
state.LastBlockTime = pb.LastBlockTime
|
||||
|
||||
vals, err := types.ValidatorSetFromProto(pb.Validators)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.Validators = vals
|
||||
|
||||
nVals, err := types.ValidatorSetFromProto(pb.NextValidators)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.NextValidators = nVals
|
||||
|
||||
if state.LastBlockHeight >= 1 { // At Block 1 LastValidators is nil
|
||||
lVals, err := types.ValidatorSetFromProto(pb.LastValidators)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.LastValidators = lVals
|
||||
} else {
|
||||
state.LastValidators = types.NewValidatorSet(nil)
|
||||
}
|
||||
|
||||
state.LastHeightValidatorsChanged = pb.LastHeightValidatorsChanged
|
||||
state.ConsensusParams = pb.ConsensusParams
|
||||
state.LastHeightConsensusParamsChanged = pb.LastHeightConsensusParamsChanged
|
||||
state.LastResultsHash = pb.LastResultsHash
|
||||
state.AppHash = pb.AppHash
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Create a block from the latest state
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -49,6 +50,7 @@ func TestStateCopy(t *testing.T) {
|
||||
stateCopy, state))
|
||||
|
||||
stateCopy.LastBlockHeight++
|
||||
stateCopy.LastValidators = state.Validators
|
||||
assert.False(state.Equals(stateCopy), fmt.Sprintf(`expected states to be different. got same
|
||||
%v`, state))
|
||||
}
|
||||
@@ -73,6 +75,7 @@ func TestStateSaveLoad(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
state.LastBlockHeight++
|
||||
state.LastValidators = state.Validators
|
||||
sm.SaveState(stateDB, state)
|
||||
|
||||
loadedState := sm.LoadState(stateDB)
|
||||
@@ -91,7 +94,11 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
|
||||
|
||||
// Build mock responses.
|
||||
block := makeBlock(state, 2)
|
||||
abciResponses := sm.NewABCIResponses(block)
|
||||
|
||||
abciResponses := new(tmstate.ABCIResponses)
|
||||
dtxs := make([]*abci.ResponseDeliverTx, 2)
|
||||
abciResponses.DeliverTxs = dtxs
|
||||
|
||||
abciResponses.DeliverTxs[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil}
|
||||
abciResponses.DeliverTxs[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil}
|
||||
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
|
||||
@@ -148,6 +155,10 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
4: {
|
||||
[]*abci.ResponseDeliverTx{nil},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
// Query all before, this should return error.
|
||||
@@ -160,7 +171,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
|
||||
// Add all cases.
|
||||
for i, tc := range cases {
|
||||
h := int64(i + 1) // last block height, one below what we save
|
||||
responses := &sm.ABCIResponses{
|
||||
responses := &tmstate.ABCIResponses{
|
||||
DeliverTxs: tc.added,
|
||||
EndBlock: &abci.ResponseEndBlock{},
|
||||
}
|
||||
@@ -172,7 +183,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
|
||||
h := int64(i + 1)
|
||||
res, err := sm.LoadABCIResponses(stateDB, h)
|
||||
assert.NoError(err, "%d", i)
|
||||
assert.Equal(tc.expected.Hash(), res.ResultsHash(), "%d", i)
|
||||
assert.Equal(tc.expected.Hash(), sm.ABCIResponsesResultsHash(*res), "%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +418,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -518,7 +529,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
|
||||
// no updates:
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -618,7 +629,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
// no changes in voting power and both validators have same voting power
|
||||
// -> proposers should alternate:
|
||||
oldState := updatedState3
|
||||
abciResponses = &sm.ABCIResponses{
|
||||
abciResponses = &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -633,7 +644,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
// no validator updates:
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -690,7 +701,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
oldState := state
|
||||
for i := 0; i < 10; i++ {
|
||||
// no updates:
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -719,7 +730,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
firstAddedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(firstAddedValPubKey), Power: firstAddedValVotingPower}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal})
|
||||
assert.NoError(t, err)
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}},
|
||||
}
|
||||
block := makeBlock(oldState, oldState.LastBlockHeight+1)
|
||||
@@ -730,7 +741,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
lastState := updatedState
|
||||
for i := 0; i < 200; i++ {
|
||||
// no updates:
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -764,7 +775,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal})
|
||||
assert.NoError(t, err)
|
||||
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}},
|
||||
}
|
||||
block := makeBlock(oldState, oldState.LastBlockHeight+1)
|
||||
@@ -776,7 +787,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
|
||||
// remove genesis validator:
|
||||
removeGenesisVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(genesisPubKey), Power: 0}
|
||||
abciResponses = &sm.ABCIResponses{
|
||||
abciResponses = &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}},
|
||||
}
|
||||
block = makeBlock(oldState, oldState.LastBlockHeight+1)
|
||||
@@ -794,7 +805,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
count := 0
|
||||
isProposerUnchanged := true
|
||||
for isProposerUnchanged {
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -817,7 +828,7 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
proposers := make([]*types.Validator, numVals)
|
||||
for i := 0; i < 100; i++ {
|
||||
// no updates:
|
||||
abciResponses := &sm.ABCIResponses{
|
||||
abciResponses := &tmstate.ABCIResponses{
|
||||
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||
@@ -980,7 +991,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
|
||||
for _, testCase := range testCases {
|
||||
p, err := sm.LoadConsensusParams(stateDB, testCase.height)
|
||||
assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
|
||||
assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
|
||||
assert.EqualValues(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
|
||||
height %d`, testCase.height))
|
||||
}
|
||||
}
|
||||
@@ -1019,3 +1030,36 @@ func TestApplyUpdates(t *testing.T) {
|
||||
assert.Equal(t, tc.expected, res, "case %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStateProto(t *testing.T) {
|
||||
tearDown, _, state := setupTestCase(t)
|
||||
defer tearDown(t)
|
||||
|
||||
tc := []struct {
|
||||
testName string
|
||||
state *sm.State
|
||||
expPass bool
|
||||
}{
|
||||
{"empty state", &sm.State{}, false},
|
||||
{"nil failure state", nil, false},
|
||||
{"success state", &state, true},
|
||||
}
|
||||
|
||||
for _, tt := range tc {
|
||||
tt := tt
|
||||
pbs, err := tt.state.ToProto()
|
||||
if !tt.expPass {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err, tt.testName)
|
||||
}
|
||||
|
||||
smt, err := sm.StateFromProto(pbs)
|
||||
if tt.expPass {
|
||||
require.NoError(t, err, tt.testName)
|
||||
require.Equal(t, tt.state, smt, tt.testName)
|
||||
} else {
|
||||
require.Error(t, err, tt.testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
178
state/store.go
178
state/store.go
@@ -3,11 +3,13 @@ package state
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@@ -56,6 +58,7 @@ func LoadStateFromDBOrGenesisFile(stateDB dbm.DB, genesisFilePath string) (State
|
||||
// to the database.
|
||||
func LoadStateFromDBOrGenesisDoc(stateDB dbm.DB, genesisDoc *types.GenesisDoc) (State, error) {
|
||||
state := LoadState(stateDB)
|
||||
|
||||
if state.IsEmpty() {
|
||||
var err error
|
||||
state, err = MakeGenesisState(genesisDoc)
|
||||
@@ -82,15 +85,21 @@ func loadState(db dbm.DB, key []byte) (state State) {
|
||||
return state
|
||||
}
|
||||
|
||||
err = cdc.UnmarshalBinaryBare(buf, &state)
|
||||
sp := new(tmstate.State)
|
||||
|
||||
err = proto.Unmarshal(buf, sp)
|
||||
if err != nil {
|
||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||
tmos.Exit(fmt.Sprintf(`LoadState: Data has been corrupted or its spec has changed:
|
||||
%v\n`, err))
|
||||
%v\n`, err))
|
||||
}
|
||||
// TODO: ensure that buf is completely read.
|
||||
|
||||
return state
|
||||
sm, err := StateFromProto(sp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return *sm
|
||||
}
|
||||
|
||||
// SaveState persists the State, the ValidatorsInfo, and the ConsensusParamsInfo to the database.
|
||||
@@ -110,6 +119,7 @@ func saveState(db dbm.DB, state State, key []byte) {
|
||||
}
|
||||
// Save next validators.
|
||||
saveValidatorsInfo(db, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
||||
|
||||
// Save next consensus params.
|
||||
saveConsensusParamsInfo(db, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
|
||||
err := db.SetSync(key, state.Bytes())
|
||||
@@ -130,15 +140,6 @@ func BootstrapState(db dbm.DB, state State) error {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// ABCIResponses retains the responses
|
||||
// of the various ABCI calls during block processing.
|
||||
// It is persisted to disk for each height before calling Commit.
|
||||
type ABCIResponses struct {
|
||||
DeliverTxs []*abci.ResponseDeliverTx `json:"deliver_txs"`
|
||||
EndBlock *abci.ResponseEndBlock `json:"end_block"`
|
||||
BeginBlock *abci.ResponseBeginBlock `json:"begin_block"`
|
||||
}
|
||||
|
||||
// PruneStates deletes states between the given heights (including from, excluding to). It is not
|
||||
// guaranteed to delete all states, since the last checkpointed state and states being pointed to by
|
||||
// e.g. `LastHeightChanged` must remain. The state at to must also exist.
|
||||
@@ -187,12 +188,25 @@ func PruneStates(db dbm.DB, from int64, to int64) error {
|
||||
if keepVals[h] {
|
||||
v := loadValidatorsInfo(db, h)
|
||||
if v.ValidatorSet == nil {
|
||||
v.ValidatorSet, err = LoadValidators(db, h)
|
||||
|
||||
vip, err := LoadValidators(db, h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pvi, err := vip.ToProto()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.ValidatorSet = pvi
|
||||
v.LastHeightChanged = h
|
||||
batch.Set(calcValidatorsKey(h), v.Bytes())
|
||||
|
||||
bz, err := v.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
batch.Set(calcValidatorsKey(h), bz)
|
||||
}
|
||||
} else {
|
||||
batch.Delete(calcValidatorsKey(h))
|
||||
@@ -206,7 +220,11 @@ func PruneStates(db dbm.DB, from int64, to int64) error {
|
||||
return err
|
||||
}
|
||||
p.LastHeightChanged = h
|
||||
batch.Set(calcConsensusParamsKey(h), p.Bytes())
|
||||
bz, err := p.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
batch.Set(calcConsensusParamsKey(h), bz)
|
||||
}
|
||||
} else {
|
||||
batch.Delete(calcConsensusParamsKey(h))
|
||||
@@ -235,42 +253,27 @@ func PruneStates(db dbm.DB, from int64, to int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewABCIResponses returns a new ABCIResponses
|
||||
func NewABCIResponses(block *types.Block) *ABCIResponses {
|
||||
resDeliverTxs := make([]*abci.ResponseDeliverTx, len(block.Data.Txs))
|
||||
if len(block.Data.Txs) == 0 {
|
||||
// This makes Amino encoding/decoding consistent.
|
||||
resDeliverTxs = nil
|
||||
}
|
||||
return &ABCIResponses{
|
||||
DeliverTxs: resDeliverTxs,
|
||||
}
|
||||
}
|
||||
|
||||
// Bytes serializes the ABCIResponse using go-amino.
|
||||
func (arz *ABCIResponses) Bytes() []byte {
|
||||
return cdc.MustMarshalBinaryBare(arz)
|
||||
}
|
||||
|
||||
func (arz *ABCIResponses) ResultsHash() []byte {
|
||||
results := types.NewResults(arz.DeliverTxs)
|
||||
// ABCIResponsesResultsHash returns the merkle hash of the deliverTxs within ABCIResponses
|
||||
func ABCIResponsesResultsHash(ar tmstate.ABCIResponses) []byte {
|
||||
results := types.NewResults(ar.DeliverTxs)
|
||||
return results.Hash()
|
||||
}
|
||||
|
||||
// LoadABCIResponses loads the ABCIResponses for the given height from the database.
|
||||
// This is useful for recovering from crashes where we called app.Commit and before we called
|
||||
// s.Save(). It can also be used to produce Merkle proofs of the result of txs.
|
||||
func LoadABCIResponses(db dbm.DB, height int64) (*ABCIResponses, error) {
|
||||
func LoadABCIResponses(db dbm.DB, height int64) (*tmstate.ABCIResponses, error) {
|
||||
buf, err := db.Get(calcABCIResponsesKey(height))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(buf) == 0 {
|
||||
|
||||
return nil, ErrNoABCIResponsesForHeight{height}
|
||||
}
|
||||
|
||||
abciResponses := new(ABCIResponses)
|
||||
err = cdc.UnmarshalBinaryBare(buf, abciResponses)
|
||||
abciResponses := new(tmstate.ABCIResponses)
|
||||
err = abciResponses.Unmarshal(buf)
|
||||
if err != nil {
|
||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||
tmos.Exit(fmt.Sprintf(`LoadABCIResponses: Data has been corrupted or its spec has
|
||||
@@ -287,23 +290,25 @@ func LoadABCIResponses(db dbm.DB, height int64) (*ABCIResponses, error) {
|
||||
// Merkle proofs.
|
||||
//
|
||||
// Exposed for testing.
|
||||
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
|
||||
db.SetSync(calcABCIResponsesKey(height), abciResponses.Bytes())
|
||||
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *tmstate.ABCIResponses) {
|
||||
var dtxs []*abci.ResponseDeliverTx
|
||||
//strip nil values,
|
||||
for _, tx := range abciResponses.DeliverTxs {
|
||||
if tx != nil {
|
||||
dtxs = append(dtxs, tx)
|
||||
}
|
||||
}
|
||||
abciResponses.DeliverTxs = dtxs
|
||||
|
||||
bz, err := abciResponses.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
db.SetSync(calcABCIResponsesKey(height), bz)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// ValidatorsInfo represents the latest validator set, or the last height it changed
|
||||
type ValidatorsInfo struct {
|
||||
ValidatorSet *types.ValidatorSet
|
||||
LastHeightChanged int64
|
||||
}
|
||||
|
||||
// Bytes serializes the ValidatorsInfo using go-amino.
|
||||
func (valInfo *ValidatorsInfo) Bytes() []byte {
|
||||
return cdc.MustMarshalBinaryBare(valInfo)
|
||||
}
|
||||
|
||||
// LoadValidators loads the ValidatorSet for a given height.
|
||||
// Returns ErrNoValSetForHeight if the validator set can't be found for this height.
|
||||
func LoadValidators(db dbm.DB, height int64) (*types.ValidatorSet, error) {
|
||||
@@ -322,11 +327,28 @@ func LoadValidators(db dbm.DB, height int64) (*types.ValidatorSet, error) {
|
||||
),
|
||||
)
|
||||
}
|
||||
valInfo2.ValidatorSet.IncrementProposerPriority(tmmath.SafeConvertInt32(height - lastStoredHeight)) // mutate
|
||||
|
||||
vs, err := types.ValidatorSetFromProto(valInfo2.ValidatorSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vs.IncrementProposerPriority(tmmath.SafeConvertInt32(height - lastStoredHeight)) // mutate
|
||||
vi2, err := vs.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valInfo2.ValidatorSet = vi2
|
||||
valInfo = valInfo2
|
||||
}
|
||||
|
||||
return valInfo.ValidatorSet, nil
|
||||
vip, err := types.ValidatorSetFromProto(valInfo.ValidatorSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vip, nil
|
||||
}
|
||||
|
||||
func lastStoredHeightFor(height, lastHeightChanged int64) int64 {
|
||||
@@ -335,17 +357,18 @@ func lastStoredHeightFor(height, lastHeightChanged int64) int64 {
|
||||
}
|
||||
|
||||
// CONTRACT: Returned ValidatorsInfo can be mutated.
|
||||
func loadValidatorsInfo(db dbm.DB, height int64) *ValidatorsInfo {
|
||||
func loadValidatorsInfo(db dbm.DB, height int64) *tmstate.ValidatorsInfo {
|
||||
buf, err := db.Get(calcValidatorsKey(height))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(buf) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := new(ValidatorsInfo)
|
||||
err = cdc.UnmarshalBinaryBare(buf, v)
|
||||
v := new(tmstate.ValidatorsInfo)
|
||||
err = v.Unmarshal(buf)
|
||||
if err != nil {
|
||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||
tmos.Exit(fmt.Sprintf(`LoadValidators: Data has been corrupted or its spec has changed:
|
||||
@@ -365,29 +388,30 @@ func saveValidatorsInfo(db dbm.DB, height, lastHeightChanged int64, valSet *type
|
||||
if lastHeightChanged > height {
|
||||
panic("LastHeightChanged cannot be greater than ValidatorsInfo height")
|
||||
}
|
||||
valInfo := &ValidatorsInfo{
|
||||
valInfo := &tmstate.ValidatorsInfo{
|
||||
LastHeightChanged: lastHeightChanged,
|
||||
}
|
||||
// Only persist validator set if it was updated or checkpoint height (see
|
||||
// valSetCheckpointInterval) is reached.
|
||||
if height == lastHeightChanged || height%valSetCheckpointInterval == 0 {
|
||||
valInfo.ValidatorSet = valSet
|
||||
pv, err := valSet.ToProto()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
valInfo.ValidatorSet = pv
|
||||
}
|
||||
db.Set(calcValidatorsKey(height), valInfo.Bytes())
|
||||
|
||||
bz, err := valInfo.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
db.Set(calcValidatorsKey(height), bz)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// ConsensusParamsInfo represents the latest consensus params, or the last height it changed
|
||||
type ConsensusParamsInfo struct {
|
||||
ConsensusParams tmproto.ConsensusParams
|
||||
LastHeightChanged int64
|
||||
}
|
||||
|
||||
// Bytes serializes the ConsensusParamsInfo using go-amino.
|
||||
func (params ConsensusParamsInfo) Bytes() []byte {
|
||||
return cdc.MustMarshalBinaryBare(params)
|
||||
}
|
||||
|
||||
// LoadConsensusParams loads the ConsensusParams for a given height.
|
||||
func LoadConsensusParams(db dbm.DB, height int64) (tmproto.ConsensusParams, error) {
|
||||
@@ -409,13 +433,14 @@ func LoadConsensusParams(db dbm.DB, height int64) (tmproto.ConsensusParams, erro
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
paramsInfo = paramsInfo2
|
||||
}
|
||||
|
||||
return paramsInfo.ConsensusParams, nil
|
||||
}
|
||||
|
||||
func loadConsensusParamsInfo(db dbm.DB, height int64) *ConsensusParamsInfo {
|
||||
func loadConsensusParamsInfo(db dbm.DB, height int64) *tmstate.ConsensusParamsInfo {
|
||||
buf, err := db.Get(calcConsensusParamsKey(height))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -424,9 +449,8 @@ func loadConsensusParamsInfo(db dbm.DB, height int64) *ConsensusParamsInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
paramsInfo := new(ConsensusParamsInfo)
|
||||
err = cdc.UnmarshalBinaryBare(buf, paramsInfo)
|
||||
if err != nil {
|
||||
paramsInfo := new(tmstate.ConsensusParamsInfo)
|
||||
if err = paramsInfo.Unmarshal(buf); err != nil {
|
||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||
tmos.Exit(fmt.Sprintf(`LoadConsensusParams: Data has been corrupted or its spec has changed:
|
||||
%v\n`, err))
|
||||
@@ -441,11 +465,17 @@ func loadConsensusParamsInfo(db dbm.DB, height int64) *ConsensusParamsInfo {
|
||||
// If the consensus params did not change after processing the latest block,
|
||||
// only the last height for which they changed is persisted.
|
||||
func saveConsensusParamsInfo(db dbm.DB, nextHeight, changeHeight int64, params tmproto.ConsensusParams) {
|
||||
paramsInfo := &ConsensusParamsInfo{
|
||||
paramsInfo := &tmstate.ConsensusParamsInfo{
|
||||
LastHeightChanged: changeHeight,
|
||||
}
|
||||
|
||||
if changeHeight == nextHeight {
|
||||
paramsInfo.ConsensusParams = params
|
||||
}
|
||||
db.Set(calcConsensusParamsKey(nextHeight), paramsInfo.Bytes())
|
||||
bz, err := paramsInfo.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
db.Set(calcConsensusParamsKey(nextHeight), bz)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ import (
|
||||
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
tmproto "github.com/tendermint/tendermint/proto/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -48,6 +51,7 @@ func BenchmarkLoadValidators(b *testing.B) {
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
state.Validators = genValSet(valSetSize)
|
||||
state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
|
||||
sm.SaveState(stateDB, state)
|
||||
@@ -91,10 +95,11 @@ func TestPruneStates(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
pk := ed25519.GenPrivKey().PubKey()
|
||||
|
||||
// Generate a bunch of state data. Validators change for heights ending with 3, and
|
||||
// parameters when ending with 5.
|
||||
validator := &types.Validator{Address: []byte{1, 2, 3}, VotingPower: 100}
|
||||
validator := &types.Validator{Address: []byte{1, 2, 3}, VotingPower: 100, PubKey: pk}
|
||||
validatorSet := &types.ValidatorSet{
|
||||
Validators: []*types.Validator{validator},
|
||||
Proposer: validator,
|
||||
@@ -110,7 +115,7 @@ func TestPruneStates(t *testing.T) {
|
||||
paramsChanged = h
|
||||
}
|
||||
|
||||
sm.SaveState(db, sm.State{
|
||||
state := sm.State{
|
||||
LastBlockHeight: h - 1,
|
||||
Validators: validatorSet,
|
||||
NextValidators: validatorSet,
|
||||
@@ -119,17 +124,21 @@ func TestPruneStates(t *testing.T) {
|
||||
},
|
||||
LastHeightValidatorsChanged: valsChanged,
|
||||
LastHeightConsensusParamsChanged: paramsChanged,
|
||||
})
|
||||
sm.SaveABCIResponses(db, h, sm.NewABCIResponses(&types.Block{
|
||||
Header: types.Header{Height: h},
|
||||
Data: types.Data{
|
||||
Txs: types.Txs{
|
||||
[]byte{1},
|
||||
[]byte{2},
|
||||
[]byte{3},
|
||||
},
|
||||
}
|
||||
|
||||
if state.LastBlockHeight >= 1 {
|
||||
state.LastValidators = state.Validators
|
||||
}
|
||||
|
||||
sm.SaveState(db, state)
|
||||
|
||||
sm.SaveABCIResponses(db, h, &tmstate.ABCIResponses{
|
||||
DeliverTxs: []*abci.ResponseDeliverTx{
|
||||
{Data: []byte{1}},
|
||||
{Data: []byte{2}},
|
||||
{Data: []byte{3}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
// Test assertions
|
||||
|
||||
@@ -40,7 +40,6 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
|
||||
block.Height,
|
||||
)
|
||||
}
|
||||
|
||||
// Validate prev block info.
|
||||
if !block.LastBlockID.Equals(state.LastBlockID) {
|
||||
return fmt.Errorf("wrong Block.Header.LastBlockID. Expected %v, got %v",
|
||||
@@ -103,7 +102,6 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
|
||||
state.LastBlockTime,
|
||||
)
|
||||
}
|
||||
|
||||
medianTime := MedianTime(block.LastCommit, state.LastValidators)
|
||||
if !block.Time.Equal(medianTime) {
|
||||
return fmt.Errorf("invalid block time. Expected %v, got %v",
|
||||
@@ -199,7 +197,6 @@ func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence, commit
|
||||
state.LastBlockTime.Add(evidenceParams.MaxAgeDuration),
|
||||
)
|
||||
}
|
||||
|
||||
if ev, ok := evidence.(*types.LunaticValidatorEvidence); ok {
|
||||
if err := ev.VerifyHeader(committedHeader); err != nil {
|
||||
return err
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
lighthttp "github.com/tendermint/tendermint/light/provider/http"
|
||||
lightrpc "github.com/tendermint/tendermint/light/rpc"
|
||||
lightdb "github.com/tendermint/tendermint/light/store/db"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
rpchttp "github.com/tendermint/tendermint/rpc/client/http"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -36,14 +37,14 @@ type StateProvider interface {
|
||||
type lightClientStateProvider struct {
|
||||
sync.Mutex // light.Client is not concurrency-safe
|
||||
lc *light.Client
|
||||
version sm.Version
|
||||
version tmstate.Version
|
||||
providers map[lightprovider.Provider]string
|
||||
}
|
||||
|
||||
// NewLightClientStateProvider creates a new StateProvider using a light client and RPC clients.
|
||||
func NewLightClientStateProvider(
|
||||
chainID string,
|
||||
version sm.Version,
|
||||
version tmstate.Version,
|
||||
servers []string,
|
||||
trustOptions light.TrustOptions,
|
||||
logger log.Logger,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
p2pmocks "github.com/tendermint/tendermint/p2p/mocks"
|
||||
tmstate "github.com/tendermint/tendermint/proto/state"
|
||||
ssproto "github.com/tendermint/tendermint/proto/statesync"
|
||||
tmversion "github.com/tendermint/tendermint/proto/version"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
@@ -44,7 +45,7 @@ func simplePeer(id string) *p2pmocks.Peer {
|
||||
func TestSyncer_SyncAny(t *testing.T) {
|
||||
state := sm.State{
|
||||
ChainID: "chain",
|
||||
Version: sm.Version{
|
||||
Version: tmstate.Version{
|
||||
Consensus: tmversion.Consensus{
|
||||
Block: version.BlockProtocol,
|
||||
App: 0,
|
||||
|
||||
Reference in New Issue
Block a user