Skip to content

Commit

Permalink
feat(consensus): add create_proof_block_range config option (#243)
Browse files Browse the repository at this point in the history
Added create_proof_block_range configuration option to control the proof block creation algorithm.
  • Loading branch information
lklimek authored Jan 7, 2022
1 parent 954c301 commit 8acb1d0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,9 @@ type ConsensusConfig struct {
// EmptyBlocks mode and possible interval between empty blocks
CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"`
CreateEmptyBlocksInterval time.Duration `mapstructure:"create_empty_blocks_interval"`
// CreateProofBlockRange determines how many past blocks are inspected in order to determine if we need to create
// additional proof block.
CreateProofBlockRange int64 `mapstructure:"create_proof_block_range"`

// Reactor sleep duration parameters
PeerGossipSleepDuration time.Duration `mapstructure:"peer_gossip_sleep_duration"`
Expand Down Expand Up @@ -947,6 +950,7 @@ func DefaultConsensusConfig() *ConsensusConfig {
DontAutoPropose: false,
CreateEmptyBlocks: true,
CreateEmptyBlocksInterval: 0 * time.Second,
CreateProofBlockRange: 2,
PeerGossipSleepDuration: 100 * time.Millisecond,
PeerQueryMaj23SleepDuration: 2000 * time.Millisecond,
DoubleSignCheckHeight: int64(0),
Expand Down Expand Up @@ -1050,6 +1054,9 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
if cfg.CreateEmptyBlocksInterval < 0 {
return errors.New("create_empty_blocks_interval can't be negative")
}
if cfg.CreateProofBlockRange < 1 {
return errors.New("create_proof_block_range must be greater or equal to 1")
}
if cfg.PeerGossipSleepDuration < 0 {
return errors.New("peer_gossip_sleep_duration can't be negative")
}
Expand Down
3 changes: 3 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }}
create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }}
create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
# How many blocks are inspected in order to determine if we need to create additional proof block.
create_proof_block_range = "{{ .Consensus.CreateProofBlockRange }}"
# Reactor sleep duration parameters
peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
Expand Down
44 changes: 25 additions & 19 deletions consensus/mempool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,31 @@ func assertMempool(txn txNotifier) mempl.Mempool {
}

func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) {
config := ResetConfig("consensus_mempool_txs_available_test")
defer os.RemoveAll(config.RootDir)
config.Consensus.CreateEmptyBlocks = false

state, privVals := randGenesisState(1, false, 100)

cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication())
assertMempool(cs.txNotifier).EnableTxsAvailable()
height, round := cs.Height, cs.Round
newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock)
startTestRound(cs, height, round)

ensureNewEventOnChannel(newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(newBlockCh)
deliverTxsRange(cs, 0, 1)
ensureNewEventOnChannel(newBlockCh) // commit txs
ensureNewEventOnChannel(newBlockCh) // commit updated app hash
ensureNewEventOnChannel(newBlockCh) // commit 2nd block for updated app hash
ensureNoNewEventOnChannel(newBlockCh)
for proofBlockRange := int64(1); proofBlockRange <= 3; proofBlockRange++ {
t.Logf("Checking proof block range %d", proofBlockRange)

config := ResetConfig("consensus_mempool_txs_available_test")
defer os.RemoveAll(config.RootDir)
config.Consensus.CreateEmptyBlocks = false
config.Consensus.CreateProofBlockRange = proofBlockRange

state, privVals := randGenesisState(1, false, types.DefaultDashVotingPower)

cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication())
assertMempool(cs.txNotifier).EnableTxsAvailable()
height, round := cs.Height, cs.Round
newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock)
startTestRound(cs, height, round)

ensureNewEventOnChannel(newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(newBlockCh)
deliverTxsRange(cs, 0, 1)
ensureNewEventOnChannel(newBlockCh) // commit txs
for i := int64(0); i < proofBlockRange; i++ {
ensureNewEventOnChannel(newBlockCh) // commit updated app hash
}
ensureNoNewEventOnChannel(newBlockCh)
}
}

func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) {
Expand Down
15 changes: 10 additions & 5 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1088,21 +1088,26 @@ func (cs *State) needProofBlock(height int64) bool {
return true
}

heights := []int64{height - 1, height - 2}
for _, blockHeight := range heights {
proofBlockRange := cs.config.CreateProofBlockRange

for blockHeight := height - 1; blockHeight >= height-proofBlockRange; blockHeight-- {
if blockHeight >= cs.state.InitialHeight {
blockMeta := cs.blockStore.LoadBlockMeta(blockHeight)
if blockMeta == nil {
panic(fmt.Sprintf("needProofBlock: last block meta for height %d not found", height-1))
panic(fmt.Sprintf("needProofBlock (height=%d): last block meta for height %d not found", height, blockHeight))
}
if !bytes.Equal(cs.state.AppHash, blockMeta.Header.AppHash) {
cs.Logger.Debug("needProofBlock: proof block needed", "height", height, "modified_since", blockHeight)
cs.Logger.Debug(
"needProofBlock: proof block needed",
"height", height,
"modified_height", blockHeight,
"range", proofBlockRange,
)
return true
}
}
}

cs.Logger.Debug("needProofBlock: proof block not needed", "height", height)
return false
}

Expand Down

0 comments on commit 8acb1d0

Please sign in to comment.