github.com/devwanda/aphelion-staking@v0.33.9/crypto/merkle/proof_test.go (about)

     1  package merkle
     2  
     3  import (
     4  	"testing"
     5  
     6  	amino "github.com/evdatsion/go-amino"
     7  	"github.com/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  //nolint:unused
    30  func DominoOpDecoder(pop ProofOp) (ProofOperator, error) {
    31  	if pop.Type != ProofOpDomino {
    32  		panic("unexpected proof op type")
    33  	}
    34  	var op DominoOp // a bit strange as we'll discard this, but it works.
    35  	err := amino.UnmarshalBinaryLengthPrefixed(pop.Data, &op)
    36  	if err != nil {
    37  		return nil, errors.Wrap(err, "decoding ProofOp.Data into SimpleValueOp")
    38  	}
    39  	return NewDominoOp(string(pop.Key), op.Input, op.Output), nil
    40  }
    41  
    42  func (dop DominoOp) ProofOp() ProofOp {
    43  	bz := amino.MustMarshalBinaryLengthPrefixed(dop)
    44  	return ProofOp{
    45  		Type: ProofOpDomino,
    46  		Key:  []byte(dop.key),
    47  		Data: bz,
    48  	}
    49  }
    50  
    51  func (dop DominoOp) Run(input [][]byte) (output [][]byte, err error) {
    52  	if len(input) != 1 {
    53  		return nil, errors.New("expected input of length 1")
    54  	}
    55  	if string(input[0]) != dop.Input {
    56  		return nil, errors.Errorf("expected input %v, got %v",
    57  			dop.Input, string(input[0]))
    58  	}
    59  	return [][]byte{[]byte(dop.Output)}, nil
    60  }
    61  
    62  func (dop DominoOp) GetKey() []byte {
    63  	return []byte(dop.key)
    64  }
    65  
    66  //----------------------------------------
    67  
    68  func TestProofOperators(t *testing.T) {
    69  	var err error
    70  
    71  	// ProofRuntime setup
    72  	// TODO test this somehow.
    73  	// prt := NewProofRuntime()
    74  	// prt.RegisterOpDecoder(ProofOpDomino, DominoOpDecoder)
    75  
    76  	// ProofOperators setup
    77  	op1 := NewDominoOp("KEY1", "INPUT1", "INPUT2")
    78  	op2 := NewDominoOp("KEY2", "INPUT2", "INPUT3")
    79  	op3 := NewDominoOp("", "INPUT3", "INPUT4")
    80  	op4 := NewDominoOp("KEY4", "INPUT4", "OUTPUT4")
    81  
    82  	// Good
    83  	popz := ProofOperators([]ProofOperator{op1, op2, op3, op4})
    84  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
    85  	assert.Nil(t, err)
    86  	err = popz.VerifyValue(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", bz("INPUT1"))
    87  	assert.Nil(t, err)
    88  
    89  	// BAD INPUT
    90  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1_WRONG")})
    91  	assert.NotNil(t, err)
    92  	err = popz.VerifyValue(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", bz("INPUT1_WRONG"))
    93  	assert.NotNil(t, err)
    94  
    95  	// BAD KEY 1
    96  	err = popz.Verify(bz("OUTPUT4"), "/KEY3/KEY2/KEY1", [][]byte{bz("INPUT1")})
    97  	assert.NotNil(t, err)
    98  
    99  	// BAD KEY 2
   100  	err = popz.Verify(bz("OUTPUT4"), "KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   101  	assert.NotNil(t, err)
   102  
   103  	// BAD KEY 3
   104  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1/", [][]byte{bz("INPUT1")})
   105  	assert.NotNil(t, err)
   106  
   107  	// BAD KEY 4
   108  	err = popz.Verify(bz("OUTPUT4"), "//KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   109  	assert.NotNil(t, err)
   110  
   111  	// BAD KEY 5
   112  	err = popz.Verify(bz("OUTPUT4"), "/KEY2/KEY1", [][]byte{bz("INPUT1")})
   113  	assert.NotNil(t, err)
   114  
   115  	// BAD OUTPUT 1
   116  	err = popz.Verify(bz("OUTPUT4_WRONG"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   117  	assert.NotNil(t, err)
   118  
   119  	// BAD OUTPUT 2
   120  	err = popz.Verify(bz(""), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   121  	assert.NotNil(t, err)
   122  
   123  	// BAD POPZ 1
   124  	popz = []ProofOperator{op1, op2, op4}
   125  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   126  	assert.NotNil(t, err)
   127  
   128  	// BAD POPZ 2
   129  	popz = []ProofOperator{op4, op3, op2, op1}
   130  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   131  	assert.NotNil(t, err)
   132  
   133  	// BAD POPZ 3
   134  	popz = []ProofOperator{}
   135  	err = popz.Verify(bz("OUTPUT4"), "/KEY4/KEY2/KEY1", [][]byte{bz("INPUT1")})
   136  	assert.NotNil(t, err)
   137  }
   138  
   139  func bz(s string) []byte {
   140  	return []byte(s)
   141  }