github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/merkle/proof_test.go (about)

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