diff --git a/crypto/merkle/proof.go b/crypto/merkle/proof.go index 358e8518e..b4f68417a 100644 --- a/crypto/merkle/proof.go +++ b/crypto/merkle/proof.go @@ -46,6 +46,9 @@ func (poz ProofOperators) Verify(root []byte, keypath string, args [][]byte) (er if !bytes.Equal(root, args[0]) { return cmn.NewError("Calculated root hash is invalid: expected %+v but %+v", root, args[0]) } + if len(keys) != 0 { + return cmn.NewError("Keypath not consumed all") + } return nil } @@ -92,22 +95,16 @@ func (prt *ProofRuntime) DecodeProof(proof *Proof) (poz ProofOperators, err erro return } -// XXX Reorder value/keys. -// XXX Replace keys with keyString (the result of KeyPath.String()). func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, keypath string, value []byte) (err error) { return prt.Verify(proof, root, keypath, [][]byte{value}) } -// XXX Reorder value/keys. -// XXX Replace keys with keyString (the result of KeyPath.String()). // TODO In the long run we'll need a method of classifcation of ops, // whether existence or absence or perhaps a third? func (prt *ProofRuntime) VerifyAbsence(proof *Proof, keypath string, root []byte) (err error) { return prt.Verify(proof, root, keypath, nil) } -// XXX Reorder value/keys. -// XXX Replace keys with keyString (the result of KeyPath.String()). func (prt *ProofRuntime) Verify(proof *Proof, root []byte, keypath string, args [][]byte) (err error) { poz, err := prt.DecodeProof(proof) if err != nil { diff --git a/crypto/merkle/proof_key_path_test.go b/crypto/merkle/proof_key_path_test.go index b185d5e36..48fda3032 100644 --- a/crypto/merkle/proof_key_path_test.go +++ b/crypto/merkle/proof_key_path_test.go @@ -10,12 +10,24 @@ import ( func TestKeyPath(t *testing.T) { var path KeyPath keys := make([][]byte, 10) + alphanum := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + for d := 0; d < 1e4; d++ { + path = nil - for d := 0; d < 20; d++ { for i := range keys { - keys[i] = make([]byte, rand.Uint32()%20) - rand.Read(keys[i]) enc := keyEncoding(rand.Intn(int(KeyEncodingMax))) + keys[i] = make([]byte, rand.Uint32()%20) + switch enc { + case KeyEncodingURL: + for j := range keys[i] { + keys[i][j] = alphanum[rand.Intn(len(alphanum))] + } + case KeyEncodingHex: + rand.Read(keys[i]) + default: + panic("Unexpected encoding") + } path = path.AppendKey(keys[i], enc) }