mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-22 17:31:34 +00:00
Merge branch 'develop' into jae/literefactor4
This commit is contained in:
@ -5,10 +5,10 @@ import (
|
||||
|
||||
fail "github.com/ebuchman/fail-test"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -86,7 +86,7 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Update the state with the block and responses.
|
||||
state, err = updateState(state, blockID, block.Header, abciResponses)
|
||||
state, err = updateState(state, blockID, &block.Header, abciResponses)
|
||||
if err != nil {
|
||||
return state, fmt.Errorf("Commit failed for application: %v", err)
|
||||
}
|
||||
@ -189,7 +189,7 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus,
|
||||
// Begin block.
|
||||
_, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{
|
||||
Hash: block.Hash(),
|
||||
Header: types.TM2PB.Header(block.Header),
|
||||
Header: types.TM2PB.Header(&block.Header),
|
||||
Validators: signVals,
|
||||
ByzantineValidators: byzVals,
|
||||
})
|
||||
@ -278,20 +278,24 @@ func updateValidators(currentSet *types.ValidatorSet, abciUpdates []abci.Validat
|
||||
|
||||
// these are tendermint types now
|
||||
for _, valUpdate := range updates {
|
||||
if valUpdate.VotingPower < 0 {
|
||||
return fmt.Errorf("Voting power can't be negative %v", valUpdate)
|
||||
}
|
||||
|
||||
address := valUpdate.Address
|
||||
_, val := currentSet.GetByAddress(address)
|
||||
if val == nil {
|
||||
// add val
|
||||
added := currentSet.Add(valUpdate)
|
||||
if !added {
|
||||
return fmt.Errorf("Failed to add new validator %v", valUpdate)
|
||||
}
|
||||
} else if valUpdate.VotingPower == 0 {
|
||||
if valUpdate.VotingPower == 0 {
|
||||
// remove val
|
||||
_, removed := currentSet.Remove(address)
|
||||
if !removed {
|
||||
return fmt.Errorf("Failed to remove validator %X", address)
|
||||
}
|
||||
} else if val == nil {
|
||||
// add val
|
||||
added := currentSet.Add(valUpdate)
|
||||
if !added {
|
||||
return fmt.Errorf("Failed to add new validator %v", valUpdate)
|
||||
}
|
||||
} else {
|
||||
// update val
|
||||
updated := currentSet.Update(valUpdate)
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/abci/example/kvstore"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
@ -149,6 +149,89 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateValidators(t *testing.T) {
|
||||
pubkey1 := ed25519.GenPrivKey().PubKey()
|
||||
val1 := types.NewValidator(pubkey1, 10)
|
||||
pubkey2 := ed25519.GenPrivKey().PubKey()
|
||||
val2 := types.NewValidator(pubkey2, 20)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
||||
currentSet *types.ValidatorSet
|
||||
abciUpdates []abci.Validator
|
||||
|
||||
resultingSet *types.ValidatorSet
|
||||
shouldErr bool
|
||||
}{
|
||||
{
|
||||
"adding a validator is OK",
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
[]abci.Validator{{[]byte{}, types.TM2PB.PubKey(pubkey2), 20}},
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1, val2}),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"updating a validator is OK",
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
[]abci.Validator{{[]byte{}, types.TM2PB.PubKey(pubkey1), 20}},
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"removing a validator is OK",
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1, val2}),
|
||||
[]abci.Validator{{[]byte{}, types.TM2PB.PubKey(pubkey2), 0}},
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"removing a non-existing validator results in error",
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
[]abci.Validator{{[]byte{}, types.TM2PB.PubKey(pubkey2), 0}},
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"adding a validator with negative power results in error",
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
[]abci.Validator{{[]byte{}, types.TM2PB.PubKey(pubkey2), -100}},
|
||||
|
||||
types.NewValidatorSet([]*types.Validator{val1}),
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := updateValidators(tc.currentSet, tc.abciUpdates)
|
||||
if tc.shouldErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
require.Equal(t, tc.resultingSet.Size(), tc.currentSet.Size())
|
||||
|
||||
assert.Equal(t, tc.resultingSet.TotalVotingPower(), tc.currentSet.TotalVotingPower())
|
||||
|
||||
assert.Equal(t, tc.resultingSet.Validators[0].Address, tc.currentSet.Validators[0].Address)
|
||||
if tc.resultingSet.Size() > 1 {
|
||||
assert.Equal(t, tc.resultingSet.Validators[1].Address, tc.currentSet.Validators[1].Address)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// make some bogus txs
|
||||
@ -163,7 +246,7 @@ func state(nVals, height int) (State, dbm.DB) {
|
||||
vals := make([]types.GenesisValidator, nVals)
|
||||
for i := 0; i < nVals; i++ {
|
||||
secret := []byte(fmt.Sprintf("test%d", i))
|
||||
pk := crypto.GenPrivKeyEd25519FromSecret(secret)
|
||||
pk := ed25519.GenPrivKeyFromSecret(secret)
|
||||
vals[i] = types.GenesisValidator{
|
||||
pk.PubKey(), 1000, fmt.Sprintf("test%d", i),
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ type Mempool interface {
|
||||
Flush()
|
||||
FlushAppConn() error
|
||||
|
||||
TxsAvailable() <-chan int64
|
||||
TxsAvailable() <-chan struct{}
|
||||
EnableTxsAvailable()
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ func (m MockMempool) Reap(n int) types.Txs { retur
|
||||
func (m MockMempool) Update(height int64, txs types.Txs) error { return nil }
|
||||
func (m MockMempool) Flush() {}
|
||||
func (m MockMempool) FlushAppConn() error { return nil }
|
||||
func (m MockMempool) TxsAvailable() <-chan int64 { return make(chan int64) }
|
||||
func (m MockMempool) TxsAvailable() <-chan struct{} { return make(chan struct{}) }
|
||||
func (m MockMempool) EnableTxsAvailable() {}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
|
||||
@ -78,7 +79,7 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
|
||||
abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil}
|
||||
abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil}
|
||||
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.Validator{
|
||||
types.TM2PB.ValidatorFromPubKeyAndPower(crypto.GenPrivKeyEd25519().PubKey(), 10),
|
||||
types.TM2PB.ValidatorFromPubKeyAndPower(ed25519.GenPrivKey().PubKey(), 10),
|
||||
}}
|
||||
|
||||
saveABCIResponses(stateDB, block.Height, abciResponses)
|
||||
@ -213,8 +214,8 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
|
||||
changeIndex++
|
||||
power++
|
||||
}
|
||||
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, power)
|
||||
state, err = updateState(state, blockID, header, responses)
|
||||
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
|
||||
state, err = updateState(state, blockID, &header, responses)
|
||||
assert.Nil(t, err)
|
||||
nextHeight := state.LastBlockHeight + 1
|
||||
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
||||
@ -258,14 +259,15 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
|
||||
|
||||
_, valOld := state.Validators.GetByIndex(0)
|
||||
var pubkeyOld = valOld.PubKey
|
||||
var pubkey = crypto.GenPrivKeyEd25519().PubKey()
|
||||
pubkey := ed25519.GenPrivKey().PubKey()
|
||||
const height = 1
|
||||
|
||||
// Swap the first validator with a new one (validator set size stays the same).
|
||||
header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, pubkey)
|
||||
header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey)
|
||||
|
||||
// Save state etc.
|
||||
var err error
|
||||
state, err = updateState(state, blockID, header, responses)
|
||||
state, err = updateState(state, blockID, &header, responses)
|
||||
require.Nil(t, err)
|
||||
nextHeight := state.LastBlockHeight + 1
|
||||
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
||||
@ -294,7 +296,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
|
||||
func genValSet(size int) *types.ValidatorSet {
|
||||
vals := make([]*types.Validator, size)
|
||||
for i := 0; i < size; i++ {
|
||||
vals[i] = types.NewValidator(crypto.GenPrivKeyEd25519().PubKey(), 10)
|
||||
vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10)
|
||||
}
|
||||
return types.NewValidatorSet(vals)
|
||||
}
|
||||
@ -330,8 +332,8 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
|
||||
changeIndex++
|
||||
cp = params[changeIndex]
|
||||
}
|
||||
header, blockID, responses := makeHeaderPartsResponsesParams(state, cp)
|
||||
state, err = updateState(state, blockID, header, responses)
|
||||
header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
|
||||
state, err = updateState(state, blockID, &header, responses)
|
||||
|
||||
require.Nil(t, err)
|
||||
nextHeight := state.LastBlockHeight + 1
|
||||
@ -380,7 +382,7 @@ func makeParams(blockBytes, blockTx, blockGas, txBytes,
|
||||
}
|
||||
|
||||
func pk() []byte {
|
||||
return crypto.GenPrivKeyEd25519().PubKey().Bytes()
|
||||
return ed25519.GenPrivKey().PubKey().Bytes()
|
||||
}
|
||||
|
||||
func TestApplyUpdates(t *testing.T) {
|
||||
@ -429,8 +431,8 @@ func TestApplyUpdates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func makeHeaderPartsResponsesValPubKeyChange(state State, pubkey crypto.PubKey) (
|
||||
*types.Header, types.BlockID, *ABCIResponses) {
|
||||
func makeHeaderPartsResponsesValPubKeyChange(state State, height int64,
|
||||
pubkey crypto.PubKey) (types.Header, types.BlockID, *ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &ABCIResponses{
|
||||
@ -451,8 +453,8 @@ func makeHeaderPartsResponsesValPubKeyChange(state State, pubkey crypto.PubKey)
|
||||
return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
|
||||
}
|
||||
|
||||
func makeHeaderPartsResponsesValPowerChange(state State, power int64) (
|
||||
*types.Header, types.BlockID, *ABCIResponses) {
|
||||
func makeHeaderPartsResponsesValPowerChange(state State, height int64,
|
||||
power int64) (types.Header, types.BlockID, *ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &ABCIResponses{
|
||||
@ -472,8 +474,8 @@ func makeHeaderPartsResponsesValPowerChange(state State, power int64) (
|
||||
return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
|
||||
}
|
||||
|
||||
func makeHeaderPartsResponsesParams(state State, params types.ConsensusParams) (
|
||||
*types.Header, types.BlockID, *ABCIResponses) {
|
||||
func makeHeaderPartsResponsesParams(state State, height int64,
|
||||
params types.ConsensusParams) (types.Header, types.BlockID, *ABCIResponses) {
|
||||
|
||||
block := makeBlock(state, state.LastBlockHeight+1)
|
||||
abciResponses := &ABCIResponses{
|
||||
|
@ -4,9 +4,9 @@ import (
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -80,6 +80,7 @@ func loadState(db dbm.DB, key []byte) (state State) {
|
||||
}
|
||||
|
||||
// SaveState persists the State, the ValidatorsInfo, and the ConsensusParamsInfo to the database.
|
||||
// This flushes the writes (e.g. calls SetSync).
|
||||
func SaveState(db dbm.DB, state State) {
|
||||
saveState(db, state, stateKey)
|
||||
}
|
||||
@ -182,8 +183,13 @@ func LoadValidators(db dbm.DB, height int64) (*types.ValidatorSet, error) {
|
||||
if valInfo.ValidatorSet == nil {
|
||||
valInfo2 := loadValidatorsInfo(db, valInfo.LastHeightChanged)
|
||||
if valInfo2 == nil {
|
||||
cmn.PanicSanity(fmt.Sprintf(`Couldn't find validators at height %d as
|
||||
last changed from height %d`, valInfo.LastHeightChanged, height))
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"Couldn't find validators at height %d as last changed from height %d",
|
||||
valInfo.LastHeightChanged,
|
||||
height,
|
||||
),
|
||||
)
|
||||
}
|
||||
valInfo = valInfo2
|
||||
}
|
||||
@ -220,7 +226,7 @@ func saveValidatorsInfo(db dbm.DB, nextHeight, changeHeight int64, valSet *types
|
||||
if changeHeight == nextHeight {
|
||||
valInfo.ValidatorSet = valSet
|
||||
}
|
||||
db.SetSync(calcValidatorsKey(nextHeight), valInfo.Bytes())
|
||||
db.Set(calcValidatorsKey(nextHeight), valInfo.Bytes())
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -246,11 +252,17 @@ func LoadConsensusParams(db dbm.DB, height int64) (types.ConsensusParams, error)
|
||||
}
|
||||
|
||||
if paramsInfo.ConsensusParams == empty {
|
||||
paramsInfo = loadConsensusParamsInfo(db, paramsInfo.LastHeightChanged)
|
||||
if paramsInfo == nil {
|
||||
cmn.PanicSanity(fmt.Sprintf(`Couldn't find consensus params at height %d as
|
||||
last changed from height %d`, paramsInfo.LastHeightChanged, height))
|
||||
paramsInfo2 := loadConsensusParamsInfo(db, paramsInfo.LastHeightChanged)
|
||||
if paramsInfo2 == nil {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"Couldn't find consensus params at height %d as last changed from height %d",
|
||||
paramsInfo.LastHeightChanged,
|
||||
height,
|
||||
),
|
||||
)
|
||||
}
|
||||
paramsInfo = paramsInfo2
|
||||
}
|
||||
|
||||
return paramsInfo.ConsensusParams, nil
|
||||
@ -285,5 +297,5 @@ func saveConsensusParamsInfo(db dbm.DB, nextHeight, changeHeight int64, params t
|
||||
if changeHeight == nextHeight {
|
||||
paramsInfo.ConsensusParams = params
|
||||
}
|
||||
db.SetSync(calcConsensusParamsKey(nextHeight), paramsInfo.Bytes())
|
||||
db.Set(calcConsensusParamsKey(nextHeight), paramsInfo.Bytes())
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package state
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
)
|
||||
|
||||
var cdc = amino.NewCodec()
|
||||
|
||||
func init() {
|
||||
crypto.RegisterAmino(cdc)
|
||||
cryptoAmino.RegisterAmino(cdc)
|
||||
}
|
||||
|
Reference in New Issue
Block a user