Merge branch 'develop' into jae/literefactor4

This commit is contained in:
Ethan Buchman
2018-07-23 23:28:14 -04:00
342 changed files with 30691 additions and 6539 deletions

View File

@ -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)

View File

@ -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),
}

View File

@ -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() {}
//------------------------------------------------------

View File

@ -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{

View File

@ -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())
}

View File

@ -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)
}