You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1073 lines
39 KiB

Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
abci: Refactor tagging events using list of lists (#3643) ## PR This PR introduces a fundamental breaking change to the structure of ABCI response and tx tags and the way they're processed. Namely, the SDK can support more complex and aggregated events for distribution and slashing. In addition, block responses can include duplicate keys in events. Implement new Event type. An event has a type and a list of KV pairs (ie. list-of-lists). Typical events may look like: "rewards": [{"amount": "5000uatom", "validator": "...", "recipient": "..."}] "sender": [{"address": "...", "balance": "100uatom"}] The events are indexed by {even.type}.{even.attribute[i].key}/.... In this case a client would subscribe or query for rewards.recipient='...' ABCI response types and related types now include Events []Event instead of Tags []cmn.KVPair. PubSub logic now publishes/matches against map[string][]string instead of map[string]string to support duplicate keys in response events (from #1385). A match is successful if the value is found in the slice of strings. closes: #1859 closes: #2905 ## Commits: * Implement Event ABCI type and updates responses to use events * Update messages_test.go * Update kvstore.go * Update event_bus.go * Update subscription.go * Update pubsub.go * Update kvstore.go * Update query logic to handle slice of strings in events * Update Empty#Matches and unit tests * Update pubsub logic * Update EventBus#Publish * Update kv tx indexer * Update godocs * Update ResultEvent to use slice of strings; update RPC * Update more tests * Update abci.md * Check for key in validateAndStringifyEvents * Fix KV indexer to skip empty keys * Fix linting errors * Update CHANGELOG_PENDING.md * Update docs/spec/abci/abci.md Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update abci/types/types.proto Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update docs/spec/abci/abci.md Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update libs/pubsub/query/query.go Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update match function to match if ANY value matches * Implement TestSubscribeDuplicateKeys * Update TestMatches to include multi-key test cases * Update events.go * Update Query interface godoc * Update match godoc * Add godoc for matchValue * DRY-up tx indexing * Return error from PublishWithEvents in EventBus#Publish * Update PublishEventNewBlockHeader to return an error * Fix build * Update events doc in ABCI * Update ABCI events godoc * Implement TestEventBusPublishEventTxDuplicateKeys * Update TestSubscribeDuplicateKeys to be table-driven * Remove mod file * Remove markdown from events godoc * Implement TestTxSearchDeprecatedIndexing test
6 years ago
abci: Refactor tagging events using list of lists (#3643) ## PR This PR introduces a fundamental breaking change to the structure of ABCI response and tx tags and the way they're processed. Namely, the SDK can support more complex and aggregated events for distribution and slashing. In addition, block responses can include duplicate keys in events. Implement new Event type. An event has a type and a list of KV pairs (ie. list-of-lists). Typical events may look like: "rewards": [{"amount": "5000uatom", "validator": "...", "recipient": "..."}] "sender": [{"address": "...", "balance": "100uatom"}] The events are indexed by {even.type}.{even.attribute[i].key}/.... In this case a client would subscribe or query for rewards.recipient='...' ABCI response types and related types now include Events []Event instead of Tags []cmn.KVPair. PubSub logic now publishes/matches against map[string][]string instead of map[string]string to support duplicate keys in response events (from #1385). A match is successful if the value is found in the slice of strings. closes: #1859 closes: #2905 ## Commits: * Implement Event ABCI type and updates responses to use events * Update messages_test.go * Update kvstore.go * Update event_bus.go * Update subscription.go * Update pubsub.go * Update kvstore.go * Update query logic to handle slice of strings in events * Update Empty#Matches and unit tests * Update pubsub logic * Update EventBus#Publish * Update kv tx indexer * Update godocs * Update ResultEvent to use slice of strings; update RPC * Update more tests * Update abci.md * Check for key in validateAndStringifyEvents * Fix KV indexer to skip empty keys * Fix linting errors * Update CHANGELOG_PENDING.md * Update docs/spec/abci/abci.md Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update abci/types/types.proto Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update docs/spec/abci/abci.md Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update libs/pubsub/query/query.go Co-Authored-By: Ethan Buchman <ethan@coinculture.info> * Update match function to match if ANY value matches * Implement TestSubscribeDuplicateKeys * Update TestMatches to include multi-key test cases * Update events.go * Update Query interface godoc * Update match godoc * Add godoc for matchValue * DRY-up tx indexing * Return error from PublishWithEvents in EventBus#Publish * Update PublishEventNewBlockHeader to return an error * Fix build * Update events doc in ABCI * Update ABCI events godoc * Implement TestEventBusPublishEventTxDuplicateKeys * Update TestSubscribeDuplicateKeys to be table-driven * Remove mod file * Remove markdown from events godoc * Implement TestTxSearchDeprecatedIndexing test
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
Normalize priorities to not exceed total voting power (#3049) * more proposer priority tests - test that we don't reset to zero when updating / adding - test that same power validators alternate * add another test to track / simulate similar behaviour as in #2960 * address some of Chris' review comments * address some more of Chris' review comments * temporarily pushing branch with the following changes: The total power might change if: - a validator is added - a validator is removed - a validator is updated Decrement the accums (of all validators) directly after any of these events (by the inverse of the change) * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * Fix 2960 by re-normalizing / scaling priorities to be in bounds of total power, additionally: - remove heap where it doesn't make sense - avg. only at the end of IncrementProposerPriority instead of each iteration - update (and slightly improve) TestAveragingInIncrementProposerPriorityWithVotingPower to reflect above changes * fix tests * add comment * update changelog pending & some minor changes * comment about division will floor the result & fix typo * Update TestLargeGenesisValidator: - remove TODO and increase large genesis validator's voting power accordingly * move changelog entry to P2P Protocol * Ceil instead of flooring when dividing & update test * quickly fix failing TestProposerPriorityDoesNotGetResetToZero: - divide by Ceil((maxPriority - minPriority) / 2*totalVotingPower) * fix typo: rename getValWitMostPriority -> getValWithMostPriority * test proposer frequencies * return absolute value for diff. keep testing * use for loop for div * cleanup, more tests * spellcheck * get rid of using floats: manually ceil where necessary * Remove float, simplify, fix tests to match chris's proof (#3157)
6 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math"
  6. "math/big"
  7. "os"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. abci "github.com/tendermint/tendermint/abci/types"
  12. "github.com/tendermint/tendermint/crypto"
  13. "github.com/tendermint/tendermint/crypto/ed25519"
  14. cmn "github.com/tendermint/tendermint/libs/common"
  15. dbm "github.com/tendermint/tendermint/libs/db"
  16. cfg "github.com/tendermint/tendermint/config"
  17. "github.com/tendermint/tendermint/types"
  18. )
  19. // setupTestCase does setup common to all test cases.
  20. func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, State) {
  21. config := cfg.ResetTestRoot("state_")
  22. dbType := dbm.DBBackendType(config.DBBackend)
  23. stateDB := dbm.NewDB("state", dbType, config.DBDir())
  24. state, err := LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile())
  25. assert.NoError(t, err, "expected no error on LoadStateFromDBOrGenesisFile")
  26. tearDown := func(t *testing.T) { os.RemoveAll(config.RootDir) }
  27. return tearDown, stateDB, state
  28. }
  29. // TestStateCopy tests the correct copying behaviour of State.
  30. func TestStateCopy(t *testing.T) {
  31. tearDown, _, state := setupTestCase(t)
  32. defer tearDown(t)
  33. // nolint: vetshadow
  34. assert := assert.New(t)
  35. stateCopy := state.Copy()
  36. assert.True(state.Equals(stateCopy),
  37. fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  38. stateCopy, state))
  39. stateCopy.LastBlockHeight++
  40. assert.False(state.Equals(stateCopy), fmt.Sprintf(`expected states to be different. got same
  41. %v`, state))
  42. }
  43. //TestMakeGenesisStateNilValidators tests state's consistency when genesis file's validators field is nil.
  44. func TestMakeGenesisStateNilValidators(t *testing.T) {
  45. doc := types.GenesisDoc{
  46. ChainID: "dummy",
  47. Validators: nil,
  48. }
  49. require.Nil(t, doc.ValidateAndComplete())
  50. state, err := MakeGenesisState(&doc)
  51. require.Nil(t, err)
  52. require.Equal(t, 0, len(state.Validators.Validators))
  53. require.Equal(t, 0, len(state.NextValidators.Validators))
  54. }
  55. // TestStateSaveLoad tests saving and loading State from a db.
  56. func TestStateSaveLoad(t *testing.T) {
  57. tearDown, stateDB, state := setupTestCase(t)
  58. defer tearDown(t)
  59. // nolint: vetshadow
  60. assert := assert.New(t)
  61. state.LastBlockHeight++
  62. SaveState(stateDB, state)
  63. loadedState := LoadState(stateDB)
  64. assert.True(state.Equals(loadedState),
  65. fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  66. loadedState, state))
  67. }
  68. // TestABCIResponsesSaveLoad tests saving and loading ABCIResponses.
  69. func TestABCIResponsesSaveLoad1(t *testing.T) {
  70. tearDown, stateDB, state := setupTestCase(t)
  71. defer tearDown(t)
  72. // nolint: vetshadow
  73. assert := assert.New(t)
  74. state.LastBlockHeight++
  75. // Build mock responses.
  76. block := makeBlock(state, 2)
  77. abciResponses := NewABCIResponses(block)
  78. abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil}
  79. abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil}
  80. abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
  81. types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10),
  82. }}
  83. saveABCIResponses(stateDB, block.Height, abciResponses)
  84. loadedABCIResponses, err := LoadABCIResponses(stateDB, block.Height)
  85. assert.Nil(err)
  86. assert.Equal(abciResponses, loadedABCIResponses,
  87. fmt.Sprintf("ABCIResponses don't match:\ngot: %v\nexpected: %v\n",
  88. loadedABCIResponses, abciResponses))
  89. }
  90. // TestResultsSaveLoad tests saving and loading ABCI results.
  91. func TestABCIResponsesSaveLoad2(t *testing.T) {
  92. tearDown, stateDB, _ := setupTestCase(t)
  93. defer tearDown(t)
  94. // nolint: vetshadow
  95. assert := assert.New(t)
  96. cases := [...]struct {
  97. // Height is implied to equal index+2,
  98. // as block 1 is created from genesis.
  99. added []*abci.ResponseDeliverTx
  100. expected types.ABCIResults
  101. }{
  102. 0: {
  103. nil,
  104. nil,
  105. },
  106. 1: {
  107. []*abci.ResponseDeliverTx{
  108. {Code: 32, Data: []byte("Hello"), Log: "Huh?"},
  109. },
  110. types.ABCIResults{
  111. {32, []byte("Hello")},
  112. }},
  113. 2: {
  114. []*abci.ResponseDeliverTx{
  115. {Code: 383},
  116. {
  117. Data: []byte("Gotcha!"),
  118. Events: []abci.Event{
  119. {Type: "type1", Attributes: []cmn.KVPair{{Key: []byte("a"), Value: []byte("1")}}},
  120. {Type: "type2", Attributes: []cmn.KVPair{{Key: []byte("build"), Value: []byte("stuff")}}},
  121. },
  122. },
  123. },
  124. types.ABCIResults{
  125. {383, nil},
  126. {0, []byte("Gotcha!")},
  127. }},
  128. 3: {
  129. nil,
  130. nil,
  131. },
  132. }
  133. // Query all before, this should return error.
  134. for i := range cases {
  135. h := int64(i + 1)
  136. res, err := LoadABCIResponses(stateDB, h)
  137. assert.Error(err, "%d: %#v", i, res)
  138. }
  139. // Add all cases.
  140. for i, tc := range cases {
  141. h := int64(i + 1) // last block height, one below what we save
  142. responses := &ABCIResponses{
  143. DeliverTx: tc.added,
  144. EndBlock: &abci.ResponseEndBlock{},
  145. }
  146. saveABCIResponses(stateDB, h, responses)
  147. }
  148. // Query all before, should return expected value.
  149. for i, tc := range cases {
  150. h := int64(i + 1)
  151. res, err := LoadABCIResponses(stateDB, h)
  152. assert.NoError(err, "%d", i)
  153. assert.Equal(tc.expected.Hash(), res.ResultsHash(), "%d", i)
  154. }
  155. }
  156. // TestValidatorSimpleSaveLoad tests saving and loading validators.
  157. func TestValidatorSimpleSaveLoad(t *testing.T) {
  158. tearDown, stateDB, state := setupTestCase(t)
  159. defer tearDown(t)
  160. // nolint: vetshadow
  161. assert := assert.New(t)
  162. // Can't load anything for height 0.
  163. v, err := LoadValidators(stateDB, 0)
  164. assert.IsType(ErrNoValSetForHeight{}, err, "expected err at height 0")
  165. // Should be able to load for height 1.
  166. v, err = LoadValidators(stateDB, 1)
  167. assert.Nil(err, "expected no err at height 1")
  168. assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  169. // Should be able to load for height 2.
  170. v, err = LoadValidators(stateDB, 2)
  171. assert.Nil(err, "expected no err at height 2")
  172. assert.Equal(v.Hash(), state.NextValidators.Hash(), "expected validator hashes to match")
  173. // Increment height, save; should be able to load for next & next next height.
  174. state.LastBlockHeight++
  175. nextHeight := state.LastBlockHeight + 1
  176. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  177. vp0, err := LoadValidators(stateDB, nextHeight+0)
  178. assert.Nil(err, "expected no err")
  179. vp1, err := LoadValidators(stateDB, nextHeight+1)
  180. assert.Nil(err, "expected no err")
  181. assert.Equal(vp0.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  182. assert.Equal(vp1.Hash(), state.NextValidators.Hash(), "expected next validator hashes to match")
  183. }
  184. // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes.
  185. func TestOneValidatorChangesSaveLoad(t *testing.T) {
  186. tearDown, stateDB, state := setupTestCase(t)
  187. defer tearDown(t)
  188. // Change vals at these heights.
  189. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  190. N := len(changeHeights)
  191. // Build the validator history by running updateState
  192. // with the right validator set for each height.
  193. highestHeight := changeHeights[N-1] + 5
  194. changeIndex := 0
  195. _, val := state.Validators.GetByIndex(0)
  196. power := val.VotingPower
  197. var err error
  198. var validatorUpdates []*types.Validator
  199. for i := int64(1); i < highestHeight; i++ {
  200. // When we get to a change height, use the next pubkey.
  201. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  202. changeIndex++
  203. power++
  204. }
  205. header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
  206. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  207. require.NoError(t, err)
  208. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  209. require.NoError(t, err)
  210. nextHeight := state.LastBlockHeight + 1
  211. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  212. }
  213. // On each height change, increment the power by one.
  214. testCases := make([]int64, highestHeight)
  215. changeIndex = 0
  216. power = val.VotingPower
  217. for i := int64(1); i < highestHeight+1; i++ {
  218. // We get to the height after a change height use the next pubkey (note
  219. // our counter starts at 0 this time).
  220. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  221. changeIndex++
  222. power++
  223. }
  224. testCases[i-1] = power
  225. }
  226. for i, power := range testCases {
  227. v, err := LoadValidators(stateDB, int64(i+1+1)) // +1 because vset changes delayed by 1 block.
  228. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
  229. assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
  230. _, val := v.GetByIndex(0)
  231. assert.Equal(t, val.VotingPower, power, fmt.Sprintf(`unexpected powerat
  232. height %d`, i))
  233. }
  234. }
  235. func TestProposerFrequency(t *testing.T) {
  236. // some explicit test cases
  237. testCases := []struct {
  238. powers []int64
  239. }{
  240. // 2 vals
  241. {[]int64{1, 1}},
  242. {[]int64{1, 2}},
  243. {[]int64{1, 100}},
  244. {[]int64{5, 5}},
  245. {[]int64{5, 100}},
  246. {[]int64{50, 50}},
  247. {[]int64{50, 100}},
  248. {[]int64{1, 1000}},
  249. // 3 vals
  250. {[]int64{1, 1, 1}},
  251. {[]int64{1, 2, 3}},
  252. {[]int64{1, 2, 3}},
  253. {[]int64{1, 1, 10}},
  254. {[]int64{1, 1, 100}},
  255. {[]int64{1, 10, 100}},
  256. {[]int64{1, 1, 1000}},
  257. {[]int64{1, 10, 1000}},
  258. {[]int64{1, 100, 1000}},
  259. // 4 vals
  260. {[]int64{1, 1, 1, 1}},
  261. {[]int64{1, 2, 3, 4}},
  262. {[]int64{1, 1, 1, 10}},
  263. {[]int64{1, 1, 1, 100}},
  264. {[]int64{1, 1, 1, 1000}},
  265. {[]int64{1, 1, 10, 100}},
  266. {[]int64{1, 1, 10, 1000}},
  267. {[]int64{1, 1, 100, 1000}},
  268. {[]int64{1, 10, 100, 1000}},
  269. }
  270. for caseNum, testCase := range testCases {
  271. // run each case 5 times to sample different
  272. // initial priorities
  273. for i := 0; i < 5; i++ {
  274. valSet := genValSetWithPowers(testCase.powers)
  275. testProposerFreq(t, caseNum, valSet)
  276. }
  277. }
  278. // some random test cases with up to 100 validators
  279. maxVals := 100
  280. maxPower := 1000
  281. nTestCases := 5
  282. for i := 0; i < nTestCases; i++ {
  283. N := cmn.RandInt()%maxVals + 1
  284. vals := make([]*types.Validator, N)
  285. totalVotePower := int64(0)
  286. for j := 0; j < N; j++ {
  287. // make sure votePower > 0
  288. votePower := int64(cmn.RandInt()%maxPower) + 1
  289. totalVotePower += votePower
  290. privVal := types.NewMockPV()
  291. pubKey := privVal.GetPubKey()
  292. val := types.NewValidator(pubKey, votePower)
  293. val.ProposerPriority = cmn.RandInt64()
  294. vals[j] = val
  295. }
  296. valSet := types.NewValidatorSet(vals)
  297. valSet.RescalePriorities(totalVotePower)
  298. testProposerFreq(t, i, valSet)
  299. }
  300. }
  301. // new val set with given powers and random initial priorities
  302. func genValSetWithPowers(powers []int64) *types.ValidatorSet {
  303. size := len(powers)
  304. vals := make([]*types.Validator, size)
  305. totalVotePower := int64(0)
  306. for i := 0; i < size; i++ {
  307. totalVotePower += powers[i]
  308. val := types.NewValidator(ed25519.GenPrivKey().PubKey(), powers[i])
  309. val.ProposerPriority = cmn.RandInt64()
  310. vals[i] = val
  311. }
  312. valSet := types.NewValidatorSet(vals)
  313. valSet.RescalePriorities(totalVotePower)
  314. return valSet
  315. }
  316. // test a proposer appears as frequently as expected
  317. func testProposerFreq(t *testing.T, caseNum int, valSet *types.ValidatorSet) {
  318. N := valSet.Size()
  319. totalPower := valSet.TotalVotingPower()
  320. // run the proposer selection and track frequencies
  321. runMult := 1
  322. runs := int(totalPower) * runMult
  323. freqs := make([]int, N)
  324. for i := 0; i < runs; i++ {
  325. prop := valSet.GetProposer()
  326. idx, _ := valSet.GetByAddress(prop.Address)
  327. freqs[idx] += 1
  328. valSet.IncrementProposerPriority(1)
  329. }
  330. // assert frequencies match expected (max off by 1)
  331. for i, freq := range freqs {
  332. _, val := valSet.GetByIndex(i)
  333. expectFreq := int(val.VotingPower) * runMult
  334. gotFreq := freq
  335. abs := int(math.Abs(float64(expectFreq - gotFreq)))
  336. // max bound on expected vs seen freq was proven
  337. // to be 1 for the 2 validator case in
  338. // https://github.com/cwgoes/tm-proposer-idris
  339. // and inferred to generalize to N-1
  340. bound := N - 1
  341. require.True(t, abs <= bound, fmt.Sprintf("Case %d val %d (%d): got %d, expected %d", caseNum, i, N, gotFreq, expectFreq))
  342. }
  343. }
  344. // TestProposerPriorityDoesNotGetResetToZero assert that we preserve accum when calling updateState
  345. // see https://github.com/tendermint/tendermint/issues/2718
  346. func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
  347. tearDown, _, state := setupTestCase(t)
  348. defer tearDown(t)
  349. val1VotingPower := int64(10)
  350. val1PubKey := ed25519.GenPrivKey().PubKey()
  351. val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower}
  352. state.Validators = types.NewValidatorSet([]*types.Validator{val1})
  353. state.NextValidators = state.Validators
  354. // NewValidatorSet calls IncrementProposerPriority but uses on a copy of val1
  355. assert.EqualValues(t, 0, val1.ProposerPriority)
  356. block := makeBlock(state, state.LastBlockHeight+1)
  357. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  358. abciResponses := &ABCIResponses{
  359. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  360. }
  361. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  362. require.NoError(t, err)
  363. updatedState, err := updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  364. assert.NoError(t, err)
  365. curTotal := val1VotingPower
  366. // one increment step and one validator: 0 + power - total_power == 0
  367. assert.Equal(t, 0+val1VotingPower-curTotal, updatedState.NextValidators.Validators[0].ProposerPriority)
  368. // add a validator
  369. val2PubKey := ed25519.GenPrivKey().PubKey()
  370. val2VotingPower := int64(100)
  371. updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: val2VotingPower}
  372. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
  373. assert.NoError(t, err)
  374. updatedState2, err := updateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
  375. assert.NoError(t, err)
  376. require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
  377. _, updatedVal1 := updatedState2.NextValidators.GetByAddress(val1PubKey.Address())
  378. _, addedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
  379. // adding a validator should not lead to a ProposerPriority equal to zero (unless the combination of averaging and
  380. // incrementing would cause so; which is not the case here)
  381. // Steps from adding new validator:
  382. // 0 - val1 prio is 0, TVP after add:
  383. wantVal1Prio := int64(0)
  384. totalPowerAfter := val1VotingPower + val2VotingPower
  385. // 1. Add - Val2 should be initially added with (-123) =>
  386. wantVal2Prio := -(totalPowerAfter + (totalPowerAfter >> 3))
  387. // 2. Scale - noop
  388. // 3. Center - with avg, resulting val2:-61, val1:62
  389. avg := big.NewInt(0).Add(big.NewInt(wantVal1Prio), big.NewInt(wantVal2Prio))
  390. avg.Div(avg, big.NewInt(2))
  391. wantVal2Prio = wantVal2Prio - avg.Int64() // -61
  392. wantVal1Prio = wantVal1Prio - avg.Int64() // 62
  393. // 4. Steps from IncrementProposerPriority
  394. wantVal1Prio = wantVal1Prio + val1VotingPower // 72
  395. wantVal2Prio = wantVal2Prio + val2VotingPower // 39
  396. wantVal1Prio = wantVal1Prio - totalPowerAfter // -38 as val1 is proposer
  397. assert.Equal(t, wantVal1Prio, updatedVal1.ProposerPriority)
  398. assert.Equal(t, wantVal2Prio, addedVal2.ProposerPriority)
  399. // Updating a validator does not reset the ProposerPriority to zero:
  400. // 1. Add - Val2 VotingPower change to 1 =>
  401. updatedVotingPowVal2 := int64(1)
  402. updateVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: updatedVotingPowVal2}
  403. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateVal})
  404. assert.NoError(t, err)
  405. // this will cause the diff of priorities (77)
  406. // to be larger than threshold == 2*totalVotingPower (22):
  407. updatedState3, err := updateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
  408. assert.NoError(t, err)
  409. require.Equal(t, len(updatedState3.NextValidators.Validators), 2)
  410. _, prevVal1 := updatedState3.Validators.GetByAddress(val1PubKey.Address())
  411. _, prevVal2 := updatedState3.Validators.GetByAddress(val2PubKey.Address())
  412. _, updatedVal1 = updatedState3.NextValidators.GetByAddress(val1PubKey.Address())
  413. _, updatedVal2 := updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
  414. // 2. Scale
  415. // old prios: v1(10):-38, v2(1):39
  416. wantVal1Prio = prevVal1.ProposerPriority
  417. wantVal2Prio = prevVal2.ProposerPriority
  418. // scale to diffMax = 22 = 2 * tvp, diff=39-(-38)=77
  419. // new totalPower
  420. totalPower := updatedVal1.VotingPower + updatedVal2.VotingPower
  421. dist := wantVal2Prio - wantVal1Prio
  422. // ratio := (dist + 2*totalPower - 1) / 2*totalPower = 98/22 = 4
  423. ratio := (dist + 2*totalPower - 1) / (2 * totalPower)
  424. // v1(10):-38/4, v2(1):39/4
  425. wantVal1Prio /= ratio // -9
  426. wantVal2Prio /= ratio // 9
  427. // 3. Center - noop
  428. // 4. IncrementProposerPriority() ->
  429. // v1(10):-9+10, v2(1):9+1 -> v2 proposer so subsract tvp(11)
  430. // v1(10):1, v2(1):-1
  431. wantVal2Prio += updatedVal2.VotingPower // 10 -> prop
  432. wantVal1Prio += updatedVal1.VotingPower // 1
  433. wantVal2Prio -= totalPower // -1
  434. assert.Equal(t, wantVal2Prio, updatedVal2.ProposerPriority)
  435. assert.Equal(t, wantVal1Prio, updatedVal1.ProposerPriority)
  436. }
  437. func TestProposerPriorityProposerAlternates(t *testing.T) {
  438. // Regression test that would fail if the inner workings of
  439. // IncrementProposerPriority change.
  440. // Additionally, make sure that same power validators alternate if both
  441. // have the same voting power (and the 2nd was added later).
  442. tearDown, _, state := setupTestCase(t)
  443. defer tearDown(t)
  444. val1VotingPower := int64(10)
  445. val1PubKey := ed25519.GenPrivKey().PubKey()
  446. val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower}
  447. // reset state validators to above validator
  448. state.Validators = types.NewValidatorSet([]*types.Validator{val1})
  449. state.NextValidators = state.Validators
  450. // we only have one validator:
  451. assert.Equal(t, val1PubKey.Address(), state.Validators.Proposer.Address)
  452. block := makeBlock(state, state.LastBlockHeight+1)
  453. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  454. // no updates:
  455. abciResponses := &ABCIResponses{
  456. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  457. }
  458. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  459. require.NoError(t, err)
  460. updatedState, err := updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  461. assert.NoError(t, err)
  462. // 0 + 10 (initial prio) - 10 (avg) - 10 (mostest - total) = -10
  463. totalPower := val1VotingPower
  464. wantVal1Prio := 0 + val1VotingPower - totalPower
  465. assert.Equal(t, wantVal1Prio, updatedState.NextValidators.Validators[0].ProposerPriority)
  466. assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
  467. // add a validator with the same voting power as the first
  468. val2PubKey := ed25519.GenPrivKey().PubKey()
  469. updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: val1VotingPower}
  470. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
  471. assert.NoError(t, err)
  472. updatedState2, err := updateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
  473. assert.NoError(t, err)
  474. require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
  475. assert.Equal(t, updatedState2.Validators, updatedState.NextValidators)
  476. // val1 will still be proposer as val2 just got added:
  477. assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
  478. assert.Equal(t, updatedState2.Validators.Proposer.Address, updatedState2.NextValidators.Proposer.Address)
  479. assert.Equal(t, updatedState2.Validators.Proposer.Address, val1PubKey.Address())
  480. assert.Equal(t, updatedState2.NextValidators.Proposer.Address, val1PubKey.Address())
  481. _, updatedVal1 := updatedState2.NextValidators.GetByAddress(val1PubKey.Address())
  482. _, oldVal1 := updatedState2.Validators.GetByAddress(val1PubKey.Address())
  483. _, updatedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
  484. // 1. Add
  485. val2VotingPower := val1VotingPower
  486. totalPower = val1VotingPower + val2VotingPower // 20
  487. v2PrioWhenAddedVal2 := -(totalPower + (totalPower >> 3)) // -22
  488. // 2. Scale - noop
  489. // 3. Center
  490. avgSum := big.NewInt(0).Add(big.NewInt(v2PrioWhenAddedVal2), big.NewInt(oldVal1.ProposerPriority))
  491. avg := avgSum.Div(avgSum, big.NewInt(2)) // -11
  492. expectedVal2Prio := v2PrioWhenAddedVal2 - avg.Int64() // -11
  493. expectedVal1Prio := oldVal1.ProposerPriority - avg.Int64() // 11
  494. // 4. Increment
  495. expectedVal2Prio = expectedVal2Prio + val2VotingPower // -11 + 10 = -1
  496. expectedVal1Prio = expectedVal1Prio + val1VotingPower // 11 + 10 == 21
  497. expectedVal1Prio = expectedVal1Prio - totalPower // 1, val1 proposer
  498. assert.EqualValues(t, expectedVal1Prio, updatedVal1.ProposerPriority)
  499. assert.EqualValues(t, expectedVal2Prio, updatedVal2.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  500. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  501. require.NoError(t, err)
  502. updatedState3, err := updateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
  503. assert.NoError(t, err)
  504. assert.Equal(t, updatedState3.Validators.Proposer.Address, updatedState3.NextValidators.Proposer.Address)
  505. assert.Equal(t, updatedState3.Validators, updatedState2.NextValidators)
  506. _, updatedVal1 = updatedState3.NextValidators.GetByAddress(val1PubKey.Address())
  507. _, updatedVal2 = updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
  508. // val1 will still be proposer:
  509. assert.Equal(t, val1PubKey.Address(), updatedState3.NextValidators.Proposer.Address)
  510. // check if expected proposer prio is matched:
  511. // Increment
  512. expectedVal2Prio2 := expectedVal2Prio + val2VotingPower // -1 + 10 = 9
  513. expectedVal1Prio2 := expectedVal1Prio + val1VotingPower // 1 + 10 == 11
  514. expectedVal1Prio2 = expectedVal1Prio2 - totalPower // -9, val1 proposer
  515. assert.EqualValues(t, expectedVal1Prio2, updatedVal1.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  516. assert.EqualValues(t, expectedVal2Prio2, updatedVal2.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  517. // no changes in voting power and both validators have same voting power
  518. // -> proposers should alternate:
  519. oldState := updatedState3
  520. abciResponses = &ABCIResponses{
  521. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  522. }
  523. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  524. require.NoError(t, err)
  525. oldState, err = updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  526. assert.NoError(t, err)
  527. expectedVal1Prio2 = 1
  528. expectedVal2Prio2 = -1
  529. expectedVal1Prio = -9
  530. expectedVal2Prio = 9
  531. for i := 0; i < 1000; i++ {
  532. // no validator updates:
  533. abciResponses := &ABCIResponses{
  534. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  535. }
  536. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  537. require.NoError(t, err)
  538. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  539. assert.NoError(t, err)
  540. // alternate (and cyclic priorities):
  541. assert.NotEqual(t, updatedState.Validators.Proposer.Address, updatedState.NextValidators.Proposer.Address, "iter: %v", i)
  542. assert.Equal(t, oldState.Validators.Proposer.Address, updatedState.NextValidators.Proposer.Address, "iter: %v", i)
  543. _, updatedVal1 = updatedState.NextValidators.GetByAddress(val1PubKey.Address())
  544. _, updatedVal2 = updatedState.NextValidators.GetByAddress(val2PubKey.Address())
  545. if i%2 == 0 {
  546. assert.Equal(t, updatedState.Validators.Proposer.Address, val2PubKey.Address())
  547. assert.Equal(t, expectedVal1Prio, updatedVal1.ProposerPriority) // -19
  548. assert.Equal(t, expectedVal2Prio, updatedVal2.ProposerPriority) // 0
  549. } else {
  550. assert.Equal(t, updatedState.Validators.Proposer.Address, val1PubKey.Address())
  551. assert.Equal(t, expectedVal1Prio2, updatedVal1.ProposerPriority) // -9
  552. assert.Equal(t, expectedVal2Prio2, updatedVal2.ProposerPriority) // -10
  553. }
  554. // update for next iteration:
  555. oldState = updatedState
  556. }
  557. }
  558. func TestLargeGenesisValidator(t *testing.T) {
  559. tearDown, _, state := setupTestCase(t)
  560. defer tearDown(t)
  561. genesisVotingPower := int64(types.MaxTotalVotingPower / 1000)
  562. genesisPubKey := ed25519.GenPrivKey().PubKey()
  563. // fmt.Println("genesis addr: ", genesisPubKey.Address())
  564. genesisVal := &types.Validator{Address: genesisPubKey.Address(), PubKey: genesisPubKey, VotingPower: genesisVotingPower}
  565. // reset state validators to above validator
  566. state.Validators = types.NewValidatorSet([]*types.Validator{genesisVal})
  567. state.NextValidators = state.Validators
  568. require.True(t, len(state.Validators.Validators) == 1)
  569. // update state a few times with no validator updates
  570. // asserts that the single validator's ProposerPrio stays the same
  571. oldState := state
  572. for i := 0; i < 10; i++ {
  573. // no updates:
  574. abciResponses := &ABCIResponses{
  575. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  576. }
  577. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  578. require.NoError(t, err)
  579. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  580. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  581. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  582. require.NoError(t, err)
  583. // no changes in voting power (ProposerPrio += VotingPower == Voting in 1st round; than shiftByAvg == 0,
  584. // than -Total == -Voting)
  585. // -> no change in ProposerPrio (stays zero):
  586. assert.EqualValues(t, oldState.NextValidators, updatedState.NextValidators)
  587. assert.EqualValues(t, 0, updatedState.NextValidators.Proposer.ProposerPriority)
  588. oldState = updatedState
  589. }
  590. // add another validator, do a few iterations (create blocks),
  591. // add more validators with same voting power as the 2nd
  592. // let the genesis validator "unbond",
  593. // see how long it takes until the effect wears off and both begin to alternate
  594. // see: https://github.com/tendermint/tendermint/issues/2960
  595. firstAddedValPubKey := ed25519.GenPrivKey().PubKey()
  596. firstAddedValVotingPower := int64(10)
  597. firstAddedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(firstAddedValPubKey), Power: firstAddedValVotingPower}
  598. validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal})
  599. assert.NoError(t, err)
  600. abciResponses := &ABCIResponses{
  601. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}},
  602. }
  603. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  604. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  605. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  606. require.NoError(t, err)
  607. lastState := updatedState
  608. for i := 0; i < 200; i++ {
  609. // no updates:
  610. abciResponses := &ABCIResponses{
  611. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  612. }
  613. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  614. require.NoError(t, err)
  615. block := makeBlock(lastState, lastState.LastBlockHeight+1)
  616. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  617. updatedStateInner, err := updateState(lastState, blockID, &block.Header, abciResponses, validatorUpdates)
  618. require.NoError(t, err)
  619. lastState = updatedStateInner
  620. }
  621. // set state to last state of above iteration
  622. state = lastState
  623. // set oldState to state before above iteration
  624. oldState = updatedState
  625. _, oldGenesisVal := oldState.NextValidators.GetByAddress(genesisVal.Address)
  626. _, newGenesisVal := state.NextValidators.GetByAddress(genesisVal.Address)
  627. _, addedOldVal := oldState.NextValidators.GetByAddress(firstAddedValPubKey.Address())
  628. _, addedNewVal := state.NextValidators.GetByAddress(firstAddedValPubKey.Address())
  629. // expect large negative proposer priority for both (genesis validator decreased, 2nd validator increased):
  630. assert.True(t, oldGenesisVal.ProposerPriority > newGenesisVal.ProposerPriority)
  631. assert.True(t, addedOldVal.ProposerPriority < addedNewVal.ProposerPriority)
  632. // add 10 validators with the same voting power as the one added directly after genesis:
  633. for i := 0; i < 10; i++ {
  634. addedPubKey := ed25519.GenPrivKey().PubKey()
  635. addedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(addedPubKey), Power: firstAddedValVotingPower}
  636. validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal})
  637. assert.NoError(t, err)
  638. abciResponses := &ABCIResponses{
  639. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}},
  640. }
  641. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  642. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  643. state, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  644. require.NoError(t, err)
  645. }
  646. require.Equal(t, 10+2, len(state.NextValidators.Validators))
  647. // remove genesis validator:
  648. removeGenesisVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(genesisPubKey), Power: 0}
  649. abciResponses = &ABCIResponses{
  650. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}},
  651. }
  652. block = makeBlock(oldState, oldState.LastBlockHeight+1)
  653. blockID = types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  654. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  655. require.NoError(t, err)
  656. updatedState, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  657. require.NoError(t, err)
  658. // only the first added val (not the genesis val) should be left
  659. assert.Equal(t, 11, len(updatedState.NextValidators.Validators))
  660. // call update state until the effect for the 3rd added validator
  661. // being proposer for a long time after the genesis validator left wears off:
  662. curState := updatedState
  663. count := 0
  664. isProposerUnchanged := true
  665. for isProposerUnchanged {
  666. abciResponses := &ABCIResponses{
  667. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  668. }
  669. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  670. require.NoError(t, err)
  671. block = makeBlock(curState, curState.LastBlockHeight+1)
  672. blockID = types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  673. curState, err = updateState(curState, blockID, &block.Header, abciResponses, validatorUpdates)
  674. require.NoError(t, err)
  675. if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) {
  676. isProposerUnchanged = false
  677. }
  678. count++
  679. }
  680. updatedState = curState
  681. // the proposer changes after this number of blocks
  682. firstProposerChangeExpectedAfter := 1
  683. assert.Equal(t, firstProposerChangeExpectedAfter, count)
  684. // store proposers here to see if we see them again in the same order:
  685. numVals := len(updatedState.Validators.Validators)
  686. proposers := make([]*types.Validator, numVals)
  687. for i := 0; i < 100; i++ {
  688. // no updates:
  689. abciResponses := &ABCIResponses{
  690. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  691. }
  692. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  693. require.NoError(t, err)
  694. block := makeBlock(updatedState, updatedState.LastBlockHeight+1)
  695. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  696. updatedState, err = updateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
  697. require.NoError(t, err)
  698. if i > numVals { // expect proposers to cycle through after the first iteration (of numVals blocks):
  699. if proposers[i%numVals] == nil {
  700. proposers[i%numVals] = updatedState.NextValidators.Proposer
  701. } else {
  702. assert.Equal(t, proposers[i%numVals], updatedState.NextValidators.Proposer)
  703. }
  704. }
  705. }
  706. }
  707. func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) {
  708. const valSetSize = 2
  709. tearDown, stateDB, state := setupTestCase(t)
  710. defer tearDown(t)
  711. state.Validators = genValSet(valSetSize)
  712. state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
  713. SaveState(stateDB, state)
  714. nextHeight := state.LastBlockHeight + 1
  715. v0, err := LoadValidators(stateDB, nextHeight)
  716. assert.Nil(t, err)
  717. acc0 := v0.Validators[0].ProposerPriority
  718. v1, err := LoadValidators(stateDB, nextHeight+1)
  719. assert.Nil(t, err)
  720. acc1 := v1.Validators[0].ProposerPriority
  721. assert.NotEqual(t, acc1, acc0, "expected ProposerPriority value to change between heights")
  722. }
  723. // TestValidatorChangesSaveLoad tests saving and loading a validator set with
  724. // changes.
  725. func TestManyValidatorChangesSaveLoad(t *testing.T) {
  726. const valSetSize = 7
  727. tearDown, stateDB, state := setupTestCase(t)
  728. defer tearDown(t)
  729. require.Equal(t, int64(0), state.LastBlockHeight)
  730. state.Validators = genValSet(valSetSize)
  731. state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
  732. SaveState(stateDB, state)
  733. _, valOld := state.Validators.GetByIndex(0)
  734. var pubkeyOld = valOld.PubKey
  735. pubkey := ed25519.GenPrivKey().PubKey()
  736. const height = 1
  737. // Swap the first validator with a new one (validator set size stays the same).
  738. header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey)
  739. // Save state etc.
  740. var err error
  741. var validatorUpdates []*types.Validator
  742. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  743. require.NoError(t, err)
  744. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  745. require.Nil(t, err)
  746. nextHeight := state.LastBlockHeight + 1
  747. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  748. // Load nextheight, it should be the oldpubkey.
  749. v0, err := LoadValidators(stateDB, nextHeight)
  750. assert.Nil(t, err)
  751. assert.Equal(t, valSetSize, v0.Size())
  752. index, val := v0.GetByAddress(pubkeyOld.Address())
  753. assert.NotNil(t, val)
  754. if index < 0 {
  755. t.Fatal("expected to find old validator")
  756. }
  757. // Load nextheight+1, it should be the new pubkey.
  758. v1, err := LoadValidators(stateDB, nextHeight+1)
  759. assert.Nil(t, err)
  760. assert.Equal(t, valSetSize, v1.Size())
  761. index, val = v1.GetByAddress(pubkey.Address())
  762. assert.NotNil(t, val)
  763. if index < 0 {
  764. t.Fatal("expected to find newly added validator")
  765. }
  766. }
  767. func genValSet(size int) *types.ValidatorSet {
  768. vals := make([]*types.Validator, size)
  769. for i := 0; i < size; i++ {
  770. vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10)
  771. }
  772. return types.NewValidatorSet(vals)
  773. }
  774. func TestStateMakeBlock(t *testing.T) {
  775. tearDown, _, state := setupTestCase(t)
  776. defer tearDown(t)
  777. proposerAddress := state.Validators.GetProposer().Address
  778. stateVersion := state.Version.Consensus
  779. block := makeBlock(state, 2)
  780. // test we set some fields
  781. assert.Equal(t, stateVersion, block.Version)
  782. assert.Equal(t, proposerAddress, block.ProposerAddress)
  783. }
  784. // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params
  785. // with changes.
  786. func TestConsensusParamsChangesSaveLoad(t *testing.T) {
  787. tearDown, stateDB, state := setupTestCase(t)
  788. defer tearDown(t)
  789. // Change vals at these heights.
  790. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  791. N := len(changeHeights)
  792. // Each valset is just one validator.
  793. // create list of them.
  794. params := make([]types.ConsensusParams, N+1)
  795. params[0] = state.ConsensusParams
  796. for i := 1; i < N+1; i++ {
  797. params[i] = *types.DefaultConsensusParams()
  798. params[i].Block.MaxBytes += int64(i)
  799. }
  800. // Build the params history by running updateState
  801. // with the right params set for each height.
  802. highestHeight := changeHeights[N-1] + 5
  803. changeIndex := 0
  804. cp := params[changeIndex]
  805. var err error
  806. var validatorUpdates []*types.Validator
  807. for i := int64(1); i < highestHeight; i++ {
  808. // When we get to a change height, use the next params.
  809. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  810. changeIndex++
  811. cp = params[changeIndex]
  812. }
  813. header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
  814. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  815. require.NoError(t, err)
  816. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  817. require.Nil(t, err)
  818. nextHeight := state.LastBlockHeight + 1
  819. saveConsensusParamsInfo(stateDB, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
  820. }
  821. // Make all the test cases by using the same params until after the change.
  822. testCases := make([]paramsChangeTestCase, highestHeight)
  823. changeIndex = 0
  824. cp = params[changeIndex]
  825. for i := int64(1); i < highestHeight+1; i++ {
  826. // We get to the height after a change height use the next pubkey (note
  827. // our counter starts at 0 this time).
  828. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  829. changeIndex++
  830. cp = params[changeIndex]
  831. }
  832. testCases[i-1] = paramsChangeTestCase{i, cp}
  833. }
  834. for _, testCase := range testCases {
  835. p, err := LoadConsensusParams(stateDB, testCase.height)
  836. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
  837. assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
  838. height %d`, testCase.height))
  839. }
  840. }
  841. func makeParams(
  842. blockBytes, blockGas int64,
  843. blockTimeIotaMs int64,
  844. evidenceAge int64,
  845. ) types.ConsensusParams {
  846. return types.ConsensusParams{
  847. Block: types.BlockParams{
  848. MaxBytes: blockBytes,
  849. MaxGas: blockGas,
  850. TimeIotaMs: blockTimeIotaMs,
  851. },
  852. Evidence: types.EvidenceParams{
  853. MaxAge: evidenceAge,
  854. },
  855. }
  856. }
  857. func TestApplyUpdates(t *testing.T) {
  858. initParams := makeParams(1, 2, 3, 4)
  859. cases := [...]struct {
  860. init types.ConsensusParams
  861. updates abci.ConsensusParams
  862. expected types.ConsensusParams
  863. }{
  864. 0: {initParams, abci.ConsensusParams{}, initParams},
  865. 1: {initParams, abci.ConsensusParams{}, initParams},
  866. 2: {initParams,
  867. abci.ConsensusParams{
  868. Block: &abci.BlockParams{
  869. MaxBytes: 44,
  870. MaxGas: 55,
  871. },
  872. },
  873. makeParams(44, 55, 3, 4)},
  874. 3: {initParams,
  875. abci.ConsensusParams{
  876. Evidence: &abci.EvidenceParams{
  877. MaxAge: 66,
  878. },
  879. },
  880. makeParams(1, 2, 3, 66)},
  881. }
  882. for i, tc := range cases {
  883. res := tc.init.Update(&(tc.updates))
  884. assert.Equal(t, tc.expected, res, "case %d", i)
  885. }
  886. }
  887. func makeHeaderPartsResponsesValPubKeyChange(state State, height int64,
  888. pubkey crypto.PubKey) (types.Header, types.BlockID, *ABCIResponses) {
  889. block := makeBlock(state, state.LastBlockHeight+1)
  890. abciResponses := &ABCIResponses{
  891. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  892. }
  893. // If the pubkey is new, remove the old and add the new.
  894. _, val := state.NextValidators.GetByIndex(0)
  895. if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
  896. abciResponses.EndBlock = &abci.ResponseEndBlock{
  897. ValidatorUpdates: []abci.ValidatorUpdate{
  898. types.TM2PB.NewValidatorUpdate(val.PubKey, 0),
  899. types.TM2PB.NewValidatorUpdate(pubkey, 10),
  900. },
  901. }
  902. }
  903. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  904. }
  905. func makeHeaderPartsResponsesValPowerChange(state State, height int64,
  906. power int64) (types.Header, types.BlockID, *ABCIResponses) {
  907. block := makeBlock(state, state.LastBlockHeight+1)
  908. abciResponses := &ABCIResponses{
  909. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  910. }
  911. // If the pubkey is new, remove the old and add the new.
  912. _, val := state.NextValidators.GetByIndex(0)
  913. if val.VotingPower != power {
  914. abciResponses.EndBlock = &abci.ResponseEndBlock{
  915. ValidatorUpdates: []abci.ValidatorUpdate{
  916. types.TM2PB.NewValidatorUpdate(val.PubKey, power),
  917. },
  918. }
  919. }
  920. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  921. }
  922. func makeHeaderPartsResponsesParams(state State, height int64,
  923. params types.ConsensusParams) (types.Header, types.BlockID, *ABCIResponses) {
  924. block := makeBlock(state, state.LastBlockHeight+1)
  925. abciResponses := &ABCIResponses{
  926. EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(&params)},
  927. }
  928. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  929. }
  930. type paramsChangeTestCase struct {
  931. height int64
  932. params types.ConsensusParams
  933. }