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.

138 lines
4.1 KiB

  1. package lite
  2. import (
  3. "errors"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. lerr "github.com/tendermint/tendermint/lite/errors"
  8. "github.com/tendermint/tendermint/types"
  9. dbm "github.com/tendermint/tmlibs/db"
  10. )
  11. // missingProvider doesn't store anything, always a miss.
  12. // Designed as a mock for testing.
  13. type missingProvider struct{}
  14. // NewMissingProvider returns a provider which does not store anything and always misses.
  15. func NewMissingProvider() PersistentProvider {
  16. return missingProvider{}
  17. }
  18. func (missingProvider) SaveFullCommit(FullCommit) error { return nil }
  19. func (missingProvider) LatestFullCommit(chainID string, minHeight, maxHeight int64) (FullCommit, error) {
  20. return FullCommit{}, lerr.ErrCommitNotFound()
  21. }
  22. func (missingProvider) ValidatorSet(chainID string, height int64) (*types.ValidatorSet, error) {
  23. return nil, errors.New("missing validator set")
  24. }
  25. func TestMemProvider(t *testing.T) {
  26. p := NewDBProvider(dbm.NewMemDB())
  27. checkProvider(t, p, "test-mem", "empty")
  28. }
  29. func TestMultiProvider(t *testing.T) {
  30. p := NewMultiProvider(
  31. NewMissingProvider(),
  32. NewDBProvider(dbm.NewMemDB()),
  33. NewMissingProvider(),
  34. )
  35. checkProvider(t, p, "test-cache", "kjfhekfhkewhgit")
  36. }
  37. func checkProvider(t *testing.T, p PersistentProvider, chainID, app string) {
  38. assert, require := assert.New(t), require.New(t)
  39. appHash := []byte(app)
  40. keys := genPrivKeys(5)
  41. count := 10
  42. // Make a bunch of full commits.
  43. fcz := make([]FullCommit, count)
  44. for i := 0; i < count; i++ {
  45. vals := keys.ToValidators(10, int64(count/2))
  46. h := int64(20 + 10*i)
  47. fcz[i] = keys.GenFullCommit(chainID, h, nil, vals, vals, appHash, []byte("params"), []byte("results"), 0, 5)
  48. }
  49. // Check that provider is initially empty.
  50. fc, err := p.LatestFullCommit(chainID, 1, 1<<63-1)
  51. require.NotNil(err)
  52. assert.True(lerr.IsErrCommitNotFound(err))
  53. // Save all full commits to the provider.
  54. for _, fc := range fcz {
  55. err = p.SaveFullCommit(fc)
  56. require.Nil(err)
  57. // Make sure we can get it back.
  58. fc2, err := p.LatestFullCommit(chainID, fc.Height(), fc.Height())
  59. assert.Nil(err)
  60. assert.Equal(fc.SignedHeader, fc2.SignedHeader)
  61. assert.Equal(fc.Validators, fc2.Validators)
  62. assert.Equal(fc.NextValidators, fc2.NextValidators)
  63. }
  64. // Make sure we get the last hash if we overstep.
  65. fc, err = p.LatestFullCommit(chainID, 1, 5000)
  66. if assert.Nil(err) {
  67. assert.Equal(fcz[count-1].Height(), fc.Height())
  68. assert.Equal(fcz[count-1], fc)
  69. }
  70. // ... and middle ones as well.
  71. fc, err = p.LatestFullCommit(chainID, 1, 47)
  72. if assert.Nil(err) {
  73. // we only step by 10, so 40 must be the one below this
  74. assert.EqualValues(40, fc.Height())
  75. }
  76. }
  77. // This will make a get height, and if it is good, set the data as well.
  78. func checkLatestFullCommit(t *testing.T, p PersistentProvider, chainID string, ask, expect int64) {
  79. fc, err := p.LatestFullCommit(chainID, 1, ask)
  80. require.Nil(t, err)
  81. if assert.Equal(t, expect, fc.Height()) {
  82. err = p.SaveFullCommit(fc)
  83. require.Nil(t, err)
  84. }
  85. }
  86. func TestMultiLatestFullCommit(t *testing.T) {
  87. require := require.New(t)
  88. // We will write data to the second level of the cache (p2), and see what
  89. // gets cached/stored in.
  90. p := NewDBProvider(dbm.NewMemDB())
  91. p2 := NewDBProvider(dbm.NewMemDB())
  92. cp := NewMultiProvider(p, p2)
  93. chainID := "cache-best-height"
  94. appHash := []byte("01234567")
  95. keys := genPrivKeys(5)
  96. count := 10
  97. // Set a bunch of full commits.
  98. for i := 0; i < count; i++ {
  99. vals := keys.ToValidators(10, int64(count/2))
  100. h := int64(10 * (i + 1))
  101. fc := keys.GenFullCommit(chainID, h, nil, vals, vals, appHash, []byte("params"), []byte("results"), 0, 5)
  102. err := p2.SaveFullCommit(fc)
  103. require.NoError(err)
  104. }
  105. // Get a few heights from the cache and set them proper.
  106. checkLatestFullCommit(t, cp, chainID, 57, 50)
  107. checkLatestFullCommit(t, cp, chainID, 33, 30)
  108. // make sure they are set in p as well (but nothing else)
  109. checkLatestFullCommit(t, p, chainID, 44, 30)
  110. checkLatestFullCommit(t, p, chainID, 50, 50)
  111. checkLatestFullCommit(t, p, chainID, 99, 50)
  112. // now, query the cache for a higher value
  113. checkLatestFullCommit(t, p2, chainID, 99, 90)
  114. checkLatestFullCommit(t, cp, chainID, 99, 90)
  115. }