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.

588 lines
17 KiB

7 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
add support for block pruning via ABCI Commit response (#4588) * Added BlockStore.DeleteBlock() * Added initial block pruner prototype * wip * Added BlockStore.PruneBlocks() * Added consensus setting for block pruning * Added BlockStore base * Error on replay if base does not have blocks * Handle missing blocks when sending VoteSetMaj23Message * Error message tweak * Properly update blockstore state * Error message fix again * blockchain: ignore peer missing blocks * Added FIXME * Added test for block replay with truncated history * Handle peer base in blockchain reactor * Improved replay error handling * Added tests for Store.PruneBlocks() * Fix non-RPC handling of truncated block history * Panic on missing block meta in needProofBlock() * Updated changelog * Handle truncated block history in RPC layer * Added info about earliest block in /status RPC * Reorder height and base in blockchain reactor messages * Updated changelog * Fix tests * Appease linter * Minor review fixes * Non-empty BlockStores should always have base > 0 * Update code to assume base > 0 invariant * Added blockstore tests for pruning to 0 * Make sure we don't prune below the current base * Added BlockStore.Size() * config: added retain_blocks recommendations * Update v1 blockchain reactor to handle blockstore base * Added state database pruning * Propagate errors on missing validator sets * Comment tweaks * Improved error message Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com> * use ABCI field ResponseCommit.retain_height instead of retain-blocks config option * remove State.RetainHeight, return value instead * fix minor issues * rename pruneHeights() to pruneBlocks() * noop to fix GitHub borkage Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package state
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/gogo/protobuf/proto"
  6. dbm "github.com/tendermint/tm-db"
  7. abci "github.com/tendermint/tendermint/abci/types"
  8. tmmath "github.com/tendermint/tendermint/libs/math"
  9. tmos "github.com/tendermint/tendermint/libs/os"
  10. tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
  11. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  12. "github.com/tendermint/tendermint/types"
  13. )
  14. const (
  15. // persist validators every valSetCheckpointInterval blocks to avoid
  16. // LoadValidators taking too much time.
  17. // https://github.com/tendermint/tendermint/pull/3438
  18. // 100000 results in ~ 100ms to get 100 validators (see BenchmarkLoadValidators)
  19. valSetCheckpointInterval = 100000
  20. )
  21. //------------------------------------------------------------------------
  22. func calcValidatorsKey(height int64) []byte {
  23. return []byte(fmt.Sprintf("validatorsKey:%v", height))
  24. }
  25. func calcConsensusParamsKey(height int64) []byte {
  26. return []byte(fmt.Sprintf("consensusParamsKey:%v", height))
  27. }
  28. func calcABCIResponsesKey(height int64) []byte {
  29. return []byte(fmt.Sprintf("abciResponsesKey:%v", height))
  30. }
  31. //----------------------
  32. type Store interface {
  33. // LoadFromDBOrGenesisFile loads the most recent state.
  34. // If the chain is new it will use the genesis file from the provided genesis file path as the current state.
  35. LoadFromDBOrGenesisFile(string) (State, error)
  36. // LoadFromDBOrGenesisDoc loads the most recent state.
  37. // If the chain is new it will use the genesis doc as the current state.
  38. LoadFromDBOrGenesisDoc(*types.GenesisDoc) (State, error)
  39. // Load loads the current state of the blockchain
  40. Load() (State, error)
  41. // LoadValidators loads the validator set at a given height
  42. LoadValidators(int64) (*types.ValidatorSet, error)
  43. // LoadABCIResponses loads the abciResponse for a given height
  44. LoadABCIResponses(int64) (*tmstate.ABCIResponses, error)
  45. // LoadConsensusParams loads the consensus params for a given height
  46. LoadConsensusParams(int64) (tmproto.ConsensusParams, error)
  47. // Save overwrites the previous state with the updated one
  48. Save(State) error
  49. // SaveABCIResponses saves ABCIResponses for a given height
  50. SaveABCIResponses(int64, *tmstate.ABCIResponses) error
  51. // Bootstrap is used for bootstrapping state when not starting from a initial height.
  52. Bootstrap(State) error
  53. // PruneStates takes the height from which to start prning and which height stop at
  54. PruneStates(int64, int64) error
  55. }
  56. //dbStore wraps a db (github.com/tendermint/tm-db)
  57. type dbStore struct {
  58. db dbm.DB
  59. }
  60. var _ Store = (*dbStore)(nil)
  61. // NewStore creates the dbStore of the state pkg.
  62. func NewStore(db dbm.DB) Store {
  63. return dbStore{db}
  64. }
  65. // LoadStateFromDBOrGenesisFile loads the most recent state from the database,
  66. // or creates a new one from the given genesisFilePath.
  67. func (store dbStore) LoadFromDBOrGenesisFile(genesisFilePath string) (State, error) {
  68. state, err := store.Load()
  69. if err != nil {
  70. return State{}, err
  71. }
  72. if state.IsEmpty() {
  73. var err error
  74. state, err = MakeGenesisStateFromFile(genesisFilePath)
  75. if err != nil {
  76. return state, err
  77. }
  78. }
  79. return state, nil
  80. }
  81. // LoadStateFromDBOrGenesisDoc loads the most recent state from the database,
  82. // or creates a new one from the given genesisDoc.
  83. func (store dbStore) LoadFromDBOrGenesisDoc(genesisDoc *types.GenesisDoc) (State, error) {
  84. state, err := store.Load()
  85. if err != nil {
  86. return State{}, err
  87. }
  88. if state.IsEmpty() {
  89. var err error
  90. state, err = MakeGenesisState(genesisDoc)
  91. if err != nil {
  92. return state, err
  93. }
  94. }
  95. return state, nil
  96. }
  97. // LoadState loads the State from the database.
  98. func (store dbStore) Load() (State, error) {
  99. return store.loadState(stateKey)
  100. }
  101. func (store dbStore) loadState(key []byte) (state State, err error) {
  102. buf, err := store.db.Get(key)
  103. if err != nil {
  104. return state, err
  105. }
  106. if len(buf) == 0 {
  107. return state, nil
  108. }
  109. sp := new(tmstate.State)
  110. err = proto.Unmarshal(buf, sp)
  111. if err != nil {
  112. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  113. tmos.Exit(fmt.Sprintf(`LoadState: Data has been corrupted or its spec has changed:
  114. %v\n`, err))
  115. }
  116. sm, err := StateFromProto(sp)
  117. if err != nil {
  118. return state, err
  119. }
  120. return *sm, nil
  121. }
  122. // Save persists the State, the ValidatorsInfo, and the ConsensusParamsInfo to the database.
  123. // This flushes the writes (e.g. calls SetSync).
  124. func (store dbStore) Save(state State) error {
  125. return store.save(state, stateKey)
  126. }
  127. func (store dbStore) save(state State, key []byte) error {
  128. nextHeight := state.LastBlockHeight + 1
  129. // If first block, save validators for the block.
  130. if nextHeight == 1 {
  131. nextHeight = state.InitialHeight
  132. // This extra logic due to Tendermint validator set changes being delayed 1 block.
  133. // It may get overwritten due to InitChain validator updates.
  134. if err := store.saveValidatorsInfo(nextHeight, nextHeight, state.Validators); err != nil {
  135. return err
  136. }
  137. }
  138. // Save next validators.
  139. if err := store.saveValidatorsInfo(nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators); err != nil {
  140. return err
  141. }
  142. // Save next consensus params.
  143. if err := store.saveConsensusParamsInfo(nextHeight,
  144. state.LastHeightConsensusParamsChanged, state.ConsensusParams); err != nil {
  145. return err
  146. }
  147. err := store.db.SetSync(key, state.Bytes())
  148. if err != nil {
  149. return err
  150. }
  151. return nil
  152. }
  153. // BootstrapState saves a new state, used e.g. by state sync when starting from non-zero height.
  154. func (store dbStore) Bootstrap(state State) error {
  155. height := state.LastBlockHeight + 1
  156. if height == 1 {
  157. height = state.InitialHeight
  158. }
  159. if height > 1 && !state.LastValidators.IsNilOrEmpty() {
  160. if err := store.saveValidatorsInfo(height-1, height-1, state.LastValidators); err != nil {
  161. return err
  162. }
  163. }
  164. if err := store.saveValidatorsInfo(height, height, state.Validators); err != nil {
  165. return err
  166. }
  167. if err := store.saveValidatorsInfo(height+1, height+1, state.NextValidators); err != nil {
  168. return err
  169. }
  170. if err := store.saveConsensusParamsInfo(height, height, state.ConsensusParams); err != nil {
  171. return err
  172. }
  173. return store.db.SetSync(stateKey, state.Bytes())
  174. }
  175. // PruneStates deletes states between the given heights (including from, excluding to). It is not
  176. // guaranteed to delete all states, since the last checkpointed state and states being pointed to by
  177. // e.g. `LastHeightChanged` must remain. The state at to must also exist.
  178. //
  179. // The from parameter is necessary since we can't do a key scan in a performant way due to the key
  180. // encoding not preserving ordering: https://github.com/tendermint/tendermint/issues/4567
  181. // This will cause some old states to be left behind when doing incremental partial prunes,
  182. // specifically older checkpoints and LastHeightChanged targets.
  183. func (store dbStore) PruneStates(from int64, to int64) error {
  184. if from <= 0 || to <= 0 {
  185. return fmt.Errorf("from height %v and to height %v must be greater than 0", from, to)
  186. }
  187. if from >= to {
  188. return fmt.Errorf("from height %v must be lower than to height %v", from, to)
  189. }
  190. valInfo, err := loadValidatorsInfo(store.db, to)
  191. if err != nil {
  192. return fmt.Errorf("validators at height %v not found: %w", to, err)
  193. }
  194. paramsInfo, err := store.loadConsensusParamsInfo(to)
  195. if err != nil {
  196. return fmt.Errorf("consensus params at height %v not found: %w", to, err)
  197. }
  198. keepVals := make(map[int64]bool)
  199. if valInfo.ValidatorSet == nil {
  200. keepVals[valInfo.LastHeightChanged] = true
  201. keepVals[lastStoredHeightFor(to, valInfo.LastHeightChanged)] = true // keep last checkpoint too
  202. }
  203. keepParams := make(map[int64]bool)
  204. if paramsInfo.ConsensusParams.Equal(&tmproto.ConsensusParams{}) {
  205. keepParams[paramsInfo.LastHeightChanged] = true
  206. }
  207. batch := store.db.NewBatch()
  208. defer batch.Close()
  209. pruned := uint64(0)
  210. // We have to delete in reverse order, to avoid deleting previous heights that have validator
  211. // sets and consensus params that we may need to retrieve.
  212. for h := to - 1; h >= from; h-- {
  213. // For heights we keep, we must make sure they have the full validator set or consensus
  214. // params, otherwise they will panic if they're retrieved directly (instead of
  215. // indirectly via a LastHeightChanged pointer).
  216. if keepVals[h] {
  217. v, err := loadValidatorsInfo(store.db, h)
  218. if err != nil || v.ValidatorSet == nil {
  219. vip, err := store.LoadValidators(h)
  220. if err != nil {
  221. return err
  222. }
  223. pvi, err := vip.ToProto()
  224. if err != nil {
  225. return err
  226. }
  227. v.ValidatorSet = pvi
  228. v.LastHeightChanged = h
  229. bz, err := v.Marshal()
  230. if err != nil {
  231. return err
  232. }
  233. err = batch.Set(calcValidatorsKey(h), bz)
  234. if err != nil {
  235. return err
  236. }
  237. }
  238. } else {
  239. err = batch.Delete(calcValidatorsKey(h))
  240. if err != nil {
  241. return err
  242. }
  243. }
  244. if keepParams[h] {
  245. p, err := store.loadConsensusParamsInfo(h)
  246. if err != nil {
  247. return err
  248. }
  249. if p.ConsensusParams.Equal(&tmproto.ConsensusParams{}) {
  250. p.ConsensusParams, err = store.LoadConsensusParams(h)
  251. if err != nil {
  252. return err
  253. }
  254. p.LastHeightChanged = h
  255. bz, err := p.Marshal()
  256. if err != nil {
  257. return err
  258. }
  259. err = batch.Set(calcConsensusParamsKey(h), bz)
  260. if err != nil {
  261. return err
  262. }
  263. }
  264. } else {
  265. err = batch.Delete(calcConsensusParamsKey(h))
  266. if err != nil {
  267. return err
  268. }
  269. }
  270. err = batch.Delete(calcABCIResponsesKey(h))
  271. if err != nil {
  272. return err
  273. }
  274. pruned++
  275. // avoid batches growing too large by flushing to database regularly
  276. if pruned%1000 == 0 && pruned > 0 {
  277. err := batch.Write()
  278. if err != nil {
  279. return err
  280. }
  281. batch.Close()
  282. batch = store.db.NewBatch()
  283. defer batch.Close()
  284. }
  285. }
  286. err = batch.WriteSync()
  287. if err != nil {
  288. return err
  289. }
  290. return nil
  291. }
  292. //------------------------------------------------------------------------
  293. // ABCIResponsesResultsHash returns the root hash of a Merkle tree of
  294. // ResponseDeliverTx responses (see ABCIResults.Hash)
  295. //
  296. // See merkle.SimpleHashFromByteSlices
  297. func ABCIResponsesResultsHash(ar *tmstate.ABCIResponses) []byte {
  298. return types.NewResults(ar.DeliverTxs).Hash()
  299. }
  300. // LoadABCIResponses loads the ABCIResponses for the given height from the
  301. // database. If not found, ErrNoABCIResponsesForHeight is returned.
  302. //
  303. // This is useful for recovering from crashes where we called app.Commit and
  304. // before we called s.Save(). It can also be used to produce Merkle proofs of
  305. // the result of txs.
  306. func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, error) {
  307. buf, err := store.db.Get(calcABCIResponsesKey(height))
  308. if err != nil {
  309. return nil, err
  310. }
  311. if len(buf) == 0 {
  312. return nil, ErrNoABCIResponsesForHeight{height}
  313. }
  314. abciResponses := new(tmstate.ABCIResponses)
  315. err = abciResponses.Unmarshal(buf)
  316. if err != nil {
  317. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  318. tmos.Exit(fmt.Sprintf(`LoadABCIResponses: Data has been corrupted or its spec has
  319. changed: %v\n`, err))
  320. }
  321. // TODO: ensure that buf is completely read.
  322. return abciResponses, nil
  323. }
  324. // SaveABCIResponses persists the ABCIResponses to the database.
  325. // This is useful in case we crash after app.Commit and before s.Save().
  326. // Responses are indexed by height so they can also be loaded later to produce
  327. // Merkle proofs.
  328. //
  329. // Exposed for testing.
  330. func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error {
  331. var dtxs []*abci.ResponseDeliverTx
  332. //strip nil values,
  333. for _, tx := range abciResponses.DeliverTxs {
  334. if tx != nil {
  335. dtxs = append(dtxs, tx)
  336. }
  337. }
  338. abciResponses.DeliverTxs = dtxs
  339. bz, err := abciResponses.Marshal()
  340. if err != nil {
  341. return err
  342. }
  343. err = store.db.SetSync(calcABCIResponsesKey(height), bz)
  344. if err != nil {
  345. return err
  346. }
  347. return nil
  348. }
  349. //-----------------------------------------------------------------------------
  350. // LoadValidators loads the ValidatorSet for a given height.
  351. // Returns ErrNoValSetForHeight if the validator set can't be found for this height.
  352. func (store dbStore) LoadValidators(height int64) (*types.ValidatorSet, error) {
  353. valInfo, err := loadValidatorsInfo(store.db, height)
  354. if err != nil {
  355. return nil, ErrNoValSetForHeight{height}
  356. }
  357. if valInfo.ValidatorSet == nil {
  358. lastStoredHeight := lastStoredHeightFor(height, valInfo.LastHeightChanged)
  359. valInfo2, err := loadValidatorsInfo(store.db, lastStoredHeight)
  360. if err != nil || valInfo2.ValidatorSet == nil {
  361. return nil,
  362. fmt.Errorf("couldn't find validators at height %d (height %d was originally requested): %w",
  363. lastStoredHeight,
  364. height,
  365. err,
  366. )
  367. }
  368. vs, err := types.ValidatorSetFromProto(valInfo2.ValidatorSet)
  369. if err != nil {
  370. return nil, err
  371. }
  372. vs.IncrementProposerPriority(tmmath.SafeConvertInt32(height - lastStoredHeight)) // mutate
  373. vi2, err := vs.ToProto()
  374. if err != nil {
  375. return nil, err
  376. }
  377. valInfo2.ValidatorSet = vi2
  378. valInfo = valInfo2
  379. }
  380. vip, err := types.ValidatorSetFromProto(valInfo.ValidatorSet)
  381. if err != nil {
  382. return nil, err
  383. }
  384. return vip, nil
  385. }
  386. func lastStoredHeightFor(height, lastHeightChanged int64) int64 {
  387. checkpointHeight := height - height%valSetCheckpointInterval
  388. return tmmath.MaxInt64(checkpointHeight, lastHeightChanged)
  389. }
  390. // CONTRACT: Returned ValidatorsInfo can be mutated.
  391. func loadValidatorsInfo(db dbm.DB, height int64) (*tmstate.ValidatorsInfo, error) {
  392. buf, err := db.Get(calcValidatorsKey(height))
  393. if err != nil {
  394. return nil, err
  395. }
  396. if len(buf) == 0 {
  397. return nil, errors.New("value retrieved from db is empty")
  398. }
  399. v := new(tmstate.ValidatorsInfo)
  400. err = v.Unmarshal(buf)
  401. if err != nil {
  402. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  403. tmos.Exit(fmt.Sprintf(`LoadValidators: Data has been corrupted or its spec has changed:
  404. %v\n`, err))
  405. }
  406. // TODO: ensure that buf is completely read.
  407. return v, nil
  408. }
  409. // saveValidatorsInfo persists the validator set.
  410. //
  411. // `height` is the effective height for which the validator is responsible for
  412. // signing. It should be called from s.Save(), right before the state itself is
  413. // persisted.
  414. func (store dbStore) saveValidatorsInfo(height, lastHeightChanged int64, valSet *types.ValidatorSet) error {
  415. if lastHeightChanged > height {
  416. return errors.New("lastHeightChanged cannot be greater than ValidatorsInfo height")
  417. }
  418. valInfo := &tmstate.ValidatorsInfo{
  419. LastHeightChanged: lastHeightChanged,
  420. }
  421. // Only persist validator set if it was updated or checkpoint height (see
  422. // valSetCheckpointInterval) is reached.
  423. if height == lastHeightChanged || height%valSetCheckpointInterval == 0 {
  424. pv, err := valSet.ToProto()
  425. if err != nil {
  426. return err
  427. }
  428. valInfo.ValidatorSet = pv
  429. }
  430. bz, err := valInfo.Marshal()
  431. if err != nil {
  432. return err
  433. }
  434. err = store.db.Set(calcValidatorsKey(height), bz)
  435. if err != nil {
  436. return err
  437. }
  438. return nil
  439. }
  440. //-----------------------------------------------------------------------------
  441. // ConsensusParamsInfo represents the latest consensus params, or the last height it changed
  442. // LoadConsensusParams loads the ConsensusParams for a given height.
  443. func (store dbStore) LoadConsensusParams(height int64) (tmproto.ConsensusParams, error) {
  444. empty := tmproto.ConsensusParams{}
  445. paramsInfo, err := store.loadConsensusParamsInfo(height)
  446. if err != nil {
  447. return empty, fmt.Errorf("could not find consensus params for height #%d: %w", height, err)
  448. }
  449. if paramsInfo.ConsensusParams.Equal(&empty) {
  450. paramsInfo2, err := store.loadConsensusParamsInfo(paramsInfo.LastHeightChanged)
  451. if err != nil {
  452. return empty, fmt.Errorf(
  453. "couldn't find consensus params at height %d as last changed from height %d: %w",
  454. paramsInfo.LastHeightChanged,
  455. height,
  456. err,
  457. )
  458. }
  459. paramsInfo = paramsInfo2
  460. }
  461. return paramsInfo.ConsensusParams, nil
  462. }
  463. func (store dbStore) loadConsensusParamsInfo(height int64) (*tmstate.ConsensusParamsInfo, error) {
  464. buf, err := store.db.Get(calcConsensusParamsKey(height))
  465. if err != nil {
  466. return nil, err
  467. }
  468. if len(buf) == 0 {
  469. return nil, errors.New("value retrieved from db is empty")
  470. }
  471. paramsInfo := new(tmstate.ConsensusParamsInfo)
  472. if err = paramsInfo.Unmarshal(buf); err != nil {
  473. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  474. tmos.Exit(fmt.Sprintf(`LoadConsensusParams: Data has been corrupted or its spec has changed:
  475. %v\n`, err))
  476. }
  477. // TODO: ensure that buf is completely read.
  478. return paramsInfo, nil
  479. }
  480. // saveConsensusParamsInfo persists the consensus params for the next block to disk.
  481. // It should be called from s.Save(), right before the state itself is persisted.
  482. // If the consensus params did not change after processing the latest block,
  483. // only the last height for which they changed is persisted.
  484. func (store dbStore) saveConsensusParamsInfo(nextHeight, changeHeight int64, params tmproto.ConsensusParams) error {
  485. paramsInfo := &tmstate.ConsensusParamsInfo{
  486. LastHeightChanged: changeHeight,
  487. }
  488. if changeHeight == nextHeight {
  489. paramsInfo.ConsensusParams = params
  490. }
  491. bz, err := paramsInfo.Marshal()
  492. if err != nil {
  493. return err
  494. }
  495. err = store.db.Set(calcConsensusParamsKey(nextHeight), bz)
  496. if err != nil {
  497. return err
  498. }
  499. return nil
  500. }