General Merkle Follow Up (#2510)

* tmlibs -> libs

* update changelog

* address some comments from review of #2298
This commit is contained in:
Ethan Buchman 2018-09-28 23:32:13 -04:00 committed by GitHub
parent 71a34adfe5
commit f36ed7e7ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 29 deletions

View File

@ -5,21 +5,29 @@ Special thanks to external contributors on this release:
BREAKING CHANGES: BREAKING CHANGES:
* CLI/RPC/Config * CLI/RPC/Config
- [config] `mempool.wal` is disabled by default * [config] `mempool.wal` is disabled by default
* [rpc] \#2298 `/abci_query` takes `prove` argument instead of `trusted` and switches the default
behaviour to `prove=false`
* [privval] \#2459 Split `SocketPVMsg`s implementations into Request and Response, where the Response may contain a error message (returned by the remote signer).
* Apps * Apps
* [abci] \#2298 ResponseQuery.Proof is now a structured merkle.Proof, not just
arbitrary bytes
* Go API * Go API
- [node] Remove node.RunForever * [node] Remove node.RunForever
- [config] \#2232 timeouts as time.Duration, not ints * [config] \#2232 timeouts as time.Duration, not ints
* [rpc/client] \#2298 `ABCIQueryOptions.Trusted` -> `ABCIQueryOptions.Prove`
* [types] \#2298 Remove `Index` and `Total` fields from `TxProof`.
* [crypto/merkle & lite] \#2298 Various changes to accomodate General Merkle trees
* Blockchain Protocol * Blockchain Protocol
* [types] \#2459 `Vote`/`Proposal`/`Heartbeat` use amino encoding instead of JSON in `SignBytes`. * [types] \#2459 `Vote`/`Proposal`/`Heartbeat` use amino encoding instead of JSON in `SignBytes`.
* [privval] \#2459 Split `SocketPVMsg`s implementations into Request and Response, where the Response may contain a error message (returned by the remote signer).
* P2P Protocol * P2P Protocol
FEATURES: FEATURES:
- [crypto/merkle] \#2298 General Merkle Proof scheme for chaining various types of Merkle trees together
IMPROVEMENTS: IMPROVEMENTS:
- [consensus] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) add additional metrics - [consensus] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) add additional metrics

View File

@ -118,11 +118,12 @@ CHANGELOG even if they don't lead to MINOR version bumps:
- rpc/client - rpc/client
- config - config
- node - node
- libs/bech32 - libs
- libs/common - bech32
- libs/db - common
- libs/errors - db
- libs/log - errors
- log
Exported objects in these packages that are not covered by the versioning scheme Exported objects in these packages that are not covered by the versioning scheme
are explicitly marked by `// UNSTABLE` in their go doc comment and may change at any are explicitly marked by `// UNSTABLE` in their go doc comment and may change at any

View File

@ -20,7 +20,7 @@ const (
// generate the config.toml. Please reflect any changes // generate the config.toml. Please reflect any changes
// made here in the defaultConfigTemplate constant in // made here in the defaultConfigTemplate constant in
// config/toml.go // config/toml.go
// NOTE: tmlibs/cli must know to look in the config dir! // NOTE: libs/cli must know to look in the config dir!
var ( var (
DefaultTendermintDir = ".tendermint" DefaultTendermintDir = ".tendermint"
defaultConfigDir = "config" defaultConfigDir = "config"

View File

@ -3,17 +3,19 @@ package merkle
import ( import (
"bytes" "bytes"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tendermint/libs/common"
) )
//---------------------------------------- //----------------------------------------
// ProofOp gets converted to an instance of ProofOperator: // ProofOp gets converted to an instance of ProofOperator:
// ProofOperator is a layer for calculating intermediate Merkle root // ProofOperator is a layer for calculating intermediate Merkle roots
// Run() takes a list of bytes because it can be more than one // when a series of Merkle trees are chained together.
// for example in range proofs // Run() takes leaf values from a tree and returns the Merkle
// ProofOp() defines custom encoding which can be decoded later with // root for the corresponding tree. It takes and returns a list of bytes
// OpDecoder // to allow multiple leaves to be part of a single proof, for instance in a range proof.
// ProofOp() encodes the ProofOperator in a generic way so it can later be
// decoded with OpDecoder.
type ProofOperator interface { type ProofOperator interface {
Run([][]byte) ([][]byte, error) Run([][]byte) ([][]byte, error)
GetKey() []byte GetKey() []byte
@ -23,8 +25,8 @@ type ProofOperator interface {
//---------------------------------------- //----------------------------------------
// Operations on a list of ProofOperators // Operations on a list of ProofOperators
// ProofOperators is a slice of ProofOperator(s) // ProofOperators is a slice of ProofOperator(s).
// Each operator will be applied to the input value sequencially // Each operator will be applied to the input value sequentially
// and the last Merkle root will be verified with already known data // and the last Merkle root will be verified with already known data
type ProofOperators []ProofOperator type ProofOperators []ProofOperator
@ -91,8 +93,8 @@ func (prt *ProofRuntime) Decode(pop ProofOp) (ProofOperator, error) {
return decoder(pop) return decoder(pop)
} }
func (prt *ProofRuntime) DecodeProof(proof *Proof) (poz ProofOperators, err error) { func (prt *ProofRuntime) DecodeProof(proof *Proof) (ProofOperators, error) {
poz = ProofOperators(nil) var poz ProofOperators
for _, pop := range proof.Ops { for _, pop := range proof.Ops {
operator, err := prt.Decode(pop) operator, err := prt.Decode(pop)
if err != nil { if err != nil {
@ -100,7 +102,7 @@ func (prt *ProofRuntime) DecodeProof(proof *Proof) (poz ProofOperators, err erro
} }
poz = append(poz, operator) poz = append(poz, operator)
} }
return return poz, nil
} }
func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, keypath string, value []byte) (err error) { func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, keypath string, value []byte) (err error) {

View File

@ -35,6 +35,8 @@ import (
kp.AppendKey([]byte{0x01, 0x02, 0x03}, KeyEncodingURL) kp.AppendKey([]byte{0x01, 0x02, 0x03}, KeyEncodingURL)
kp.String() // Should return "/App/IBC/x:010203" kp.String() // Should return "/App/IBC/x:010203"
NOTE: Key paths must begin with a `/`.
NOTE: All encodings *MUST* work compatibly, such that you can choose to use NOTE: All encodings *MUST* work compatibly, such that you can choose to use
whatever encoding, and the decoded keys will always be the same. In other whatever encoding, and the decoded keys will always be the same. In other
words, it's just as good to encode all three keys using URL encoding or HEX words, it's just as good to encode all three keys using URL encoding or HEX
@ -52,7 +54,7 @@ type keyEncoding int
const ( const (
KeyEncodingURL keyEncoding = iota KeyEncodingURL keyEncoding = iota
KeyEncodingHex KeyEncodingHex
KeyEncodingMax KeyEncodingMax // Number of known encodings. Used for testing
) )
type Key struct { type Key struct {
@ -81,6 +83,8 @@ func (pth KeyPath) String() string {
return res return res
} }
// Decode a path to a list of keys. Path must begin with `/`.
// Each key must use a known encoding.
func KeyPathToKeys(path string) (keys [][]byte, err error) { func KeyPathToKeys(path string) (keys [][]byte, err error) {
if path == "" || path[0] != '/' { if path == "" || path[0] != '/' {
return nil, cmn.NewError("key path string must start with a forward slash '/'") return nil, cmn.NewError("key path string must start with a forward slash '/'")

View File

@ -25,7 +25,7 @@ type SimpleValueOp struct {
key []byte key []byte
// To encode in ProofOp.Data // To encode in ProofOp.Data
Proof *SimpleProof `json:"simple-proof"` Proof *SimpleProof `json:"simple_proof"`
} }
var _ ProofOperator = SimpleValueOp{} var _ ProofOperator = SimpleValueOp{}

View File

@ -26,7 +26,7 @@ var _ = math.Inf
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// Define these here for compatibility but use tmlibs/common.KVPair. // Define these here for compatibility but use libs/common.KVPair.
type KVPair struct { type KVPair struct {
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
@ -82,7 +82,7 @@ func (m *KVPair) GetValue() []byte {
return nil return nil
} }
// Define these here for compatibility but use tmlibs/common.KI64Pair. // Define these here for compatibility but use libs/common.KI64Pair.
type KI64Pair struct { type KI64Pair struct {
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`

View File

@ -88,7 +88,7 @@ type PersistentProvider interface {
} }
``` ```
* DBProvider - persistence provider for use with any tmlibs/DB. * DBProvider - persistence provider for use with any libs/DB.
* MultiProvider - combine multiple providers. * MultiProvider - combine multiple providers.
The suggested use for local light clients is client.NewHTTPProvider(...) for The suggested use for local light clients is client.NewHTTPProvider(...) for

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"sync" "sync"
log "github.com/tendermint/tendermint/libs/log" log "github.com/tendermint/tendermint/libs/log"
lerr "github.com/tendermint/tendermint/lite/errors" lerr "github.com/tendermint/tendermint/lite/errors"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@ -25,10 +26,9 @@ type DynamicVerifier struct {
// This is a source of new info, like a node rpc, or other import method. // This is a source of new info, like a node rpc, or other import method.
source Provider source Provider
// pending map for synchronize concurrent verification requests // pending map to synchronize concurrent verification requests
pendingVerifications map[int64]chan struct{}
mtx sync.Mutex mtx sync.Mutex
pendingVerifications map[int64]chan struct{}
} }
// NewDynamicVerifier returns a new DynamicVerifier. It uses the // NewDynamicVerifier returns a new DynamicVerifier. It uses the