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.

141 lines
3.7 KiB

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