mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
consensus: fix test for blocks with evidence
This commit is contained in:
parent
40d6dc2ee5
commit
fe5b0d7074
@ -17,14 +17,14 @@ import (
|
|||||||
bc "github.com/tendermint/tendermint/blockchain"
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
cstypes "github.com/tendermint/tendermint/consensus/types"
|
cstypes "github.com/tendermint/tendermint/consensus/types"
|
||||||
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
mempl "github.com/tendermint/tendermint/mempool"
|
mempl "github.com/tendermint/tendermint/mempool"
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
"github.com/tendermint/tendermint/privval"
|
"github.com/tendermint/tendermint/privval"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
|
||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/abci/example/counter"
|
"github.com/tendermint/tendermint/abci/example/counter"
|
||||||
"github.com/tendermint/tendermint/abci/example/kvstore"
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
||||||
@ -429,7 +429,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
|
|||||||
func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) {
|
func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) {
|
||||||
genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower)
|
genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower)
|
||||||
s0, _ := sm.MakeGenesisState(genDoc)
|
s0, _ := sm.MakeGenesisState(genDoc)
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB() // remove this ?
|
||||||
sm.SaveState(db, s0)
|
sm.SaveState(db, s0)
|
||||||
return s0, privValidators
|
return s0, privValidators
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,21 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
abcicli "github.com/tendermint/tendermint/abci/client"
|
||||||
"github.com/tendermint/tendermint/abci/example/kvstore"
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
mempl "github.com/tendermint/tendermint/mempool"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
@ -94,49 +100,118 @@ func TestReactorBasic(t *testing.T) {
|
|||||||
|
|
||||||
// Ensure we can process blocks with evidence
|
// Ensure we can process blocks with evidence
|
||||||
func TestReactorWithEvidence(t *testing.T) {
|
func TestReactorWithEvidence(t *testing.T) {
|
||||||
N := 4
|
nValidators := 4
|
||||||
css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter)
|
testName := "consensus_reactor_test"
|
||||||
evpool := mockEvidencePool{
|
tickerFunc := newMockTickerFunc(true)
|
||||||
t: t,
|
appFunc := newCounter
|
||||||
ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, []byte("somone"))},
|
|
||||||
|
// heed the advice from https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction
|
||||||
|
// to unroll unwieldy abstractions. Here we duplicate the code from:
|
||||||
|
// css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter)
|
||||||
|
|
||||||
|
genDoc, privVals := randGenesisDoc(nValidators, false, 30)
|
||||||
|
css := make([]*ConsensusState, nValidators)
|
||||||
|
logger := consensusLogger()
|
||||||
|
for i := 0; i < nValidators; i++ {
|
||||||
|
stateDB := dbm.NewMemDB() // each state needs its own db
|
||||||
|
state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc)
|
||||||
|
thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i))
|
||||||
|
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||||
|
app := appFunc()
|
||||||
|
vals := types.TM2PB.Validators(state.Validators)
|
||||||
|
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||||
|
|
||||||
|
pv := privVals[i]
|
||||||
|
// duplicate code from:
|
||||||
|
// css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app)
|
||||||
|
|
||||||
|
blockDB := dbm.NewMemDB()
|
||||||
|
blockStore := bc.NewBlockStore(blockDB)
|
||||||
|
|
||||||
|
// one for mempool, one for consensus
|
||||||
|
mtx := new(sync.Mutex)
|
||||||
|
proxyAppConnMem := abcicli.NewLocalClient(mtx, app)
|
||||||
|
proxyAppConnCon := abcicli.NewLocalClient(mtx, app)
|
||||||
|
|
||||||
|
// Make Mempool
|
||||||
|
mempool := mempl.NewMempool(thisConfig.Mempool, proxyAppConnMem, 0)
|
||||||
|
mempool.SetLogger(log.TestingLogger().With("module", "mempool"))
|
||||||
|
if thisConfig.Consensus.WaitForTxs() {
|
||||||
|
mempool.EnableTxsAvailable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// mock the evidence pool
|
||||||
|
// everyone includes evidence of another double signing
|
||||||
|
vIdx := (i + 1) % nValidators
|
||||||
|
evpool := newMockEvidencePool(privVals[vIdx].GetAddress())
|
||||||
|
|
||||||
|
// Make ConsensusState
|
||||||
|
blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool)
|
||||||
|
cs := NewConsensusState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool)
|
||||||
|
cs.SetLogger(log.TestingLogger().With("module", "consensus"))
|
||||||
|
cs.SetPrivValidator(pv)
|
||||||
|
|
||||||
|
eventBus := types.NewEventBus()
|
||||||
|
eventBus.SetLogger(log.TestingLogger().With("module", "events"))
|
||||||
|
eventBus.Start()
|
||||||
|
cs.SetEventBus(eventBus)
|
||||||
|
|
||||||
|
cs.SetTimeoutTicker(tickerFunc())
|
||||||
|
cs.SetLogger(logger.With("validator", i, "module", "consensus"))
|
||||||
|
|
||||||
|
css[i] = cs
|
||||||
}
|
}
|
||||||
for i := 0; i < N; i++ {
|
|
||||||
css[i].evpool = evpool
|
reactors, eventChans, eventBuses := startConsensusNet(t, css, nValidators)
|
||||||
}
|
|
||||||
reactors, eventChans, eventBuses := startConsensusNet(t, css, N)
|
|
||||||
defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses)
|
defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses)
|
||||||
// wait till everyone makes the first new block
|
|
||||||
timeoutWaitGroup(t, N, func(j int) {
|
// wait till everyone makes the first new block with no evidence
|
||||||
<-eventChans[j]
|
timeoutWaitGroup(t, nValidators, func(j int) {
|
||||||
|
blockI := <-eventChans[j]
|
||||||
|
block := blockI.(types.EventDataNewBlock).Block
|
||||||
|
assert.True(t, len(block.Evidence.Evidence) == 0)
|
||||||
}, css)
|
}, css)
|
||||||
|
|
||||||
// second block should have evidence
|
// second block should have evidence
|
||||||
timeoutWaitGroup(t, N, func(j int) {
|
timeoutWaitGroup(t, nValidators, func(j int) {
|
||||||
<-eventChans[j]
|
blockI := <-eventChans[j]
|
||||||
|
block := blockI.(types.EventDataNewBlock).Block
|
||||||
|
assert.True(t, len(block.Evidence.Evidence) > 0)
|
||||||
}, css)
|
}, css)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mock evidence pool returns no evidence for block 1,
|
||||||
|
// and returnes one piece for all higher blocks. The one piece
|
||||||
|
// is for a given validator at block 1.
|
||||||
type mockEvidencePool struct {
|
type mockEvidencePool struct {
|
||||||
height int
|
height int
|
||||||
ev []types.Evidence
|
ev []types.Evidence
|
||||||
t *testing.T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mockEvidencePool) PendingEvidence() []types.Evidence {
|
func newMockEvidencePool(val []byte) *mockEvidencePool {
|
||||||
|
return &mockEvidencePool{
|
||||||
|
ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, val)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockEvidencePool) PendingEvidence() []types.Evidence {
|
||||||
if m.height > 0 {
|
if m.height > 0 {
|
||||||
return m.ev
|
return m.ev
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (m mockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
func (m *mockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
||||||
func (m mockEvidencePool) Update(block *types.Block, state sm.State) {
|
func (m *mockEvidencePool) Update(block *types.Block, state sm.State) {
|
||||||
m.height += 1
|
|
||||||
|
|
||||||
if m.height > 0 {
|
if m.height > 0 {
|
||||||
require.True(m.t, len(block.Evidence.Evidence) > 0)
|
if len(block.Evidence.Evidence) == 0 {
|
||||||
|
panic("block has no evidence")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
m.height += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------
|
||||||
|
|
||||||
// Ensure a testnet sends proposal heartbeats and makes blocks when there are txs
|
// Ensure a testnet sends proposal heartbeats and makes blocks when there are txs
|
||||||
func TestReactorProposalHeartbeats(t *testing.T) {
|
func TestReactorProposalHeartbeats(t *testing.T) {
|
||||||
N := 4
|
N := 4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user