commit empty blocks when needed to prove app hash

This commit is contained in:
Ethan Buchman 2017-07-20 14:43:16 -04:00
parent fc3fe9292f
commit ecdda69fab
2 changed files with 23 additions and 6 deletions

View File

@ -15,7 +15,7 @@ func init() {
config = ResetConfig("consensus_mempool_test")
}
func TestTxsAvailable(t *testing.T) {
func TestNoProgressUntilTxsAvailable(t *testing.T) {
config := ResetConfig("consensus_mempool_txs_available_test")
config.Consensus.NoEmptyBlocks = true
state, privVals := randGenesisState(1, false, 10)
@ -25,10 +25,12 @@ func TestTxsAvailable(t *testing.T) {
newBlockCh := subscribeToEvent(cs.evsw, "tester", types.EventStringNewBlock(), 1)
startTestRound(cs, height, round)
// we shouldnt make progress until theres a tx
ensureNewStep(newBlockCh) // first block gets committed
ensureNoNewStep(newBlockCh)
deliverTxsRange(cs, 0, 2)
ensureNewStep(newBlockCh) // commit txs
ensureNewStep(newBlockCh) // commit updated app hash
ensureNoNewStep(newBlockCh)
deliverTxsRange(cs, 0, 100)
ensureNewStep(newBlockCh)
}
func deliverTxsRange(cs *ConsensusState, start, end int) {

View File

@ -779,14 +779,29 @@ func (cs *ConsensusState) enterNewRound(height int, round int) {
types.FireEventNewRound(cs.evsw, cs.RoundStateEvent())
// Wait for txs to be available in the mempool
// before we enterPropose
if cs.config.NoEmptyBlocks {
// before we enterPropose. If the last block changed the app hash,
// we may need an empty "proof" block, and enterPropose immediately.
if cs.config.NoEmptyBlocks && !cs.needProofBlock(height) {
go cs.waitForTxs(height, round)
} else {
cs.enterPropose(height, round)
}
}
// needProofBlock returns true on the first height (so the genesis app hash is signed right away)
// and where the last block (height-1) caused the app hash to change
func (cs *ConsensusState) needProofBlock(height int) bool {
if height == 1 {
return true
}
lastBlockMeta := cs.blockStore.LoadBlockMeta(height - 1)
if !bytes.Equal(cs.state.AppHash, lastBlockMeta.Header.AppHash) {
return true
}
return false
}
func (cs *ConsensusState) waitForTxs(height, round int) {
// if we're the proposer, start a heartbeat routine
// to tell other peers we're just waiting for txs (for debugging)