refactor: clean-up SDK tools (#13603)

This commit is contained in:
Julien Robert 2022-10-21 17:15:20 +02:00 committed by GitHub
parent 6a371842df
commit 7d6601e1fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 41 additions and 2082 deletions

View File

@ -56,7 +56,7 @@ updates:
- "A:automerge"
- dependencies
- package-ecosystem: gomod
directory: "/cosmovisor"
directory: "/tools/cosmovisor"
schedule:
interval: weekly
labels:
@ -90,13 +90,6 @@ updates:
labels:
- "A:automerge"
- dependencies
- package-ecosystem: gomod
directory: "/store/tools/ics23"
schedule:
interval: weekly
labels:
- "A:automerge"
- dependencies
- package-ecosystem: gomod
directory: "/tx"
schedule:

View File

@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements
* (tools) [#13603](https://github.com/cosmos/cosmos-sdk/pull/13603) Rename cosmovisor package name to `cosmossdk.io/tools/cosmovisor`. The new tool directory contains Cosmos SDK tools.
* (deps) [#13397](https://github.com/cosmos/cosmos-sdk/pull/13397) Bump Go version minimum requirement to `1.19`.
* [#13070](https://github.com/cosmos/cosmos-sdk/pull/13070) Migrate from `gogo/protobuf` to `cosmos/gogoproto`.
* [#12995](https://github.com/cosmos/cosmos-sdk/pull/12995) Add `FormatTime` and `ParseTimeString` methods.

View File

@ -138,7 +138,7 @@ $(BUILDDIR)/:
mkdir -p $(BUILDDIR)/
cosmovisor:
$(MAKE) -C cosmovisor cosmovisor
$(MAKE) -C tools/cosmovisor cosmovisor
.PHONY: build build-linux-amd64 build-linux-arm64 cosmovisor

View File

@ -10,7 +10,6 @@ COPY math/go.mod math/go.sum /work/math/
COPY api/go.mod api/go.sum /work/api/
COPY core/go.mod core/go.sum /work/core/
COPY depinject/go.mod depinject/go.sum /work/depinject/
COPY store/tools/ics23/go.mod store/tools/ics23/go.sum /work/store/tools/ics23/
RUN go mod download
COPY ./ /work

View File

@ -9,7 +9,6 @@ COPY math/go.mod math/go.sum /work/math/
COPY api/go.mod api/go.sum /work/api/
COPY core/go.mod core/go.sum /work/core/
COPY depinject/go.mod depinject/go.sum /work/depinject/
COPY store/tools/ics23/go.mod store/tools/ics23/go.sum /work/store/tools/ics23/
RUN go mod download
COPY ./ /work

View File

@ -1,7 +0,0 @@
# Cosmovisor v1.3.0 Release Notes
* Fix failure when installing cosmovisor via `go install`.
### Changelog
For more details, please see the [CHANGELOG](https://github.com/cosmos/cosmos-sdk/blob/cosmovisor/v1.2.1/cosmovisor/CHANGELOG.md).

View File

@ -21,7 +21,7 @@ cp -r ../x/auth/vesting/README.md ./docs/modules/vesting/README.md
cat ../x/README.md | sed 's/\.\.\/docs\/building-modules\/README\.md/\/building-modules\/intro\.html/g' > ./docs/modules/README.md
## Add Cosmovisor documentation
cp ../cosmovisor/README.md ./docs/tooling/01-cosmovisor.md
cp ../tools/cosmovisor/README.md ./docs/tooling/01-cosmovisor.md
## Add depinject documentation
cp ../depinject/README.md ./docs/building-apps/01-depinject.md

View File

@ -1,43 +0,0 @@
//go:build gofuzz || go1.18
package tests
import (
"encoding/json"
"testing"
iavlproofs "github.com/cosmos/cosmos-sdk/store/tools/ics23/iavl"
"github.com/cosmos/iavl"
db "github.com/tendermint/tm-db"
)
type serialize struct {
Data map[string][]byte
Key string
}
func FuzzStoreInternalProofsCreateNonmembershipProof(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
sz := new(serialize)
if err := json.Unmarshal(data, sz); err != nil {
return
}
if len(sz.Data) == 0 || len(sz.Key) == 0 {
return
}
tree, err := iavl.NewMutableTree(db.NewMemDB(), 0, false)
if err != nil {
t.Fatal(err)
}
for k, v := range sz.Data {
tree.Set([]byte(k), v)
}
icp, err := iavlproofs.CreateNonMembershipProof(tree, []byte(sz.Key))
if err != nil {
return
}
if icp == nil {
panic("nil CommitmentProof with nil error")
}
})
}

3
go.mod
View File

@ -20,7 +20,6 @@ require (
github.com/cosmos/btcutil v1.0.4
github.com/cosmos/cosmos-proto v1.0.0-alpha8
github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1.0.20220726092710-f848e4300a8a
github.com/cosmos/cosmos-sdk/store/tools/ics23 v0.0.0-20220820010601-dc361be9e3ff
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/gogoproto v1.4.2
github.com/cosmos/iavl v0.19.3
@ -126,7 +125,7 @@ require (
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/onsi/gomega v1.20.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect

6
go.sum
View File

@ -189,8 +189,6 @@ github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dy
github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I=
github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1.0.20220726092710-f848e4300a8a h1:2humuGPw3O5riJVFq/E2FRjF57UrO97W1qJcGVmK+6k=
github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1.0.20220726092710-f848e4300a8a/go.mod h1:c8IO23vgNxueCCJlSI9awQtcxsvc+buzaeThB85qfBU=
github.com/cosmos/cosmos-sdk/store/tools/ics23 v0.0.0-20220820010601-dc361be9e3ff h1:bK16sWoQcV03WnZiX9ljUWumWEzMFB3SWpZ0uKhIiXQ=
github.com/cosmos/cosmos-sdk/store/tools/ics23 v0.0.0-20220820010601-dc361be9e3ff/go.mod h1:oY2d/HzjjpHVVNlz5quA0is2Zj/v1CI7mu4bkgMg2Yc=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
@ -304,6 +302,7 @@ github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
@ -633,6 +632,7 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
@ -1048,6 +1048,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1158,6 +1159,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=

View File

@ -5,12 +5,11 @@ use (
./api
./client/v2
./core
./cosmovisor
./tools/cosmovisor
./depinject
./errors
./math
./orm
./store/tools/ics23
./tx
./simapp
./tests

View File

@ -1,44 +0,0 @@
GO_RUN= go run -mod=readonly
GENDIR ?= ./testdata
.PHONY: testgen testgen-iavl testgen-smt testgen-simple
# make sure we turn on go modules
export GO111MODULE := on
# Usage: GENDIR=/path/to/ics23/testdata/iavl make testgen-iavl
testgen: testgen-iavl testgen-smt testgen-simple
testgen-iavl:
@mkdir -p "$(GENDIR)"
$(GO_RUN) ./iavl/cmd/testgen-iavl exist left 987 > "$(GENDIR)"/exist_left.json
$(GO_RUN) ./iavl/cmd/testgen-iavl exist middle 812 > "$(GENDIR)"/exist_middle.json
$(GO_RUN) ./iavl/cmd/testgen-iavl exist right 1261 > "$(GENDIR)"/exist_right.json
$(GO_RUN) ./iavl/cmd/testgen-iavl nonexist left 813 > "$(GENDIR)"/nonexist_left.json
$(GO_RUN) ./iavl/cmd/testgen-iavl nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
$(GO_RUN) ./iavl/cmd/testgen-iavl nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
$(GO_RUN) ./iavl/cmd/testgen-iavl batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
$(GO_RUN) ./iavl/cmd/testgen-iavl batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json
testgen-smt:
@mkdir -p "$(GENDIR)"
$(GO_RUN) ./smt/cmd/testgen-smt exist left 987 > "$(GENDIR)"/exist_left.json
$(GO_RUN) ./smt/cmd/testgen-smt exist middle 812 > "$(GENDIR)"/exist_middle.json
$(GO_RUN) ./smt/cmd/testgen-smt exist right 1261 > "$(GENDIR)"/exist_right.json
$(GO_RUN) ./smt/cmd/testgen-smt nonexist left 813 > "$(GENDIR)"/nonexist_left.json
$(GO_RUN) ./smt/cmd/testgen-smt nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
$(GO_RUN) ./smt/cmd/testgen-smt nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
$(GO_RUN) ./smt/cmd/testgen-smt batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
$(GO_RUN) ./smt/cmd/testgen-smt batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json
testgen-simple:
@mkdir -p "$(GENDIR)"
$(GO_RUN) ./tendermint/cmd/testgen-simple exist left 987 > "$(GENDIR)"/exist_left.json
$(GO_RUN) ./tendermint/cmd/testgen-simple exist middle 812 > "$(GENDIR)"/exist_middle.json
$(GO_RUN) ./tendermint/cmd/testgen-simple exist right 1261 > "$(GENDIR)"/exist_right.json
$(GO_RUN) ./tendermint/cmd/testgen-simple nonexist left 813 > "$(GENDIR)"/nonexist_left.json
$(GO_RUN) ./tendermint/cmd/testgen-simple nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
$(GO_RUN) ./tendermint/cmd/testgen-simple nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
$(GO_RUN) ./tendermint/cmd/testgen-simple batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
$(GO_RUN) ./tendermint/cmd/testgen-simple batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json

View File

@ -1,43 +0,0 @@
module github.com/cosmos/cosmos-sdk/store/tools/ics23
go 1.19
require (
github.com/confio/ics23/go v0.7.0
github.com/cosmos/cosmos-sdk v0.46.2
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313
github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554
github.com/tendermint/tendermint v0.37.0-alpha.2
github.com/tendermint/tm-db v0.6.7
)
require (
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cosmos/gogoproto v1.4.2 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.0 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/onsi/gomega v1.20.0 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
google.golang.org/protobuf v1.28.1 // indirect
)
replace github.com/cosmos/cosmos-sdk/store/tools/ics23 => ./

View File

@ -1,210 +0,0 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8=
github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cosmos/cosmos-sdk v0.46.2 h1:3dUNqbLas94ud5aTcJKCwxVOmNXpuGBtVQTMrYczTwY=
github.com/cosmos/cosmos-sdk v0.46.2/go.mod h1:0aUPGPU6PWaDEaHNjtgrpNhgxo9bAUrQ7BO7XCvFOfs=
github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAYw=
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y=
github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 h1:R7CnaI/0OLwOusy7n9750n8fqQ3yCQ8OJQI2L3ws9RA=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o=
github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk=
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI=
github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 h1:nDOkLO7klmnEw1s4AyKt1Arvpgyh33uj1JmkYlJaDsk=
github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554/go.mod h1:9+Pb2/tg1PvEgW7aFx4bFhDE4bvbI03zuJ8kb7nJ9Jc=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tendermint/tendermint v0.37.0-alpha.2 h1:G82quAWZUDYMTc9G7b/tntFATfm7nm6PrsvjsuMZDPI=
github.com/tendermint/tendermint v0.37.0-alpha.2/go.mod h1:DSnBfCufF48DhIpmU2inmVo8YiEGus6uInwf46Iu01k=
github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8=
github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20220726230323-06994584191e h1:wOQNKh1uuDGRnmgF0jDxh7ctgGy/3P4rYWQRVJD4/Yg=
golang.org/x/net v0.0.0-20220726230323-06994584191e/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,62 +0,0 @@
package ics23_tools
import (
"fmt"
"strconv"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
)
func ParseArgs(args []string) (exist bool, loc tmproofs.Where, size int, err error) {
if len(args) != 3 && len(args) != 4 {
err = fmt.Errorf("Insufficient args")
return
}
switch args[1] {
case "exist":
exist = true
case "nonexist":
exist = false
default:
err = fmt.Errorf("Invalid arg: %s", args[1])
return
}
switch args[2] {
case "left":
loc = tmproofs.Left
case "middle":
loc = tmproofs.Middle
case "right":
loc = tmproofs.Right
default:
err = fmt.Errorf("Invalid arg: %s", args[2])
return
}
size = 400
if len(args) == 4 {
size, err = strconv.Atoi(args[3])
}
return
}
func ParseBatchArgs(args []string) (size int, exist int, nonexist int, err error) {
if len(args) != 3 {
err = fmt.Errorf("Insufficient args")
return
}
size, err = strconv.Atoi(args[0])
if err != nil {
return
}
exist, err = strconv.Atoi(args[1])
if err != nil {
return
}
nonexist, err = strconv.Atoi(args[2])
return
}

View File

@ -1,18 +0,0 @@
.PHONY: testgen
GENDIR ?= ./testdata
# make sure we turn on go modules
export GO111MODULE := on
# Usage: GENDIR=../ics23/testdata/iavl make testgen
testgen:
@mkdir -p "$(GENDIR)"
go run -mod=readonly ./cmd/testgen-iavl exist left 987 > "$(GENDIR)"/exist_left.json
go run -mod=readonly ./cmd/testgen-iavl exist middle 812 > "$(GENDIR)"/exist_middle.json
go run -mod=readonly ./cmd/testgen-iavl exist right 1261 > "$(GENDIR)"/exist_right.json
go run -mod=readonly ./cmd/testgen-iavl nonexist left 813 > "$(GENDIR)"/nonexist_left.json
go run -mod=readonly ./cmd/testgen-iavl nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
go run -mod=readonly ./cmd/testgen-iavl nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
go run -mod=readonly ./cmd/testgen-iavl batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
go run -mod=readonly ./cmd/testgen-iavl batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json

View File

@ -1,44 +0,0 @@
# Proofs IAVL
This is a demo project to show converting proofs from cosmos/iavl into the format
specified in confio/proofs and validating that they still work.
## Library usage
It exposes a two main functions :
`func CreateMembershipProof(tree *iavl.MutableTree, key []byte) (*proofs.CommitmentProof, error)`
produces a CommitmentProof that the given key exists in the iavl tree (and contains the
current value). This returns an error if the key does not exist in the tree.
`func CreateNonMembershipProof(tree *iavl.MutableTree, key []byte) (*proofs.CommitmentProof, error)`
produces a CommitmentProof that the given key doesn't exist in the iavl tree.
This returns an error if the key exists in the tree.
Generalized range proofs are lower in priority, as they are just an optimization of the
two basic proof types, and don't provide any additional capabilities.
We will soon add some `Batch` capabilities that can represent these.
## CLI usage
We also expose a simple script to generate test data for the confio proofs package.
```shell
go install ./cmd/testgen-iavl
testgen-iavl
```
Will output some json data, from a randomly generated merkle tree each time.
```json
{
"existence": "0a146f65436a684273735a34567543774b567a435963121e76616c75655f666f725f6f65436a684273735a34567543774b567a4359631a0d0a0b0801180120012a030002021a2d122b08011204020402201a2120d307032505383dee34ea9eadf7649c31d1ce294b6d62b273d804da478ac161da1a2d122b08011204040802201a2120306b7d51213bd93bac17c5ee3d727ec666300370b19fd55cc13d7341dc589a991a2b12290801122508160220857103d59863ac55d1f34008a681f837c01975a223c0f54883a05a446d49c7c6201a2b1229080112250a2202204498eb5c93e40934bc8bad9626f19e333c1c0be4541b9098f139585c3471bae2201a2d122b080112040e6c02201a212022648db12dbf830485cc41435ecfe37bcac26c6c305ac4304f649977ddc339d51a2c122a0801122610c60102204e0b7996a7104f5b1ac1a2caa0704c4b63f60112e0e13763b2ba03f40a54e845201a2c122a08011226129003022017858e28e0563f7252eaca19acfc1c3828c892e635f76f971b3fbdc9bbd2742e20",
"root": "cea07656c77e8655521f4c904730cf4649242b8e482be786b2b220a15150d5f0"
}
```
`"root"` is the hex-encoded root hash of the merkle tree
`"existence"` is the hex-encoding of the protobuf binary encoding of a `proofs.ExistenceProof` object. This contains a (key, value) pair,
along with all steps to reach the root hash. This provides a non-trivial test case, to ensure client in multiple languages can verify the
protobuf proofs we generate from the iavl tree

View File

@ -1,201 +0,0 @@
package main
import (
"encoding/hex"
"encoding/json"
"fmt"
"os"
ics23 "github.com/confio/ics23/go"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
tools "github.com/cosmos/cosmos-sdk/store/tools/ics23"
iavlproofs "github.com/cosmos/cosmos-sdk/store/tools/ics23/iavl"
"github.com/cosmos/cosmos-sdk/store/tools/ics23/iavl/helpers"
)
/**
testgen-iavl will generate a json struct on stdout (meant to be saved to file for testdata).
this will be an auto-generated existence proof in the form:
{
"root": "<hex encoded root hash of tree>",
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof>"
}
It accepts two or three arguments (optional size: default 400)
testgen-iavl [exist|nonexist] [left|right|middle] <size>
If you make a batch, we have a different format:
{
"root": "<hex encoded root hash of tree>",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof (Compressed Batch)>",
"items": [{
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
}, ...]
}
The batch variant accepts 5 arguments:
testgen-iavl [batch] [size] [num exist] [num nonexist]
**/
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: testgen-iavl batch [size] [# exist] [# nonexist]")
fmt.Println(" testgen-iavl [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
if os.Args[1] == "batch" {
err := doBatch(os.Args[2:])
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-iavl [batch] [size] [# exist] [# nonexist]")
os.Exit(1)
}
return
}
exist, loc, size, err := tools.ParseArgs(os.Args)
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-iavl [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
tree, allkeys, err := helpers.BuildTree(size)
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-iavl [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
root, _ := tree.WorkingHash()
var key, value []byte
if exist {
key = helpers.GetKey(allkeys, loc)
value, _ = tree.Get(key)
} else {
key = helpers.GetNonKey(allkeys, loc)
}
var proof *ics23.CommitmentProof
if exist {
proof, err = iavlproofs.CreateMembershipProof(tree, key)
} else {
proof, err = iavlproofs.CreateNonMembershipProof(tree, key)
}
if err != nil {
fmt.Printf("Error: create proof: %+v\n", err)
os.Exit(1)
}
binary, err := proof.Marshal()
if err != nil {
fmt.Printf("Error: protobuf marshal: %+v\n", err)
os.Exit(1)
}
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"key": hex.EncodeToString(key),
"value": hex.EncodeToString(value),
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Printf("Error: json encoding: %+v\n", err)
os.Exit(1)
}
fmt.Println(string(out))
}
type item struct {
Key string `json:"key"`
Value string `json:"value"`
}
func doBatch(args []string) error {
size, exist, nonexist, err := tools.ParseBatchArgs(args)
if err != nil {
return err
}
tree, allkeys, err := helpers.BuildTree(size)
if err != nil {
return err
}
root, err := tree.WorkingHash()
if err != nil {
return err
}
items := []item{}
proofs := []*ics23.CommitmentProof{}
for i := 0; i < exist; i++ {
key := []byte(helpers.GetKey(allkeys, tmproofs.Middle))
value, err := tree.Get(key)
if err != nil {
return err
}
proof, err := iavlproofs.CreateMembershipProof(tree, key)
if err != nil {
return fmt.Errorf("create proof: %+v", err)
}
proofs = append(proofs, proof)
item := item{
Key: hex.EncodeToString(key),
Value: hex.EncodeToString(value),
}
items = append(items, item)
}
for i := 0; i < nonexist; i++ {
key := []byte(helpers.GetNonKey(allkeys, tmproofs.Middle))
proof, err := iavlproofs.CreateNonMembershipProof(tree, key)
if err != nil {
return fmt.Errorf("create proof: %+v", err)
}
proofs = append(proofs, proof)
item := item{
Key: hex.EncodeToString(key),
}
items = append(items, item)
}
// combine all proofs into batch and compress
proof, err := ics23.CombineProofs(proofs)
if err != nil {
fmt.Printf("Error: combine proofs: %+v\n", err)
os.Exit(1)
}
binary, err := proof.Marshal()
if err != nil {
fmt.Printf("Error: protobuf marshal: %+v\n", err)
os.Exit(1)
}
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"items": items,
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Printf("Error: json encoding: %+v\n", err)
os.Exit(1)
}
fmt.Println(string(out))
return nil
}

View File

@ -1,98 +0,0 @@
package iavlproofs
import (
"fmt"
ics23 "github.com/confio/ics23/go"
"github.com/cosmos/iavl"
)
// convertExistenceProof will convert the given proof into a valid
// existence proof, if that's what it is.
//
// This is the simplest case of the range proof and we will focus on
// demoing compatibility here
func convertExistenceProof(p *iavl.RangeProof, key, value []byte) (*ics23.ExistenceProof, error) {
if len(p.Leaves) != 1 {
return nil, fmt.Errorf("Existence proof requires RangeProof to have exactly one leaf")
}
return &ics23.ExistenceProof{
Key: key,
Value: value,
Leaf: convertLeafOp(p.Leaves[0].Version),
Path: convertInnerOps(p.LeftPath),
}, nil
}
func convertLeafOp(version int64) *ics23.LeafOp {
// this is adapted from iavl/proof.go:proofLeafNode.Hash()
prefix := aminoVarInt(0)
prefix = append(prefix, aminoVarInt(1)...)
prefix = append(prefix, aminoVarInt(version)...)
return &ics23.LeafOp{
Hash: ics23.HashOp_SHA256,
PrehashValue: ics23.HashOp_SHA256,
Length: ics23.LengthOp_VAR_PROTO,
Prefix: prefix,
}
}
// we cannot get the proofInnerNode type, so we need to do the whole path in one function
func convertInnerOps(path iavl.PathToLeaf) []*ics23.InnerOp {
steps := make([]*ics23.InnerOp, 0, len(path))
// lengthByte is the length prefix prepended to each of the sha256 sub-hashes
var lengthByte byte = 0x20
// we need to go in reverse order, iavl starts from root to leaf,
// we want to go up from the leaf to the root
for i := len(path) - 1; i >= 0; i-- {
// this is adapted from iavl/proof.go:proofInnerNode.Hash()
prefix := aminoVarInt(int64(path[i].Height))
prefix = append(prefix, aminoVarInt(path[i].Size)...)
prefix = append(prefix, aminoVarInt(path[i].Version)...)
var suffix []byte
if len(path[i].Left) > 0 {
// length prefixed left side
prefix = append(prefix, lengthByte)
prefix = append(prefix, path[i].Left...)
// prepend the length prefix for child
prefix = append(prefix, lengthByte)
} else {
// prepend the length prefix for child
prefix = append(prefix, lengthByte)
// length-prefixed right side
suffix = []byte{lengthByte}
suffix = append(suffix, path[i].Right...)
}
op := &ics23.InnerOp{
Hash: ics23.HashOp_SHA256,
Prefix: prefix,
Suffix: suffix,
}
steps = append(steps, op)
}
return steps
}
func aminoVarInt(orig int64) []byte {
// amino-specific byte swizzling
i := uint64(orig) << 1
if orig < 0 {
i = ^i
}
// avoid multiple allocs for normal case
res := make([]byte, 0, 8)
// standard protobuf encoding
for i >= 1<<7 {
res = append(res, uint8(i&0x7f|0x80))
i >>= 7
}
res = append(res, uint8(i))
return res
}

View File

@ -1,30 +0,0 @@
package iavlproofs
import (
"bytes"
"testing"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
"github.com/cosmos/cosmos-sdk/store/tools/ics23/iavl/helpers"
)
func TestConvertExistence(t *testing.T) {
proof, err := helpers.GenerateIavlResult(200, tmproofs.Middle)
if err != nil {
t.Fatal(err)
}
converted, err := convertExistenceProof(proof.Proof, proof.Key, proof.Value)
if err != nil {
t.Fatal(err)
}
calc, err := converted.Calculate()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(calc, proof.RootHash) {
t.Errorf("Calculated: %X\nExpected: %X", calc, proof.RootHash)
}
}

View File

@ -1,102 +0,0 @@
package iavlproofs
import (
"fmt"
ics23 "github.com/confio/ics23/go"
"github.com/cosmos/iavl"
)
// IavlSpec constrains the format from ics23-iavl (iavl merkle ics23)
var IavlSpec = &ics23.ProofSpec{
LeafSpec: &ics23.LeafOp{
Prefix: []byte{0},
Hash: ics23.HashOp_SHA256,
PrehashValue: ics23.HashOp_SHA256,
Length: ics23.LengthOp_VAR_PROTO,
},
InnerSpec: &ics23.InnerSpec{
ChildOrder: []int32{0, 1},
MinPrefixLength: 4,
MaxPrefixLength: 12,
ChildSize: 33, // (with length byte)
Hash: ics23.HashOp_SHA256,
},
}
/*
CreateMembershipProof will produce a CommitmentProof that the given key (and queries value) exists in the iavl tree.
If the key doesn't exist in the tree, this will return an error.
*/
func CreateMembershipProof(tree *iavl.MutableTree, key []byte) (*ics23.CommitmentProof, error) {
exist, err := createExistenceProof(tree, key)
if err != nil {
return nil, err
}
proof := &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Exist{
Exist: exist,
},
}
return proof, nil
}
/*
CreateNonMembershipProof will produce a CommitmentProof that the given key doesn't exist in the iavl tree.
If the key exists in the tree, this will return an error.
*/
func CreateNonMembershipProof(tree *iavl.MutableTree, key []byte) (*ics23.CommitmentProof, error) {
// idx is one node right of what we want....
idx, val, err := tree.GetWithIndex(key)
if err != nil {
return nil, err
}
if val != nil {
return nil, fmt.Errorf("Cannot create NonExistanceProof when Key in State")
}
nonexist := &ics23.NonExistenceProof{
Key: key,
}
if idx >= 1 {
leftkey, _, err := tree.GetByIndex(idx - 1)
if err != nil {
return nil, err
}
nonexist.Left, err = createExistenceProof(tree, leftkey)
if err != nil {
return nil, err
}
}
// this will be nil if nothing right of the queried key
rightkey, _, err := tree.GetByIndex(idx)
if err != nil {
return nil, err
}
if rightkey != nil {
nonexist.Right, err = createExistenceProof(tree, rightkey)
if err != nil {
return nil, err
}
}
proof := &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Nonexist{
Nonexist: nonexist,
},
}
return proof, nil
}
func createExistenceProof(tree *iavl.MutableTree, key []byte) (*ics23.ExistenceProof, error) {
value, proof, err := tree.GetWithProof(key)
if err != nil {
return nil, err
}
if value == nil {
return nil, fmt.Errorf("Cannot create ExistanceProof when Key not in State")
}
return convertExistenceProof(proof, key, value)
}

View File

@ -1,80 +0,0 @@
package iavlproofs
import (
"testing"
ics23 "github.com/confio/ics23/go"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
"github.com/cosmos/cosmos-sdk/store/tools/ics23/iavl/helpers"
)
func TestCreateMembership(t *testing.T) {
cases := map[string]struct {
size int
loc tmproofs.Where
}{
"small left": {size: 100, loc: tmproofs.Left},
"small middle": {size: 100, loc: tmproofs.Middle},
"small right": {size: 100, loc: tmproofs.Right},
"big left": {size: 5431, loc: tmproofs.Left},
"big middle": {size: 5431, loc: tmproofs.Middle},
"big right": {size: 5431, loc: tmproofs.Right},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
tree, allkeys, err := helpers.BuildTree(tc.size)
if err != nil {
t.Fatalf("Creating tree: %+v", err)
}
key := helpers.GetKey(allkeys, tc.loc)
val, err := tree.Get(key)
proof, err := CreateMembershipProof(tree, key)
if err != nil {
t.Fatalf("Creating Proof: %+v", err)
}
root, _ := tree.WorkingHash()
valid := ics23.VerifyMembership(IavlSpec, root, proof, key, val)
if !valid {
t.Fatalf("Membership Proof Invalid")
}
})
}
}
func TestCreateNonMembership(t *testing.T) {
cases := map[string]struct {
size int
loc tmproofs.Where
}{
"small left": {size: 100, loc: tmproofs.Left},
"small middle": {size: 100, loc: tmproofs.Middle},
"small right": {size: 100, loc: tmproofs.Right},
"big left": {size: 5431, loc: tmproofs.Left},
"big middle": {size: 5431, loc: tmproofs.Middle},
"big right": {size: 5431, loc: tmproofs.Right},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
tree, allkeys, err := helpers.BuildTree(tc.size)
if err != nil {
t.Fatalf("Creating tree: %+v", err)
}
key := helpers.GetNonKey(allkeys, tc.loc)
proof, err := CreateNonMembershipProof(tree, key)
if err != nil {
t.Fatalf("Creating Proof: %+v", err)
}
root, _ := tree.WorkingHash()
valid := ics23.VerifyNonMembership(IavlSpec, root, proof, key)
if !valid {
t.Fatalf("Non Membership Proof Invalid")
}
})
}
}

View File

@ -1,108 +0,0 @@
/*
Package helpers contains functions to build sample data for tests/testgen
In it's own package to avoid polluting the godoc for ics23-iavl
*/
package helpers
import (
"bytes"
"fmt"
"sort"
"github.com/cosmos/iavl"
"github.com/tendermint/tendermint/libs/rand"
db "github.com/tendermint/tm-db"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
)
// IavlResult is the result of one match
type IavlResult struct {
Key []byte
Value []byte
Proof *iavl.RangeProof
RootHash []byte
}
// GenerateIavlResult makes a tree of size and returns a range proof for one random element
//
// returns a range proof and the root hash of the tree
func GenerateIavlResult(size int, loc tmproofs.Where) (*IavlResult, error) {
tree, allkeys, err := BuildTree(size)
if err != nil {
return nil, err
}
key := GetKey(allkeys, loc)
value, proof, err := tree.GetWithProof(key)
if err != nil {
return nil, err
}
if value == nil {
return nil, fmt.Errorf("GetWithProof returned nil value")
}
if len(proof.Leaves) != 1 {
return nil, fmt.Errorf("GetWithProof returned %d leaves", len(proof.Leaves))
}
root, _ := tree.WorkingHash()
res := &IavlResult{
Key: key,
Value: value,
Proof: proof,
RootHash: root,
}
return res, nil
}
// GetKey returns a key, on Left/Right/Middle
func GetKey(allkeys [][]byte, loc tmproofs.Where) []byte {
if loc == tmproofs.Left {
return allkeys[0]
}
if loc == tmproofs.Right {
return allkeys[len(allkeys)-1]
}
// select a random index between 1 and allkeys-2
idx := rand.NewRand().Int()%(len(allkeys)-2) + 1
return allkeys[idx]
}
// GetNonKey returns a missing key - Left of all, Right of all, or in the Middle
func GetNonKey(allkeys [][]byte, loc tmproofs.Where) []byte {
if loc == tmproofs.Left {
return []byte{0, 0, 0, 1}
}
if loc == tmproofs.Right {
return []byte{0xff, 0xff, 0xff, 0xff}
}
// otherwise, next to an existing key (copy before mod)
key := append([]byte{}, GetKey(allkeys, loc)...)
key[len(key)-2] = 255
key[len(key)-1] = 255
return key
}
// BuildTree creates random key/values and stores in tree
// returns a list of all keys in sorted order
func BuildTree(size int) (tree *iavl.MutableTree, keys [][]byte, err error) {
tree, err = iavl.NewMutableTree(db.NewMemDB(), 0)
if err != nil {
return nil, nil, err
}
// insert lots of info and store the bytes
keys = make([][]byte, size)
for i := 0; i < size; i++ {
key := rand.Str(20)
value := "value_for_" + key
tree.Set([]byte(key), []byte(value))
keys[i] = []byte(key)
}
sort.Slice(keys, func(i, j int) bool {
return bytes.Compare(keys[i], keys[j]) < 0
})
return tree, keys, nil
}

View File

@ -1,24 +0,0 @@
.PHONY: build test testgen
GENDIR ?= ./testdata
# make sure we turn on go modules
export GO111MODULE := on
build:
go build -mod=readonly ./cmd/testgen-smt
test:
go test -mod=readonly .
# Usage: GENDIR=../ics23/testdata/smt make testgen
testgen:
@mkdir -p "$(GENDIR)"
go run -mod=readonly ./cmd/testgen-smt exist left 987 > "$(GENDIR)"/exist_left.json
go run -mod=readonly ./cmd/testgen-smt exist middle 812 > "$(GENDIR)"/exist_middle.json
go run -mod=readonly ./cmd/testgen-smt exist right 1261 > "$(GENDIR)"/exist_right.json
go run -mod=readonly ./cmd/testgen-smt nonexist left 813 > "$(GENDIR)"/nonexist_left.json
go run -mod=readonly ./cmd/testgen-smt nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
go run -mod=readonly ./cmd/testgen-smt nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
go run -mod=readonly ./cmd/testgen-smt batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
go run -mod=readonly ./cmd/testgen-smt batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json

View File

@ -1,39 +0,0 @@
# Proofs SMT
This project demonstrates the generation and validation of ICS-23 proofs for a sparse Merkle tree (SMT) as implemented by [Celestia](https://github.com/celestiaorg/smt).
## Library usage
It exposes a two main functions :
`func CreateMembershipProof(tree *smt.SparseMerkleTree, key []byte) (*ics23.CommitmentProof, error)`
produces a CommitmentProof that the given key exists in the SMT (and contains the current value). This returns an error if the key does not exist in the tree.
`func CreateNonMembershipProof(tree *smt.SparseMerkleTree, key []byte, preimages PreimageMap) (*ics23.CommitmentProof, error)`
produces a CommitmentProof that the given key doesn't exist in the SMT. This returns an error if the key exists in the tree.
This relies on an auxiliary `PreimageMap` object which provides access to the preimages of all keys in the tree based on their (hashed) path ordering.
## CLI usage
We also expose a simple script to generate test data for the confio proofs package.
```shell
go install ./cmd/testgen-smt
testgen-smt exist left 10
```
Will output some json data, from a randomly generated Merkle tree each time.
```json
{
"key": "574f516c4364415274743845444d397347484937",
"proof": "0a9d010a2024910c64b5b74b6b72e6b9d3310a1d0bd599032e05e8abc43112d194e1a78f30121e76616c75655f666f725f574f516c4364415274743845444d3973474849371a07080118012a0100222708011201011a20b51557119b6985d54a48a4510e528d5f929f0b1c8b57914bb6cd8f9eab035d75222708011201011a20fff8248ca9e98cbb05c81612d38e74780b2c02d9c88ee628cfbdb8ca44769a63",
"root": "f69ef3599b7f0471b61735490636608a8ff43a327b2b5a3a5528ca7f7059ffa5",
"value": "76616c75655f666f725f574f516c4364415274743845444d397347484937"
}
```
`"root"` is the hex-encoded root hash of the Merkle tree.
`"proof"` is the hex-encoding of the protobuf binary encoding of a `proofs.ExistenceProof` object. This contains a (key, value) pair, along with all steps to reach the root hash. This provides a non-trivial test case, to ensure clients in multiple languages can verify the protobuf proofs we generate from the SMT.

View File

@ -1,214 +0,0 @@
package main
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"os"
ics23 "github.com/confio/ics23/go"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
tools "github.com/cosmos/cosmos-sdk/store/tools/ics23"
smtproofs "github.com/cosmos/cosmos-sdk/store/tools/ics23/smt"
"github.com/cosmos/cosmos-sdk/store/tools/ics23/smt/helpers"
)
/**
testgen-smt will generate a json struct on stdout (meant to be saved to file for testdata).
this will be an auto-generated existence proof in the form:
{
"root": "<hex encoded root hash of tree>",
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof>"
}
It accepts two or three arguments (optional size: default 400)
testgen-smt [exist|nonexist] [left|right|middle] <size>
If you make a batch, we have a different format:
{
"root": "<hex encoded root hash of tree>",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof (Compressed Batch)>",
"items": [{
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
}, ...]
}
The batch variant accepts 5 arguments:
testgen-smt [batch] [size] [num exist] [num nonexist]
**/
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: testgen-smt batch [size] [# exist] [# nonexist]")
fmt.Println(" testgen-smt [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
if os.Args[1] == "batch" {
size, exist, nonexist, err := tools.ParseBatchArgs(os.Args[2:])
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-smt batch [size] [# exist] [# nonexist]")
os.Exit(1)
}
err = doBatch(size, exist, nonexist)
if err != nil {
fmt.Printf("Error: %+v\n", err)
os.Exit(1)
}
return
}
exist, loc, size, err := tools.ParseArgs(os.Args)
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-smt [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
err = doSingle(exist, loc, size)
if err != nil {
fmt.Printf("Error: %+v\n", err)
os.Exit(1)
}
}
func doSingle(exist bool, loc tmproofs.Where, size int) error {
tree, preim, err := helpers.BuildTree(size)
if err != nil {
return err
}
root := tree.Root()
var key, value []byte
if exist {
key = preim.GetKey(loc)
value, err = tree.Get(key)
if err != nil {
return fmt.Errorf("get key: %w", err)
}
} else {
key = preim.GetNonKey(loc)
}
var proof *ics23.CommitmentProof
if exist {
proof, err = smtproofs.CreateMembershipProof(tree, key)
} else {
proof, err = smtproofs.CreateNonMembershipProof(tree, key, preim)
}
if err != nil {
return fmt.Errorf("create proof: %w", err)
}
binary, err := proof.Marshal()
if err != nil {
return fmt.Errorf("protobuf marshal: %w", err)
}
path := sha256.Sum256(key)
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"key": hex.EncodeToString(path[:]),
"value": hex.EncodeToString(value),
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
return fmt.Errorf("json encoding: %w", err)
}
fmt.Println(string(out))
return nil
}
type item struct {
Key string `json:"key"`
Value string `json:"value"`
}
func pickWhere(i int) tmproofs.Where {
if i > 2 {
return tmproofs.Middle
}
return tmproofs.Where(i)
}
func doBatch(size, exist, nonexist int) error {
tree, preim, err := helpers.BuildTree(size)
if err != nil {
return err
}
root := tree.Root()
items := []item{}
proofs := []*ics23.CommitmentProof{}
for i := 0; i < exist; i++ {
where := pickWhere(i)
key := []byte(preim.GetKey(where))
value, err := tree.Get(key)
if err != nil {
return fmt.Errorf("get key: %w", err)
}
proof, err := smtproofs.CreateMembershipProof(tree, key)
if err != nil {
return fmt.Errorf("create proof: %w", err)
}
proofs = append(proofs, proof)
path := sha256.Sum256(key)
item := item{
Key: hex.EncodeToString(path[:]),
Value: hex.EncodeToString(value),
}
items = append(items, item)
}
for i := 0; i < nonexist; i++ {
where := pickWhere(i)
key := []byte(preim.GetNonKey(where))
proof, err := smtproofs.CreateNonMembershipProof(tree, key, preim)
if err != nil {
return fmt.Errorf("create proof: %w", err)
}
proofs = append(proofs, proof)
path := sha256.Sum256(key)
item := item{
Key: hex.EncodeToString(path[:]),
}
items = append(items, item)
}
// combine all proofs into batch and compress
proof, err := ics23.CombineProofs(proofs)
if err != nil {
return fmt.Errorf("combine proofs: %w", err)
}
binary, err := proof.Marshal()
if err != nil {
return fmt.Errorf("protobuf marshal: %w", err)
}
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"items": items,
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
return fmt.Errorf("json encoding: %w", err)
}
fmt.Println(string(out))
return nil
}

View File

@ -1,126 +0,0 @@
package smtproofs
import (
"crypto/sha256"
"fmt"
ics23 "github.com/confio/ics23/go"
"github.com/lazyledger/smt"
)
// PreimageMap represents an interface for accessing hashed tree paths and retrieving their
// corresponding preimages.
type PreimageMap interface {
// KeyFor returns the preimage (key) for given path index.
KeyFor(int) []byte
// FindPath returns the ordered index of a given path, and whether it's contained in the tree.
// If not found, the returned index is where the path would be inserted.
FindPath([32]byte) (int, bool)
// Len returns the number of mapped paths.
Len() int
}
// CreateMembershipProof will produce a CommitmentProof that the given key (and queries value) exists in the SMT.
// If the key doesn't exist in the tree, this will return an error.
func CreateMembershipProof(tree *smt.SparseMerkleTree, key []byte) (*ics23.CommitmentProof, error) {
exist, err := createExistenceProof(tree, key)
if err != nil {
return nil, err
}
proof := &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Exist{
Exist: exist,
},
}
return proof, nil
}
func createExistenceProof(tree *smt.SparseMerkleTree, key []byte) (*ics23.ExistenceProof, error) {
has, err := tree.Has(key)
if err != nil {
return nil, err
}
if !has {
return nil, fmt.Errorf("Cannot create ExistenceProof when key not in state")
}
value, err := tree.Get(key)
if err != nil {
return nil, err
}
proof, err := tree.Prove(key)
if err != nil {
return nil, err
}
path := sha256.Sum256(key)
return &ics23.ExistenceProof{
Key: path[:],
Value: value,
Leaf: ics23.SmtSpec.LeafSpec,
Path: convertInnerOps(path[:], proof.SideNodes),
}, nil
}
// CreateNonMembershipProof will produce a CommitmentProof that the given key doesn't exist in the SMT.
// If the key exists in the tree, this will return an error.
func CreateNonMembershipProof(tree *smt.SparseMerkleTree, key []byte, preimages PreimageMap) (*ics23.CommitmentProof, error) {
path := sha256.Sum256(key)
has, err := tree.Has(key)
if err != nil {
return nil, err
}
if has {
return nil, fmt.Errorf("Cannot create NonExistenceProof when key in state")
}
nonexist := &ics23.NonExistenceProof{
Key: path[:],
}
ix, found := preimages.FindPath(path)
if found {
return nil, fmt.Errorf("Found index for key not in state")
}
if ix > 0 {
nonexist.Left, err = createExistenceProof(tree, preimages.KeyFor(ix-1))
if err != nil {
return nil, err
}
}
if ix < preimages.Len() {
nonexist.Right, err = createExistenceProof(tree, preimages.KeyFor(ix))
if err != nil {
return nil, err
}
}
return &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Nonexist{
nonexist,
},
}, nil
}
func convertInnerOps(path []byte, sideNodes [][]byte) []*ics23.InnerOp {
depth := len(sideNodes)
inners := make([]*ics23.InnerOp, 0, depth)
for i := 0; i < len(sideNodes); i++ {
op := &ics23.InnerOp{
Hash: ics23.HashOp_SHA256,
Prefix: []byte{1},
}
if getBitAtFromMSB(path[:], depth-1-i) == 1 {
// right child is on path
op.Prefix = append(op.Prefix, sideNodes[i]...)
} else {
op.Suffix = sideNodes[i]
}
inners = append(inners, op)
}
return inners
}
// getBitAtFromMSB gets the bit at an offset from the most significant bit
// Copied from github.com/celestiaorg/smt
func getBitAtFromMSB(data []byte, position int) int {
if int(data[position/8])&(1<<(8-1-uint(position)%8)) > 0 {
return 1
}
return 0
}

View File

@ -1,84 +0,0 @@
package smtproofs
import (
"crypto/sha256"
"testing"
ics23 "github.com/confio/ics23/go"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
"github.com/cosmos/cosmos-sdk/store/tools/ics23/smt/helpers"
)
var (
numKeys = 50
cases = map[string]struct {
size int
loc tmproofs.Where
}{
"tiny left": {size: 10, loc: tmproofs.Left},
"tiny middle": {size: 10, loc: tmproofs.Middle},
"tiny right": {size: 10, loc: tmproofs.Right},
"small left": {size: 100, loc: tmproofs.Left},
"small middle": {size: 100, loc: tmproofs.Middle},
"small right": {size: 100, loc: tmproofs.Right},
"big left": {size: 5431, loc: tmproofs.Left},
"big middle": {size: 5431, loc: tmproofs.Middle},
"big right": {size: 5431, loc: tmproofs.Right},
}
)
func TestCreateMembership(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
tree, preim, err := helpers.BuildTree(tc.size)
if err != nil {
t.Fatalf("Creating tree: %+v", err)
}
for i := 0; i < numKeys; i++ {
key := preim.GetKey(tc.loc)
val, err := tree.Get(key)
if err != nil {
t.Fatalf("Getting key: %+v", err)
}
proof, err := CreateMembershipProof(tree, key)
if err != nil {
t.Fatalf("Creating proof: %+v", err)
}
root := tree.Root()
path := sha256.Sum256(key)
valid := ics23.VerifyMembership(ics23.SmtSpec, root, proof, path[:], val)
if !valid {
t.Fatalf("Membership proof invalid")
}
}
})
}
}
func TestCreateNonMembership(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
tree, preim, err := helpers.BuildTree(tc.size)
if err != nil {
t.Fatalf("Creating tree: %+v", err)
}
for i := 0; i < numKeys; i++ {
key := preim.GetNonKey(tc.loc)
proof, err := CreateNonMembershipProof(tree, key, preim)
if err != nil {
t.Fatalf("Creating proof: %+v", err)
}
root := tree.Root()
path := sha256.Sum256(key)
valid := ics23.VerifyNonMembership(ics23.SmtSpec, root, proof, path[:])
if !valid {
t.Fatalf("Non-membership proof invalid")
}
}
})
}
}

View File

@ -1,131 +0,0 @@
/*
Package helpers contains functions to build sample data for tests/testgen
In it's own package to avoid polluting the godoc for ics23-smt
*/
package helpers
import (
"bytes"
"crypto/sha256"
"math/rand"
"sort"
"github.com/lazyledger/smt"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
)
// PreimageMap maps each tree path back to its preimage
// needed because SparseMerkleTree methods take preimage as arg and hash internally
type PreimageMap struct {
paths []preimageMapping
keys [][]byte
// known non-keys at left and rightmost positions
nonKeys []preimageMapping
}
type preimageMapping struct {
path [32]byte
keyIdx int // index of preimage in keys list
}
// BuildTree creates random key/values and stores in tree
// returns a list of all keys in sorted order
func BuildTree(size int) (*smt.SparseMerkleTree, *PreimageMap, error) {
nodes, values := smt.NewSimpleMap(), smt.NewSimpleMap()
tree := smt.NewSparseMerkleTree(nodes, values, sha256.New())
// insert lots of info and store the bytes
keys := make([][]byte, size+2)
for i := 0; i < len(keys); i++ {
key := randStr(20)
value := "value_for_" + key
_, err := tree.Update([]byte(key), []byte(value))
if err != nil {
return nil, nil, err
}
keys[i] = []byte(key)
}
var paths []preimageMapping
for i, key := range keys {
paths = append(paths, preimageMapping{sha256.Sum256(key), i})
}
sort.Slice(paths, func(i, j int) bool {
return bytes.Compare(paths[i].path[:], paths[j].path[:]) < 0
})
// now, find the edge paths and remove them from the tree
leftmost, rightmost := paths[0], paths[len(paths)-1]
_, err := tree.Delete(keys[leftmost.keyIdx])
if err != nil {
return nil, nil, err
}
_, err = tree.Delete(keys[rightmost.keyIdx])
if err != nil {
return nil, nil, err
}
pim := PreimageMap{
keys: keys,
paths: paths[1 : len(paths)-1],
nonKeys: []preimageMapping{leftmost, rightmost},
}
return tree, &pim, nil
}
// FindPath returns the closest index to path in paths, and whether it's a match.
// If not found, the returned index is where the path would be.
func (pim PreimageMap) FindPath(path [32]byte) (int, bool) {
var mid int
from, to := 0, len(pim.paths)-1
for from <= to {
mid = (from + to) / 2
switch bytes.Compare(pim.paths[mid].path[:], path[:]) {
case -1:
from = mid + 1
case 1:
to = mid - 1
default:
return mid, true
}
}
return from, false
}
// Len returns the number of mapped paths.
func (pim PreimageMap) Len() int { return len(pim.paths) }
// KeyFor returns the preimage (key) for given path index.
func (pim PreimageMap) KeyFor(pathIx int) []byte {
return pim.keys[pim.paths[pathIx].keyIdx]
}
// GetKey this returns a key, on Left/Right/Middle
func (pim PreimageMap) GetKey(loc tmproofs.Where) []byte {
if loc == tmproofs.Left {
return pim.KeyFor(0)
}
if loc == tmproofs.Right {
return pim.KeyFor(len(pim.paths) - 1)
}
// select a random index between 1 and len-2
idx := rand.Int()%(len(pim.paths)-2) + 1
return pim.KeyFor(idx)
}
// GetNonKey returns a missing key - Left of all, Right of all, or in the Middle
func (pim PreimageMap) GetNonKey(loc tmproofs.Where) []byte {
if loc == tmproofs.Left {
return pim.keys[pim.nonKeys[0].keyIdx]
}
if loc == tmproofs.Right {
return pim.keys[pim.nonKeys[1].keyIdx]
}
// otherwise, next to an existing key (copy before mod)
key := append([]byte{}, pim.GetKey(tmproofs.Middle)...)
key[len(key)-2] = 255
key[len(key)-1] = 255
return key
}

View File

@ -1,34 +0,0 @@
package helpers
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
rand "math/rand"
)
const (
strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
)
func init() {
rand.Seed(42)
// rand.Seed(crandSeed())
}
func randStr(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = strChars[rand.Intn(len(strChars))]
}
return string(b)
}
func crandSeed() int64 {
var seed int64
err := binary.Read(crand.Reader, binary.BigEndian, &seed)
if err != nil {
panic(fmt.Sprintf("could not read random seed from crypto/rand: %v", err))
}
return seed
}

View File

@ -1,24 +0,0 @@
.PHONY: build test testgen
GENDIR ?= ./testdata
# make sure we turn on go modules
export GO111MODULE := on
build:
go build -mod=readonly ./cmd/testgen-simple
test:
go test -mod=readonly .
testgen:
# Usage: GENDIR=../ics23/testdata/tendermint make testgen
@mkdir -p "$(GENDIR)"
go run -mod=readonly ./cmd/testgen-simple exist left 987 > "$(GENDIR)"/exist_left.json
go run -mod=readonly ./cmd/testgen-simple exist middle 812 > "$(GENDIR)"/exist_middle.json
go run -mod=readonly ./cmd/testgen-simple exist right 1261 > "$(GENDIR)"/exist_right.json
go run -mod=readonly ./cmd/testgen-simple nonexist left 813 > "$(GENDIR)"/nonexist_left.json
go run -mod=readonly ./cmd/testgen-simple nonexist middle 691 > "$(GENDIR)"/nonexist_middle.json
go run -mod=readonly ./cmd/testgen-simple nonexist right 1535 > "$(GENDIR)"/nonexist_right.json
go run -mod=readonly ./cmd/testgen-simple batch 1801 20 0 > "$(GENDIR)"/batch_exist.json
go run -mod=readonly ./cmd/testgen-simple batch 1807 0 20 > "$(GENDIR)"/batch_nonexist.json

View File

@ -1,39 +0,0 @@
# Proofs Tendermint
This is an adapter library to convert the `SimpleProof` from
[tendermint/crypto/merkle](https://github.com/tendermint/tendermint/tree/master/crypto/merkle)
into the standard confio/proofs format.
As non-existence proofs depend on ordered keys, and all proofs require the key-value pair
to be encoded in a predictable format in the leaves, we will only support proofs generated
from `SimpleProofsFromMap`, which handles the key-value pairs for leafs in a standard format.
## Library usage
It exposes a top-level function `func ConvertSimpleProof(p *merkle.SimpleProof, key, value []byte) (*proofs.ExistenceProof, error)`
that can convert from `merkle.SimpleProof` with the KVPair encoding for leafs, into confio/proof protobuf objects.
It currently only works for existence proofs. We plan to soon support non-existence proofs.
## CLI usage
We also expose a simple script to generate test data for the confio proofs package.
```shell
make testgen
```
Will output some json data, from a randomly generated merkle tree each time.
```json
{
"existence": "0a146f65436a684273735a34567543774b567a435963121e76616c75655f666f725f6f65436a684273735a34567543774b567a4359631a0d0a0b0801180120012a030002021a2d122b08011204020402201a2120d307032505383dee34ea9eadf7649c31d1ce294b6d62b273d804da478ac161da1a2d122b08011204040802201a2120306b7d51213bd93bac17c5ee3d727ec666300370b19fd55cc13d7341dc589a991a2b12290801122508160220857103d59863ac55d1f34008a681f837c01975a223c0f54883a05a446d49c7c6201a2b1229080112250a2202204498eb5c93e40934bc8bad9626f19e333c1c0be4541b9098f139585c3471bae2201a2d122b080112040e6c02201a212022648db12dbf830485cc41435ecfe37bcac26c6c305ac4304f649977ddc339d51a2c122a0801122610c60102204e0b7996a7104f5b1ac1a2caa0704c4b63f60112e0e13763b2ba03f40a54e845201a2c122a08011226129003022017858e28e0563f7252eaca19acfc1c3828c892e635f76f971b3fbdc9bbd2742e20",
"root": "cea07656c77e8655521f4c904730cf4649242b8e482be786b2b220a15150d5f0"
}
```
`"root"` is the hex-encoded root hash of the merkle tree
`"existence"` is the hex-encoding of the protobuf binary encoding of a `proofs.ExistenceProof` object. This contains a (key, value) pair,
along with all steps to reach the root hash. This provides a non-trivial test case, to ensure client in multiple languages can verify the
protobuf proofs we generate from the iavl tree

View File

@ -1,241 +0,0 @@
package main
import (
"encoding/hex"
"encoding/json"
"fmt"
"os"
"strconv"
tmproofs "github.com/cosmos/cosmos-sdk/store/internal/proofs"
ics23 "github.com/confio/ics23/go"
)
/**
testgen-simple will generate a json struct on stdout (meant to be saved to file for testdata).
this will be an auto-generated existence proof in the form:
{
"root": "<hex encoded root hash of tree>",
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof>"
}
It accepts two or three arguments (optional size: default 400)
testgen-simple [exist|nonexist] [left|right|middle] <size>
If you make a batch, we have a different format:
{
"root": "<hex encoded root hash of tree>",
"proof": "<hex encoded protobuf marshaling of a CommitmentProof (Compressed Batch)>",
"items": [{
"key": "<hex encoded key to prove>",
"value": "<hex encoded value to prove> (empty on non-existence)",
}, ...]
}
The batch variant accepts 5 arguments:
testgen-simple [batch] [size] [num exist] [num nonexist]
**/
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: testgen-simple batch [size] [# exist] [# nonexist]")
fmt.Println(" testgen-simple [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
if os.Args[1] == "batch" {
err := doBatch(os.Args[2:])
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-simple [batch] [size] [# exist] [# nonexist]")
os.Exit(1)
}
return
}
exist, loc, size, err := parseArgs(os.Args)
if err != nil {
fmt.Printf("%+v\n", err)
fmt.Println("Usage: testgen-simple [exist|nonexist] [left|right|middle] <size>")
os.Exit(1)
}
data := tmproofs.BuildMap(size)
allkeys := tmproofs.SortedKeys(data)
root := tmproofs.CalcRoot(data)
var key, value []byte
if exist {
key = []byte(tmproofs.GetKey(allkeys, loc))
value = data[string(key)]
} else {
key = []byte(tmproofs.GetNonKey(allkeys, loc))
}
var proof *ics23.CommitmentProof
if exist {
proof, err = tmproofs.CreateMembershipProof(data, key)
} else {
proof, err = tmproofs.CreateNonMembershipProof(data, key)
}
if err != nil {
fmt.Printf("Error: create proof: %+v\n", err)
os.Exit(1)
}
binary, err := proof.Marshal()
if err != nil {
fmt.Printf("Error: protobuf marshal: %+v\n", err)
os.Exit(1)
}
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"key": hex.EncodeToString(key),
"value": hex.EncodeToString(value),
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Printf("Error: json encoding: %+v\n", err)
os.Exit(1)
}
fmt.Println(string(out))
}
func parseArgs(args []string) (exist bool, loc tmproofs.Where, size int, err error) {
if len(args) != 3 && len(args) != 4 {
err = fmt.Errorf("Insufficient args")
return
}
switch args[1] {
case "exist":
exist = true
case "nonexist":
exist = false
default:
err = fmt.Errorf("Invalid arg: %s", args[1])
return
}
switch args[2] {
case "left":
loc = tmproofs.Left
case "middle":
loc = tmproofs.Middle
case "right":
loc = tmproofs.Right
default:
err = fmt.Errorf("Invalid arg: %s", args[2])
return
}
size = 400
if len(args) == 4 {
size, err = strconv.Atoi(args[3])
}
return
}
type item struct {
Key string `json:"key"`
Value string `json:"value"`
}
func doBatch(args []string) error {
size, exist, nonexist, err := parseBatchArgs(args)
if err != nil {
return err
}
data := tmproofs.BuildMap(size)
allkeys := tmproofs.SortedKeys(data)
root := tmproofs.CalcRoot(data)
items := []item{}
proofs := []*ics23.CommitmentProof{}
for i := 0; i < exist; i++ {
key := []byte(tmproofs.GetKey(allkeys, tmproofs.Middle))
value := data[string(key)]
proof, err := tmproofs.CreateMembershipProof(data, key)
if err != nil {
return fmt.Errorf("create proof: %+v", err)
}
proofs = append(proofs, proof)
item := item{
Key: hex.EncodeToString(key),
Value: hex.EncodeToString(value),
}
items = append(items, item)
}
for i := 0; i < nonexist; i++ {
key := []byte(tmproofs.GetNonKey(allkeys, tmproofs.Middle))
proof, err := tmproofs.CreateNonMembershipProof(data, key)
if err != nil {
return fmt.Errorf("create proof: %+v", err)
}
proofs = append(proofs, proof)
item := item{
Key: hex.EncodeToString(key),
}
items = append(items, item)
}
// combine all proofs into batch and compress
proof, err := ics23.CombineProofs(proofs)
if err != nil {
fmt.Printf("Error: combine proofs: %+v\n", err)
os.Exit(1)
}
binary, err := proof.Marshal()
if err != nil {
fmt.Printf("Error: protobuf marshal: %+v\n", err)
os.Exit(1)
}
res := map[string]interface{}{
"root": hex.EncodeToString(root),
"items": items,
"proof": hex.EncodeToString(binary),
}
out, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Printf("Error: json encoding: %+v\n", err)
os.Exit(1)
}
fmt.Println(string(out))
return nil
}
func parseBatchArgs(args []string) (size int, exist int, nonexist int, err error) {
if len(args) != 3 {
err = fmt.Errorf("Insufficient args")
return
}
size, err = strconv.Atoi(args[0])
if err != nil {
return
}
exist, err = strconv.Atoi(args[1])
if err != nil {
return
}
nonexist, err = strconv.Atoi(args[2])
return
}

View File

@ -36,6 +36,12 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
## v1.4.0 2022-10-21
### API Breaking Changes
* [#13603](https://github.com/cosmos-sdk/pull/13603) Rename cosmovisor package to `cosmossdk.io/tools/cosmovisor`.
## v1.3.0 2022-09-11
### Improvements

View File

@ -49,7 +49,7 @@ You can download Cosmovisor from the [GitHub releases](https://github.com/cosmos
To install the latest version of `cosmovisor`, run the following command:
```shell
go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@latest
go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest
```
To install a previous version, you can specify the version. IMPORTANT: Chains that use Cosmos-SDK v0.44.3 or earlier (eg v0.44.2) and want to use auto-download feature MUST use `cosmovisor v0.1.0`

View File

@ -0,0 +1,7 @@
# Cosmovisor v1.4.0 Release Notes
* Rename cosmovisor package to `cosmossdk.io/tools/cosmovisor`.
### Changelog
For more details, please see the [CHANGELOG](https://github.com/cosmos/cosmos-sdk/blob/cosmovisor/v1.4.0/cosmovisor/CHANGELOG.md).

View File

@ -10,7 +10,7 @@ import (
"strings"
"time"
cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors"
cverrors "cosmossdk.io/tools/cosmovisor/errors"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/rs/zerolog"

View File

@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/cosmovisor/errors"
"cosmossdk.io/tools/cosmovisor/errors"
)
type argsTestSuite struct {

View File

@ -3,7 +3,7 @@ package main
import (
"fmt"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
)
// GetHelpText creates the help text multi-line string.

View File

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
)
type HelpTestSuite struct {

View File

@ -10,8 +10,8 @@ import (
"github.com/rs/zerolog"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/cosmovisor"
cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors"
"cosmossdk.io/tools/cosmovisor"
cverrors "cosmossdk.io/tools/cosmovisor/errors"
)
func init() {

View File

@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
)
type InitTestSuite struct {

View File

@ -4,8 +4,8 @@ import (
"context"
"os"
"github.com/cosmos/cosmos-sdk/cosmovisor"
cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors"
"cosmossdk.io/tools/cosmovisor"
cverrors "cosmossdk.io/tools/cosmovisor/errors"
)
func main() {

View File

@ -1,7 +1,7 @@
package main
import (
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
)

View File

@ -6,7 +6,7 @@ import (
"runtime/debug"
"strings"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
)

View File

@ -4,7 +4,7 @@ import (
"context"
"testing"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/stretchr/testify/require"
)

View File

@ -1,4 +1,4 @@
module github.com/cosmos/cosmos-sdk/cosmovisor
module cosmossdk.io/tools/cosmovisor
go 1.19

View File

@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

View File

@ -17,7 +17,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"cosmossdk.io/tools/cosmovisor"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

View File

@ -321,7 +321,7 @@ Once a block contains more than 2/3rd *precommits* where a common
nodes, non-validating full nodes and light-nodes) are expected to switch to the
new version of the software.
Validators and full nodes can use an automation tool, such as [Cosmovisor](https://github.com/cosmos/cosmos-sdk/blob/main/cosmovisor/README.md), for automatically switching version of the chain.
Validators and full nodes can use an automation tool, such as [Cosmovisor](https://github.com/cosmos/cosmos-sdk/blob/main/tools/cosmovisor/README.md), for automatically switching version of the chain.
# State

View File

@ -45,7 +45,7 @@ automatically upgrade to.
If an operator running the application binary also runs a sidecar process to assist
in the automatic download and upgrade of a binary, the `Info` allows this process to
be seamless. This tool is [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/cosmovisor#readme).
be seamless. This tool is [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor#readme).
```go
type Plan struct {