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.

277 lines
7.7 KiB

  1. package lite
  2. import (
  3. "fmt"
  4. "sync"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. dbm "github.com/tendermint/tendermint/libs/db"
  9. log "github.com/tendermint/tendermint/libs/log"
  10. "github.com/tendermint/tendermint/types"
  11. )
  12. func TestInquirerValidPath(t *testing.T) {
  13. assert, require := assert.New(t), require.New(t)
  14. trust := NewDBProvider("trust", dbm.NewMemDB())
  15. source := NewDBProvider("source", dbm.NewMemDB())
  16. // Set up the validators to generate test blocks.
  17. var vote int64 = 10
  18. keys := genPrivKeys(5)
  19. nkeys := keys.Extend(1)
  20. // Construct a bunch of commits, each with one more height than the last.
  21. chainID := "inquiry-test"
  22. consHash := []byte("params")
  23. resHash := []byte("results")
  24. count := 50
  25. fcz := make([]FullCommit, count)
  26. for i := 0; i < count; i++ {
  27. vals := keys.ToValidators(vote, 0)
  28. nextVals := nkeys.ToValidators(vote, 0)
  29. h := int64(1 + i)
  30. appHash := []byte(fmt.Sprintf("h=%d", h))
  31. fcz[i] = keys.GenFullCommit(
  32. chainID, h, nil,
  33. vals, nextVals,
  34. appHash, consHash, resHash, 0, len(keys))
  35. // Extend the keys by 1 each time.
  36. keys = nkeys
  37. nkeys = nkeys.Extend(1)
  38. }
  39. // Initialize a Verifier with the initial state.
  40. err := trust.SaveFullCommit(fcz[0])
  41. require.Nil(err)
  42. cert := NewDynamicVerifier(chainID, trust, source)
  43. cert.SetLogger(log.TestingLogger())
  44. // This should fail validation:
  45. sh := fcz[count-1].SignedHeader
  46. err = cert.Verify(sh)
  47. require.NotNil(err)
  48. // Adding a few commits in the middle should be insufficient.
  49. for i := 10; i < 13; i++ {
  50. err := source.SaveFullCommit(fcz[i])
  51. require.Nil(err)
  52. }
  53. err = cert.Verify(sh)
  54. assert.NotNil(err)
  55. // With more info, we succeed.
  56. for i := 0; i < count; i++ {
  57. err := source.SaveFullCommit(fcz[i])
  58. require.Nil(err)
  59. }
  60. err = cert.Verify(sh)
  61. assert.Nil(err, "%+v", err)
  62. }
  63. func TestDynamicVerify(t *testing.T) {
  64. trust := NewDBProvider("trust", dbm.NewMemDB())
  65. source := NewDBProvider("source", dbm.NewMemDB())
  66. // 10 commits with one valset, 1 to change,
  67. // 10 commits with the next one
  68. n1, n2 := 10, 10
  69. nCommits := n1 + n2 + 1
  70. maxHeight := int64(nCommits)
  71. fcz := make([]FullCommit, nCommits)
  72. // gen the 2 val sets
  73. chainID := "dynamic-verifier"
  74. power := int64(10)
  75. keys1 := genPrivKeys(5)
  76. vals1 := keys1.ToValidators(power, 0)
  77. keys2 := genPrivKeys(5)
  78. vals2 := keys2.ToValidators(power, 0)
  79. // make some commits with the first
  80. for i := 0; i < n1; i++ {
  81. fcz[i] = makeFullCommit(int64(i), keys1, vals1, vals1, chainID)
  82. }
  83. // update the val set
  84. fcz[n1] = makeFullCommit(int64(n1), keys1, vals1, vals2, chainID)
  85. // make some commits with the new one
  86. for i := n1 + 1; i < nCommits; i++ {
  87. fcz[i] = makeFullCommit(int64(i), keys2, vals2, vals2, chainID)
  88. }
  89. // Save everything in the source
  90. for _, fc := range fcz {
  91. source.SaveFullCommit(fc)
  92. }
  93. // Initialize a Verifier with the initial state.
  94. err := trust.SaveFullCommit(fcz[0])
  95. require.Nil(t, err)
  96. ver := NewDynamicVerifier(chainID, trust, source)
  97. ver.SetLogger(log.TestingLogger())
  98. // fetch the latest from the source
  99. latestFC, err := source.LatestFullCommit(chainID, 1, maxHeight)
  100. require.NoError(t, err)
  101. // try to update to the latest
  102. err = ver.Verify(latestFC.SignedHeader)
  103. require.NoError(t, err)
  104. }
  105. func makeFullCommit(height int64, keys privKeys, vals, nextVals *types.ValidatorSet, chainID string) FullCommit {
  106. height += 1
  107. consHash := []byte("special-params")
  108. appHash := []byte(fmt.Sprintf("h=%d", height))
  109. resHash := []byte(fmt.Sprintf("res=%d", height))
  110. return keys.GenFullCommit(
  111. chainID, height, nil,
  112. vals, nextVals,
  113. appHash, consHash, resHash, 0, len(keys))
  114. }
  115. func TestInquirerVerifyHistorical(t *testing.T) {
  116. assert, require := assert.New(t), require.New(t)
  117. trust := NewDBProvider("trust", dbm.NewMemDB())
  118. source := NewDBProvider("source", dbm.NewMemDB())
  119. // Set up the validators to generate test blocks.
  120. var vote int64 = 10
  121. keys := genPrivKeys(5)
  122. nkeys := keys.Extend(1)
  123. // Construct a bunch of commits, each with one more height than the last.
  124. chainID := "inquiry-test"
  125. count := 10
  126. consHash := []byte("special-params")
  127. fcz := make([]FullCommit, count)
  128. for i := 0; i < count; i++ {
  129. vals := keys.ToValidators(vote, 0)
  130. nextVals := nkeys.ToValidators(vote, 0)
  131. h := int64(1 + i)
  132. appHash := []byte(fmt.Sprintf("h=%d", h))
  133. resHash := []byte(fmt.Sprintf("res=%d", h))
  134. fcz[i] = keys.GenFullCommit(
  135. chainID, h, nil,
  136. vals, nextVals,
  137. appHash, consHash, resHash, 0, len(keys))
  138. // Extend the keys by 1 each time.
  139. keys = nkeys
  140. nkeys = nkeys.Extend(1)
  141. }
  142. // Initialize a Verifier with the initial state.
  143. err := trust.SaveFullCommit(fcz[0])
  144. require.Nil(err)
  145. cert := NewDynamicVerifier(chainID, trust, source)
  146. cert.SetLogger(log.TestingLogger())
  147. // Store a few full commits as trust.
  148. for _, i := range []int{2, 5} {
  149. trust.SaveFullCommit(fcz[i])
  150. }
  151. // See if we can jump forward using trusted full commits.
  152. // Souce doesn't have fcz[9] so cert.LastTrustedHeight wont' change.
  153. err = source.SaveFullCommit(fcz[7])
  154. require.Nil(err, "%+v", err)
  155. sh := fcz[8].SignedHeader
  156. err = cert.Verify(sh)
  157. require.Nil(err, "%+v", err)
  158. assert.Equal(fcz[7].Height(), cert.LastTrustedHeight())
  159. fc_, err := trust.LatestFullCommit(chainID, fcz[8].Height(), fcz[8].Height())
  160. require.NotNil(err, "%+v", err)
  161. assert.Equal(fc_, (FullCommit{}))
  162. // With fcz[9] Verify will update last trusted height.
  163. err = source.SaveFullCommit(fcz[9])
  164. require.Nil(err, "%+v", err)
  165. sh = fcz[8].SignedHeader
  166. err = cert.Verify(sh)
  167. require.Nil(err, "%+v", err)
  168. assert.Equal(fcz[8].Height(), cert.LastTrustedHeight())
  169. fc_, err = trust.LatestFullCommit(chainID, fcz[8].Height(), fcz[8].Height())
  170. require.Nil(err, "%+v", err)
  171. assert.Equal(fc_.Height(), fcz[8].Height())
  172. // Add access to all full commits via untrusted source.
  173. for i := 0; i < count; i++ {
  174. err := source.SaveFullCommit(fcz[i])
  175. require.Nil(err)
  176. }
  177. // Try to check an unknown seed in the past.
  178. sh = fcz[3].SignedHeader
  179. err = cert.Verify(sh)
  180. require.Nil(err, "%+v", err)
  181. assert.Equal(fcz[8].Height(), cert.LastTrustedHeight())
  182. // Jump all the way forward again.
  183. sh = fcz[count-1].SignedHeader
  184. err = cert.Verify(sh)
  185. require.Nil(err, "%+v", err)
  186. assert.Equal(fcz[9].Height(), cert.LastTrustedHeight())
  187. }
  188. func TestConcurrencyInquirerVerify(t *testing.T) {
  189. _, require := assert.New(t), require.New(t)
  190. trust := NewDBProvider("trust", dbm.NewMemDB()).SetLimit(10)
  191. source := NewDBProvider("source", dbm.NewMemDB())
  192. // Set up the validators to generate test blocks.
  193. var vote int64 = 10
  194. keys := genPrivKeys(5)
  195. nkeys := keys.Extend(1)
  196. // Construct a bunch of commits, each with one more height than the last.
  197. chainID := "inquiry-test"
  198. count := 10
  199. consHash := []byte("special-params")
  200. fcz := make([]FullCommit, count)
  201. for i := 0; i < count; i++ {
  202. vals := keys.ToValidators(vote, 0)
  203. nextVals := nkeys.ToValidators(vote, 0)
  204. h := int64(1 + i)
  205. appHash := []byte(fmt.Sprintf("h=%d", h))
  206. resHash := []byte(fmt.Sprintf("res=%d", h))
  207. fcz[i] = keys.GenFullCommit(
  208. chainID, h, nil,
  209. vals, nextVals,
  210. appHash, consHash, resHash, 0, len(keys))
  211. // Extend the keys by 1 each time.
  212. keys = nkeys
  213. nkeys = nkeys.Extend(1)
  214. }
  215. // Initialize a Verifier with the initial state.
  216. err := trust.SaveFullCommit(fcz[0])
  217. require.Nil(err)
  218. cert := NewDynamicVerifier(chainID, trust, source)
  219. cert.SetLogger(log.TestingLogger())
  220. err = source.SaveFullCommit(fcz[7])
  221. require.Nil(err, "%+v", err)
  222. err = source.SaveFullCommit(fcz[8])
  223. require.Nil(err, "%+v", err)
  224. sh := fcz[8].SignedHeader
  225. var wg sync.WaitGroup
  226. count = 100
  227. errList := make([]error, count)
  228. for i := 0; i < count; i++ {
  229. wg.Add(1)
  230. go func(index int) {
  231. errList[index] = cert.Verify(sh)
  232. defer wg.Done()
  233. }(i)
  234. }
  235. wg.Wait()
  236. for _, err := range errList {
  237. require.Nil(err)
  238. }
  239. }