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.

192 lines
6.1 KiB

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>
4 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>
4 years ago
  1. package config
  2. import (
  3. "reflect"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. )
  9. func TestDefaultConfig(t *testing.T) {
  10. assert := assert.New(t)
  11. // set up some defaults
  12. cfg := DefaultConfig()
  13. assert.NotNil(cfg.P2P)
  14. assert.NotNil(cfg.Mempool)
  15. assert.NotNil(cfg.Consensus)
  16. // check the root dir stuff...
  17. cfg.SetRoot("/foo")
  18. cfg.Genesis = "bar"
  19. cfg.DBPath = "/opt/data"
  20. cfg.Mempool.WalPath = "wal/mem/"
  21. assert.Equal("/foo/bar", cfg.GenesisFile())
  22. assert.Equal("/opt/data", cfg.DBDir())
  23. assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir())
  24. }
  25. func TestConfigValidateBasic(t *testing.T) {
  26. cfg := DefaultConfig()
  27. assert.NoError(t, cfg.ValidateBasic())
  28. // tamper with timeout_propose
  29. cfg.Consensus.TimeoutPropose = -10 * time.Second
  30. assert.Error(t, cfg.ValidateBasic())
  31. }
  32. func TestTLSConfiguration(t *testing.T) {
  33. assert := assert.New(t)
  34. cfg := DefaultConfig()
  35. cfg.SetRoot("/home/user")
  36. cfg.RPC.TLSCertFile = "file.crt"
  37. assert.Equal("/home/user/config/file.crt", cfg.RPC.CertFile())
  38. cfg.RPC.TLSKeyFile = "file.key"
  39. assert.Equal("/home/user/config/file.key", cfg.RPC.KeyFile())
  40. cfg.RPC.TLSCertFile = "/abs/path/to/file.crt"
  41. assert.Equal("/abs/path/to/file.crt", cfg.RPC.CertFile())
  42. cfg.RPC.TLSKeyFile = "/abs/path/to/file.key"
  43. assert.Equal("/abs/path/to/file.key", cfg.RPC.KeyFile())
  44. }
  45. func TestBaseConfigValidateBasic(t *testing.T) {
  46. cfg := TestBaseConfig()
  47. assert.NoError(t, cfg.ValidateBasic())
  48. // tamper with log format
  49. cfg.LogFormat = "invalid"
  50. assert.Error(t, cfg.ValidateBasic())
  51. }
  52. func TestRPCConfigValidateBasic(t *testing.T) {
  53. cfg := TestRPCConfig()
  54. assert.NoError(t, cfg.ValidateBasic())
  55. fieldsToTest := []string{
  56. "GRPCMaxOpenConnections",
  57. "MaxOpenConnections",
  58. "MaxSubscriptionClients",
  59. "MaxSubscriptionsPerClient",
  60. "TimeoutBroadcastTxCommit",
  61. "MaxBodyBytes",
  62. "MaxHeaderBytes",
  63. }
  64. for _, fieldName := range fieldsToTest {
  65. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(-1)
  66. assert.Error(t, cfg.ValidateBasic())
  67. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(0)
  68. }
  69. }
  70. func TestP2PConfigValidateBasic(t *testing.T) {
  71. cfg := TestP2PConfig()
  72. assert.NoError(t, cfg.ValidateBasic())
  73. fieldsToTest := []string{
  74. "MaxNumInboundPeers",
  75. "MaxNumOutboundPeers",
  76. "FlushThrottleTimeout",
  77. "MaxPacketMsgPayloadSize",
  78. "SendRate",
  79. "RecvRate",
  80. }
  81. for _, fieldName := range fieldsToTest {
  82. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(-1)
  83. assert.Error(t, cfg.ValidateBasic())
  84. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(0)
  85. }
  86. }
  87. func TestMempoolConfigValidateBasic(t *testing.T) {
  88. cfg := TestMempoolConfig()
  89. assert.NoError(t, cfg.ValidateBasic())
  90. fieldsToTest := []string{
  91. "Size",
  92. "MaxTxsBytes",
  93. "CacheSize",
  94. "MaxTxBytes",
  95. }
  96. for _, fieldName := range fieldsToTest {
  97. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(-1)
  98. assert.Error(t, cfg.ValidateBasic())
  99. reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(0)
  100. }
  101. }
  102. func TestStateSyncConfigValidateBasic(t *testing.T) {
  103. cfg := TestStateSyncConfig()
  104. require.NoError(t, cfg.ValidateBasic())
  105. }
  106. func TestFastSyncConfigValidateBasic(t *testing.T) {
  107. cfg := TestFastSyncConfig()
  108. assert.NoError(t, cfg.ValidateBasic())
  109. // tamper with version
  110. cfg.Version = "v2"
  111. assert.NoError(t, cfg.ValidateBasic())
  112. cfg.Version = "invalid"
  113. assert.Error(t, cfg.ValidateBasic())
  114. }
  115. func TestConsensusConfig_ValidateBasic(t *testing.T) {
  116. // nolint: lll
  117. testcases := map[string]struct {
  118. modify func(*ConsensusConfig)
  119. expectErr bool
  120. }{
  121. "TimeoutPropose": {func(c *ConsensusConfig) { c.TimeoutPropose = time.Second }, false},
  122. "TimeoutPropose negative": {func(c *ConsensusConfig) { c.TimeoutPropose = -1 }, true},
  123. "TimeoutProposeDelta": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = time.Second }, false},
  124. "TimeoutProposeDelta negative": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = -1 }, true},
  125. "TimeoutPrevote": {func(c *ConsensusConfig) { c.TimeoutPrevote = time.Second }, false},
  126. "TimeoutPrevote negative": {func(c *ConsensusConfig) { c.TimeoutPrevote = -1 }, true},
  127. "TimeoutPrevoteDelta": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = time.Second }, false},
  128. "TimeoutPrevoteDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = -1 }, true},
  129. "TimeoutPrecommit": {func(c *ConsensusConfig) { c.TimeoutPrecommit = time.Second }, false},
  130. "TimeoutPrecommit negative": {func(c *ConsensusConfig) { c.TimeoutPrecommit = -1 }, true},
  131. "TimeoutPrecommitDelta": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = time.Second }, false},
  132. "TimeoutPrecommitDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = -1 }, true},
  133. "TimeoutCommit": {func(c *ConsensusConfig) { c.TimeoutCommit = time.Second }, false},
  134. "TimeoutCommit negative": {func(c *ConsensusConfig) { c.TimeoutCommit = -1 }, true},
  135. "PeerGossipSleepDuration": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = time.Second }, false},
  136. "PeerGossipSleepDuration negative": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = -1 }, true},
  137. "PeerQueryMaj23SleepDuration": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = time.Second }, false},
  138. "PeerQueryMaj23SleepDuration negative": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true},
  139. "DoubleSignCheckHeight negative": {func(c *ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true},
  140. }
  141. for desc, tc := range testcases {
  142. tc := tc // appease linter
  143. t.Run(desc, func(t *testing.T) {
  144. cfg := DefaultConsensusConfig()
  145. tc.modify(cfg)
  146. err := cfg.ValidateBasic()
  147. if tc.expectErr {
  148. assert.Error(t, err)
  149. } else {
  150. assert.NoError(t, err)
  151. }
  152. })
  153. }
  154. }
  155. func TestInstrumentationConfigValidateBasic(t *testing.T) {
  156. cfg := TestInstrumentationConfig()
  157. assert.NoError(t, cfg.ValidateBasic())
  158. // tamper with maximum open connections
  159. cfg.MaxOpenConnections = -1
  160. assert.Error(t, cfg.ValidateBasic())
  161. }