Skip to content

Commit

Permalink
test: add tests for each validator type (#189)
Browse files Browse the repository at this point in the history
* test: add test GenFilePV() with the addition of new privKeyType

* test: add aggregate signature test
  • Loading branch information
Kynea0b committed Mar 1, 2021
1 parent cf85d26 commit 18e0466
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 5 deletions.
108 changes: 108 additions & 0 deletions consensus/aggregate_signature_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package consensus

import (
"crypto/ed25519"
"testing"

"github.com/tendermint/tendermint/crypto/bls"

"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
)

func startConsensusAndMakeBlocks(t *testing.T, nPeers, nVals, nValsWithComposite int) []*State {
css, _, _, cleanup := consensusNetWithPeers(
nVals,
nPeers,
t.Name(),
newMockTickerFunc(true),
newPersistentKVStoreWithPath,
nValsWithComposite)

defer cleanup()
logger := log.TestingLogger()

reactors, blocksSubs, eventBuses := startConsensusNet(t, css, nPeers)
defer stopConsensusNet(logger, reactors, eventBuses)

// map of active validators
activeVals := make(map[string]struct{})
for i := 0; i < nVals; i++ {
pubKey, err := css[i].privValidator.GetPubKey()
require.NoError(t, err)
activeVals[string(pubKey.Address())] = struct{}{}
}

// wait till everyone makes block 1
timeoutWaitGroup(t, nPeers, func(j int) {
<-blocksSubs[j].Out()
}, css)

// wait till everyone makes block 2
waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css)

return css
}

func TestAggregateSignature(t *testing.T) {
const (
nPeers = 4
nVals = 4
nValsWithComposite = 0
)
css := startConsensusAndMakeBlocks(t, nPeers, nVals, nValsWithComposite)
for _, state := range css {
block := state.blockStore.LoadBlock(2)

// validators are ed25519 only
for _, comsig := range block.LastCommit.Signatures {
require.EqualValues(t, ed25519.PrivateKeySize, len(comsig.Signature))
}
require.EqualValues(t, nVals, len(block.LastCommit.Signatures))
require.Nil(t, block.LastCommit.AggregatedSignature)
}
}

func TestAggregateSignatureWithComposite(t *testing.T) {
const (
nPeers = 4
nVals = 4
nValsWithComposite = 4
)
css := startConsensusAndMakeBlocks(t, nPeers, nVals, nValsWithComposite)

for _, state := range css {
block := state.blockStore.LoadBlock(2)
// validators are composite only
for _, comsig := range block.LastCommit.Signatures {
require.Nil(t, comsig.Signature)
}
require.EqualValues(t, nVals, len(block.LastCommit.Signatures))
require.EqualValues(t, bls.SignatureSize, len(block.LastCommit.AggregatedSignature))
}
}

func TestAggregateSignatureWithMix(t *testing.T) {
const (
nPeers = 4
nVals = 4
nValsWithComposite = 2
expectedCntNotNilSig = nVals - nValsWithComposite
)
css := startConsensusAndMakeBlocks(t, nPeers, nVals, nValsWithComposite)

for _, state := range css {
block := state.blockStore.LoadBlock(2)
// composite and ed25519 validators
cnt := 0
for _, comsig := range block.LastCommit.Signatures {
if comsig.Signature != nil {
cnt++
}
}
// count the unaggregated sig
require.EqualValues(t, expectedCntNotNilSig, cnt)
// count the aggregated sig
require.EqualValues(t, nValsWithComposite, len(block.LastCommit.Signatures)-cnt)
}
}
92 changes: 87 additions & 5 deletions consensus/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,28 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
}
}

// nPeers = nValidators(ed25519 or composite) + nNotValidator
// (0 <= numOfComposite <= nValidators)
func consensusNetWithPeers(
nValidators,
nPeers int,
testName string,
tickerFunc func() TimeoutTicker,
appFunc func(string) abci.Application,
nValsWithComposite int,
) ([]*State, *types.GenesisDoc, *cfg.Config, cleanupFunc) {
genDoc, privVals := genesisDoc(nValidators, testMinPower, types.DefaultVoterParams(), nValsWithComposite)

css, peer0Config, configRootDirs := createPeersAndValidators(nValidators, nPeers, testName,
genDoc, privVals, tickerFunc, appFunc)

return css, genDoc, peer0Config, func() {
for _, dir := range configRootDirs {
os.RemoveAll(dir)
}
}
}

// nPeers = nValidators + nNotValidator
func randConsensusNetWithPeers(
nValidators,
Expand All @@ -777,6 +799,19 @@ func randConsensusNetWithPeers(
appFunc func(string) abci.Application,
) ([]*State, *types.GenesisDoc, *cfg.Config, cleanupFunc) {
genDoc, privVals := randGenesisDoc(nValidators, false, testMinPower, types.DefaultVoterParams())
css, peer0Config, configRootDirs := createPeersAndValidators(nValidators, nPeers, testName,
genDoc, privVals, tickerFunc, appFunc)

return css, genDoc, peer0Config, func() {
for _, dir := range configRootDirs {
os.RemoveAll(dir)
}
}
}

func createPeersAndValidators(nValidators, nPeers int, testName string,
genDoc *types.GenesisDoc, privVals []types.PrivValidator, tickerFunc func() TimeoutTicker,
appFunc func(string) abci.Application) ([]*State, *cfg.Config, []string) {
css := make([]*State, nPeers)
logger := consensusLogger()
var peer0Config *cfg.Config
Expand Down Expand Up @@ -819,11 +854,8 @@ func randConsensusNetWithPeers(
css[i].SetTimeoutTicker(tickerFunc())
css[i].SetLogger(logger.With("validator", i, "module", "consensus"))
}
return css, genDoc, peer0Config, func() {
for _, dir := range configRootDirs {
os.RemoveAll(dir)
}
}

return css, peer0Config, configRootDirs
}

func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int {
Expand All @@ -837,6 +869,41 @@ func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int {

//-------------------------------------------------------------------------------
// genesis
func genesisDoc(
numValidators int,
minPower int64,
voterParams *types.VoterParams,
nValsWithComposite int,
) (*types.GenesisDoc, []types.PrivValidator) {
validators := make([]types.GenesisValidator, numValidators)
privValidators := make([]types.PrivValidator, numValidators)
var val *types.Validator
var privVal types.PrivValidator
for i := 0; i < nValsWithComposite; i++ {
val, privVal = createTestValidator(minPower, types.PrivKeyComposite)
validators[i] = types.GenesisValidator{
PubKey: val.PubKey,
Power: val.StakingPower,
}
privValidators[i] = privVal
}
for i := nValsWithComposite; i < numValidators; i++ {
val, privVal = createTestValidator(minPower, types.PrivKeyEd25519)
validators[i] = types.GenesisValidator{
PubKey: val.PubKey,
Power: val.StakingPower,
}
privValidators[i] = privVal
}
sort.Sort(types.PrivValidatorsByAddress(privValidators))

return &types.GenesisDoc{
GenesisTime: tmtime.Now(),
ChainID: config.ChainID(),
Validators: validators,
VoterParams: voterParams,
}, privValidators
}

func randGenesisDoc(
numValidators int,
Expand Down Expand Up @@ -936,3 +1003,18 @@ func newPersistentKVStore() abci.Application {
func newPersistentKVStoreWithPath(dbDir string) abci.Application {
return kvstore.NewPersistentKVStoreApplication(dbDir)
}

//----------------------------------------
// Validator
func createTestValidator(minPower int64, keytype types.PrivKeyType) (*types.Validator, types.PrivValidator) {
privVal := types.NewMockPV(keytype)
stakingPower := minPower
stakingPower += 100

pubKey, err := privVal.GetPubKey()
if err != nil {
panic(fmt.Errorf("could not retrieve pubkey %w", err))
}
val := types.NewValidator(pubKey, stakingPower)
return val, privVal
}
20 changes: 20 additions & 0 deletions privval/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (
"fmt"
"io/ioutil"
"os"
"reflect"
"testing"
"time"

"github.com/tendermint/tendermint/crypto/composite"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand All @@ -17,6 +20,23 @@ import (
tmtime "github.com/tendermint/tendermint/types/time"
)

func TestGenFilePV(t *testing.T) {
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
require.Nil(t, err)
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
require.Nil(t, err)

privValEd25519, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), PrivKeyTypeEd25519)
require.EqualValues(t, reflect.TypeOf(ed25519.PubKeyEd25519{}), reflect.TypeOf(privValEd25519.Key.PubKey))

privValComposite, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), PrivKeyTypeComposite)
require.EqualValues(t, reflect.TypeOf(composite.PubKeyComposite{}), reflect.TypeOf(privValComposite.Key.PubKey))

privValUndefinedPrivKeyType, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NotNil(t, err)
require.Nil(t, privValUndefinedPrivKeyType)
}

func TestGenLoadValidator(t *testing.T) {
assert := assert.New(t)

Expand Down

0 comments on commit 18e0466

Please sign in to comment.