ibc: proof fixes (#7869)
* change proof proto def * progress fixing tests * complete proof restructure * remove use of KeyPath * improve error msgs * docs and lint * Apply suggestions from code review Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * address code review * fix string tests * add ConvertProofs tests * Apply suggestions from code review Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com>
This commit is contained in:
parent
15b285dd0d
commit
fdcb028636
|
@ -4,7 +4,7 @@ package ibc.core.commitment.v1;
|
|||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "tendermint/crypto/proof.proto";
|
||||
import "confio/proofs.proto";
|
||||
|
||||
// MerkleRoot defines a merkle root hash.
|
||||
// In the Cosmos SDK, the AppHash of a block header becomes the root.
|
||||
|
@ -23,42 +23,18 @@ message MerklePrefix {
|
|||
|
||||
// MerklePath is the path used to verify commitment proofs, which can be an
|
||||
// arbitrary structured object (defined by a commitment type).
|
||||
// MerklePath is represented from root-to-leaf
|
||||
message MerklePath {
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
|
||||
KeyPath key_path = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"key_path\""];
|
||||
repeated string key_path = 1 [(gogoproto.moretags) = "yaml:\"key_path\""];
|
||||
}
|
||||
|
||||
// MerkleProof is a wrapper type that contains a merkle proof.
|
||||
// MerkleProof is a wrapper type over a chain of CommitmentProofs.
|
||||
// It demonstrates membership or non-membership for an element or set of
|
||||
// elements, verifiable in conjunction with a known commitment root. Proofs
|
||||
// should be succinct.
|
||||
// MerkleProofs are ordered from leaf-to-root
|
||||
message MerkleProof {
|
||||
tendermint.crypto.ProofOps proof = 1;
|
||||
}
|
||||
|
||||
// KeyPath defines a slice of keys
|
||||
message KeyPath {
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
repeated Key keys = 1;
|
||||
}
|
||||
|
||||
// Key defines a proof Key
|
||||
message Key {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
bytes name = 1;
|
||||
KeyEncoding enc = 2;
|
||||
}
|
||||
|
||||
// KeyEncoding defines the encoding format of a key's bytes.
|
||||
enum KeyEncoding {
|
||||
option (gogoproto.goproto_enum_prefix) = false;
|
||||
|
||||
// URL encoding
|
||||
KEY_ENCODING_URL_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "URL"];
|
||||
// Hex encoding
|
||||
KEY_ENCODING_HEX = 1 [(gogoproto.enumvalue_customname) = "HEX"];
|
||||
}
|
||||
repeated ics23.CommitmentProof proofs = 1;
|
||||
}
|
|
@ -62,9 +62,10 @@ func (suite *MsgTestSuite) SetupTest() {
|
|||
Prove: true,
|
||||
})
|
||||
|
||||
merkleProof := commitmenttypes.MerkleProof{Proof: res.ProofOps}
|
||||
merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
|
||||
suite.Require().NoError(err)
|
||||
proof, err := app.AppCodec().MarshalBinaryBare(&merkleProof)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.proof = proof
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ func (suite *KeeperTestSuite) SetupTest() {
|
|||
suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2)
|
||||
suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(0))
|
||||
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
|
||||
// commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1)
|
||||
suite.coordinator.CommitNBlocks(suite.chainA, 2)
|
||||
suite.coordinator.CommitNBlocks(suite.chainB, 2)
|
||||
}
|
||||
|
||||
// TestSetChannel create clients and connections on both chains. It tests for the non-existence
|
||||
|
|
|
@ -93,9 +93,10 @@ func (suite *TypesTestSuite) SetupTest() {
|
|||
Prove: true,
|
||||
})
|
||||
|
||||
merkleProof := commitmenttypes.MerkleProof{Proof: res.ProofOps}
|
||||
merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
|
||||
suite.Require().NoError(err)
|
||||
proof, err := app.AppCodec().MarshalBinaryBare(&merkleProof)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.proof = proof
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ package types
|
|||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_go "github.com/confio/ics23/go"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
crypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
|
@ -24,34 +24,6 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// KeyEncoding defines the encoding format of a key's bytes.
|
||||
type KeyEncoding int32
|
||||
|
||||
const (
|
||||
// URL encoding
|
||||
URL KeyEncoding = 0
|
||||
// Hex encoding
|
||||
HEX KeyEncoding = 1
|
||||
)
|
||||
|
||||
var KeyEncoding_name = map[int32]string{
|
||||
0: "KEY_ENCODING_URL_UNSPECIFIED",
|
||||
1: "KEY_ENCODING_HEX",
|
||||
}
|
||||
|
||||
var KeyEncoding_value = map[string]int32{
|
||||
"KEY_ENCODING_URL_UNSPECIFIED": 0,
|
||||
"KEY_ENCODING_HEX": 1,
|
||||
}
|
||||
|
||||
func (x KeyEncoding) String() string {
|
||||
return proto.EnumName(KeyEncoding_name, int32(x))
|
||||
}
|
||||
|
||||
func (KeyEncoding) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7921d88972a41469, []int{0}
|
||||
}
|
||||
|
||||
// MerkleRoot defines a merkle root hash.
|
||||
// In the Cosmos SDK, the AppHash of a block header becomes the root.
|
||||
type MerkleRoot struct {
|
||||
|
@ -141,7 +113,7 @@ func (m *MerklePrefix) GetKeyPrefix() []byte {
|
|||
// MerklePath is the path used to verify commitment proofs, which can be an
|
||||
// arbitrary structured object (defined by a commitment type).
|
||||
type MerklePath struct {
|
||||
KeyPath KeyPath `protobuf:"bytes,1,opt,name=key_path,json=keyPath,proto3" json:"key_path" yaml:"key_path"`
|
||||
KeyPath []string `protobuf:"bytes,1,rep,name=key_path,json=keyPath,proto3" json:"key_path,omitempty" yaml:"key_path"`
|
||||
}
|
||||
|
||||
func (m *MerklePath) Reset() { *m = MerklePath{} }
|
||||
|
@ -176,19 +148,19 @@ func (m *MerklePath) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_MerklePath proto.InternalMessageInfo
|
||||
|
||||
func (m *MerklePath) GetKeyPath() KeyPath {
|
||||
func (m *MerklePath) GetKeyPath() []string {
|
||||
if m != nil {
|
||||
return m.KeyPath
|
||||
}
|
||||
return KeyPath{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MerkleProof is a wrapper type that contains a merkle proof.
|
||||
// MerkleProof is a wrapper type over a chain of CommitmentProofs.
|
||||
// It demonstrates membership or non-membership for an element or set of
|
||||
// elements, verifiable in conjunction with a known commitment root. Proofs
|
||||
// should be succinct.
|
||||
type MerkleProof struct {
|
||||
Proof *crypto.ProofOps `protobuf:"bytes,1,opt,name=proof,proto3" json:"proof,omitempty"`
|
||||
Proofs []*_go.CommitmentProof `protobuf:"bytes,1,rep,name=proofs,proto3" json:"proofs,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MerkleProof) Reset() { *m = MerkleProof{} }
|
||||
|
@ -224,97 +196,18 @@ func (m *MerkleProof) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_MerkleProof proto.InternalMessageInfo
|
||||
|
||||
func (m *MerkleProof) GetProof() *crypto.ProofOps {
|
||||
func (m *MerkleProof) GetProofs() []*_go.CommitmentProof {
|
||||
if m != nil {
|
||||
return m.Proof
|
||||
return m.Proofs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeyPath defines a slice of keys
|
||||
type KeyPath struct {
|
||||
Keys []*Key `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"`
|
||||
}
|
||||
|
||||
func (m *KeyPath) Reset() { *m = KeyPath{} }
|
||||
func (*KeyPath) ProtoMessage() {}
|
||||
func (*KeyPath) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7921d88972a41469, []int{4}
|
||||
}
|
||||
func (m *KeyPath) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *KeyPath) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_KeyPath.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *KeyPath) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_KeyPath.Merge(m, src)
|
||||
}
|
||||
func (m *KeyPath) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *KeyPath) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_KeyPath.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_KeyPath proto.InternalMessageInfo
|
||||
|
||||
// Key defines a proof Key
|
||||
type Key struct {
|
||||
Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Enc KeyEncoding `protobuf:"varint,2,opt,name=enc,proto3,enum=ibc.core.commitment.v1.KeyEncoding" json:"enc,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Key) Reset() { *m = Key{} }
|
||||
func (m *Key) String() string { return proto.CompactTextString(m) }
|
||||
func (*Key) ProtoMessage() {}
|
||||
func (*Key) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7921d88972a41469, []int{5}
|
||||
}
|
||||
func (m *Key) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_Key.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *Key) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Key.Merge(m, src)
|
||||
}
|
||||
func (m *Key) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *Key) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Key.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Key proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("ibc.core.commitment.v1.KeyEncoding", KeyEncoding_name, KeyEncoding_value)
|
||||
proto.RegisterType((*MerkleRoot)(nil), "ibc.core.commitment.v1.MerkleRoot")
|
||||
proto.RegisterType((*MerklePrefix)(nil), "ibc.core.commitment.v1.MerklePrefix")
|
||||
proto.RegisterType((*MerklePath)(nil), "ibc.core.commitment.v1.MerklePath")
|
||||
proto.RegisterType((*MerkleProof)(nil), "ibc.core.commitment.v1.MerkleProof")
|
||||
proto.RegisterType((*KeyPath)(nil), "ibc.core.commitment.v1.KeyPath")
|
||||
proto.RegisterType((*Key)(nil), "ibc.core.commitment.v1.Key")
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -322,39 +215,28 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_7921d88972a41469 = []byte{
|
||||
// 499 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x4f, 0x6f, 0xd3, 0x30,
|
||||
0x18, 0xc6, 0x13, 0x5a, 0xe8, 0x70, 0x27, 0x28, 0x16, 0x7f, 0xaa, 0xc2, 0x92, 0x2a, 0x48, 0x30,
|
||||
0x90, 0x16, 0xab, 0x1d, 0x5c, 0xca, 0x05, 0x75, 0x0d, 0xac, 0xea, 0xe8, 0x2a, 0x4f, 0x45, 0x03,
|
||||
0x09, 0x55, 0x69, 0xea, 0x26, 0x51, 0x96, 0x38, 0x4a, 0xcc, 0xb4, 0x7c, 0x83, 0x89, 0x13, 0x47,
|
||||
0x2e, 0x48, 0x48, 0x7c, 0x99, 0x1d, 0x77, 0xe4, 0x54, 0xa1, 0xf6, 0x1b, 0xec, 0x13, 0x20, 0xdb,
|
||||
0x2d, 0x0b, 0x12, 0x70, 0xca, 0x6b, 0xbd, 0xbf, 0x37, 0xcf, 0xe3, 0xc7, 0x2f, 0x78, 0xec, 0x8f,
|
||||
0x1d, 0xe4, 0xd0, 0x84, 0x20, 0x87, 0x86, 0xa1, 0xcf, 0x42, 0x12, 0x31, 0x74, 0xdc, 0xc8, 0x9d,
|
||||
0xcc, 0x38, 0xa1, 0x8c, 0xc2, 0xbb, 0xfe, 0xd8, 0x31, 0x39, 0x68, 0xe6, 0x5a, 0xc7, 0x8d, 0xda,
|
||||
0x6d, 0x97, 0xba, 0x54, 0x20, 0x88, 0x57, 0x92, 0xae, 0x6d, 0x30, 0x12, 0x4d, 0x48, 0x12, 0xfa,
|
||||
0x11, 0x43, 0x4e, 0x92, 0xc5, 0x8c, 0xa2, 0x38, 0xa1, 0x74, 0x2a, 0xdb, 0xc6, 0x23, 0x00, 0xde,
|
||||
0x90, 0x24, 0x38, 0x22, 0x98, 0x52, 0x06, 0x21, 0x28, 0x7a, 0x76, 0xea, 0x55, 0xd5, 0xba, 0xba,
|
||||
0xb9, 0x8e, 0x45, 0xdd, 0x2a, 0x9e, 0x7e, 0xd3, 0x15, 0xa3, 0x03, 0xd6, 0x25, 0x37, 0x48, 0xc8,
|
||||
0xd4, 0x3f, 0x81, 0xcf, 0x00, 0x08, 0x48, 0x36, 0x8a, 0xc5, 0x49, 0xf2, 0xed, 0x3b, 0x17, 0x33,
|
||||
0xfd, 0x56, 0x66, 0x87, 0x47, 0x2d, 0xe3, 0xb2, 0x67, 0xe0, 0xeb, 0x01, 0xc9, 0xe4, 0x94, 0xe1,
|
||||
0xae, 0xd4, 0x06, 0x36, 0xf3, 0xe0, 0x01, 0x58, 0x13, 0x9c, 0xcd, 0xa4, 0x62, 0xb9, 0xa9, 0x9b,
|
||||
0x7f, 0xbf, 0x9b, 0xd9, 0x23, 0x19, 0x1f, 0x69, 0xdf, 0x3b, 0x9b, 0xe9, 0xca, 0xc5, 0x4c, 0xbf,
|
||||
0x99, 0x93, 0xb1, 0x99, 0x67, 0xe0, 0x52, 0x20, 0x89, 0x56, 0xf1, 0x0b, 0xb7, 0xfb, 0x12, 0x94,
|
||||
0x57, 0x76, 0x29, 0x9d, 0xc2, 0x06, 0xb8, 0x2a, 0x2e, 0xbd, 0x94, 0xb9, 0x6f, 0x5e, 0x86, 0x62,
|
||||
0xca, 0x50, 0x4c, 0x01, 0xee, 0xc7, 0x29, 0x96, 0xa4, 0xd1, 0x01, 0xa5, 0xa5, 0x28, 0x44, 0xa0,
|
||||
0x18, 0x90, 0x2c, 0xad, 0xaa, 0xf5, 0x82, 0x18, 0xfe, 0xb7, 0x47, 0x2c, 0xc0, 0xd6, 0x1a, 0x8f,
|
||||
0x4c, 0xf8, 0x78, 0x0b, 0x0a, 0x3d, 0x92, 0xf1, 0x5c, 0x23, 0x3b, 0x24, 0xab, 0x5c, 0x79, 0x0d,
|
||||
0x9f, 0x83, 0x02, 0x89, 0x9c, 0xea, 0x95, 0xba, 0xba, 0x79, 0xa3, 0xf9, 0xf0, 0x3f, 0x3f, 0xb5,
|
||||
0x22, 0x87, 0x4e, 0xfc, 0xc8, 0xc5, 0x9c, 0x97, 0xcf, 0xf1, 0xf4, 0x03, 0x28, 0xe7, 0x3a, 0xf0,
|
||||
0x09, 0x78, 0xd0, 0xb3, 0xde, 0x8d, 0xac, 0xfe, 0xce, 0x7e, 0xa7, 0xdb, 0x7f, 0x3d, 0x1a, 0xe2,
|
||||
0xbd, 0xd1, 0xb0, 0x7f, 0x30, 0xb0, 0x76, 0xba, 0xaf, 0xba, 0x56, 0xa7, 0xa2, 0xd4, 0x4a, 0x9f,
|
||||
0xbe, 0xd6, 0x0b, 0x43, 0xbc, 0x07, 0x37, 0x40, 0xe5, 0x0f, 0x74, 0xd7, 0x3a, 0xac, 0xa8, 0xb2,
|
||||
0xbd, 0x6b, 0x1d, 0xd6, 0x8a, 0xa7, 0xdf, 0x35, 0xa5, 0x3d, 0x3c, 0x9b, 0x6b, 0xea, 0xf9, 0x5c,
|
||||
0x53, 0x7f, 0xce, 0x35, 0xf5, 0xf3, 0x42, 0x53, 0xce, 0x17, 0x9a, 0xf2, 0x63, 0xa1, 0x29, 0xef,
|
||||
0x5f, 0xb8, 0x3e, 0xf3, 0x3e, 0x8e, 0xb9, 0x4b, 0xe4, 0xd0, 0x34, 0xa4, 0xe9, 0xf2, 0xb3, 0x95,
|
||||
0x4e, 0x02, 0x74, 0x82, 0x7e, 0x2f, 0x71, 0x73, 0x7b, 0x2b, 0xb7, 0xc7, 0x2c, 0x8b, 0x49, 0x3a,
|
||||
0xbe, 0x26, 0x76, 0x6e, 0xfb, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x78, 0x4b, 0x97, 0xeb,
|
||||
0x02, 0x00, 0x00,
|
||||
// 334 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xcf, 0x4e, 0xfa, 0x40,
|
||||
0x10, 0xc7, 0xdb, 0xfc, 0x08, 0x3f, 0x59, 0x48, 0x8c, 0x45, 0x89, 0xe1, 0x50, 0x4c, 0x0f, 0xca,
|
||||
0x85, 0xdd, 0x00, 0x9e, 0x30, 0x5e, 0xaa, 0x57, 0x13, 0xd2, 0xc4, 0x8b, 0x17, 0xd3, 0xae, 0x5b,
|
||||
0xba, 0x29, 0x65, 0x9a, 0xee, 0x4a, 0xe8, 0x1b, 0x78, 0xf4, 0xe8, 0xd1, 0xc7, 0xf1, 0xc8, 0xd1,
|
||||
0x13, 0x31, 0xf0, 0x06, 0x3c, 0x81, 0xe9, 0x2e, 0x60, 0x4f, 0x3b, 0xb3, 0xf3, 0x99, 0x7f, 0xdf,
|
||||
0x41, 0x57, 0x3c, 0xa0, 0x84, 0x42, 0xc6, 0x08, 0x85, 0x24, 0xe1, 0x32, 0x61, 0x33, 0x49, 0xe6,
|
||||
0xfd, 0x92, 0x87, 0xd3, 0x0c, 0x24, 0x58, 0x2d, 0x1e, 0x50, 0x5c, 0x80, 0xb8, 0x14, 0x9a, 0xf7,
|
||||
0xdb, 0xa7, 0x13, 0x98, 0x80, 0x42, 0x48, 0x61, 0x69, 0xba, 0xdd, 0xa4, 0x30, 0x0b, 0x39, 0x90,
|
||||
0x34, 0x03, 0x08, 0x85, 0xfe, 0x74, 0x2e, 0x11, 0x7a, 0x60, 0x59, 0x3c, 0x65, 0x1e, 0x80, 0xb4,
|
||||
0x2c, 0x54, 0x89, 0x7c, 0x11, 0x9d, 0x9b, 0x17, 0x66, 0xb7, 0xe1, 0x29, 0x7b, 0x54, 0x79, 0xfb,
|
||||
0xec, 0x18, 0xce, 0x3d, 0x6a, 0x68, 0x6e, 0x9c, 0xb1, 0x90, 0x2f, 0xac, 0x6b, 0x84, 0x62, 0x96,
|
||||
0x3f, 0xa7, 0xca, 0xd3, 0xbc, 0x7b, 0xb6, 0x5d, 0x75, 0x4e, 0x72, 0x3f, 0x99, 0x8e, 0x9c, 0xbf,
|
||||
0x98, 0xe3, 0xd5, 0x62, 0x96, 0xeb, 0x2c, 0xc7, 0xdd, 0x77, 0x1b, 0xfb, 0x32, 0xb2, 0x30, 0x3a,
|
||||
0x52, 0x9c, 0x2f, 0x8b, 0x8e, 0xff, 0xba, 0x35, 0xb7, 0xb9, 0x5d, 0x75, 0x8e, 0x4b, 0x15, 0x7c,
|
||||
0x19, 0x39, 0xde, 0xff, 0x22, 0xdf, 0x97, 0xd1, 0xa8, 0xf2, 0x51, 0x4c, 0x72, 0x8b, 0xea, 0xfb,
|
||||
0x49, 0x00, 0x42, 0x0b, 0xa3, 0xaa, 0x5e, 0x48, 0x95, 0xa8, 0x0f, 0x5a, 0x98, 0x53, 0x31, 0x18,
|
||||
0xe2, 0xbb, 0x83, 0x22, 0x8a, 0xf3, 0x76, 0x94, 0xfb, 0xf8, 0xb5, 0xb6, 0xcd, 0xe5, 0xda, 0x36,
|
||||
0x7f, 0xd6, 0xb6, 0xf9, 0xbe, 0xb1, 0x8d, 0xe5, 0xc6, 0x36, 0xbe, 0x37, 0xb6, 0xf1, 0x74, 0x33,
|
||||
0xe1, 0x32, 0x7a, 0x0d, 0x0a, 0x2d, 0x09, 0x05, 0x91, 0x80, 0xd8, 0x3d, 0x3d, 0xf1, 0x12, 0x93,
|
||||
0x05, 0x39, 0x5c, 0x65, 0x30, 0xec, 0x95, 0x0e, 0x23, 0xf3, 0x94, 0x89, 0xa0, 0xaa, 0xe4, 0x1c,
|
||||
0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xe7, 0x68, 0xd0, 0xbc, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *MerkleRoot) Marshal() (dAtA []byte, err error) {
|
||||
|
@ -437,16 +319,15 @@ func (m *MerklePath) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
{
|
||||
size, err := m.KeyPath.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
if len(m.KeyPath) > 0 {
|
||||
for iNdEx := len(m.KeyPath) - 1; iNdEx >= 0; iNdEx-- {
|
||||
i -= len(m.KeyPath[iNdEx])
|
||||
copy(dAtA[i:], m.KeyPath[iNdEx])
|
||||
i = encodeVarintCommitment(dAtA, i, uint64(len(m.KeyPath[iNdEx])))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintCommitment(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
|
@ -470,45 +351,10 @@ func (m *MerkleProof) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Proof != nil {
|
||||
{
|
||||
size, err := m.Proof.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintCommitment(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *KeyPath) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *KeyPath) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *KeyPath) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Keys) > 0 {
|
||||
for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- {
|
||||
if len(m.Proofs) > 0 {
|
||||
for iNdEx := len(m.Proofs) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Keys[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
size, err := m.Proofs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -522,41 +368,6 @@ func (m *KeyPath) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *Key) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Key) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *Key) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Enc != 0 {
|
||||
i = encodeVarintCommitment(dAtA, i, uint64(m.Enc))
|
||||
i--
|
||||
dAtA[i] = 0x10
|
||||
}
|
||||
if len(m.Name) > 0 {
|
||||
i -= len(m.Name)
|
||||
copy(dAtA[i:], m.Name)
|
||||
i = encodeVarintCommitment(dAtA, i, uint64(len(m.Name)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintCommitment(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovCommitment(v)
|
||||
base := offset
|
||||
|
@ -600,8 +411,12 @@ func (m *MerklePath) Size() (n int) {
|
|||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.KeyPath.Size()
|
||||
n += 1 + l + sovCommitment(uint64(l))
|
||||
if len(m.KeyPath) > 0 {
|
||||
for _, s := range m.KeyPath {
|
||||
l = len(s)
|
||||
n += 1 + l + sovCommitment(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -611,21 +426,8 @@ func (m *MerkleProof) Size() (n int) {
|
|||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Proof != nil {
|
||||
l = m.Proof.Size()
|
||||
n += 1 + l + sovCommitment(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *KeyPath) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Keys) > 0 {
|
||||
for _, e := range m.Keys {
|
||||
if len(m.Proofs) > 0 {
|
||||
for _, e := range m.Proofs {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovCommitment(uint64(l))
|
||||
}
|
||||
|
@ -633,22 +435,6 @@ func (m *KeyPath) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *Key) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Name)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovCommitment(uint64(l))
|
||||
}
|
||||
if m.Enc != 0 {
|
||||
n += 1 + sovCommitment(uint64(m.Enc))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovCommitment(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
|
@ -862,7 +648,7 @@ func (m *MerklePath) Unmarshal(dAtA []byte) error {
|
|||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field KeyPath", wireType)
|
||||
}
|
||||
var msglen int
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
|
@ -872,24 +658,23 @@ func (m *MerklePath) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.KeyPath.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
m.KeyPath = append(m.KeyPath, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
|
@ -946,7 +731,7 @@ func (m *MerkleProof) Unmarshal(dAtA []byte) error {
|
|||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Proofs", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
|
@ -973,10 +758,8 @@ func (m *MerkleProof) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Proof == nil {
|
||||
m.Proof = &crypto.ProofOps{}
|
||||
}
|
||||
if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
m.Proofs = append(m.Proofs, &_go.CommitmentProof{})
|
||||
if err := m.Proofs[len(m.Proofs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
|
@ -1004,199 +787,6 @@ func (m *MerkleProof) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *KeyPath) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: KeyPath: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: KeyPath: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Keys = append(m.Keys, &Key{})
|
||||
if err := m.Keys[len(m.Keys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipCommitment(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *Key) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Key: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Key: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Name == nil {
|
||||
m.Name = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Enc", wireType)
|
||||
}
|
||||
m.Enc = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCommitment
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Enc |= KeyEncoding(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipCommitment(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthCommitment
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipCommitment(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// AppendKey appends a new key to a KeyPath
|
||||
func (pth KeyPath) AppendKey(key []byte, enc KeyEncoding) KeyPath {
|
||||
pth.Keys = append(pth.Keys, &Key{Name: key, Enc: enc})
|
||||
return pth
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface
|
||||
func (pth *KeyPath) String() string {
|
||||
res := ""
|
||||
for _, key := range pth.Keys {
|
||||
switch key.Enc {
|
||||
case URL:
|
||||
res += "/" + url.PathEscape(string(key.Name))
|
||||
case HEX:
|
||||
res += "/x:" + fmt.Sprintf("%X", key.Name)
|
||||
default:
|
||||
panic("unexpected key encoding type")
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// GetKey returns the bytes representation of key at given index
|
||||
// Passing in a positive index return the key at index in forward order
|
||||
// from the highest key to the lowest key
|
||||
// Passing in a negative index will return the key at index in reverse order
|
||||
// from the lowest key to the highest key. This is the order for proof verification,
|
||||
// since we prove lowest key first before moving to key of higher subtrees
|
||||
func (pth *KeyPath) GetKey(i int) []byte {
|
||||
total := len(pth.Keys)
|
||||
index := (total + i) % total
|
||||
return pth.Keys[index].Name
|
||||
}
|
|
@ -2,6 +2,7 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
ics23 "github.com/confio/ics23/go"
|
||||
|
@ -9,7 +10,6 @@ import (
|
|||
tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
|
||||
)
|
||||
|
||||
|
@ -68,51 +68,62 @@ func (mp MerklePrefix) Empty() bool {
|
|||
var _ exported.Path = (*MerklePath)(nil)
|
||||
|
||||
// NewMerklePath creates a new MerklePath instance
|
||||
func NewMerklePath(keyPathStr []string) MerklePath {
|
||||
merkleKeyPath := KeyPath{}
|
||||
for _, keyStr := range keyPathStr {
|
||||
merkleKeyPath = merkleKeyPath.AppendKey([]byte(keyStr), URL)
|
||||
}
|
||||
|
||||
// The keys must be passed in from root-to-leaf order
|
||||
func NewMerklePath(keyPath ...string) MerklePath {
|
||||
return MerklePath{
|
||||
KeyPath: merkleKeyPath,
|
||||
KeyPath: keyPath,
|
||||
}
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
// This represents the path in the same way the tendermint KeyPath will
|
||||
// represent a key path. The backslashes partition the key path into
|
||||
// the respective stores they belong to.
|
||||
func (mp MerklePath) String() string {
|
||||
return mp.KeyPath.String()
|
||||
pathStr := ""
|
||||
for _, k := range mp.KeyPath {
|
||||
pathStr += "/" + url.PathEscape(k)
|
||||
}
|
||||
return pathStr
|
||||
}
|
||||
|
||||
// Pretty returns the unescaped path of the URL string.
|
||||
// This function will unescape any backslash within a particular store key.
|
||||
// This makes the keypath more human-readable while removing information
|
||||
// about the exact partitions in the key path.
|
||||
func (mp MerklePath) Pretty() string {
|
||||
path, err := url.PathUnescape(mp.KeyPath.String())
|
||||
path, err := url.PathUnescape(mp.String())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// Empty returns true if the path is empty
|
||||
func (mp MerklePath) Empty() bool {
|
||||
return len(mp.KeyPath.Keys) == 0
|
||||
// GetKey will return a byte representation of the key
|
||||
// after URL escaping the key element
|
||||
func (mp MerklePath) GetKey(i uint64) ([]byte, error) {
|
||||
if i >= uint64(len(mp.KeyPath)) {
|
||||
return nil, fmt.Errorf("index out of range. %d (index) >= %d (len)", i, len(mp.KeyPath))
|
||||
}
|
||||
key, err := url.PathUnescape(mp.KeyPath[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(key), nil
|
||||
}
|
||||
|
||||
// ApplyPrefix constructs a new commitment path from the arguments. It interprets
|
||||
// the path argument in the context of the prefix argument.
|
||||
//
|
||||
// CONTRACT: provided path string MUST be a well formated path. See ICS24 for
|
||||
// reference.
|
||||
func ApplyPrefix(prefix exported.Prefix, path string) (MerklePath, error) {
|
||||
err := host.PathValidator(path)
|
||||
if err != nil {
|
||||
return MerklePath{}, err
|
||||
}
|
||||
// Empty returns true if the path is empty
|
||||
func (mp MerklePath) Empty() bool {
|
||||
return len(mp.KeyPath) == 0
|
||||
}
|
||||
|
||||
// ApplyPrefix constructs a new commitment path from the arguments. It prepends the prefix key
|
||||
// with the given path.
|
||||
func ApplyPrefix(prefix exported.Prefix, path MerklePath) (MerklePath, error) {
|
||||
if prefix == nil || prefix.Empty() {
|
||||
return MerklePath{}, sdkerrors.Wrap(ErrInvalidPrefix, "prefix can't be empty")
|
||||
}
|
||||
return NewMerklePath([]string{string(prefix.Bytes()), path}), nil
|
||||
return NewMerklePath(append([]string{string(prefix.Bytes())}, path.KeyPath...)...), nil
|
||||
}
|
||||
|
||||
var _ exported.Proof = (*MerkleProof)(nil)
|
||||
|
@ -128,22 +139,17 @@ func (proof MerkleProof) VerifyMembership(specs []*ics23.ProofSpec, root exporte
|
|||
if !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerklePath", path)
|
||||
}
|
||||
if len(mpath.KeyPath.Keys) != len(specs) {
|
||||
if len(mpath.KeyPath) != len(specs) {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "path length %d not same as proof %d",
|
||||
len(mpath.KeyPath.Keys), len(specs))
|
||||
len(mpath.KeyPath), len(specs))
|
||||
}
|
||||
if len(value) == 0 {
|
||||
return sdkerrors.Wrap(ErrInvalidProof, "empty value in membership proof")
|
||||
}
|
||||
|
||||
// Convert Proof to []CommitmentProof
|
||||
proofs, err := convertProofs(proof)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Since every proof in chain is a membership proof we can chain from index 0
|
||||
if err := verifyChainedMembershipProof(root.GetHash(), specs, proofs, mpath.KeyPath, value, 0); err != nil {
|
||||
// Since every proof in chain is a membership proof we can use verifyChainedMembershipProof from index 0
|
||||
// to validate entire proof
|
||||
if err := verifyChainedMembershipProof(root.GetHash(), specs, proof.Proofs, mpath, value, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -162,31 +168,37 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo
|
|||
if !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerkleProof", path)
|
||||
}
|
||||
if len(mpath.KeyPath.Keys) != len(specs) {
|
||||
if len(mpath.KeyPath) != len(specs) {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "path length %d not same as proof %d",
|
||||
len(mpath.KeyPath.Keys), len(specs))
|
||||
len(mpath.KeyPath), len(specs))
|
||||
}
|
||||
|
||||
// Convert Proof to []CommitmentProof
|
||||
proofs, err := convertProofs(proof)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch proof.Proofs[0].Proof.(type) {
|
||||
case *ics23.CommitmentProof_Nonexist:
|
||||
// VerifyNonMembership will verify the absence of key in lowest subtree, and then chain inclusion proofs
|
||||
// of all subroots up to final root
|
||||
subroot, err := proof.Proofs[0].Calculate()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not calculate root for proof index 0, merkle tree is likely empty. %v", err)
|
||||
}
|
||||
key, err := mpath.GetKey(uint64(len(mpath.KeyPath) - 1))
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key: %s", mpath.KeyPath[len(mpath.KeyPath)-1])
|
||||
}
|
||||
if ok := ics23.VerifyNonMembership(specs[0], subroot, proof.Proofs[0], key); !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not verify absence of key %s. Please ensure that the path is correct.", string(key))
|
||||
}
|
||||
|
||||
// VerifyNonMembership will verify the absence of key in lowest subtree, and then chain inclusion proofs
|
||||
// of all subroots up to final root
|
||||
subroot, err := proofs[0].Calculate()
|
||||
if err != nil {
|
||||
sdkerrors.Wrapf(ErrInvalidProof, "could not calculate root for proof index 0. %v", err)
|
||||
}
|
||||
key := mpath.KeyPath.GetKey(-1)
|
||||
if ok := ics23.VerifyNonMembership(specs[0], subroot, proofs[0], key); !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not verify absence of key %s", string(key))
|
||||
}
|
||||
|
||||
// Verify chained membership proof starting from index 1 with value = subroot
|
||||
if err := verifyChainedMembershipProof(root.GetHash(), specs, proofs, mpath.KeyPath, subroot, 1); err != nil {
|
||||
return err
|
||||
// Verify chained membership proof starting from index 1 with value = subroot
|
||||
if err := verifyChainedMembershipProof(root.GetHash(), specs, proof.Proofs, mpath, subroot, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
case *ics23.CommitmentProof_Exist:
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"got ExistenceProof in VerifyNonMembership. If this is unexpected, please ensure that proof was queried with the correct key.")
|
||||
default:
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"expected proof type: %T, got: %T", &ics23.CommitmentProof_Exist{}, proof.Proofs[0].Proof)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -208,7 +220,7 @@ func (proof MerkleProof) BatchVerifyNonMembership(specs []*ics23.ProofSpec, root
|
|||
// The proofs and specs are passed in from lowest subtree to the highest subtree, but the keys are passed in from highest subtree to lowest.
|
||||
// The index specifies what index to start chaining the membership proofs, this is useful since the lowest proof may not be a membership proof, thus we
|
||||
// will want to start the membership proof chaining from index 1 with value being the lowest subroot
|
||||
func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs []*ics23.CommitmentProof, keys KeyPath, value []byte, index int) error {
|
||||
func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs []*ics23.CommitmentProof, keys MerklePath, value []byte, index int) error {
|
||||
var (
|
||||
subroot []byte
|
||||
err error
|
||||
|
@ -218,42 +230,45 @@ func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs
|
|||
// In this case, there may be no intermediate proofs to verify and we just check that lowest proof root equals final root
|
||||
subroot = value
|
||||
for i := index; i < len(proofs); i++ {
|
||||
subroot, err = proofs[i].Calculate()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not calculate proof root at index %d. %v", i, err)
|
||||
switch proofs[i].Proof.(type) {
|
||||
case *ics23.CommitmentProof_Exist:
|
||||
subroot, err = proofs[i].Calculate()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not calculate proof root at index %d, merkle tree may be empty. %v", i, err)
|
||||
}
|
||||
// Since keys are passed in from highest to lowest, we must grab their indices in reverse order
|
||||
// from the proofs and specs which are lowest to highest
|
||||
key, err := keys.GetKey(uint64(len(keys.KeyPath) - 1 - i))
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key %s: %v", keys.KeyPath[len(keys.KeyPath)-1-i], err)
|
||||
}
|
||||
|
||||
// verify membership of the proof at this index with appropriate key and value
|
||||
if ok := ics23.VerifyMembership(specs[i], subroot, proofs[i], key, value); !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"chained membership proof failed to verify membership of value: %X in subroot %X at index %d. Please ensure the path and value are both correct.",
|
||||
value, subroot, i)
|
||||
}
|
||||
// Set value to subroot so that we verify next proof in chain commits to this subroot
|
||||
value = subroot
|
||||
case *ics23.CommitmentProof_Nonexist:
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"chained membership proof contains nonexistence proof at index %d. If this is unexpected, please ensure that proof was queried from the height that contained the value in store and was queried with the correct key.",
|
||||
i)
|
||||
default:
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"expected proof type: %T, got: %T", &ics23.CommitmentProof_Exist{}, proofs[i].Proof)
|
||||
}
|
||||
// Since keys are passed in from highest to lowest, we must grab their indices in reverse order
|
||||
// from the proofs and specs which are lowest to highest
|
||||
key := keys.GetKey(-1 * (i + 1))
|
||||
if ok := ics23.VerifyMembership(specs[i], subroot, proofs[i], key, value); !ok {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "chained membership proof failed to verify membership of value: %X in subroot %X at index %d for proof %v",
|
||||
value, subroot, i, proofs[i])
|
||||
}
|
||||
// Set value to subroot so that we verify next proof in chain commits to this subroot
|
||||
value = subroot
|
||||
}
|
||||
// Check that chained proof root equals passed-in root
|
||||
if !bytes.Equal(root, subroot) {
|
||||
return sdkerrors.Wrapf(ErrInvalidProof, "proof did not commit to expected root: %X, got: %X", root, subroot)
|
||||
return sdkerrors.Wrapf(ErrInvalidProof,
|
||||
"proof did not commit to expected root: %X, got: %X. Please ensure proof was submitted with correct proofHeight and to the correct chain.",
|
||||
root, subroot)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// convertProofs converts a MerkleProof into []*ics23.CommitmentProof
|
||||
func convertProofs(mproof MerkleProof) ([]*ics23.CommitmentProof, error) {
|
||||
// Unmarshal all proof ops to CommitmentProof
|
||||
proofs := make([]*ics23.CommitmentProof, len(mproof.Proof.Ops))
|
||||
for i, op := range mproof.Proof.Ops {
|
||||
var p ics23.CommitmentProof
|
||||
err := p.Unmarshal(op.Data)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(ErrInvalidMerkleProof, "could not unmarshal proof op into CommitmentProof at index: %d", i)
|
||||
}
|
||||
proofs[i] = &p
|
||||
}
|
||||
return proofs, nil
|
||||
}
|
||||
|
||||
// Empty returns true if the root is empty
|
||||
func (proof MerkleProof) Empty() bool {
|
||||
return proto.Equal(&proof, nil) || proto.Equal(&proof, &MerkleProof{}) || proto.Equal(&proof, &tmcrypto.ProofOps{})
|
||||
|
@ -277,10 +292,10 @@ func (proof MerkleProof) validateVerificationArgs(specs []*ics23.ProofSpec, root
|
|||
return sdkerrors.Wrap(ErrInvalidMerkleProof, "root cannot be empty")
|
||||
}
|
||||
|
||||
if len(specs) != len(proof.Proof.Ops) {
|
||||
if len(specs) != len(proof.Proofs) {
|
||||
return sdkerrors.Wrapf(ErrInvalidMerkleProof,
|
||||
"length of specs: %d not equal to length of proof: %d",
|
||||
len(specs), len(proof.Proof.Ops))
|
||||
len(specs), len(proof.Proofs))
|
||||
}
|
||||
|
||||
for i, spec := range specs {
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
tmmerkle "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
|
||||
)
|
||||
|
@ -23,9 +21,9 @@ func (suite *MerkleTestSuite) TestVerifyMembership() {
|
|||
})
|
||||
require.NotNil(suite.T(), res.ProofOps)
|
||||
|
||||
proof := types.MerkleProof{
|
||||
Proof: res.ProofOps,
|
||||
}
|
||||
proof, err := types.ConvertProofs(res.ProofOps)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
suite.Require().NoError(proof.ValidateBasic())
|
||||
suite.Require().Error(types.MerkleProof{}.ValidateBasic())
|
||||
|
||||
|
@ -49,9 +47,7 @@ func (suite *MerkleTestSuite) TestVerifyMembership() {
|
|||
{"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), func() {}, false}, // invalid proof with nil root
|
||||
{"proof is wrong length", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), func() {
|
||||
proof = types.MerkleProof{
|
||||
Proof: &tmmerkle.ProofOps{
|
||||
Ops: res.ProofOps.Ops[1:],
|
||||
},
|
||||
Proofs: proof.Proofs[1:],
|
||||
}
|
||||
}, false}, // invalid proof with wrong length
|
||||
|
||||
|
@ -63,7 +59,7 @@ func (suite *MerkleTestSuite) TestVerifyMembership() {
|
|||
tc.malleate()
|
||||
|
||||
root := types.NewMerkleRoot(tc.root)
|
||||
path := types.NewMerklePath(tc.pathArr)
|
||||
path := types.NewMerklePath(tc.pathArr...)
|
||||
|
||||
err := proof.VerifyMembership(types.GetSDKSpecs(), &root, path, tc.value)
|
||||
|
||||
|
@ -91,9 +87,9 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() {
|
|||
})
|
||||
require.NotNil(suite.T(), res.ProofOps)
|
||||
|
||||
proof := types.MerkleProof{
|
||||
Proof: res.ProofOps,
|
||||
}
|
||||
proof, err := types.ConvertProofs(res.ProofOps)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
suite.Require().NoError(proof.ValidateBasic())
|
||||
|
||||
cases := []struct {
|
||||
|
@ -114,9 +110,7 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() {
|
|||
{"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYABSENTKEY"}, func() {}, false}, // invalid proof with nil root
|
||||
{"proof is wrong length", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, func() {
|
||||
proof = types.MerkleProof{
|
||||
Proof: &tmcrypto.ProofOps{
|
||||
Ops: res.ProofOps.Ops[1:],
|
||||
},
|
||||
Proofs: proof.Proofs[1:],
|
||||
}
|
||||
}, false}, // invalid proof with wrong length
|
||||
|
||||
|
@ -129,7 +123,7 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() {
|
|||
tc.malleate()
|
||||
|
||||
root := types.NewMerkleRoot(tc.root)
|
||||
path := types.NewMerklePath(tc.pathArr)
|
||||
path := types.NewMerklePath(tc.pathArr...)
|
||||
|
||||
err := proof.VerifyNonMembership(types.GetSDKSpecs(), &root, path)
|
||||
|
||||
|
@ -149,16 +143,30 @@ func TestApplyPrefix(t *testing.T) {
|
|||
prefix := types.NewMerklePrefix([]byte("storePrefixKey"))
|
||||
|
||||
pathStr := "pathone/pathtwo/paththree/key"
|
||||
path := types.MerklePath{
|
||||
KeyPath: []string{pathStr},
|
||||
}
|
||||
|
||||
prefixedPath, err := types.ApplyPrefix(prefix, pathStr)
|
||||
require.Nil(t, err, "valid prefix returns error")
|
||||
prefixedPath, err := types.ApplyPrefix(prefix, path)
|
||||
require.NoError(t, err, "valid prefix returns error")
|
||||
|
||||
require.Equal(t, "/storePrefixKey/"+pathStr, prefixedPath.Pretty(), "Prefixed path incorrect")
|
||||
require.Equal(t, "/storePrefixKey/pathone%2Fpathtwo%2Fpaththree%2Fkey", prefixedPath.String(), "Prefixed scaped path incorrect")
|
||||
|
||||
// invalid prefix contains non-alphanumeric character
|
||||
invalidPathStr := "invalid-path/doesitfail?/hopefully"
|
||||
invalidPath, err := types.ApplyPrefix(prefix, invalidPathStr)
|
||||
require.NotNil(t, err, "invalid prefix does not returns error")
|
||||
require.Equal(t, types.MerklePath{}, invalidPath, "invalid prefix returns valid Path on ApplyPrefix")
|
||||
require.Equal(t, "/storePrefixKey/pathone%2Fpathtwo%2Fpaththree%2Fkey", prefixedPath.String(), "Prefixed escaped path incorrect")
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
path := types.NewMerklePath("rootKey", "storeKey", "path/to/leaf")
|
||||
|
||||
require.Equal(t, "/rootKey/storeKey/path%2Fto%2Fleaf", path.String(), "path String returns unxpected value")
|
||||
require.Equal(t, "/rootKey/storeKey/path/to/leaf", path.Pretty(), "path's pretty string representation is incorrect")
|
||||
|
||||
onePath := types.NewMerklePath("path/to/leaf")
|
||||
|
||||
require.Equal(t, "/path%2Fto%2Fleaf", onePath.String(), "one element path does not have correct string representation")
|
||||
require.Equal(t, "/path/to/leaf", onePath.Pretty(), "one element path has incorrect pretty string representation")
|
||||
|
||||
zeroPath := types.NewMerklePath()
|
||||
|
||||
require.Equal(t, "", zeroPath.String(), "zero element path does not have correct string representation")
|
||||
require.Equal(t, "", zeroPath.Pretty(), "zero element path does not have correct pretty string representation")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
ics23 "github.com/confio/ics23/go"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
crypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
)
|
||||
|
||||
// ConvertProofs converts crypto.ProofOps into MerkleProof
|
||||
func ConvertProofs(tmProof *crypto.ProofOps) (MerkleProof, error) {
|
||||
if tmProof == nil {
|
||||
return MerkleProof{}, sdkerrors.Wrapf(ErrInvalidMerkleProof, "tendermint proof is nil")
|
||||
}
|
||||
// Unmarshal all proof ops to CommitmentProof
|
||||
proofs := make([]*ics23.CommitmentProof, len(tmProof.Ops))
|
||||
for i, op := range tmProof.Ops {
|
||||
var p ics23.CommitmentProof
|
||||
err := p.Unmarshal(op.Data)
|
||||
if err != nil || p.Proof == nil {
|
||||
return MerkleProof{}, sdkerrors.Wrapf(ErrInvalidMerkleProof, "could not unmarshal proof op into CommitmentProof at index %d: %v", i, err)
|
||||
}
|
||||
proofs[i] = &p
|
||||
}
|
||||
return MerkleProof{
|
||||
Proofs: proofs,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package types_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
)
|
||||
|
||||
func (suite *MerkleTestSuite) TestConvertProofs() {
|
||||
suite.iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE"))
|
||||
cid := suite.store.Commit()
|
||||
|
||||
root := types.NewMerkleRoot(cid.Hash)
|
||||
existsPath := types.NewMerklePath(suite.storeKey.Name(), "MYKEY")
|
||||
nonexistPath := types.NewMerklePath(suite.storeKey.Name(), "NOTMYKEY")
|
||||
value := []byte("MYVALUE")
|
||||
|
||||
var proofOps *crypto.ProofOps
|
||||
testcases := []struct {
|
||||
name string
|
||||
malleate func()
|
||||
keyExists bool
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"success for ExistenceProof",
|
||||
func() {
|
||||
res := suite.store.Query(abci.RequestQuery{
|
||||
Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof
|
||||
Data: []byte("MYKEY"),
|
||||
Prove: true,
|
||||
})
|
||||
require.NotNil(suite.T(), res.ProofOps)
|
||||
|
||||
proofOps = res.ProofOps
|
||||
},
|
||||
true, true,
|
||||
},
|
||||
{
|
||||
"success for NonexistenceProof",
|
||||
func() {
|
||||
res := suite.store.Query(abci.RequestQuery{
|
||||
Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof
|
||||
Data: []byte("NOTMYKEY"),
|
||||
Prove: true,
|
||||
})
|
||||
require.NotNil(suite.T(), res.ProofOps)
|
||||
|
||||
proofOps = res.ProofOps
|
||||
},
|
||||
false, true,
|
||||
},
|
||||
{
|
||||
"nil proofOps",
|
||||
func() {
|
||||
proofOps = nil
|
||||
},
|
||||
true, false,
|
||||
},
|
||||
{
|
||||
"proof op data is nil",
|
||||
func() {
|
||||
res := suite.store.Query(abci.RequestQuery{
|
||||
Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof
|
||||
Data: []byte("MYKEY"),
|
||||
Prove: true,
|
||||
})
|
||||
require.NotNil(suite.T(), res.ProofOps)
|
||||
|
||||
proofOps = res.ProofOps
|
||||
proofOps.Ops[0].Data = nil
|
||||
},
|
||||
true, false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc.malleate()
|
||||
|
||||
proof, err := types.ConvertProofs(proofOps)
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err, "ConvertProofs unexpectedly returned error for case: %s", tc.name)
|
||||
if tc.keyExists {
|
||||
err := proof.VerifyMembership(types.GetSDKSpecs(), &root, existsPath, value)
|
||||
suite.Require().NoError(err, "converted proof failed to verify membership for case: %s", tc.name)
|
||||
} else {
|
||||
err := proof.VerifyNonMembership(types.GetSDKSpecs(), &root, nonexistPath)
|
||||
suite.Require().NoError(err, "converted proof failed to verify membership for case: %s", tc.name)
|
||||
}
|
||||
} else {
|
||||
suite.Require().Error(err, "ConvertProofs passed on invalid case for case: %s", tc.name)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,8 +50,9 @@ func QueryTendermintProof(clientCtx client.Context, key []byte) ([]byte, []byte,
|
|||
return nil, nil, clienttypes.Height{}, err
|
||||
}
|
||||
|
||||
merkleProof := commitmenttypes.MerkleProof{
|
||||
Proof: res.ProofOps,
|
||||
merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
|
||||
if err != nil {
|
||||
return nil, nil, clienttypes.Height{}, err
|
||||
}
|
||||
|
||||
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)
|
||||
|
|
|
@ -41,6 +41,9 @@ func (suite *KeeperTestSuite) SetupTest() {
|
|||
|
||||
suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(0))
|
||||
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
|
||||
// commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1)
|
||||
suite.coordinator.CommitNBlocks(suite.chainA, 2)
|
||||
suite.coordinator.CommitNBlocks(suite.chainB, 2)
|
||||
}
|
||||
|
||||
func TestIBCTestSuite(t *testing.T) {
|
||||
|
|
|
@ -100,7 +100,7 @@ func (cs ClientState) VerifyClientState(
|
|||
return err
|
||||
}
|
||||
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath()
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath())
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -138,7 +138,7 @@ func (cs ClientState) VerifyClientConsensusState(
|
|||
return err
|
||||
}
|
||||
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight)
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -175,7 +175,8 @@ func (cs ClientState) VerifyConnectionState(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ConnectionPath(connectionID))
|
||||
connectionPath := commitmenttypes.NewMerklePath(host.ConnectionPath(connectionID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, connectionPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -212,7 +213,8 @@ func (cs ClientState) VerifyChannelState(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ChannelPath(portID, channelID))
|
||||
channelPath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, channelPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -250,7 +252,8 @@ func (cs ClientState) VerifyPacketCommitment(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketCommitmentPath(portID, channelID, packetSequence))
|
||||
commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, packetSequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -288,7 +291,8 @@ func (cs ClientState) VerifyPacketAcknowledgement(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketAcknowledgementPath(portID, channelID, packetSequence))
|
||||
ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, packetSequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, ackPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -326,7 +330,8 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketReceiptPath(portID, channelID, packetSequence))
|
||||
receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, packetSequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -363,7 +368,8 @@ func (cs ClientState) VerifyNextSequenceRecv(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.NextSequenceRecvPath(portID, channelID))
|
||||
nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ func (cs ClientState) VerifyClientState(
|
|||
return err
|
||||
}
|
||||
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath()
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath())
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -220,7 +220,7 @@ func (cs ClientState) VerifyClientConsensusState(
|
|||
return err
|
||||
}
|
||||
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight)
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -263,7 +263,8 @@ func (cs ClientState) VerifyConnectionState(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ConnectionPath(connectionID))
|
||||
connectionPath := commitmenttypes.NewMerklePath(host.ConnectionPath(connectionID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, connectionPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -302,7 +303,8 @@ func (cs ClientState) VerifyChannelState(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ChannelPath(portID, channelID))
|
||||
channelPath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, channelPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -342,7 +344,8 @@ func (cs ClientState) VerifyPacketCommitment(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketCommitmentPath(portID, channelID, sequence))
|
||||
commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -372,7 +375,8 @@ func (cs ClientState) VerifyPacketAcknowledgement(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketAcknowledgementPath(portID, channelID, sequence))
|
||||
ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, ackPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -402,7 +406,8 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketReceiptPath(portID, channelID, sequence))
|
||||
receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -431,7 +436,8 @@ func (cs ClientState) VerifyNextSequenceRecv(
|
|||
return err
|
||||
}
|
||||
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.NextSequenceRecvPath(portID, channelID))
|
||||
nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -60,6 +60,9 @@ func (suite *TendermintTestSuite) SetupTest() {
|
|||
suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2)
|
||||
suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(0))
|
||||
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
|
||||
// commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1)
|
||||
suite.coordinator.CommitNBlocks(suite.chainA, 2)
|
||||
suite.coordinator.CommitNBlocks(suite.chainB, 2)
|
||||
|
||||
// TODO: deprecate usage in favor of testing package
|
||||
checkTx := false
|
||||
|
|
|
@ -117,5 +117,5 @@ func constructUpgradeMerklePath(upgradePath string, upgradeHeight exported.Heigh
|
|||
// append upgradeHeight to last key in merkle path
|
||||
// this will create the IAVL key that is used to store client in upgrade store
|
||||
upgradeKeys[len(upgradeKeys)-1] = fmt.Sprintf("%s/%d", lastKey, upgradeHeight.GetVersionHeight())
|
||||
return commitmenttypes.NewMerklePath(upgradeKeys), nil
|
||||
return commitmenttypes.NewMerklePath(upgradeKeys...), nil
|
||||
}
|
||||
|
|
|
@ -197,9 +197,8 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) {
|
|||
Prove: true,
|
||||
})
|
||||
|
||||
merkleProof := commitmenttypes.MerkleProof{
|
||||
Proof: res.ProofOps,
|
||||
}
|
||||
merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
|
||||
require.NoError(chain.t, err)
|
||||
|
||||
proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof)
|
||||
require.NoError(chain.t, err)
|
||||
|
@ -222,9 +221,8 @@ func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, cl
|
|||
Prove: true,
|
||||
})
|
||||
|
||||
merkleProof := commitmenttypes.MerkleProof{
|
||||
Proof: res.ProofOps,
|
||||
}
|
||||
merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
|
||||
require.NoError(chain.t, err)
|
||||
|
||||
proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof)
|
||||
require.NoError(chain.t, err)
|
||||
|
|
|
@ -251,7 +251,7 @@ func (solo *Solomachine) GenerateSignature(signBytes []byte) []byte {
|
|||
|
||||
// GetClientStatePath returns the commitment path for the client state.
|
||||
func (solo *Solomachine) GetClientStatePath(counterpartyClientIdentifier string) commitmenttypes.MerklePath {
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath()
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ClientStatePath())
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
|
@ -260,7 +260,7 @@ func (solo *Solomachine) GetClientStatePath(counterpartyClientIdentifier string)
|
|||
|
||||
// GetConsensusStatePath returns the commitment path for the consensus state.
|
||||
func (solo *Solomachine) GetConsensusStatePath(counterpartyClientIdentifier string, consensusHeight exported.Height) commitmenttypes.MerklePath {
|
||||
clientPrefixedPath := "clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight)
|
||||
clientPrefixedPath := commitmenttypes.NewMerklePath("clients/" + counterpartyClientIdentifier + "/" + host.ConsensusStatePath(consensusHeight))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
|
@ -269,7 +269,8 @@ func (solo *Solomachine) GetConsensusStatePath(counterpartyClientIdentifier stri
|
|||
|
||||
// GetConnectionStatePath returns the commitment path for the connection state.
|
||||
func (solo *Solomachine) GetConnectionStatePath(connID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ConnectionPath(connID))
|
||||
connectionPath := commitmenttypes.NewMerklePath(host.ConnectionPath(connID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, connectionPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
@ -277,7 +278,8 @@ func (solo *Solomachine) GetConnectionStatePath(connID string) commitmenttypes.M
|
|||
|
||||
// GetChannelStatePath returns the commitment path for that channel state.
|
||||
func (solo *Solomachine) GetChannelStatePath(portID, channelID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.ChannelPath(portID, channelID))
|
||||
channelPath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, channelPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
@ -285,7 +287,8 @@ func (solo *Solomachine) GetChannelStatePath(portID, channelID string) commitmen
|
|||
|
||||
// GetPacketCommitmentPath returns the commitment path for a packet commitment.
|
||||
func (solo *Solomachine) GetPacketCommitmentPath(portID, channelID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketCommitmentPath(portID, channelID, solo.Sequence))
|
||||
commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, solo.Sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
@ -293,7 +296,8 @@ func (solo *Solomachine) GetPacketCommitmentPath(portID, channelID string) commi
|
|||
|
||||
// GetPacketAcknowledgementPath returns the commitment path for a packet acknowledgement.
|
||||
func (solo *Solomachine) GetPacketAcknowledgementPath(portID, channelID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketAcknowledgementPath(portID, channelID, solo.Sequence))
|
||||
ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, solo.Sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, ackPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
@ -302,7 +306,8 @@ func (solo *Solomachine) GetPacketAcknowledgementPath(portID, channelID string)
|
|||
// GetPacketReceiptPath returns the commitment path for a packet receipt
|
||||
// and an absent receipts.
|
||||
func (solo *Solomachine) GetPacketReceiptPath(portID, channelID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.PacketReceiptPath(portID, channelID, solo.Sequence))
|
||||
receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, solo.Sequence))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
@ -310,7 +315,8 @@ func (solo *Solomachine) GetPacketReceiptPath(portID, channelID string) commitme
|
|||
|
||||
// GetNextSequenceRecvPath returns the commitment path for the next sequence recv counter.
|
||||
func (solo *Solomachine) GetNextSequenceRecvPath(portID, channelID string) commitmenttypes.MerklePath {
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, host.NextSequenceRecvPath(portID, channelID))
|
||||
nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID))
|
||||
path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath)
|
||||
require.NoError(solo.t, err)
|
||||
|
||||
return path
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue