in progress
This commit is contained in:
parent
7495528fb8
commit
b16ce7e0c2
|
@ -1,4 +1,4 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: merkle.proto
|
||||
|
||||
/*
|
||||
|
@ -11,10 +11,9 @@ It has these top-level messages:
|
|||
ProofOp
|
||||
Proof
|
||||
*/
|
||||
//nolint: gas
|
||||
package merkle
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import _ "github.com/gogo/protobuf/gogoproto"
|
||||
|
@ -28,18 +27,18 @@ var _ = math.Inf
|
|||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type ProofOp struct {
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
|
||||
Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ProofOp) Reset() { *m = ProofOp{} }
|
||||
func (m *ProofOp) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProofOp) ProtoMessage() {}
|
||||
func (*ProofOp) Descriptor() ([]byte, []int) { return fileDescriptorMerkle, []int{0} }
|
||||
func (*ProofOp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
func (m *ProofOp) GetType() string {
|
||||
if m != nil {
|
||||
|
@ -48,11 +47,11 @@ func (m *ProofOp) GetType() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *ProofOp) GetKey() string {
|
||||
func (m *ProofOp) GetKey() []byte {
|
||||
if m != nil {
|
||||
return m.Key
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProofOp) GetData() []byte {
|
||||
|
@ -63,15 +62,15 @@ func (m *ProofOp) GetData() []byte {
|
|||
}
|
||||
|
||||
type Proof struct {
|
||||
Ops []ProofOp `protobuf:"bytes,1,rep,name=ops" json:"ops"`
|
||||
Ops []*ProofOp `protobuf:"bytes,1,rep,name=ops" json:"ops,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Proof) Reset() { *m = Proof{} }
|
||||
func (m *Proof) String() string { return proto.CompactTextString(m) }
|
||||
func (*Proof) ProtoMessage() {}
|
||||
func (*Proof) Descriptor() ([]byte, []int) { return fileDescriptorMerkle, []int{1} }
|
||||
func (*Proof) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *Proof) GetOps() []ProofOp {
|
||||
func (m *Proof) GetOps() []*ProofOp {
|
||||
if m != nil {
|
||||
return m.Ops
|
||||
}
|
||||
|
@ -83,19 +82,19 @@ func init() {
|
|||
proto.RegisterType((*Proof)(nil), "merkle.Proof")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("merkle.proto", fileDescriptorMerkle) }
|
||||
func init() { proto.RegisterFile("merkle.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptorMerkle = []byte{
|
||||
var fileDescriptor0 = []byte{
|
||||
// 168 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x4d, 0x2d, 0xca,
|
||||
0xce, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0xa4, 0x74, 0xd3, 0x33,
|
||||
0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2,
|
||||
0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0x39, 0x73, 0xb1, 0x07, 0x14,
|
||||
0xe5, 0xe7, 0xa7, 0xf9, 0x17, 0x08, 0x09, 0x71, 0xb1, 0x94, 0x54, 0x16, 0xa4, 0x4a, 0x30, 0x2a,
|
||||
0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x12, 0x4c, 0x60,
|
||||
0x21, 0x10, 0x13, 0xa4, 0x2a, 0x25, 0xb1, 0x24, 0x51, 0x82, 0x59, 0x81, 0x51, 0x83, 0x27, 0x08,
|
||||
0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x12, 0x4c, 0x0a,
|
||||
0x8c, 0x1a, 0x3c, 0x41, 0x20, 0x26, 0x48, 0x55, 0x4a, 0x62, 0x49, 0xa2, 0x04, 0x33, 0x58, 0x08,
|
||||
0xcc, 0x56, 0x32, 0xe0, 0x62, 0x05, 0x1b, 0x22, 0xa4, 0xce, 0xc5, 0x9c, 0x5f, 0x50, 0x2c, 0xc1,
|
||||
0xa8, 0xc0, 0xac, 0xc1, 0x6d, 0xc4, 0xaf, 0x07, 0x75, 0x20, 0xd4, 0x02, 0x27, 0x96, 0x13, 0xf7,
|
||||
0xe4, 0x19, 0x82, 0x40, 0x2a, 0x92, 0xd8, 0xc0, 0xb6, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
|
||||
0x52, 0x58, 0x00, 0xa7, 0xc4, 0x00, 0x00, 0x00,
|
||||
0xe0, 0x7d, 0x7c, 0x4e, 0xc4, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
|||
|
||||
message ProofOp {
|
||||
string type = 1;
|
||||
string key = 2;
|
||||
bytes key = 2;
|
||||
bytes data = 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,27 +3,15 @@ package merkle
|
|||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/tendermint/go-amino"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
// Extension of ProofOp (defined in merkle.proto)
|
||||
|
||||
func (po ProofOp) Bytes() []byte {
|
||||
bz, err := amino.MarshalBinary(po)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return bz
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// ProofOp gets converted to an instance of ProofOperator:
|
||||
|
||||
type ProofOperator interface {
|
||||
Run([][]byte) ([][]byte, error)
|
||||
GetKey() string
|
||||
GetKey() []byte
|
||||
ProofOp() ProofOp
|
||||
}
|
||||
|
||||
|
@ -32,18 +20,20 @@ type ProofOperator interface {
|
|||
|
||||
type ProofOperators []ProofOperator
|
||||
|
||||
// XXX Reorder value/keys.
|
||||
// XXX Replace keys with keyString (the result of KeyPath.String())
|
||||
func (poz ProofOperators) VerifyValue(root []byte, value []byte, keys ...string) (err error) {
|
||||
return poz.Verify(root, [][]byte{value}, keys...)
|
||||
func (poz ProofOperators) VerifyValue(root []byte, keypath string, value []byte) (err error) {
|
||||
return poz.Verify(root, keypath, [][]byte{value})
|
||||
}
|
||||
|
||||
// XXX Replace keys with keyString (the result of KeyPath.String())
|
||||
func (poz ProofOperators) Verify(root []byte, args [][]byte, keys ...string) (err error) {
|
||||
func (poz ProofOperators) Verify(root []byte, keypath string, args [][]byte) (err error) {
|
||||
keys, err := KeyPathToKeys(keypath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i, op := range poz {
|
||||
key := op.GetKey()
|
||||
if key != "" {
|
||||
if keys[0] != key {
|
||||
if len(key) != 0 {
|
||||
if !bytes.Equal(keys[0], key) {
|
||||
return cmn.NewError("Key mismatch on operation #%d: expected %+v but %+v", i, []byte(keys[0]), []byte(key))
|
||||
}
|
||||
keys = keys[1:]
|
||||
|
@ -93,7 +83,7 @@ func (prt *ProofRuntime) Decode(pop ProofOp) (ProofOperator, error) {
|
|||
func (prt *ProofRuntime) DecodeProof(proof *Proof) (poz ProofOperators, err error) {
|
||||
poz = ProofOperators(nil)
|
||||
for _, pop := range proof.Ops {
|
||||
operator, err := prt.Decode(pop)
|
||||
operator, err := prt.Decode(*pop)
|
||||
if err != nil {
|
||||
return nil, cmn.ErrorWrap(err, "decoding a proof operator")
|
||||
}
|
||||
|
@ -104,26 +94,26 @@ func (prt *ProofRuntime) DecodeProof(proof *Proof) (poz ProofOperators, err erro
|
|||
|
||||
// XXX Reorder value/keys.
|
||||
// XXX Replace keys with keyString (the result of KeyPath.String()).
|
||||
func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, value []byte, keys ...string) (err error) {
|
||||
return prt.Verify(proof, root, [][]byte{value}, keys...)
|
||||
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, root []byte, keys ...string) (err error) {
|
||||
return prt.Verify(proof, root, nil, keys...)
|
||||
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, args [][]byte, keys ...string) (err error) {
|
||||
func (prt *ProofRuntime) Verify(proof *Proof, root []byte, keypath string, args [][]byte) (err error) {
|
||||
poz, err := prt.DecodeProof(proof)
|
||||
if err != nil {
|
||||
return cmn.ErrorWrap(err, "decoding proof")
|
||||
}
|
||||
return poz.Verify(root, args, keys...)
|
||||
return poz.Verify(root, keypath, args)
|
||||
}
|
||||
|
||||
// DefaultProofRuntime only knows about Simple value
|
||||
|
|
|
@ -52,27 +52,28 @@ type keyEncoding int
|
|||
const (
|
||||
KeyEncodingURL keyEncoding = iota
|
||||
KeyEncodingHex
|
||||
KeyEncodingMax
|
||||
)
|
||||
|
||||
type KeyPath struct {
|
||||
keys [][]byte
|
||||
encs []keyEncoding
|
||||
type Key struct {
|
||||
name []byte
|
||||
enc keyEncoding
|
||||
}
|
||||
|
||||
func (pth *KeyPath) AppendKey(key []byte, enc keyEncoding) {
|
||||
pth.keys = append(pth.keys, key)
|
||||
pth.encs = append(pth.encs, enc)
|
||||
type KeyPath []Key
|
||||
|
||||
func (pth KeyPath) AppendKey(key []byte, enc keyEncoding) KeyPath {
|
||||
return append(pth, Key{key, enc})
|
||||
}
|
||||
|
||||
func (pth *KeyPath) String() string {
|
||||
func (pth KeyPath) String() string {
|
||||
res := ""
|
||||
for i := 0; i < len(pth.keys); i++ {
|
||||
key, enc := pth.keys[i], pth.encs[i]
|
||||
switch enc {
|
||||
for _, key := range pth {
|
||||
switch key.enc {
|
||||
case KeyEncodingURL:
|
||||
res += "/" + url.PathEscape(string(key))
|
||||
res += "/" + url.PathEscape(string(key.name))
|
||||
case KeyEncodingHex:
|
||||
res += "/x:" + fmt.Sprintf("%X", key)
|
||||
res += "/x:" + fmt.Sprintf("%X", key.name)
|
||||
default:
|
||||
panic("unexpected key encoding type")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package merkle
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestKeyPath(t *testing.T) {
|
||||
var path KeyPath
|
||||
keys := make([][]byte, 10)
|
||||
|
||||
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)))
|
||||
path = path.AppendKey(keys[i], enc)
|
||||
}
|
||||
|
||||
res, err := KeyPathToKeys(path.String())
|
||||
require.Nil(t, err)
|
||||
|
||||
for i, key := range keys {
|
||||
require.Equal(t, key, res[i])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ const ProofOpSimpleValue = "simple:v"
|
|||
// proof is good.
|
||||
type SimpleValueOp struct {
|
||||
// Encoded in ProofOp.Key.
|
||||
key string
|
||||
key []byte
|
||||
|
||||
// To encode in ProofOp.Data
|
||||
Proof *SimpleProof `json:"simple-proof"`
|
||||
|
@ -30,7 +30,7 @@ type SimpleValueOp struct {
|
|||
|
||||
var _ ProofOperator = SimpleValueOp{}
|
||||
|
||||
func NewSimpleValueOp(key string, proof *SimpleProof) SimpleValueOp {
|
||||
func NewSimpleValueOp(key []byte, proof *SimpleProof) SimpleValueOp {
|
||||
return SimpleValueOp{
|
||||
key: key,
|
||||
Proof: proof,
|
||||
|
@ -86,6 +86,6 @@ func (op SimpleValueOp) Run(args [][]byte) ([][]byte, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (op SimpleValueOp) GetKey() string {
|
||||
func (op SimpleValueOp) GetKey() []byte {
|
||||
return op.key
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue