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.

142 lines
3.6 KiB

  1. package merkle
  2. import (
  3. "errors"
  4. "fmt"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. amino "github.com/tendermint/go-amino"
  8. )
  9. const ProofOpDomino = "test:domino"
  10. // Expects given input, produces given output.
  11. // Like the game dominos.
  12. type DominoOp struct {
  13. key string // unexported, may be empty
  14. Input string
  15. Output string
  16. }
  17. func NewDominoOp(key, input, output string) DominoOp {
  18. return DominoOp{
  19. key: key,
  20. Input: input,
  21. Output: output,
  22. }
  23. }
  24. //nolint:unused
  25. func DominoOpDecoder(pop ProofOp) (ProofOperator, error) {
  26. if pop.Type != ProofOpDomino {
  27. panic("unexpected proof op type")
  28. }
  29. var op DominoOp // a bit strange as we'll discard this, but it works.
  30. err := amino.UnmarshalBinaryLengthPrefixed(pop.Data, &op)
  31. if err != nil {
  32. return nil, fmt.Errorf("decoding ProofOp.Data into SimpleValueOp: %w", err)
  33. }
  34. return NewDominoOp(string(pop.Key), op.Input, op.Output), nil
  35. }
  36. func (dop DominoOp) ProofOp() ProofOp {
  37. bz := amino.MustMarshalBinaryLengthPrefixed(dop)
  38. return ProofOp{
  39. Type: ProofOpDomino,
  40. Key: []byte(dop.key),
  41. Data: bz,
  42. }
  43. }
  44. func (dop DominoOp) Run(input [][]byte) (output [][]byte, err error) {
  45. if len(input) != 1 {
  46. return nil, errors.New("expected input of length 1")
  47. }
  48. if string(input[0]) != dop.Input {
  49. return nil, fmt.Errorf("expected input %v, got %v",
  50. dop.Input, string(input[0]))
  51. }
  52. return [][]byte{[]byte(dop.Output)}, nil
  53. }
  54. func (dop DominoOp) GetKey() []byte {
  55. return []byte(dop.key)
  56. }
  57. //----------------------------------------
  58. func TestProofOperators(t *testing.T) {
  59. var err error
  60. // ProofRuntime setup
  61. // TODO test this somehow.
  62. // prt := NewProofRuntime()
  63. // prt.RegisterOpDecoder(ProofOpDomino, DominoOpDecoder)
  64. // ProofOperators setup
  65. op1 := NewDominoOp("KEY1", "INPUT1", "INPUT2")
  66. op2 := NewDominoOp("KEY2", "INPUT2", "INPUT3")
  67. op3 := NewDominoOp("", "INPUT3", "INPUT4")
  68. op4 := NewDominoOp("KEY4", "INPUT4", "OUTPUT4")
  69. // Good
  70. popz := ProofOperators([]ProofOperator{op1, op2, op3, op4})
  71. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  72. assert.Nil(t, err)
  73. err = popz.VerifyValue(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", bz("INPUT1"))
  74. assert.Nil(t, err)
  75. // BAD INPUT
  76. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1_WRONG")})
  77. assert.NotNil(t, err)
  78. err = popz.VerifyValue(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", bz("INPUT1_WRONG"))
  79. assert.NotNil(t, err)
  80. // BAD KEY 1
  81. err = popz.Verify(bz("OUTPUT4"), "/KEY3/KEY2/KEY1", [][]byte{bz("INPUT1")})
  82. assert.NotNil(t, err)
  83. // BAD KEY 2
  84. err = popz.Verify(bz("OUTPUT4"), "KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  85. assert.NotNil(t, err)
  86. // BAD KEY 3
  87. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1/", [][]byte{bz("INPUT1")})
  88. assert.NotNil(t, err)
  89. // BAD KEY 4
  90. err = popz.Verify(bz("OUTPUT4"), "//KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  91. assert.NotNil(t, err)
  92. // BAD KEY 5
  93. err = popz.Verify(bz("OUTPUT4"), "/KEY2/KEY1", [][]byte{bz("INPUT1")})
  94. assert.NotNil(t, err)
  95. // BAD OUTPUT 1
  96. err = popz.Verify(bz("OUTPUT4_WRONG"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  97. assert.NotNil(t, err)
  98. // BAD OUTPUT 2
  99. err = popz.Verify(bz(""), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  100. assert.NotNil(t, err)
  101. // BAD POPZ 1
  102. popz = []ProofOperator{op1, op2, op4}
  103. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  104. assert.NotNil(t, err)
  105. // BAD POPZ 2
  106. popz = []ProofOperator{op4, op3, op2, op1}
  107. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  108. assert.NotNil(t, err)
  109. // BAD POPZ 3
  110. popz = []ProofOperator{}
  111. err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
  112. assert.NotNil(t, err)
  113. }
  114. func bz(s string) []byte {
  115. return []byte(s)
  116. }