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.

122 lines
3.0 KiB

  1. package mbt
  2. import (
  3. "os"
  4. "path/filepath"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/require"
  8. tmjson "github.com/tendermint/tendermint/libs/json"
  9. "github.com/tendermint/tendermint/light"
  10. "github.com/tendermint/tendermint/types"
  11. )
  12. const jsonDir = "./json"
  13. func TestVerify(t *testing.T) {
  14. filenames := jsonFilenames(t)
  15. for _, filename := range filenames {
  16. filename := filename
  17. t.Run(filename, func(t *testing.T) {
  18. jsonBlob, err := os.ReadFile(filename)
  19. if err != nil {
  20. t.Fatal(err)
  21. }
  22. var tc testCase
  23. err = tmjson.Unmarshal(jsonBlob, &tc)
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. t.Log(tc.Description)
  28. var (
  29. trustedSignedHeader = tc.Initial.SignedHeader
  30. trustedNextVals = tc.Initial.NextValidatorSet
  31. trustingPeriod = time.Duration(tc.Initial.TrustingPeriod) * time.Nanosecond
  32. )
  33. for _, input := range tc.Input {
  34. var (
  35. newSignedHeader = input.LightBlock.SignedHeader
  36. newVals = input.LightBlock.ValidatorSet
  37. )
  38. err = light.Verify(
  39. &trustedSignedHeader,
  40. &trustedNextVals,
  41. newSignedHeader,
  42. newVals,
  43. trustingPeriod,
  44. input.Now,
  45. 1*time.Second,
  46. light.DefaultTrustLevel,
  47. )
  48. t.Logf("%d -> %d", trustedSignedHeader.Height, newSignedHeader.Height)
  49. switch input.Verdict {
  50. case "SUCCESS":
  51. require.NoError(t, err)
  52. case "NOT_ENOUGH_TRUST":
  53. require.IsType(t, light.ErrNewValSetCantBeTrusted{}, err)
  54. case "INVALID":
  55. switch err.(type) {
  56. case light.ErrOldHeaderExpired:
  57. case light.ErrInvalidHeader:
  58. default:
  59. t.Fatalf("expected either ErrInvalidHeader or ErrOldHeaderExpired, but got %v", err)
  60. }
  61. default:
  62. t.Fatalf("unexpected verdict: %q", input.Verdict)
  63. }
  64. if err == nil { // advance
  65. trustedSignedHeader = *newSignedHeader
  66. trustedNextVals = *input.LightBlock.NextValidatorSet
  67. }
  68. }
  69. })
  70. }
  71. }
  72. // jsonFilenames returns a list of files in jsonDir directory
  73. func jsonFilenames(t *testing.T) []string {
  74. matches, err := filepath.Glob(filepath.Join(jsonDir, "*.json"))
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. return matches
  79. }
  80. type testCase struct {
  81. Description string `json:"description"`
  82. Initial initialData `json:"initial"`
  83. Input []inputData `json:"input"`
  84. }
  85. type initialData struct {
  86. SignedHeader types.SignedHeader `json:"signed_header"`
  87. NextValidatorSet types.ValidatorSet `json:"next_validator_set"`
  88. TrustingPeriod uint64 `json:"trusting_period"`
  89. Now time.Time `json:"now"`
  90. }
  91. type inputData struct {
  92. LightBlock lightBlockWithNextValidatorSet `json:"block"`
  93. Now time.Time `json:"now"`
  94. Verdict string `json:"verdict"`
  95. }
  96. // In tendermint-rs, NextValidatorSet is used to verify new blocks (opposite to
  97. // Go tendermint).
  98. type lightBlockWithNextValidatorSet struct {
  99. *types.SignedHeader `json:"signed_header"`
  100. ValidatorSet *types.ValidatorSet `json:"validator_set"`
  101. NextValidatorSet *types.ValidatorSet `json:"next_validator_set"`
  102. }