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.

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