mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-12 23:07:11 +00:00
Merge pull request #1936 from tendermint/693-ensure-types-are-covered
Ensure all funcs in types pkg are well guarded (Part 1)
This commit is contained in:
commit
789666ef78
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## TBD
|
||||||
|
|
||||||
|
IMPROVEMENTS:
|
||||||
|
- [genesis] removed deprecated `app_options` field.
|
||||||
|
- [types] Genesis.AppStateJSON -> Genesis.AppState
|
||||||
|
|
||||||
## 0.22.3
|
## 0.22.3
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
@ -273,7 +273,7 @@ func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight
|
|||||||
ChainId: h.genDoc.ChainID,
|
ChainId: h.genDoc.ChainID,
|
||||||
ConsensusParams: csParams,
|
ConsensusParams: csParams,
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
AppStateBytes: h.genDoc.AppStateJSON,
|
AppStateBytes: h.genDoc.AppState,
|
||||||
}
|
}
|
||||||
res, err := proxyApp.Consensus().InitChainSync(req)
|
res, err := proxyApp.Consensus().InitChainSync(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
gen_query_parser:
|
gen_query_parser:
|
||||||
@go get github.com/pointlander/peg
|
go get -u -v github.com/pointlander/peg
|
||||||
peg -inline -switch query.peg
|
peg -inline -switch query.peg
|
||||||
|
|
||||||
fuzzy_test:
|
fuzzy_test:
|
||||||
@go get github.com/dvyukov/go-fuzz/go-fuzz
|
go get -u -v github.com/dvyukov/go-fuzz/go-fuzz
|
||||||
@go get github.com/dvyukov/go-fuzz/go-fuzz-build
|
go get -u -v github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||||
go-fuzz-build github.com/tendermint/tendermint/libs/pubsub/query/fuzz_test
|
go-fuzz-build github.com/tendermint/tendermint/libs/pubsub/query/fuzz_test
|
||||||
go-fuzz -bin=./fuzz_test-fuzz.zip -workdir=./fuzz_test/output
|
go-fuzz -bin=./fuzz_test-fuzz.zip -workdir=./fuzz_test/output
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// nolint
|
// nolint
|
||||||
package query
|
package query
|
||||||
|
|
||||||
|
//go:generate peg -inline -switch query.peg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
@ -29,9 +29,8 @@ type Genesis struct {
|
|||||||
ConsensusParams *types.ConsensusParams `json:"consensus_params,omitempty"`
|
ConsensusParams *types.ConsensusParams `json:"consensus_params,omitempty"`
|
||||||
Validators []GenesisValidator `json:"validators"`
|
Validators []GenesisValidator `json:"validators"`
|
||||||
AppHash cmn.HexBytes `json:"app_hash"`
|
AppHash cmn.HexBytes `json:"app_hash"`
|
||||||
AppStateJSON json.RawMessage `json:"app_state,omitempty"`
|
AppState json.RawMessage `json:"app_state,omitempty"`
|
||||||
AppOptions json.RawMessage `json:"app_options,omitempty"` // DEPRECATED
|
AppOptions json.RawMessage `json:"app_options,omitempty"` // DEPRECATED
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeKey struct {
|
type NodeKey struct {
|
||||||
@ -113,11 +112,11 @@ func convertGenesis(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
|||||||
ConsensusParams: genesis.ConsensusParams,
|
ConsensusParams: genesis.ConsensusParams,
|
||||||
// Validators
|
// Validators
|
||||||
AppHash: genesis.AppHash,
|
AppHash: genesis.AppHash,
|
||||||
AppStateJSON: genesis.AppStateJSON,
|
AppState: genesis.AppState,
|
||||||
}
|
}
|
||||||
|
|
||||||
if genesis.AppOptions != nil {
|
if genesis.AppOptions != nil {
|
||||||
genesisNew.AppStateJSON = genesis.AppOptions
|
genesisNew.AppState = genesis.AppOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range genesis.Validators {
|
for _, v := range genesis.Validators {
|
||||||
|
@ -107,6 +107,7 @@ func (b *Block) Hash() cmn.HexBytes {
|
|||||||
|
|
||||||
// MakePartSet returns a PartSet containing parts of a serialized block.
|
// MakePartSet returns a PartSet containing parts of a serialized block.
|
||||||
// This is the form in which the block is gossipped to peers.
|
// This is the form in which the block is gossipped to peers.
|
||||||
|
// CONTRACT: partSize is greater than zero.
|
||||||
func (b *Block) MakePartSet(partSize int) *PartSet {
|
func (b *Block) MakePartSet(partSize int) *PartSet {
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -208,7 +209,7 @@ type Header struct {
|
|||||||
// Hash returns the hash of the header.
|
// Hash returns the hash of the header.
|
||||||
// Returns nil if ValidatorHash is missing,
|
// Returns nil if ValidatorHash is missing,
|
||||||
// since a Header is not valid unless there is
|
// since a Header is not valid unless there is
|
||||||
// a ValidaotrsHash (corresponding to the validator set).
|
// a ValidatorsHash (corresponding to the validator set).
|
||||||
func (h *Header) Hash() cmn.HexBytes {
|
func (h *Header) Hash() cmn.HexBytes {
|
||||||
if h == nil || len(h.ValidatorsHash) == 0 {
|
if h == nil || len(h.ValidatorsHash) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -392,6 +393,9 @@ func (commit *Commit) ValidateBasic() error {
|
|||||||
|
|
||||||
// Hash returns the hash of the commit
|
// Hash returns the hash of the commit
|
||||||
func (commit *Commit) Hash() cmn.HexBytes {
|
func (commit *Commit) Hash() cmn.HexBytes {
|
||||||
|
if commit == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if commit.hash == nil {
|
if commit.hash == nil {
|
||||||
bs := make([]merkle.Hasher, len(commit.Precommits))
|
bs := make([]merkle.Hasher, len(commit.Precommits))
|
||||||
for i, precommit := range commit.Precommits {
|
for i, precommit := range commit.Precommits {
|
||||||
|
@ -10,7 +10,25 @@ import (
|
|||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateBlock(t *testing.T) {
|
func TestBlockAddEvidence(t *testing.T) {
|
||||||
|
txs := []Tx{Tx("foo"), Tx("bar")}
|
||||||
|
lastID := makeBlockIDRandom()
|
||||||
|
h := int64(3)
|
||||||
|
|
||||||
|
voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||||
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
block := MakeBlock(h, txs, commit)
|
||||||
|
require.NotNil(t, block)
|
||||||
|
|
||||||
|
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||||
|
block.AddEvidence([]Evidence{ev})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockValidateBasic(t *testing.T) {
|
||||||
|
require.Error(t, (*Block)(nil).ValidateBasic())
|
||||||
|
|
||||||
txs := []Tx{Tx("foo"), Tx("bar")}
|
txs := []Tx{Tx("foo"), Tx("bar")}
|
||||||
lastID := makeBlockIDRandom()
|
lastID := makeBlockIDRandom()
|
||||||
h := int64(3)
|
h := int64(3)
|
||||||
@ -57,6 +75,59 @@ func TestValidateBlock(t *testing.T) {
|
|||||||
block.DataHash = cmn.RandBytes(len(block.DataHash))
|
block.DataHash = cmn.RandBytes(len(block.DataHash))
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
|
// tamper with evidence
|
||||||
|
block = MakeBlock(h, txs, commit)
|
||||||
|
block.EvidenceHash = []byte("something else")
|
||||||
|
err = block.ValidateBasic()
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockHash(t *testing.T) {
|
||||||
|
assert.Nil(t, (*Block)(nil).Hash())
|
||||||
|
assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockMakePartSet(t *testing.T) {
|
||||||
|
assert.Nil(t, (*Block)(nil).MakePartSet(2))
|
||||||
|
|
||||||
|
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).MakePartSet(1024)
|
||||||
|
assert.NotNil(t, partSet)
|
||||||
|
assert.Equal(t, 1, partSet.Total())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockHashesTo(t *testing.T) {
|
||||||
|
assert.False(t, (*Block)(nil).HashesTo(nil))
|
||||||
|
|
||||||
|
lastID := makeBlockIDRandom()
|
||||||
|
h := int64(3)
|
||||||
|
voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||||
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit)
|
||||||
|
block.ValidatorsHash = valSet.Hash()
|
||||||
|
assert.False(t, block.HashesTo([]byte{}))
|
||||||
|
assert.False(t, block.HashesTo([]byte("something else")))
|
||||||
|
assert.True(t, block.HashesTo(block.Hash()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockSize(t *testing.T) {
|
||||||
|
size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Size()
|
||||||
|
if size <= 0 {
|
||||||
|
t.Fatal("Size of the block is zero or negative")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockString(t *testing.T) {
|
||||||
|
assert.Equal(t, "nil-Block", (*Block)(nil).String())
|
||||||
|
assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented(""))
|
||||||
|
assert.Equal(t, "nil-Block", (*Block)(nil).StringShort())
|
||||||
|
|
||||||
|
block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil)
|
||||||
|
assert.NotEqual(t, "nil-Block", block.String())
|
||||||
|
assert.NotEqual(t, "nil-Block", block.StringIndented(""))
|
||||||
|
assert.NotEqual(t, "nil-Block", block.StringShort())
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBlockIDRandom() BlockID {
|
func makeBlockIDRandom() BlockID {
|
||||||
@ -86,3 +157,61 @@ func TestNilDataHashDoesntCrash(t *testing.T) {
|
|||||||
assert.Equal(t, []byte((*Data)(nil).Hash()), nilBytes)
|
assert.Equal(t, []byte((*Data)(nil).Hash()), nilBytes)
|
||||||
assert.Equal(t, []byte(new(Data).Hash()), nilBytes)
|
assert.Equal(t, []byte(new(Data).Hash()), nilBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCommit(t *testing.T) {
|
||||||
|
lastID := makeBlockIDRandom()
|
||||||
|
h := int64(3)
|
||||||
|
voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||||
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.NotNil(t, commit.FirstPrecommit())
|
||||||
|
assert.Equal(t, h-1, commit.Height())
|
||||||
|
assert.Equal(t, 1, commit.Round())
|
||||||
|
assert.Equal(t, VoteTypePrecommit, commit.Type())
|
||||||
|
if commit.Size() <= 0 {
|
||||||
|
t.Fatalf("commit %v has a zero or negative size: %d", commit, commit.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NotNil(t, commit.BitArray())
|
||||||
|
assert.Equal(t, cmn.NewBitArray(10).Size(), commit.BitArray().Size())
|
||||||
|
|
||||||
|
assert.Equal(t, voteSet.GetByIndex(0), commit.GetByIndex(0))
|
||||||
|
assert.True(t, commit.IsCommit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitValidateBasic(t *testing.T) {
|
||||||
|
commit := randCommit()
|
||||||
|
assert.NoError(t, commit.ValidateBasic())
|
||||||
|
|
||||||
|
// nil precommit is OK
|
||||||
|
commit = randCommit()
|
||||||
|
commit.Precommits[0] = nil
|
||||||
|
assert.NoError(t, commit.ValidateBasic())
|
||||||
|
|
||||||
|
// tamper with types
|
||||||
|
commit = randCommit()
|
||||||
|
commit.Precommits[0].Type = VoteTypePrevote
|
||||||
|
assert.Error(t, commit.ValidateBasic())
|
||||||
|
|
||||||
|
// tamper with height
|
||||||
|
commit = randCommit()
|
||||||
|
commit.Precommits[0].Height = int64(100)
|
||||||
|
assert.Error(t, commit.ValidateBasic())
|
||||||
|
|
||||||
|
// tamper with round
|
||||||
|
commit = randCommit()
|
||||||
|
commit.Precommits[0].Round = 100
|
||||||
|
assert.Error(t, commit.ValidateBasic())
|
||||||
|
}
|
||||||
|
|
||||||
|
func randCommit() *Commit {
|
||||||
|
lastID := makeBlockIDRandom()
|
||||||
|
h := int64(3)
|
||||||
|
voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||||
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return commit
|
||||||
|
}
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
// Interface assertions
|
|
||||||
var _ TxEventPublisher = (*TxEventBuffer)(nil)
|
|
||||||
|
|
||||||
// TxEventBuffer is a buffer of events, which uses a slice to temporarily store
|
|
||||||
// events.
|
|
||||||
type TxEventBuffer struct {
|
|
||||||
next TxEventPublisher
|
|
||||||
capacity int
|
|
||||||
events []EventDataTx
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTxEventBuffer accepts a TxEventPublisher and returns a new buffer with the given
|
|
||||||
// capacity.
|
|
||||||
func NewTxEventBuffer(next TxEventPublisher, capacity int) *TxEventBuffer {
|
|
||||||
return &TxEventBuffer{
|
|
||||||
next: next,
|
|
||||||
capacity: capacity,
|
|
||||||
events: make([]EventDataTx, 0, capacity),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of events cached.
|
|
||||||
func (b TxEventBuffer) Len() int {
|
|
||||||
return len(b.events)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublishEventTx buffers an event to be fired upon finality.
|
|
||||||
func (b *TxEventBuffer) PublishEventTx(e EventDataTx) error {
|
|
||||||
b.events = append(b.events, e)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush publishes events by running next.PublishWithTags on all cached events.
|
|
||||||
// Blocks. Clears cached events.
|
|
||||||
func (b *TxEventBuffer) Flush() error {
|
|
||||||
for _, e := range b.events {
|
|
||||||
err := b.next.PublishEventTx(e)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear out the elements and set the length to 0
|
|
||||||
// but maintain the underlying slice's capacity.
|
|
||||||
// See Issue https://github.com/tendermint/tendermint/issues/1189
|
|
||||||
b.events = b.events[:0]
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
type eventBusMock struct{}
|
|
||||||
|
|
||||||
func (eventBusMock) PublishEventTx(e EventDataTx) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEventBuffer(t *testing.T) {
|
|
||||||
b := NewTxEventBuffer(eventBusMock{}, 1)
|
|
||||||
b.PublishEventTx(EventDataTx{})
|
|
||||||
assert.Equal(t, 1, b.Len())
|
|
||||||
b.Flush()
|
|
||||||
assert.Equal(t, 0, b.Len())
|
|
||||||
}
|
|
@ -11,9 +11,9 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
|
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
|
||||||
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
|
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEventBusPublishEventTx(t *testing.T) {
|
func TestEventBusPublishEventTx(t *testing.T) {
|
||||||
@ -59,6 +59,64 @@ func TestEventBusPublishEventTx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEventBusPublish(t *testing.T) {
|
||||||
|
eventBus := NewEventBus()
|
||||||
|
err := eventBus.Start()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer eventBus.Stop()
|
||||||
|
|
||||||
|
eventsCh := make(chan interface{})
|
||||||
|
err = eventBus.Subscribe(context.Background(), "test", tmquery.Empty{}, eventsCh)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
const numEventsExpected = 14
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
numEvents := 0
|
||||||
|
for range eventsCh {
|
||||||
|
numEvents++
|
||||||
|
if numEvents >= numEventsExpected {
|
||||||
|
close(done)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = eventBus.Publish(EventNewBlockHeader, EventDataNewBlockHeader{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventNewBlock(EventDataNewBlock{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventNewBlockHeader(EventDataNewBlockHeader{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventVote(EventDataVote{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventProposalHeartbeat(EventDataProposalHeartbeat{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventNewRoundStep(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventTimeoutPropose(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventTimeoutWait(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventNewRound(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventCompleteProposal(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventPolka(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventUnlock(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventRelock(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = eventBus.PublishEventLock(EventDataRoundState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
t.Fatalf("expected to receive %d events after 1 sec.", numEventsExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkEventBus(b *testing.B) {
|
func BenchmarkEventBus(b *testing.B) {
|
||||||
benchmarks := []struct {
|
benchmarks := []struct {
|
||||||
name string
|
name string
|
||||||
@ -126,11 +184,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = []string{EventBond,
|
var events = []string{
|
||||||
EventUnbond,
|
|
||||||
EventRebond,
|
|
||||||
EventDupeout,
|
|
||||||
EventFork,
|
|
||||||
EventNewBlock,
|
EventNewBlock,
|
||||||
EventNewBlockHeader,
|
EventNewBlockHeader,
|
||||||
EventNewRound,
|
EventNewRound,
|
||||||
@ -148,11 +202,7 @@ func randEvent() string {
|
|||||||
return events[rand.Intn(len(events))]
|
return events[rand.Intn(len(events))]
|
||||||
}
|
}
|
||||||
|
|
||||||
var queries = []tmpubsub.Query{EventQueryBond,
|
var queries = []tmpubsub.Query{
|
||||||
EventQueryUnbond,
|
|
||||||
EventQueryRebond,
|
|
||||||
EventQueryDupeout,
|
|
||||||
EventQueryFork,
|
|
||||||
EventQueryNewBlock,
|
EventQueryNewBlock,
|
||||||
EventQueryNewBlockHeader,
|
EventQueryNewBlockHeader,
|
||||||
EventQueryNewRound,
|
EventQueryNewRound,
|
||||||
|
@ -10,22 +10,17 @@ import (
|
|||||||
|
|
||||||
// Reserved event types
|
// Reserved event types
|
||||||
const (
|
const (
|
||||||
EventBond = "Bond"
|
|
||||||
EventCompleteProposal = "CompleteProposal"
|
EventCompleteProposal = "CompleteProposal"
|
||||||
EventDupeout = "Dupeout"
|
|
||||||
EventFork = "Fork"
|
|
||||||
EventLock = "Lock"
|
EventLock = "Lock"
|
||||||
EventNewBlock = "NewBlock"
|
EventNewBlock = "NewBlock"
|
||||||
EventNewBlockHeader = "NewBlockHeader"
|
EventNewBlockHeader = "NewBlockHeader"
|
||||||
EventNewRound = "NewRound"
|
EventNewRound = "NewRound"
|
||||||
EventNewRoundStep = "NewRoundStep"
|
EventNewRoundStep = "NewRoundStep"
|
||||||
EventPolka = "Polka"
|
EventPolka = "Polka"
|
||||||
EventRebond = "Rebond"
|
|
||||||
EventRelock = "Relock"
|
EventRelock = "Relock"
|
||||||
EventTimeoutPropose = "TimeoutPropose"
|
EventTimeoutPropose = "TimeoutPropose"
|
||||||
EventTimeoutWait = "TimeoutWait"
|
EventTimeoutWait = "TimeoutWait"
|
||||||
EventTx = "Tx"
|
EventTx = "Tx"
|
||||||
EventUnbond = "Unbond"
|
|
||||||
EventUnlock = "Unlock"
|
EventUnlock = "Unlock"
|
||||||
EventVote = "Vote"
|
EventVote = "Vote"
|
||||||
EventProposalHeartbeat = "ProposalHeartbeat"
|
EventProposalHeartbeat = "ProposalHeartbeat"
|
||||||
@ -113,11 +108,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
EventQueryBond = QueryForEvent(EventBond)
|
|
||||||
EventQueryUnbond = QueryForEvent(EventUnbond)
|
|
||||||
EventQueryRebond = QueryForEvent(EventRebond)
|
|
||||||
EventQueryDupeout = QueryForEvent(EventDupeout)
|
|
||||||
EventQueryFork = QueryForEvent(EventFork)
|
|
||||||
EventQueryNewBlock = QueryForEvent(EventNewBlock)
|
EventQueryNewBlock = QueryForEvent(EventNewBlock)
|
||||||
EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeader)
|
EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeader)
|
||||||
EventQueryNewRound = QueryForEvent(EventNewRound)
|
EventQueryNewRound = QueryForEvent(EventNewRound)
|
||||||
|
23
types/events_test.go
Normal file
23
types/events_test.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQueryTxFor(t *testing.T) {
|
||||||
|
tx := Tx("foo")
|
||||||
|
assert.Equal(t,
|
||||||
|
fmt.Sprintf("tm.event='Tx' AND tx.hash='%X'", tx.Hash()),
|
||||||
|
EventQueryTxFor(tx).String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQueryForEvent(t *testing.T) {
|
||||||
|
assert.Equal(t,
|
||||||
|
"tm.event='NewBlock'",
|
||||||
|
QueryForEvent(EventNewBlock).String(),
|
||||||
|
)
|
||||||
|
}
|
@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/tendermint/go-amino"
|
amino "github.com/tendermint/go-amino"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
"github.com/tendermint/tendermint/crypto/merkle"
|
"github.com/tendermint/tendermint/crypto/merkle"
|
||||||
|
@ -36,7 +36,7 @@ func TestEvidence(t *testing.T) {
|
|||||||
blockID3 := makeBlockID("blockhash", 10000, "partshash")
|
blockID3 := makeBlockID("blockhash", 10000, "partshash")
|
||||||
blockID4 := makeBlockID("blockhash", 10000, "partshash2")
|
blockID4 := makeBlockID("blockhash", 10000, "partshash2")
|
||||||
|
|
||||||
chainID := "mychain"
|
const chainID = "mychain"
|
||||||
|
|
||||||
vote1 := makeVote(val, chainID, 0, 10, 2, 1, blockID)
|
vote1 := makeVote(val, chainID, 0, 10, 2, 1, blockID)
|
||||||
badVote := makeVote(val, chainID, 0, 10, 2, 1, blockID)
|
badVote := makeVote(val, chainID, 0, 10, 2, 1, blockID)
|
||||||
@ -72,3 +72,30 @@ func TestEvidence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDuplicatedVoteEvidence(t *testing.T) {
|
||||||
|
ev := randomDuplicatedVoteEvidence()
|
||||||
|
|
||||||
|
assert.True(t, ev.Equal(ev))
|
||||||
|
assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvidenceList(t *testing.T) {
|
||||||
|
ev := randomDuplicatedVoteEvidence()
|
||||||
|
evl := EvidenceList([]Evidence{ev})
|
||||||
|
|
||||||
|
assert.NotNil(t, evl.Hash())
|
||||||
|
assert.True(t, evl.Has(ev))
|
||||||
|
assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomDuplicatedVoteEvidence() *DuplicateVoteEvidence {
|
||||||
|
val := NewMockPV()
|
||||||
|
blockID := makeBlockID("blockhash", 1000, "partshash")
|
||||||
|
blockID2 := makeBlockID("blockhash2", 1000, "partshash")
|
||||||
|
const chainID = "mychain"
|
||||||
|
return &DuplicateVoteEvidence{
|
||||||
|
VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
|
||||||
|
VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,17 +26,7 @@ type GenesisDoc struct {
|
|||||||
ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"`
|
ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"`
|
||||||
Validators []GenesisValidator `json:"validators"`
|
Validators []GenesisValidator `json:"validators"`
|
||||||
AppHash cmn.HexBytes `json:"app_hash"`
|
AppHash cmn.HexBytes `json:"app_hash"`
|
||||||
AppStateJSON json.RawMessage `json:"app_state,omitempty"`
|
AppState json.RawMessage `json:"app_state,omitempty"`
|
||||||
AppOptions json.RawMessage `json:"app_options,omitempty"` // DEPRECATED
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppState returns raw application state.
|
|
||||||
// TODO: replace with AppState field during next breaking release (0.18)
|
|
||||||
func (genDoc *GenesisDoc) AppState() json.RawMessage {
|
|
||||||
if len(genDoc.AppOptions) > 0 {
|
|
||||||
return genDoc.AppOptions
|
|
||||||
}
|
|
||||||
return genDoc.AppStateJSON
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveAs is a utility method for saving GenensisDoc as a JSON file.
|
// SaveAs is a utility method for saving GenensisDoc as a JSON file.
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,3 +63,44 @@ func TestGenesisGood(t *testing.T) {
|
|||||||
genDoc, err = GenesisDocFromJSON(genDocBytes)
|
genDoc, err = GenesisDocFromJSON(genDocBytes)
|
||||||
assert.Error(t, err, "expected error for genDoc json with block size of 0")
|
assert.Error(t, err, "expected error for genDoc json with block size of 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenesisSaveAs(t *testing.T) {
|
||||||
|
tmpfile, err := ioutil.TempFile("", "genesis")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Remove(tmpfile.Name())
|
||||||
|
|
||||||
|
genDoc := randomGenesisDoc()
|
||||||
|
|
||||||
|
// save
|
||||||
|
genDoc.SaveAs(tmpfile.Name())
|
||||||
|
stat, err := tmpfile.Stat()
|
||||||
|
require.NoError(t, err)
|
||||||
|
if err != nil && stat.Size() <= 0 {
|
||||||
|
t.Fatalf("SaveAs failed to write any bytes to %v", tmpfile.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tmpfile.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// load
|
||||||
|
genDoc2, err := GenesisDocFromFile(tmpfile.Name())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// fails to unknown reason
|
||||||
|
// assert.EqualValues(t, genDoc2, genDoc)
|
||||||
|
assert.Equal(t, genDoc2.Validators, genDoc.Validators)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenesisValidatorHash(t *testing.T) {
|
||||||
|
genDoc := randomGenesisDoc()
|
||||||
|
assert.NotEmpty(t, genDoc.ValidatorHash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomGenesisDoc() *GenesisDoc {
|
||||||
|
return &GenesisDoc{
|
||||||
|
GenesisTime: time.Now().UTC(),
|
||||||
|
ChainID: "abc",
|
||||||
|
Validators: []GenesisValidator{{crypto.GenPrivKeyEd25519().PubKey(), 10, "myval"}},
|
||||||
|
ConsensusParams: DefaultConsensusParams(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConsensusParams(blockSize, partSize int) ConsensusParams {
|
func newConsensusParams(blockSize, partSize int) ConsensusParams {
|
||||||
@ -86,3 +87,59 @@ func TestConsensusParamsHash(t *testing.T) {
|
|||||||
assert.NotEqual(t, hashes[i], hashes[i+1])
|
assert.NotEqual(t, hashes[i], hashes[i+1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConsensusParamsUpdate(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
params ConsensusParams
|
||||||
|
updates *abci.ConsensusParams
|
||||||
|
updatedParams ConsensusParams
|
||||||
|
}{
|
||||||
|
// empty updates
|
||||||
|
{
|
||||||
|
makeParams(1, 2, 3, 4, 5, 6),
|
||||||
|
&abci.ConsensusParams{},
|
||||||
|
makeParams(1, 2, 3, 4, 5, 6),
|
||||||
|
},
|
||||||
|
// negative BlockPartSizeBytes
|
||||||
|
{
|
||||||
|
makeParams(1, 2, 3, 4, 5, 6),
|
||||||
|
&abci.ConsensusParams{
|
||||||
|
BlockSize: &abci.BlockSize{
|
||||||
|
MaxBytes: -100,
|
||||||
|
MaxTxs: -200,
|
||||||
|
MaxGas: -300,
|
||||||
|
},
|
||||||
|
TxSize: &abci.TxSize{
|
||||||
|
MaxBytes: -400,
|
||||||
|
MaxGas: -500,
|
||||||
|
},
|
||||||
|
BlockGossip: &abci.BlockGossip{
|
||||||
|
BlockPartSizeBytes: -600,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
makeParams(1, 2, 3, 4, 5, 6),
|
||||||
|
},
|
||||||
|
// fine updates
|
||||||
|
{
|
||||||
|
makeParams(1, 2, 3, 4, 5, 6),
|
||||||
|
&abci.ConsensusParams{
|
||||||
|
BlockSize: &abci.BlockSize{
|
||||||
|
MaxBytes: 100,
|
||||||
|
MaxTxs: 200,
|
||||||
|
MaxGas: 300,
|
||||||
|
},
|
||||||
|
TxSize: &abci.TxSize{
|
||||||
|
MaxBytes: 400,
|
||||||
|
MaxGas: 500,
|
||||||
|
},
|
||||||
|
BlockGossip: &abci.BlockGossip{
|
||||||
|
BlockPartSizeBytes: 600,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
makeParams(100, 200, 300, 400, 500, 600),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
assert.Equal(t, tc.updatedParams, tc.params.Update(tc.updates))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,24 +15,21 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBasicPartSet(t *testing.T) {
|
func TestBasicPartSet(t *testing.T) {
|
||||||
|
|
||||||
// Construct random data of size partSize * 100
|
// Construct random data of size partSize * 100
|
||||||
data := cmn.RandBytes(testPartSize * 100)
|
data := cmn.RandBytes(testPartSize * 100)
|
||||||
|
|
||||||
partSet := NewPartSetFromData(data, testPartSize)
|
partSet := NewPartSetFromData(data, testPartSize)
|
||||||
if len(partSet.Hash()) == 0 {
|
|
||||||
t.Error("Expected to get hash")
|
assert.NotEmpty(t, partSet.Hash())
|
||||||
}
|
assert.Equal(t, 100, partSet.Total())
|
||||||
if partSet.Total() != 100 {
|
assert.Equal(t, 100, partSet.BitArray().Size())
|
||||||
t.Errorf("Expected to get 100 parts, but got %v", partSet.Total())
|
assert.True(t, partSet.HashesTo(partSet.Hash()))
|
||||||
}
|
assert.True(t, partSet.IsComplete())
|
||||||
if !partSet.IsComplete() {
|
assert.Equal(t, 100, partSet.Count())
|
||||||
t.Errorf("PartSet should be complete")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test adding parts to a new partSet.
|
// Test adding parts to a new partSet.
|
||||||
partSet2 := NewPartSetFromHeader(partSet.Header())
|
partSet2 := NewPartSetFromHeader(partSet.Header())
|
||||||
|
|
||||||
|
assert.True(t, partSet2.HasHeader(partSet.Header()))
|
||||||
for i := 0; i < partSet.Total(); i++ {
|
for i := 0; i < partSet.Total(); i++ {
|
||||||
part := partSet.GetPart(i)
|
part := partSet.GetPart(i)
|
||||||
//t.Logf("\n%v", part)
|
//t.Logf("\n%v", part)
|
||||||
@ -39,31 +38,28 @@ func TestBasicPartSet(t *testing.T) {
|
|||||||
t.Errorf("Failed to add part %v, error: %v", i, err)
|
t.Errorf("Failed to add part %v, error: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// adding part with invalid index
|
||||||
|
added, err := partSet2.AddPart(&Part{Index: 10000})
|
||||||
|
assert.False(t, added)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// adding existing part
|
||||||
|
added, err = partSet2.AddPart(partSet2.GetPart(0))
|
||||||
|
assert.False(t, added)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
if !bytes.Equal(partSet.Hash(), partSet2.Hash()) {
|
assert.Equal(t, partSet.Hash(), partSet2.Hash())
|
||||||
t.Error("Expected to get same hash")
|
assert.Equal(t, 100, partSet2.Total())
|
||||||
}
|
assert.True(t, partSet2.IsComplete())
|
||||||
if partSet2.Total() != 100 {
|
|
||||||
t.Errorf("Expected to get 100 parts, but got %v", partSet2.Total())
|
|
||||||
}
|
|
||||||
if !partSet2.IsComplete() {
|
|
||||||
t.Errorf("Reconstructed PartSet should be complete")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconstruct data, assert that they are equal.
|
// Reconstruct data, assert that they are equal.
|
||||||
data2Reader := partSet2.GetReader()
|
data2Reader := partSet2.GetReader()
|
||||||
data2, err := ioutil.ReadAll(data2Reader)
|
data2, err := ioutil.ReadAll(data2Reader)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Errorf("Error reading data2Reader: %v", err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(data, data2) {
|
|
||||||
t.Errorf("Got wrong data.")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
assert.Equal(t, data, data2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWrongProof(t *testing.T) {
|
func TestWrongProof(t *testing.T) {
|
||||||
|
|
||||||
// Construct random data of size partSize * 100
|
// Construct random data of size partSize * 100
|
||||||
data := cmn.RandBytes(testPartSize * 100)
|
data := cmn.RandBytes(testPartSize * 100)
|
||||||
partSet := NewPartSetFromData(data, testPartSize)
|
partSet := NewPartSetFromData(data, testPartSize)
|
||||||
@ -86,5 +82,4 @@ func TestWrongProof(t *testing.T) {
|
|||||||
if added || err == nil {
|
if added || err == nil {
|
||||||
t.Errorf("Expected to fail adding a part with bad bytes.")
|
t.Errorf("Expected to fail adding a part with bad bytes.")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
|
|||||||
|
|
||||||
// XXX: panics on nil or unknown pubkey type
|
// XXX: panics on nil or unknown pubkey type
|
||||||
func (tm2pb) Validators(vals *ValidatorSet) []abci.Validator {
|
func (tm2pb) Validators(vals *ValidatorSet) []abci.Validator {
|
||||||
validators := make([]abci.Validator, len(vals.Validators))
|
validators := make([]abci.Validator, vals.Size())
|
||||||
for i, val := range vals.Validators {
|
for i, val := range vals.Validators {
|
||||||
validators[i] = TM2PB.Validator(val)
|
validators[i] = TM2PB.Validator(val)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
@ -43,6 +44,9 @@ func TestABCIValidators(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, tmValExpected, tmVals[0])
|
assert.Equal(t, tmValExpected, tmVals[0])
|
||||||
|
|
||||||
|
abciVals := TM2PB.Validators(NewValidatorSet(tmVals))
|
||||||
|
assert.Equal(t, []abci.Validator{abciVal}, abciVals)
|
||||||
|
|
||||||
// val with address
|
// val with address
|
||||||
tmVal.Address = pkEd.Address()
|
tmVal.Address = pkEd.Address()
|
||||||
|
|
||||||
@ -67,3 +71,50 @@ func TestABCIConsensusParams(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, *cp, cp2)
|
assert.Equal(t, *cp, cp2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestABCIHeader(t *testing.T) {
|
||||||
|
header := &Header{
|
||||||
|
Height: int64(3),
|
||||||
|
Time: time.Now(),
|
||||||
|
NumTxs: int64(10),
|
||||||
|
}
|
||||||
|
abciHeader := TM2PB.Header(header)
|
||||||
|
|
||||||
|
assert.Equal(t, int64(3), abciHeader.Height)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestABCIEvidence(t *testing.T) {
|
||||||
|
val := NewMockPV()
|
||||||
|
blockID := makeBlockID("blockhash", 1000, "partshash")
|
||||||
|
blockID2 := makeBlockID("blockhash2", 1000, "partshash")
|
||||||
|
const chainID = "mychain"
|
||||||
|
ev := &DuplicateVoteEvidence{
|
||||||
|
PubKey: val.GetPubKey(),
|
||||||
|
VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
|
||||||
|
VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
|
||||||
|
}
|
||||||
|
abciEv := TM2PB.Evidence(
|
||||||
|
ev,
|
||||||
|
NewValidatorSet([]*Validator{NewValidator(val.GetPubKey(), 10)}),
|
||||||
|
time.Now(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Equal(t, "duplicate/vote", abciEv.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pubKeyEddie struct{}
|
||||||
|
|
||||||
|
func (pubKeyEddie) Address() Address { return []byte{} }
|
||||||
|
func (pubKeyEddie) Bytes() []byte { return []byte{} }
|
||||||
|
func (pubKeyEddie) VerifyBytes(msg []byte, sig crypto.Signature) bool { return false }
|
||||||
|
func (pubKeyEddie) Equals(crypto.PubKey) bool { return false }
|
||||||
|
|
||||||
|
func TestABCIValidatorFromPubKeyAndPower(t *testing.T) {
|
||||||
|
pubkey := crypto.GenPrivKeyEd25519().PubKey()
|
||||||
|
|
||||||
|
abciVal := TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10)
|
||||||
|
assert.Equal(t, int64(10), abciVal.Power)
|
||||||
|
|
||||||
|
assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(nil, 10) })
|
||||||
|
assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(pubKeyEddie{}, 10) })
|
||||||
|
}
|
||||||
|
@ -24,15 +24,16 @@ func (a ABCIResult) Hash() []byte {
|
|||||||
// ABCIResults wraps the deliver tx results to return a proof
|
// ABCIResults wraps the deliver tx results to return a proof
|
||||||
type ABCIResults []ABCIResult
|
type ABCIResults []ABCIResult
|
||||||
|
|
||||||
// NewResults creates ABCIResults from ResponseDeliverTx
|
// NewResults creates ABCIResults from the list of ResponseDeliverTx.
|
||||||
func NewResults(del []*abci.ResponseDeliverTx) ABCIResults {
|
func NewResults(responses []*abci.ResponseDeliverTx) ABCIResults {
|
||||||
res := make(ABCIResults, len(del))
|
res := make(ABCIResults, len(responses))
|
||||||
for i, d := range del {
|
for i, d := range responses {
|
||||||
res[i] = NewResultFromResponse(d)
|
res[i] = NewResultFromResponse(d)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewResultFromResponse creates ABCIResult from ResponseDeliverTx.
|
||||||
func NewResultFromResponse(response *abci.ResponseDeliverTx) ABCIResult {
|
func NewResultFromResponse(response *abci.ResponseDeliverTx) ABCIResult {
|
||||||
return ABCIResult{
|
return ABCIResult{
|
||||||
Code: response.Code,
|
Code: response.Code,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestABCIResults(t *testing.T) {
|
func TestABCIResults(t *testing.T) {
|
||||||
@ -41,3 +42,14 @@ func TestABCIResults(t *testing.T) {
|
|||||||
assert.True(t, valid, "%d", i)
|
assert.True(t, valid, "%d", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestABCIBytes(t *testing.T) {
|
||||||
|
results := NewResults([]*abci.ResponseDeliverTx{
|
||||||
|
{Code: 0, Data: []byte{}},
|
||||||
|
{Code: 0, Data: []byte("one")},
|
||||||
|
{Code: 14, Data: nil},
|
||||||
|
{Code: 14, Data: []byte("foo")},
|
||||||
|
{Code: 14, Data: []byte("bar")},
|
||||||
|
})
|
||||||
|
assert.NotNil(t, results.Bytes())
|
||||||
|
}
|
||||||
|
@ -24,21 +24,32 @@ func randInt(low, high int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTxIndex(t *testing.T) {
|
func TestTxIndex(t *testing.T) {
|
||||||
assert := assert.New(t)
|
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
txs := makeTxs(15, 60)
|
txs := makeTxs(15, 60)
|
||||||
for j := 0; j < len(txs); j++ {
|
for j := 0; j < len(txs); j++ {
|
||||||
tx := txs[j]
|
tx := txs[j]
|
||||||
idx := txs.Index(tx)
|
idx := txs.Index(tx)
|
||||||
assert.Equal(j, idx)
|
assert.Equal(t, j, idx)
|
||||||
}
|
}
|
||||||
assert.Equal(-1, txs.Index(nil))
|
assert.Equal(t, -1, txs.Index(nil))
|
||||||
assert.Equal(-1, txs.Index(Tx("foodnwkf")))
|
assert.Equal(t, -1, txs.Index(Tx("foodnwkf")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTxIndexByHash(t *testing.T) {
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
txs := makeTxs(15, 60)
|
||||||
|
for j := 0; j < len(txs); j++ {
|
||||||
|
tx := txs[j]
|
||||||
|
idx := txs.IndexByHash(tx.Hash())
|
||||||
|
assert.Equal(t, j, idx)
|
||||||
|
}
|
||||||
|
assert.Equal(t, -1, txs.IndexByHash(nil))
|
||||||
|
assert.Equal(t, -1, txs.IndexByHash(Tx("foodnwkf").Hash()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidTxProof(t *testing.T) {
|
func TestValidTxProof(t *testing.T) {
|
||||||
assert := assert.New(t)
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
txs Txs
|
txs Txs
|
||||||
}{
|
}{
|
||||||
@ -58,21 +69,21 @@ func TestValidTxProof(t *testing.T) {
|
|||||||
leaf := txs[i]
|
leaf := txs[i]
|
||||||
leafHash := leaf.Hash()
|
leafHash := leaf.Hash()
|
||||||
proof := txs.Proof(i)
|
proof := txs.Proof(i)
|
||||||
assert.Equal(i, proof.Index, "%d: %d", h, i)
|
assert.Equal(t, i, proof.Index, "%d: %d", h, i)
|
||||||
assert.Equal(len(txs), proof.Total, "%d: %d", h, i)
|
assert.Equal(t, len(txs), proof.Total, "%d: %d", h, i)
|
||||||
assert.EqualValues(root, proof.RootHash, "%d: %d", h, i)
|
assert.EqualValues(t, root, proof.RootHash, "%d: %d", h, i)
|
||||||
assert.EqualValues(leaf, proof.Data, "%d: %d", h, i)
|
assert.EqualValues(t, leaf, proof.Data, "%d: %d", h, i)
|
||||||
assert.EqualValues(leafHash, proof.LeafHash(), "%d: %d", h, i)
|
assert.EqualValues(t, leafHash, proof.LeafHash(), "%d: %d", h, i)
|
||||||
assert.Nil(proof.Validate(root), "%d: %d", h, i)
|
assert.Nil(t, proof.Validate(root), "%d: %d", h, i)
|
||||||
assert.NotNil(proof.Validate([]byte("foobar")), "%d: %d", h, i)
|
assert.NotNil(t, proof.Validate([]byte("foobar")), "%d: %d", h, i)
|
||||||
|
|
||||||
// read-write must also work
|
// read-write must also work
|
||||||
var p2 TxProof
|
var p2 TxProof
|
||||||
bin, err := cdc.MarshalBinary(proof)
|
bin, err := cdc.MarshalBinary(proof)
|
||||||
assert.Nil(err)
|
assert.Nil(t, err)
|
||||||
err = cdc.UnmarshalBinary(bin, &p2)
|
err = cdc.UnmarshalBinary(bin, &p2)
|
||||||
if assert.Nil(err, "%d: %d: %+v", h, i, err) {
|
if assert.Nil(t, err, "%d: %d: %+v", h, i, err) {
|
||||||
assert.Nil(p2.Validate(root), "%d: %d", h, i)
|
assert.Nil(t, p2.Validate(root), "%d: %d", h, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,8 +97,6 @@ func TestTxProofUnchangable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testTxProofUnchangable(t *testing.T) {
|
func testTxProofUnchangable(t *testing.T) {
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
// make some proof
|
// make some proof
|
||||||
txs := makeTxs(randInt(2, 100), randInt(16, 128))
|
txs := makeTxs(randInt(2, 100), randInt(16, 128))
|
||||||
root := txs.Hash()
|
root := txs.Hash()
|
||||||
@ -95,9 +104,9 @@ func testTxProofUnchangable(t *testing.T) {
|
|||||||
proof := txs.Proof(i)
|
proof := txs.Proof(i)
|
||||||
|
|
||||||
// make sure it is valid to start with
|
// make sure it is valid to start with
|
||||||
assert.Nil(proof.Validate(root))
|
assert.Nil(t, proof.Validate(root))
|
||||||
bin, err := cdc.MarshalBinary(proof)
|
bin, err := cdc.MarshalBinary(proof)
|
||||||
assert.Nil(err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// try mutating the data and make sure nothing breaks
|
// try mutating the data and make sure nothing breaks
|
||||||
for j := 0; j < 500; j++ {
|
for j := 0; j < 500; j++ {
|
||||||
|
@ -39,14 +39,15 @@ func NewValidatorSet(vals []*Validator) *ValidatorSet {
|
|||||||
Validators: validators,
|
Validators: validators,
|
||||||
}
|
}
|
||||||
|
|
||||||
if vals != nil {
|
if len(vals) > 0 {
|
||||||
vs.IncrementAccum(1)
|
vs.IncrementAccum(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vs
|
return vs
|
||||||
}
|
}
|
||||||
|
|
||||||
// incrementAccum and update the proposer
|
// IncrementAccum increments accum of each validator and updates the
|
||||||
|
// proposer. Panics if validator set is empty.
|
||||||
func (valSet *ValidatorSet) IncrementAccum(times int) {
|
func (valSet *ValidatorSet) IncrementAccum(times int) {
|
||||||
// Add VotingPower * times to each validator and order into heap.
|
// Add VotingPower * times to each validator and order into heap.
|
||||||
validatorsHeap := cmn.NewHeap()
|
validatorsHeap := cmn.NewHeap()
|
||||||
|
@ -14,6 +14,60 @@ import (
|
|||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestValidatorSetBasic(t *testing.T) {
|
||||||
|
for _, vset := range []*ValidatorSet{NewValidatorSet([]*Validator{}), NewValidatorSet(nil)} {
|
||||||
|
assert.Panics(t, func() { vset.IncrementAccum(1) })
|
||||||
|
|
||||||
|
assert.EqualValues(t, vset, vset.Copy())
|
||||||
|
assert.False(t, vset.HasAddress([]byte("some val")))
|
||||||
|
idx, val := vset.GetByAddress([]byte("some val"))
|
||||||
|
assert.Equal(t, -1, idx)
|
||||||
|
assert.Nil(t, val)
|
||||||
|
addr, val := vset.GetByIndex(-100)
|
||||||
|
assert.Nil(t, addr)
|
||||||
|
assert.Nil(t, val)
|
||||||
|
addr, val = vset.GetByIndex(0)
|
||||||
|
assert.Nil(t, addr)
|
||||||
|
assert.Nil(t, val)
|
||||||
|
addr, val = vset.GetByIndex(100)
|
||||||
|
assert.Nil(t, addr)
|
||||||
|
assert.Nil(t, val)
|
||||||
|
assert.Zero(t, vset.Size())
|
||||||
|
assert.Equal(t, int64(0), vset.TotalVotingPower())
|
||||||
|
assert.Nil(t, vset.GetProposer())
|
||||||
|
assert.Nil(t, vset.Hash())
|
||||||
|
|
||||||
|
// add
|
||||||
|
val = randValidator_()
|
||||||
|
assert.True(t, vset.Add(val))
|
||||||
|
assert.True(t, vset.HasAddress(val.Address))
|
||||||
|
idx, val2 := vset.GetByAddress(val.Address)
|
||||||
|
assert.Equal(t, 0, idx)
|
||||||
|
assert.Equal(t, val, val2)
|
||||||
|
addr, val2 = vset.GetByIndex(0)
|
||||||
|
assert.Equal(t, []byte(val.Address), addr)
|
||||||
|
assert.Equal(t, val, val2)
|
||||||
|
assert.Equal(t, 1, vset.Size())
|
||||||
|
assert.Equal(t, val.VotingPower, vset.TotalVotingPower())
|
||||||
|
assert.Equal(t, val, vset.GetProposer())
|
||||||
|
assert.NotNil(t, vset.Hash())
|
||||||
|
assert.NotPanics(t, func() { vset.IncrementAccum(1) })
|
||||||
|
|
||||||
|
// update
|
||||||
|
assert.False(t, vset.Update(randValidator_()))
|
||||||
|
val.VotingPower = 100
|
||||||
|
assert.True(t, vset.Update(val))
|
||||||
|
|
||||||
|
// remove
|
||||||
|
val2, removed := vset.Remove(randValidator_().Address)
|
||||||
|
assert.Nil(t, val2)
|
||||||
|
assert.False(t, removed)
|
||||||
|
val2, removed = vset.Remove(val.Address)
|
||||||
|
assert.Equal(t, val.Address, val2.Address)
|
||||||
|
assert.True(t, removed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
vset := randValidatorSet(10)
|
vset := randValidatorSet(10)
|
||||||
vsetHash := vset.Hash()
|
vsetHash := vset.Hash()
|
||||||
|
@ -4,7 +4,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tendermint/tendermint/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func examplePrevote() *Vote {
|
func examplePrevote() *Vote {
|
||||||
@ -50,29 +52,9 @@ func TestVoteSignable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVoteString(t *testing.T) {
|
|
||||||
tc := []struct {
|
|
||||||
name string
|
|
||||||
in string
|
|
||||||
out string
|
|
||||||
}{
|
|
||||||
{"Precommit", examplePrecommit().String(), `Vote{56789:616464720000 12345/02/2(Precommit) 686173680000 <nil> @ 2017-12-25T03:00:01.234Z}`},
|
|
||||||
{"Prevote", examplePrevote().String(), `Vote{56789:616464720000 12345/02/1(Prevote) 686173680000 <nil> @ 2017-12-25T03:00:01.234Z}`},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tc {
|
|
||||||
tt := tt
|
|
||||||
t.Run(tt.name, func(st *testing.T) {
|
|
||||||
if tt.in != tt.out {
|
|
||||||
t.Errorf("Got unexpected string for Proposal. Expected:\n%v\nGot:\n%v", tt.in, tt.out)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVoteVerifySignature(t *testing.T) {
|
func TestVoteVerifySignature(t *testing.T) {
|
||||||
privVal := NewMockPV()
|
privVal := NewMockPV()
|
||||||
pubKey := privVal.GetPubKey()
|
pubkey := privVal.GetPubKey()
|
||||||
|
|
||||||
vote := examplePrecommit()
|
vote := examplePrecommit()
|
||||||
signBytes := vote.SignBytes("test_chain_id")
|
signBytes := vote.SignBytes("test_chain_id")
|
||||||
@ -82,7 +64,7 @@ func TestVoteVerifySignature(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// verify the same vote
|
// verify the same vote
|
||||||
valid := pubKey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
|
valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
|
||||||
require.True(t, valid)
|
require.True(t, valid)
|
||||||
|
|
||||||
// serialize, deserialize and verify again....
|
// serialize, deserialize and verify again....
|
||||||
@ -95,7 +77,7 @@ func TestVoteVerifySignature(t *testing.T) {
|
|||||||
// verify the transmitted vote
|
// verify the transmitted vote
|
||||||
newSignBytes := precommit.SignBytes("test_chain_id")
|
newSignBytes := precommit.SignBytes("test_chain_id")
|
||||||
require.Equal(t, string(signBytes), string(newSignBytes))
|
require.Equal(t, string(signBytes), string(newSignBytes))
|
||||||
valid = pubKey.VerifyBytes(newSignBytes, precommit.Signature)
|
valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
|
||||||
require.True(t, valid)
|
require.True(t, valid)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,3 +101,21 @@ func TestIsVoteTypeValid(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVoteVerify(t *testing.T) {
|
||||||
|
privVal := NewMockPV()
|
||||||
|
pubkey := privVal.GetPubKey()
|
||||||
|
|
||||||
|
vote := examplePrevote()
|
||||||
|
vote.ValidatorAddress = pubkey.Address()
|
||||||
|
|
||||||
|
err := vote.Verify("test_chain_id", crypto.GenPrivKeyEd25519().PubKey())
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.Equal(t, ErrVoteInvalidValidatorAddress, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = vote.Verify("test_chain_id", pubkey)
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.Equal(t, ErrVoteInvalidSignature, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user