diff --git a/go.mod b/go.mod index 7e2db88013..c7686bcefd 100644 --- a/go.mod +++ b/go.mod @@ -6,26 +6,27 @@ require ( github.com/99designs/keyring v1.1.6 github.com/DataDog/zstd v1.4.5 // indirect github.com/VictoriaMetrics/fastcache v1.5.8 - github.com/armon/go-metrics v0.3.6 + github.com/armon/go-metrics v0.3.8 github.com/bgentry/speakeasy v0.1.0 github.com/btcsuite/btcd v0.21.0-beta github.com/btcsuite/btcutil v1.0.2 - github.com/confio/ics23/go v0.6.3 + github.com/confio/ics23/go v0.6.6 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ledger-cosmos-go v0.11.1 - github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de + github.com/dgraph-io/ristretto v0.0.3 + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25 github.com/go-kit/kit v0.10.0 github.com/gogo/gateway v1.1.0 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.4.4 - github.com/golang/protobuf v1.4.3 - github.com/google/go-cmp v0.5.4 // indirect + github.com/golang/protobuf v1.5.2 + github.com/golangci/golangci-lint v1.41.1 // indirect github.com/google/gofuzz v1.2.0 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 - github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/kr/text v0.2.0 // indirect @@ -33,23 +34,23 @@ require ( github.com/line/ostracon v0.34.9-0.20210610071151-a52812ac9add github.com/line/tm-db/v2 v2.0.0-init.1.0.20210413083915-5bb60e117524 github.com/line/wasmvm v0.14.0-0.5.0 - github.com/magiconair/properties v1.8.4 + github.com/magiconair/properties v1.8.5 github.com/mailru/easyjson v0.7.7 github.com/mattn/go-isatty v0.0.12 - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/onsi/ginkgo v1.15.0 // indirect - github.com/onsi/gomega v1.10.5 // indirect - github.com/pelletier/go-toml v1.8.0 // indirect + github.com/mitchellh/mapstructure v1.3.3 // indirect + github.com/onsi/ginkgo v1.16.1 // indirect + github.com/onsi/gomega v1.11.0 // indirect + github.com/pelletier/go-toml v1.8.1 // indirect github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.8.0 - github.com/prometheus/common v0.15.0 + github.com/prometheus/client_golang v1.10.0 + github.com/prometheus/common v0.23.0 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 - github.com/rs/zerolog v1.20.0 + github.com/rs/zerolog v1.21.0 github.com/spf13/afero v1.3.4 // indirect github.com/spf13/cast v1.3.1 github.com/spf13/cobra v1.1.3 + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.7.0 @@ -57,15 +58,17 @@ require ( github.com/tendermint/btcd v0.1.1 github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 github.com/tendermint/go-amino v0.16.0 + github.com/tendermint/tendermint v0.34.11 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect - golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect golang.org/x/text v0.3.5 // indirect google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f - google.golang.org/grpc v1.35.0 - google.golang.org/protobuf v1.25.0 - gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + google.golang.org/grpc v1.37.0 + google.golang.org/protobuf v1.26.0 + gopkg.in/ini.v1 v1.61.0 // indirect gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) replace ( diff --git a/go.sum b/go.sum index 5cd2759a1f..b129d9ba4d 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,39 @@ +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= +cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= @@ -21,11 +46,22 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VictoriaMetrics/fastcache v1.5.8 h1:XW+YVx9lEXITBVv35ugK9OyotdNJVcbza69o3jmqWuI= github.com/VictoriaMetrics/fastcache v1.5.8/go.mod h1:SiMZNgwEPJ9qWLshu9tyuE6bKc9ZWYhcNV/L7jurprQ= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -39,20 +75,32 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.6 h1:x/tmtOF9cDBoXH7XoAGOz2qqm1DknFD1590XmD/DUJ8= -github.com/armon/go-metrics v0.3.6/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.8 h1:oOxq3KPj0WhCuy50EhzwiyMyG2ovRQZpZLXQuOh2a/M= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/ashanbrown/forbidigo v1.2.0 h1:RMlEFupPCxQ1IogYOQUnIQwGEUGK8g5vAPMRyJoSxbc= +github.com/ashanbrown/forbidigo v1.2.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde h1:YOsoVXsZQPA9aOTy1g0lAJv5VzZUvwQuZqug8XPeqfM= +github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -61,6 +109,10 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= +github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= @@ -84,14 +136,23 @@ 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 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.8 h1:cnZrThioNW9gSV5JsRIXmkyHUbcDH7Y9hkzFDVc9/j0= +github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/confio/ics23/go v0.6.3 h1:PuGK2V1NJWZ8sSkNDq91jgT/cahFEW9RGp4Y5jxulf0= +github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/confio/ics23/go v0.6.3/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= +github.com/confio/ics23/go v0.6.6 h1:pkOy18YxxJ/r0XFDCnrl4Bjv6h4LkBSpLS6F38mrKL8= +github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -100,11 +161,15 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 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= +github.com/cosmos/iavl v0.15.0-rc3.0.20201009144442-230e9bdf52cd/go.mod h1:3xOIaNNX19p0QrX0VqWa6voPRoJRGGYtny+DH8NEPvE= +github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7uMjgxke/I= +github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= @@ -114,20 +179,28 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= +github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= +github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= +github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= +github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= 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/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= @@ -141,7 +214,12 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25 h1:2vLKys4RBU4pn2T/hjXMbvwTr1Cvy5THHrQkbeY9HRk= github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25/go.mod h1:hTr8+TLQmkUkgcuh3mcr5fjrT9c64ZzsBCdCEC6UppY= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68= +github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= @@ -151,6 +229,12 @@ github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+ne github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -160,8 +244,14 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= +github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc= +github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-critic/go-critic v0.5.6 h1:siUR1+322iVikWXoV75I1YRfNaC/yaLzhdF9Zwd8Tus= +github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -171,26 +261,60 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 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/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= +github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 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= @@ -199,36 +323,77 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/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.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.41.1 h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM= +github.com/golangci/golangci-lint v1.41.1/go.mod h1:LPtcY3aAAU8wydHrKpnanx9Og8K/cblZSyGmI5CJZUk= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= @@ -237,16 +402,35 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8= +github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= @@ -260,6 +444,7 @@ github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBt github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -267,6 +452,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxB github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -287,16 +474,32 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= +github.com/jingyugao/rowserrcheck v1.1.0 h1:u6h4eiNuCLqk73Ic5TXQq9yZS+uEXTdusn7c3w1Mr6A= +github.com/jingyugao/rowserrcheck v1.1.0/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -307,17 +510,28 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d h1:XeSMXURZPtUffuWAaq90o6kLgZdgu+QA8wk4MPC8ikI= +github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= +github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -326,6 +540,21 @@ 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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= +github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= +github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= +github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= +github.com/ldez/tagliatelle v0.2.0 h1:693V8Bf1NdShJ8eu/s84QySA0J2VWBanVBa2WwXD/Wk= +github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -339,45 +568,85 @@ github.com/line/ostracon v0.34.9-0.20210610071151-a52812ac9add h1:WVSJIT1mDMMhBt github.com/line/ostracon v0.34.9-0.20210610071151-a52812ac9add/go.mod h1:ttnbq+yQJMQ9a2MT5SEisOoa/+pOgh2KenTiK/rVdiw= github.com/line/tm-db/v2 v2.0.0-init.1.0.20210413083915-5bb60e117524 h1:eKXXnUm1SblC0AIXAMNDaSyvIbQ50yXqFbh9+Q8Kjvg= github.com/line/tm-db/v2 v2.0.0-init.1.0.20210413083915-5bb60e117524/go.mod h1:wmkyPabXjtVZ1dvRofmurjaceghywtCSYGqFuFS+TbI= -github.com/line/wasmvm v0.14.0-0.5.0 h1:FRjzcUh+LiTMvCrSoucL7a5DlWHHRQgZ78h8YB8l4Fs= -github.com/line/wasmvm v0.14.0-0.5.0/go.mod h1:cgsILoCDigfQ2XplFI4rOo2ImOLEZH/OM8sulxGoKUA= +github.com/line/wasmvm v0.14.0-0.6.0-temp h1:negK9BIB/vO/xPHo3grciu9tktsL9t1P8m1IabQjISk= +github.com/line/wasmvm v0.14.0-0.6.0-temp/go.mod h1:cgsILoCDigfQ2XplFI4rOo2ImOLEZH/OM8sulxGoKUA= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= -github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= +github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/revive v1.0.7 h1:5kEWTY/W5a0Eiqnkn2BAWsRZpxbs1ft15PsyNC7Rml8= +github.com/mgechev/revive v1.0.7/go.mod h1:vuE5ox/4L/HDd63MCcCk3H6wTLQ6XXezRphJ8cJJOxY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0= github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= +github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= +github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= +github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -385,8 +654,15 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= +github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= +github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= +github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= 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= @@ -394,18 +670,23 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/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.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54= +github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 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= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= +github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -421,11 +702,14 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 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/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -434,8 +718,11 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea h1:Sk6Xawg57ZkjXmFYD1xCHSKN6FtYM+km51MM7Lveyyc= +github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -444,8 +731,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= +github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -461,17 +749,31 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.23.0 h1:GXWvPYuTUenIa+BhOq/x+L/QZzCqASkVRny5KTlPDGM= +github.com/prometheus/common v0.23.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= +github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= +github.com/quasilyte/go-ruleguard v0.3.4 h1:F6l5p6+7WBcTKS7foNQ4wqA39zjn2+RbdbyzGxIq1B0= +github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA= +github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -484,29 +786,52 @@ github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= -github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.21.0 h1:Q3vdXlfLNT+OftyBHsU0Y445MD+8m8axjKgf2si0QcM= +github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.2 h1:ZJQeYHZ2kaJpojoQBaGqpsn5g7GMcePY36uUGW1umbs= +github.com/ryancurrah/gomodguard v1.2.2/go.mod h1:tpI+C/nzvfUR3bF28b5QHpTn/jM/zlGniI++6ZlIWeE= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.8.0 h1:iHg9cVmHWf5n6/ijUJ4F10h5bKlNtvXmcWzRw0lxiKE= +github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= 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= @@ -518,19 +843,24 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= +github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -538,9 +868,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -549,6 +882,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= @@ -557,39 +892,87 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tm-db v0.6.0 h1:Us30k7H1UDcdqoSPhmP8ztAW/SWV6c6OfsfeCiboTC4= +github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= +github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= +github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= +github.com/tendermint/tendermint v0.34.11 h1:q1Yh76oG4QbS07xhmIJh5iAE0fYpJ8P8YKYtjnWfJRY= +github.com/tendermint/tendermint v0.34.11/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0= github.com/tendermint/tm-db v0.6.0/go.mod h1:xj3AWJ08kBDlCHKijnhJ7mTcDMOikT1r8Poxy2pJn7Q= +github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= +github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8= +github.com/tendermint/tm-db v0.6.4 h1:3N2jlnYQkXNQclQwd/eKV/NzlqPlfK21cpRRIx80XXQ= +github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw= +github.com/tetafro/godot v1.4.7 h1:zBaoSY4JRVVz33y/qnODsdaKj2yAaMr91HCbqHCifVc= +github.com/tetafro/godot v1.4.7/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomarrell/wrapcheck/v2 v2.1.0 h1:LTzwrYlgBUwi9JldazhbJN84fN9nS2UNGrZIo2syqxE= +github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/tommy-muehle/go-mnd/v2 v2.4.0 h1:1t0f8Uiaq+fqKteUR4N9Umr6E99R+lDnLnq7PwX2PPE= +github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= +github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yeya24/promlinter v0.1.0 h1:goWULN0jH5Yajmu/K+v1xCqIREeB+48OiJ2uu2ssc7U= +github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -605,7 +988,10 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -613,6 +999,11 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -622,6 +1013,9 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -630,6 +1024,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -644,32 +1042,54 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -680,6 +1100,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -692,18 +1113,32 @@ golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -711,12 +1146,17 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -727,11 +1167,18 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -740,18 +1187,72 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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= @@ -762,13 +1263,29 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -777,11 +1294,31 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f h1:izedQ6yVIc5mZsRuXzmSreCOlzI0lCU1HpG8yEdMiKw= google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -796,20 +1333,25 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= +gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 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= @@ -820,17 +1362,33 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE= +honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA= +mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 1a1c4924d9..5e0b1d10bb 100755 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -18,12 +18,12 @@ protoc_gen_gocosmos() { protoc_gen_gocosmos -proto_dirs=$(find ./proto ./x/wasm/internal/types -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) +proto_dirs=$(find ./proto ./x/wasm/types -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) for dir in $proto_dirs; do buf protoc \ -I "proto" \ -I "third_party/proto" \ - -I "x/wasm/internal/types" \ + -I "x/wasm/types" \ --gocosmos_out=plugins=interfacetype+grpc,\ Mgoogle/protobuf/any.proto=github.com/line/lfb-sdk/codec/types:. \ --grpc-gateway_out=logtostderr=true:. \ diff --git a/x/wasm/Governance.md b/x/wasm/Governance.md index 5be058497d..39295a0d7b 100644 --- a/x/wasm/Governance.md +++ b/x/wasm/Governance.md @@ -14,22 +14,22 @@ We have added 5 new wasm specific proposal types that cover the contract's live * `UpdateAdminProposal` - set a new admin for a contract * `ClearAdminProposal` - clear admin for a contract to prevent further migrations -For details see the proposal type [implementation](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/types/proposal.go) +For details see the proposal type [implementation](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/proposal.go) A wasm message but no proposal type: * `ExecuteContract` - execute a command on a wasm contract ### Unit tests -[Proposal type validations](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/types/proposal_test.go) +[Proposal type validations](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/proposal_test.go) ## Proposal Handler -The [wasmd proposal_handler](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/keeper/proposal_handler.go) implements the `gov.Handler` function +The [wasmd proposal_handler](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/keeper/proposal_handler.go) implements the `gov.Handler` function and executes the wasmd proposal types after a successful tally. -The proposal handler uses a [`GovAuthorizationPolicy`](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/keeper/authz_policy.go#L29) to bypass the existing contract's authorization policy. +The proposal handler uses a [`GovAuthorizationPolicy`](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/keeper/authz_policy.go#L29) to bypass the existing contract's authorization policy. ### Tests -* [Integration: Submit and execute proposal](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/keeper/proposal_integration_test.go) +* [Integration: Submit and execute proposal](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/keeper/proposal_integration_test.go) ## Gov Integration The wasmd proposal handler can be added to the gov router in the [abci app](https://github.com/CosmWasm/wasmd/blob/master/app/app.go#L306) @@ -44,7 +44,7 @@ Settings via sdk `params` module: - `code_upload_access` - who can upload a wasm binary: `Nobody`, `Everybody`, `OnlyAddress` - `instantiate_default_permission` - platform default, who can instantiate a wasm binary when the code owner has not set it -See [params.go](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/types/params.go) +See [params.go](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/params.go) ### Init Params Via Genesis @@ -69,9 +69,9 @@ As gov proposals bypass the existing authorzation policy they are diabled and re ``` ### Tests -* [params validation unit tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/types/params_test.go) -* [genesis validation tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/types/genesis_test.go) -* [policy integration tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/internal/keeper/keeper_test.go) +* [params validation unit tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/params_test.go) +* [genesis validation tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/genesis_test.go) +* [policy integration tests](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/keeper/keeper_test.go) ## CLI diff --git a/x/wasm/IBC.md b/x/wasm/IBC.md index d5f1b8144b..c3cd0a0023 100644 --- a/x/wasm/IBC.md +++ b/x/wasm/IBC.md @@ -27,9 +27,9 @@ as how contracts can properly identify their counterparty. (We considered on port for the `x/wasm` module and multiplexing on it, but [dismissed that idea](#rejected-ideas)) * Upon `Instantiate`, if a contract is *IBC Enabled*, we dynamically - bind a port for this contract. The port name is `wasm-`, - eg. `wasm-cosmos1hmdudppzceg27qsuq707tjg8rkgj7g5hnvnw29` -* If a *Channel* is being established with a registered `wasm-xyz` port, + bind a port for this contract. The port name is `wasm.`, + eg. `wasm.cosmos1hmdudppzceg27qsuq707tjg8rkgj7g5hnvnw29` +* If a *Channel* is being established with a registered `wasm.xyz` port, the `x/wasm.Keeper` will handle this and call into the appropriate contract to determine supported protocol versions during the [`ChanOpenTry` and `ChanOpenAck` phases](https://docs.cosmos.network/master/ibc/overview.html#channels). @@ -42,7 +42,7 @@ as how contracts can properly identify their counterparty. * When sending a packet, the CosmWasm contract must specify the local *ChannelID*. As there is a unique *PortID* per contract, that is filled in by `x/wasm` to produce the globally unique `(PortID, ChannelID)` -* When receiving a Packet (or Ack or Timeout), the contracts receives the +* When receiving a Packet (or Ack or Timeout), the contracts receives the local *ChannelID* it came from, as well as the packet that was sent by the counterparty. * When receiving an Ack or Timeout packet, the contract also receives the original packet that it sent earlier. @@ -54,320 +54,17 @@ as how contracts can properly identify their counterparty. Establishing *Clients* and *Connections* is out of the scope of this module and must be created by the same means as for `ibc-transfer` -(via the cli or otherwise). `x/wasm` will bind a unique *Port* for each -"IBC Enabled" contract. +(via the [go cli](https://github.com/cosmos/relayer) or better [ts-relayer](https://github.com/confio/ts-relayer)). +`x/wasm` will bind a unique *Port* for each "IBC Enabled" contract. For mocks, all the Packet Handling and Channel Lifecycle Hooks are routed to some Golang stub handler, but containing the contract address, so we -can perform contract-specific actions for each packet. +can perform contract-specific actions for each packet. In a real setting, +we route to the contract that owns the port/channel and call one of it's various +entry points. -### Messages - -An "IBC Enabled" contract may dispatch the following messages not available -to other contracts: - -* `IBCSendMsg` - this sends an IBC packet over an established channel. -* `IBCCloseChannel` - given an existing channelID bound to this contract's Port, - initiate the closing sequence and reject all pending packets. - -They are returned from `handle` just like any other `CosmosMsg` -(For mocks, we will trigger this externally, later only valid contract addresses -should be able to do so). - -### Packet Handling - -An "IBC Enabled" contract must support the following callbacks from the runtime -(we will likely multiplex many over one wasm export, as we do with handle, but these -are the different calls we must support): - -* `IBCRecvPacket` - when another chain sends a packet destined to - an IBCEnabled contract, this will be routed to the proper contract - and call a function exposed for this purpose. -* `IBCPacketAck` - The original sender of `IBCSendMsg` will - get this callback eventually if the message was - processed on the other chain (this may be either a success or an error, - but comes from the app-level protocol, not the IBC protocol). -* `IBCPacketTimeout` - The original sender of `IBCSendMsg` will - get this callback eventually if the message failed to be - processed on the other chain (for timeout, closed channel, or - other IBC-level failure) - -Note: We may add some helpers inside the contract to map `IBCPacketAck` / `IBCPacketTimeout` -to `IBCPacketSucceeded` / `IBCPacketFailed` assuming they use the standard envelope. However, -we decided not to enforce this on the Go-level, to allow contracts to communicate using protocols -that do not use this envelope. - -### Channel Lifecycle Hooks - -If you look at the [4 step process](https://docs.cosmos.network/master/ibc/overview.html#channels) for -channel handshakes, we simplify this from the view of the contract: - -1. The main path to initiate a channel from a contract to an external port is via an external - client executing `simd tx ibc channel open-init` or such. This allows the initiating party - to select which version/protocol they want to connect with. There must be a callback for - the initiating contract to verify if the version and/or ordering are valid. - **Question**: can we reuse the same check-logic as for step 2 -2. The counterparty has a chance for version negotiation in `OnChanOpenTry`, where the contract - can apply custom logic. It provides the protocol versions that the initiating party expects, and - the contract can reject the connection or accept it and return the protocol version it will communicate with. - Implementing this (contract selects a version, not just the relayer) requires that we support - [ADR 025](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-025-ibc-passive-channels.md). - TODO: check with Agoric and cwgoes to upstream any Cosmos SDK changes so this can work out of the box. -3. `OnChanOpened` is called on the contract for both `OnChanOpenAck` and `OnChanOpenConfirm` containing - the final version string (counterparty version). This gives a chance to abort the process - if we realize this doesn't work. Or save the info (we may need to define this channel uses an older version - of the protocol for example). -4. `OnChanClosed` is called on both sides if the channel is closed for any reason, allowing them to - perform any cleanup. This will be followed by `IBCPacketTimeout` callbacks for all the in-progress - packets that were not processed before it closed, as well as all pending acks (pending the relayer - to provide that). - -We require the following callbacks on the contract - -* `OnChanNegotiate` - called on the initiating side on `OnChanOpenInit` and on receiving end for `OnChanOpenTry`. - @alpe: does it make sense to use the same shape for both of these? Rather than `CounterPartyVersion`, they would - have `ProposedVersion`, but otherwise the same logic. -* `OnChanOpened` - called on both sides after the initial 2 steps have passed to confirm the version used -* `OnChanClosed` - this is called when an existing channel is closed for any reason - -### Queries - -We may want to expose some basic queries of IBC State to the contract. -We should check if this is useful to the contract and if it opens up -any possible DoS: - -* `GetPortID` - return PortID given a contract address -* `ListChannels` - return a list of all (portID, channelID) pairs - that are bound to a given port. -* `ListPendingPackets` - given a (portID, channelID) identifier, return all packets - in that channel, that have been sent by this chain, but for which no acknowledgement - or timeout has yet been received -* `ListPendingAcknowledgements` - given a (portID, channelID) identifier, return all packets - in that channel, that have been received and processed by this chain, but for which - we have no proof the acknowledgement has been relayed -* `GetCounterparty` - given a local (portID, channelID) identifier, it will look up - what (portID, channelID) are bound to the remote end of the channel. - -## Contract Details - -Here we map out the workflow with the exact arguments passed with those calls -from the Go side (which we will use with our mock), and then a -proposal for multiplexing this over fewer wasm exports (define some rust types) - -Messages: - -```go -package messages - -type IBCSendMsg struct { - // This is our contract-local ID - ChannelID string - Msg []byte - // optional fields (or do we need exactly/at least one of these?) - TimeoutHeight uint64 - TimeoutTimestamp uint64 -} - -type IBCCloseChannel struct { - ChannelID string -} - -// "Versions must be strings but and implement any versioning structure..." -// https://docs.cosmos.network/master/ibc/custom.html#channel-handshake-version-negotiation -// Use the same approach here -type Version string -``` - -Packet callbacks: - -```go -package packets - -// for reference: this is more like what we pass to wasmvm -// func (c *mockContract) OnReceive(params cosmwasm2.Env, msg []byte, store prefix.Store, api cosmwasm.GoAPI, -// querier keeper.QueryHandler, meter sdk.GasMeter, gas uint64) (*cosmwasm2.OnReceiveIBCResponse, uint64, error) {} -// below is how we want to expose it in x/wasm: - -// IBCRecvPacket is called when we receive a packet sent from the other end of a channel -// The response bytes listed here will be returned to the caller as "result" in IBCPacketAck -// What do we do with error? -// -// If we were to assume/enforce an envelope, then we could wrap response/error into the acknowledge packet, -// but we delegated that encoding to the contract -func IBCRecvPacket(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, env IBCPacketInfo, msg []byte) - (response []byte, err error) {} - -// how to handle error here? if we push it up the ibc stack and fail the transaction (normal handling), -// the packet may be posted again and again. just log and ignore failures here? what does a failure even mean? -// only realistic one I can imagine is OutOfGas (panic) to retry with higher gas limit. -// -// if there any point in returning a response, what does it mean? -func IBCPacketAck(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, env IBCPacketInfo, - originalMsg []byte, result []byte) error {} - -// same question as for IBCPacketAck -func IBCPacketDropped(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, env IBCPacketInfo, - originalMsg []byte, errorMsg string) error {} - -// do we need/want all this info? -type IBCPacketInfo struct { - // local id for the Channel packet was sent/received on - ChannelID string - - // sequence for the packet (will already be enforced in order if ORDERED channel) - Sequence uint64 - - // Note: Timeout if guaranteed ONLY to be exceeded iff we are processing IBCPacketDropped - // otherwise, this is just interesting metadata - - // block height after which the packet times out - TimeoutHeight uint64 - // block timestamp (in nanoseconds) after which the packet times out - TimeoutTimestamp uint64 -} -``` - -Channel Lifecycle: - -```go -package lifecycle - -// if this returns error, we reject the channel opening -// otherwise response has the versions we accept -// -// It is provided the full ChannelInfo being proposed to do any needed checks -func OnChanNegotiate(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, request ChannelInfo) - (version Version, err error) {} - -// This is called with the full ChannelInfo once the other side has agreed. -// An error here will still abort the handshake process. (so you can double check the order/version here) -// -// The main purpose is to allow the contract to set up any internal state knowing the channel was established, -// and keep a registry with that ChannelID -func OnChanOpened(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, request ChannelInfo) error {} - -// This is called when the channel is closed for any reason -// TODO: any meaning to return an error here? we cannot abort closing a channel -func OnChanClosed(ctx sdk.Context, k *wasm.Keeper, contractAddress sdk.AccAddress, request ChannelClosedInfo) error {} - -type ChannelInfo struct { - // key info to enforce (error if not what is expected) - Order channeltypes.Order - // The proposed version. This may come from the relayer, from the initiating contract, or the responding contract. - // In any case, this is the currently agreed upon version to use and if there is disagreement, the contract should - // propose another one (if possible in return value), or return an error - ProposedVersion Version - // local id for the Channel that is being initiated - ChannelID string - // these two are taken from channeltypes.Counterparty - RemotePortID string - RemoteChannelID string -} - -type ChannelClosedInfo struct { - // local id for the Channel that is being shut down - ChannelID string -} -``` - -Queries: - -These are callbacks that the contract can make, calling into a QueryPlugin. -The general type definition for a `QueryPlugin` is -`func(ctx sdk.Context, request *wasmTypes.IBCQuery) ([]byte, error)`. -All other info (like the contract address we are querying for) must be passed in -from the contract (which knows it's own address). - -Here we just defined the request and response types (which will be serialized into `[]byte`) - -```go -package queries - -type QueryPort struct { - ContractAddress string -} - -type QueryPortResponse struct { - PortID string -} - -type QueryChannels struct { - // exactly one of these must be set. ContractAddress is a shortcut to save the Contract->PortID mapping - PortID string - ContractAddress string -} - -type QueryChannelsResponse struct { - ChannelIDs []ChannelMetadata -} - -type ChannelMetadata struct { - // Local portID, channelID is our unique identifier - PortID string - ChannelID string - RemotePortID string - Order channeltypes.Order - Verson Version -} - -type QueryPendingPackets struct { - // Always required - ChannelID string - - // exactly one of these must be set. ContractAddress is a shortcut to save the Contract->PortID mapping - PortID string - ContractAddress string -} - -type QueryPendingPacketsResponse struct { - Packets []PacketMetadata -} - -type PacketMetadata struct { - // The original (serialized) message we sent - Msg []byte - - Sequence uint64 - // block height after which the packet times out - TimeoutHeight uint64 - // block timestamp (in nanoseconds) after which the packet times out - TimeoutTimestamp uint64 -} - -type QueryPendingAcknowlegdements struct { - // Always required - ChannelID string - - // exactly one of these must be set. ContractAddress is a shortcut to save the Contract->PortID mapping - PortID string - ContractAddress string -} - -type QueryPendingPacketsResponse struct { - // Do we need another struct for the metadata? - Packets []PacketMetadata -} - - -type QueryCounterparty struct { - // Always required - ChannelID string - - // exactly one of these must be set. ContractAddress is a shortcut to save the Contract->PortID mapping - PortID string - ContractAddress string -} - -// lists (port, channel) on the counterparty for our local channel -type QueryCounterpartyResponse struct { - PortID string - ChannelID string -} -``` - -### Contract (Wasm) entrypoints - -**TODO** +Please refer to the CosmWasm repo for all +[details on the IBC API from the point of view of a CosmWasm contract](https://github.com/CosmWasm/cosmwasm/blob/main/IBC.md). ## Future Ideas diff --git a/x/wasm/alias.go b/x/wasm/alias.go index aed821df76..e643f73223 100644 --- a/x/wasm/alias.go +++ b/x/wasm/alias.go @@ -1,13 +1,13 @@ // nolint // autogenerated code using github.com/rigelrozanski/multitool // aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmwasm/wasmd/x/wasm/internal/types -// ALIASGEN: github.com/cosmwasm/wasmd/x/wasm/internal/keeper +// ALIASGEN: github.com/Cosmwasm/wasmd/x/wasm/types +// ALIASGEN: github.com/CosmWasm/wasmd/x/wasm/keeper package wasm import ( - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" + "github.com/line/lfb-sdk/x/wasm/types" ) const ( @@ -73,7 +73,7 @@ var ( CreateTestInput = keeper.CreateTestInput TestHandler = keeper.TestHandler NewWasmProposalHandler = keeper.NewWasmProposalHandler - NewQuerier = keeper.NewQuerier + NewQuerier = keeper.Querier ContractFromPortID = keeper.ContractFromPortID WithWasmEngine = keeper.WithWasmEngine @@ -126,7 +126,7 @@ type ( Config = types.WasmConfig ContractInfoWithAddress = types.ContractInfoWithAddress CodeInfoResponse = types.CodeInfoResponse - MessageHandler = keeper.DefaultMessageHandler + MessageHandler = keeper.SDKMessageHandler BankEncoder = keeper.BankEncoder CustomEncoder = keeper.CustomEncoder StakingEncoder = keeper.StakingEncoder diff --git a/x/wasm/client/cli/genesis_msg.go b/x/wasm/client/cli/genesis_msg.go index 7c2d6a33f4..6a728431bd 100644 --- a/x/wasm/client/cli/genesis_msg.go +++ b/x/wasm/client/cli/genesis_msg.go @@ -18,15 +18,30 @@ import ( banktypes "github.com/line/lfb-sdk/x/bank/types" "github.com/line/lfb-sdk/x/genutil" genutiltypes "github.com/line/lfb-sdk/x/genutil/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/crypto" osttypes "github.com/line/ostracon/types" "github.com/spf13/cobra" ) +// GenesisReader reads genesis data. Extension point for custom genesis state readers. +type GenesisReader interface { + ReadWasmGenesis(cmd *cobra.Command) (*GenesisData, error) +} + +// GenesisMutator extension point to modify the wasm module genesis state. +// This gives flexibility to customize the data structure in the genesis file a bit. +type GenesisMutator interface { + // AlterWasmModuleState loads the genesis from the default or set home dir, + // unmarshalls the wasm module section into the object representation + // calls the callback function to modify it + // and marshals the modified state back into the genesis file + AlterWasmModuleState(cmd *cobra.Command, callback func(state *types.GenesisState, appState map[string]json.RawMessage) error) error +} + // GenesisStoreCodeCmd cli command to add a `MsgStoreCode` to the wasm section of the genesis // that is executed on block 0. -func GenesisStoreCodeCmd(defaultNodeHome string) *cobra.Command { +func GenesisStoreCodeCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { cmd := &cobra.Command{ Use: "store [wasm file] --source [source] --builder [builder] --run-as [owner_address_or_key_name]\",", Short: "Upload a wasm binary", @@ -45,7 +60,7 @@ func GenesisStoreCodeCmd(defaultNodeHome string) *cobra.Command { return err } - return alterModuleState(cmd, func(state *types.GenesisState, _ map[string]json.RawMessage) error { + return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, _ map[string]json.RawMessage) error { state.GenMsgs = append(state.GenMsgs, types.GenesisState_GenMsgs{ Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: &msg}, }) @@ -67,7 +82,7 @@ func GenesisStoreCodeCmd(defaultNodeHome string) *cobra.Command { // GenesisInstantiateContractCmd cli command to add a `MsgInstantiateContract` to the wasm section of the genesis // that is executed on block 0. -func GenesisInstantiateContractCmd(defaultNodeHome string) *cobra.Command { +func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { cmd := &cobra.Command{ Use: "instantiate-contract [code_id_int64] [json_encoded_init_args] --label [text] --run-as [address] --admin [address,optional] --amount [coins,optional]", Short: "Instantiate a wasm contract", @@ -86,7 +101,7 @@ func GenesisInstantiateContractCmd(defaultNodeHome string) *cobra.Command { return err } - return alterModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { + return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { // simple sanity check that sender has some balance although it may be consumed by appState previous message already switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); { case err != nil: @@ -132,9 +147,9 @@ func GenesisInstantiateContractCmd(defaultNodeHome string) *cobra.Command { return cmd } -// GenesisInstantiateContractCmd cli command to add a `MsgExecuteContract` to the wasm section of the genesis +// GenesisExecuteContractCmd cli command to add a `MsgExecuteContract` to the wasm section of the genesis // that is executed on block 0. -func GenesisExecuteContractCmd(defaultNodeHome string) *cobra.Command { +func GenesisExecuteContractCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { cmd := &cobra.Command{ Use: "execute [contract_addr_bech32] [json_encoded_send_args] --run-as [address] --amount [coins,optional]", Short: "Execute a command on a wasm contract", @@ -153,7 +168,7 @@ func GenesisExecuteContractCmd(defaultNodeHome string) *cobra.Command { return err } - return alterModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { + return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { // simple sanity check that sender has some balance although it may be consumed by appState previous message already switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); { case err != nil: @@ -184,17 +199,17 @@ func GenesisExecuteContractCmd(defaultNodeHome string) *cobra.Command { // GenesisListCodesCmd cli command to list all codes stored in the genesis wasm.code section // as well as from messages that are queued in the wasm.genMsgs section. -func GenesisListCodesCmd(defaultNodeHome string) *cobra.Command { +func GenesisListCodesCmd(defaultNodeHome string, genReader GenesisReader) *cobra.Command { cmd := &cobra.Command{ Use: "list-codes ", Short: "Lists all codes from genesis code dump and queued messages", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - g, err := readGenesis(cmd) + g, err := genReader.ReadWasmGenesis(cmd) if err != nil { return err } - all, err := getAllCodes(g.wasmModuleState) + all, err := getAllCodes(g.WasmModuleState) if err != nil { return err } @@ -209,17 +224,17 @@ func GenesisListCodesCmd(defaultNodeHome string) *cobra.Command { // GenesisListContractsCmd cli command to list all contracts stored in the genesis wasm.contract section // as well as from messages that are queued in the wasm.genMsgs section. -func GenesisListContractsCmd(defaultNodeHome string) *cobra.Command { +func GenesisListContractsCmd(defaultNodeHome string, genReader GenesisReader) *cobra.Command { cmd := &cobra.Command{ Use: "list-contracts ", Short: "Lists all contracts from genesis contract dump and queued messages", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - g, err := readGenesis(cmd) + g, err := genReader.ReadWasmGenesis(cmd) if err != nil { return err } - state := g.wasmModuleState + state := g.WasmModuleState all := getAllContracts(state) return printJSONOutput(cmd, all) }, @@ -352,15 +367,21 @@ func hasContract(state *types.GenesisState, contractAddr string) bool { return false } -// genesisData contains raw and unmarshalled data from the genesis file -type genesisData struct { - genesisFile string - genDoc *osttypes.GenesisDoc - appState map[string]json.RawMessage - wasmModuleState *types.GenesisState +// GenesisData contains raw and unmarshalled data from the genesis file +type GenesisData struct { + GenesisFile string + GenDoc *osttypes.GenesisDoc + AppState map[string]json.RawMessage + WasmModuleState *types.GenesisState +} + +func NewGenesisData(genesisFile string, genDoc *osttypes.GenesisDoc, appState map[string]json.RawMessage, wasmModuleState *types.GenesisState) *GenesisData { + return &GenesisData{GenesisFile: genesisFile, GenDoc: genDoc, AppState: appState, WasmModuleState: wasmModuleState} } -func readGenesis(cmd *cobra.Command) (*genesisData, error) { +type DefaultGenesisReader struct{} + +func (d DefaultGenesisReader) ReadWasmGenesis(cmd *cobra.Command) (*GenesisData, error) { clientCtx := client.GetClientContextFromCmd(cmd) serverCtx := server.GetServerContextFromCmd(cmd) config := serverCtx.Config @@ -377,44 +398,58 @@ func readGenesis(cmd *cobra.Command) (*genesisData, error) { clientCtx.JSONMarshaler.MustUnmarshalJSON(appState[types.ModuleName], &wasmGenesisState) } - return &genesisData{ - genesisFile: genFile, - genDoc: genDoc, - appState: appState, - wasmModuleState: &wasmGenesisState, - }, nil + return NewGenesisData( + genFile, + genDoc, + appState, + &wasmGenesisState, + ), nil +} + +var _ GenesisReader = DefaultGenesisIO{} +var _ GenesisMutator = DefaultGenesisIO{} + +// DefaultGenesisIO implements both interfaces to read and modify the genesis state for this module. +// This implementation uses the default data structure that is used by the module.go genesis import/ export. +type DefaultGenesisIO struct { + DefaultGenesisReader +} + +// NewDefaultGenesisIO constructor to create a new instance +func NewDefaultGenesisIO() *DefaultGenesisIO { + return &DefaultGenesisIO{DefaultGenesisReader: DefaultGenesisReader{}} } -// alterModuleState loads the genesis from the default or set home dir, +// AlterWasmModuleState loads the genesis from the default or set home dir, // unmarshalls the wasm module section into the object representation // calls the callback function to modify it // and marshals the modified state back into the genesis file -func alterModuleState(cmd *cobra.Command, callback func(state *types.GenesisState, appState map[string]json.RawMessage) error) error { - g, err := readGenesis(cmd) +func (x DefaultGenesisIO) AlterWasmModuleState(cmd *cobra.Command, callback func(state *types.GenesisState, appState map[string]json.RawMessage) error) error { + g, err := x.ReadWasmGenesis(cmd) if err != nil { return err } - if err := callback(g.wasmModuleState, g.appState); err != nil { + if err := callback(g.WasmModuleState, g.AppState); err != nil { return err } // and store update - if err := g.wasmModuleState.ValidateBasic(); err != nil { + if err := g.WasmModuleState.ValidateBasic(); err != nil { return err } clientCtx := client.GetClientContextFromCmd(cmd) - wasmGenStateBz, err := clientCtx.JSONMarshaler.MarshalJSON(g.wasmModuleState) + wasmGenStateBz, err := clientCtx.JSONMarshaler.MarshalJSON(g.WasmModuleState) if err != nil { return sdkerrors.Wrap(err, "marshal wasm genesis state") } - g.appState[types.ModuleName] = wasmGenStateBz - appStateJSON, err := json.Marshal(g.appState) + g.AppState[types.ModuleName] = wasmGenStateBz + appStateJSON, err := json.Marshal(g.AppState) if err != nil { return sdkerrors.Wrap(err, "marshal application genesis state") } - g.genDoc.AppState = appStateJSON - return genutil.ExportGenesisFile(g.genDoc, g.genesisFile) + g.GenDoc.AppState = appStateJSON + return genutil.ExportGenesisFile(g.GenDoc, g.GenesisFile) } // contractSeqValue reads the contract sequence from the genesis or diff --git a/x/wasm/client/cli/genesis_msg_test.go b/x/wasm/client/cli/genesis_msg_test.go index 295f4d4dee..58284b4a20 100644 --- a/x/wasm/client/cli/genesis_msg_test.go +++ b/x/wasm/client/cli/genesis_msg_test.go @@ -20,8 +20,8 @@ import ( genutiltest "github.com/line/lfb-sdk/x/genutil/client/testutil" genutiltypes "github.com/line/lfb-sdk/x/genutil/types" stakingtypes "github.com/line/lfb-sdk/x/staking/types" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/libs/log" osttypes "github.com/line/ostracon/types" "github.com/spf13/cobra" @@ -101,7 +101,7 @@ func TestGenesisStoreCodeCmd(t *testing.T) { homeDir := setupGenesis(t, spec.srcGenesis) // when - cmd := GenesisStoreCodeCmd(homeDir) + cmd := GenesisStoreCodeCmd(homeDir, NewDefaultGenesisIO()) spec.mutator(cmd) err := executeCmdWithContext(t, homeDir, cmd) if spec.expError { @@ -299,7 +299,7 @@ func TestInstantiateContractCmd(t *testing.T) { homeDir := setupGenesis(t, spec.srcGenesis) // when - cmd := GenesisInstantiateContractCmd(homeDir) + cmd := GenesisInstantiateContractCmd(homeDir, NewDefaultGenesisIO()) spec.mutator(cmd) err := executeCmdWithContext(t, homeDir, cmd) if spec.expError { @@ -498,7 +498,7 @@ func TestExecuteContractCmd(t *testing.T) { for msg, spec := range specs { t.Run(msg, func(t *testing.T) { homeDir := setupGenesis(t, spec.srcGenesis) - cmd := GenesisExecuteContractCmd(homeDir) + cmd := GenesisExecuteContractCmd(homeDir, NewDefaultGenesisIO()) spec.mutator(cmd) // when diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 38119289bb..8bb5c9629b 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -8,7 +8,7 @@ import ( sdk "github.com/line/lfb-sdk/types" "github.com/line/lfb-sdk/x/gov/client/cli" govtypes "github.com/line/lfb-sdk/x/gov/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/pkg/errors" "github.com/spf13/cobra" ) diff --git a/x/wasm/client/cli/new_tx.go b/x/wasm/client/cli/new_tx.go index bb4e34cd82..b3c0ca159b 100644 --- a/x/wasm/client/cli/new_tx.go +++ b/x/wasm/client/cli/new_tx.go @@ -7,7 +7,7 @@ import ( "github.com/line/lfb-sdk/client/flags" "github.com/line/lfb-sdk/client/tx" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/spf13/cobra" ) diff --git a/x/wasm/client/cli/query.go b/x/wasm/client/cli/query.go index e8c6f218d1..05d3e97798 100644 --- a/x/wasm/client/cli/query.go +++ b/x/wasm/client/cli/query.go @@ -10,12 +10,10 @@ import ( "io/ioutil" "strconv" - "github.com/gogo/protobuf/proto" "github.com/line/lfb-sdk/client" "github.com/line/lfb-sdk/client/flags" - codectypes "github.com/line/lfb-sdk/codec/types" sdk "github.com/line/lfb-sdk/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/spf13/cobra" flag "github.com/spf13/pflag" ) @@ -66,7 +64,7 @@ func GetCmdListCode() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } flags.AddQueryFlagsToCmd(cmd) @@ -107,7 +105,7 @@ func GetCmdListContractByCode() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } flags.AddQueryFlagsToCmd(cmd) @@ -183,7 +181,7 @@ func GetCmdGetContractInfo() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } flags.AddQueryFlagsToCmd(cmd) @@ -240,7 +238,7 @@ func GetCmdGetContractStateAll() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } flags.AddQueryFlagsToCmd(cmd) @@ -281,7 +279,7 @@ func GetCmdGetContractStateRaw() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } decoder.RegisterFlags(cmd.PersistentFlags(), "key argument") @@ -329,7 +327,7 @@ func GetCmdGetContractStateSmart() *cobra.Command { if err != nil { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } decoder.RegisterFlags(cmd.PersistentFlags(), "query argument") @@ -371,7 +369,7 @@ func GetCmdGetContractHistory() *cobra.Command { return err } - return clientCtx.WithJSONMarshaler(&VanillaStdJSONMarshaller{}).PrintProto(res) + return clientCtx.PrintProto(res) }, } @@ -423,41 +421,6 @@ func asciiDecodeString(s string) ([]byte, error) { return []byte(s), nil } -type VanillaStdJSONMarshaller struct { -} - -func (x VanillaStdJSONMarshaller) MarshalInterfaceJSON(i proto.Message) ([]byte, error) { - any, err := codectypes.NewAnyWithValue(i) - if err != nil { - return nil, err - } - return x.MarshalJSON(any) -} - -func (x VanillaStdJSONMarshaller) MarshalJSON(o proto.Message) ([]byte, error) { - return json.MarshalIndent(o, "", " ") -} - -func (x VanillaStdJSONMarshaller) MustMarshalJSON(o proto.Message) []byte { - b, err := x.MarshalJSON(o) - if err != nil { - panic(err) - } - return b -} - -func (x VanillaStdJSONMarshaller) UnmarshalInterfaceJSON(bz []byte, ptr interface{}) error { - panic("not supported") -} - -func (x VanillaStdJSONMarshaller) UnmarshalJSON(bz []byte, ptr proto.Message) error { - panic("not supported") -} - -func (x VanillaStdJSONMarshaller) MustUnmarshalJSON(bz []byte, ptr proto.Message) { - panic("not supported") -} - // sdk ReadPageRequest expects binary but we encoded to base64 in our marshaller func withPageKeyDecoded(flagSet *flag.FlagSet) *flag.FlagSet { encoded, err := flagSet.GetString(flags.FlagPageKey) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index dec1bf84ee..a2f11b8790 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -12,7 +12,7 @@ import ( sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" wasmUtils "github.com/line/lfb-sdk/x/wasm/client/utils" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/spf13/cobra" flag "github.com/spf13/pflag" ) diff --git a/x/wasm/client/codec/marshaller.go b/x/wasm/client/codec/marshaller.go new file mode 100644 index 0000000000..df8a017e13 --- /dev/null +++ b/x/wasm/client/codec/marshaller.go @@ -0,0 +1,79 @@ +package codec + +import ( + "bytes" + "fmt" + + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/proto" + "github.com/line/lfb-sdk/codec" + "github.com/line/lfb-sdk/codec/types" +) + +var _ codec.Marshaler = (*ProtoCodec)(nil) + +// ProtoCodec that omits empty values. +// This Marshaler can be used globally when setting up the client context or individually +// for each command via `clientCtx.WithJSONMarshaler(myMarshaler)`. +type ProtoCodec struct { + codec.Marshaler + interfaceRegistry types.InterfaceRegistry +} + +func NewProtoCodec(marshaler codec.Marshaler, registry types.InterfaceRegistry) *ProtoCodec { + return &ProtoCodec{Marshaler: marshaler, interfaceRegistry: registry} +} + +// MarshalJSON implements JSONMarshaler.MarshalJSON method, +// it marshals to JSON using proto codec. +func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) { + m, ok := o.(codec.ProtoMarshaler) + if !ok { + return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o) + } + return ProtoMarshalJSON(m, pc.interfaceRegistry) +} + +// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method, +// it executes MarshalJSON except it panics upon failure. +func (pc *ProtoCodec) MustMarshalJSON(o proto.Message) []byte { + bz, err := pc.MarshalJSON(o) + if err != nil { + panic(err) + } + return bz +} + +// MarshalInterfaceJSON is a convenience function for proto marshalling interfaces. It +// packs the provided value in an Any and then marshals it to bytes. +// NOTE: to marshal a concrete type, you should use MarshalJSON instead +func (pc *ProtoCodec) MarshalInterfaceJSON(x proto.Message) ([]byte, error) { + any, err := types.NewAnyWithValue(x) + if err != nil { + return nil, err + } + return pc.MarshalJSON(any) +} + +// ProtoMarshalJSON provides an auxiliary function to return Proto3 JSON encoded +// bytes of a message. +func ProtoMarshalJSON(msg proto.Message, resolver jsonpb.AnyResolver) ([]byte, error) { + // method copied from sdk codec/json.go with EmitDefaults set to `false` + // so that empty fields are not rendered + + // We use the OrigName because camel casing fields just doesn't make sense. + // EmitDefaults is also often the more expected behavior for CLI users + jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: false, AnyResolver: resolver} + err := types.UnpackInterfaces(msg, types.ProtoJSONPacker{JSONPBMarshaler: jm}) + if err != nil { + return nil, err + } + + buf := new(bytes.Buffer) + + if err := jm.Marshal(buf, msg); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} diff --git a/x/wasm/client/proposal_handler_test.go b/x/wasm/client/proposal_handler_test.go index f5580fdcde..f556662964 100644 --- a/x/wasm/client/proposal_handler_test.go +++ b/x/wasm/client/proposal_handler_test.go @@ -13,7 +13,7 @@ import ( "github.com/line/lfb-sdk/client" "github.com/line/lfb-sdk/client/flags" authtypes "github.com/line/lfb-sdk/x/auth/types" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" + "github.com/line/lfb-sdk/x/wasm/keeper" "github.com/stretchr/testify/require" ) diff --git a/x/wasm/client/rest/gov.go b/x/wasm/client/rest/gov.go index 5e5356f129..90c97eab80 100644 --- a/x/wasm/client/rest/gov.go +++ b/x/wasm/client/rest/gov.go @@ -10,7 +10,7 @@ import ( "github.com/line/lfb-sdk/types/rest" govrest "github.com/line/lfb-sdk/x/gov/client/rest" govtypes "github.com/line/lfb-sdk/x/gov/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) type StoreCodeProposalJSONReq struct { diff --git a/x/wasm/client/rest/new_tx.go b/x/wasm/client/rest/new_tx.go index 13ef680d8f..c45cdcc0df 100644 --- a/x/wasm/client/rest/new_tx.go +++ b/x/wasm/client/rest/new_tx.go @@ -7,7 +7,7 @@ import ( "github.com/line/lfb-sdk/client" "github.com/line/lfb-sdk/client/tx" "github.com/line/lfb-sdk/types/rest" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) func registerNewTxRoutes(cliCtx client.Context, r *mux.Router) { diff --git a/x/wasm/client/rest/query.go b/x/wasm/client/rest/query.go index 9798204c7f..1f324f6697 100644 --- a/x/wasm/client/rest/query.go +++ b/x/wasm/client/rest/query.go @@ -13,8 +13,8 @@ import ( "github.com/line/lfb-sdk/client" sdk "github.com/line/lfb-sdk/types" "github.com/line/lfb-sdk/types/rest" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" + "github.com/line/lfb-sdk/x/wasm/types" ) func registerQueryRoutes(cliCtx client.Context, r *mux.Router) { diff --git a/x/wasm/client/rest/tx.go b/x/wasm/client/rest/tx.go index e6f71cea96..b43fcb8026 100644 --- a/x/wasm/client/rest/tx.go +++ b/x/wasm/client/rest/tx.go @@ -10,7 +10,7 @@ import ( sdk "github.com/line/lfb-sdk/types" "github.com/line/lfb-sdk/types/rest" wasmUtils "github.com/line/lfb-sdk/x/wasm/client/utils" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) func registerTxRoutes(cliCtx client.Context, r *mux.Router) { diff --git a/x/wasm/client/utils/utils_test.go b/x/wasm/client/utils/utils_test.go index b6075d1b27..87a859911e 100644 --- a/x/wasm/client/utils/utils_test.go +++ b/x/wasm/client/utils/utils_test.go @@ -7,7 +7,7 @@ import ( ) func GetTestData() ([]byte, []byte, []byte, error) { - wasmCode, err := ioutil.ReadFile("../../internal/keeper/testdata/hackatom.wasm") + wasmCode, err := ioutil.ReadFile("../../keeper/testdata/hackatom.wasm") if err != nil { return nil, nil, nil, err diff --git a/x/wasm/genesis_test.go b/x/wasm/genesis_test.go index f81adce674..abf87cd229 100644 --- a/x/wasm/genesis_test.go +++ b/x/wasm/genesis_test.go @@ -68,9 +68,9 @@ func TestInitGenesis(t *testing.T) { assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}) assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator) assertContractState(t, q, data.ctx, contractBech32Addr, state{ - Verifier: []byte(fred), - Beneficiary: []byte(bob), - Funder: []byte(creator), + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), }) // export into genstate @@ -90,8 +90,8 @@ func TestInitGenesis(t *testing.T) { assertContractList(t, q2, newData.ctx, 1, []string{contractBech32Addr}) assertContractInfo(t, q2, newData.ctx, contractBech32Addr, 1, creator) assertContractState(t, q2, newData.ctx, contractBech32Addr, state{ - Verifier: []byte(fred), - Beneficiary: []byte(bob), - Funder: []byte(creator), + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), }) } diff --git a/x/wasm/handler.go b/x/wasm/handler.go index 86428c3eb2..48c2c9041e 100644 --- a/x/wasm/handler.go +++ b/x/wasm/handler.go @@ -2,18 +2,17 @@ package wasm import ( "fmt" - "github.com/gogo/protobuf/proto" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" ) -// NewHandler returns a handler for "bank" type messages. -func NewHandler(k *Keeper) sdk.Handler { +// NewHandler returns a handler for "wasm" type messages. +func NewHandler(k types.ContractOpsKeeper) sdk.Handler { msgServer := keeper.NewMsgServerImpl(k) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { diff --git a/x/wasm/ibc.go b/x/wasm/ibc.go index 1fcae5f962..20ddc74726 100644 --- a/x/wasm/ibc.go +++ b/x/wasm/ibc.go @@ -9,19 +9,20 @@ import ( channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" porttypes "github.com/line/lfb-sdk/x/ibc/core/05-port/types" host "github.com/line/lfb-sdk/x/ibc/core/24-host" - wasmTypes "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" + wasmTypes "github.com/line/lfb-sdk/x/wasm/types" wasmvmtypes "github.com/line/wasmvm/types" ) var _ porttypes.IBCModule = IBCHandler{} type IBCHandler struct { - keeper Keeper + keeper wasmTypes.IBCContractKeeper channelKeeper wasmTypes.ChannelKeeper } -func NewIBCHandler(keeper Keeper) IBCHandler { - return IBCHandler{keeper: keeper, channelKeeper: keeper.ChannelKeeper} +func NewIBCHandler(k wasmTypes.IBCContractKeeper, ck types.ChannelKeeper) IBCHandler { + return IBCHandler{keeper: k, channelKeeper: ck} } // OnChanOpenInit implements the IBCModule interface @@ -245,16 +246,22 @@ func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet) } func newIBCPacket(packet channeltypes.Packet) wasmvmtypes.IBCPacket { + timeout := wasmvmtypes.IBCTimeout{ + Timestamp: packet.TimeoutTimestamp, + } + if !packet.TimeoutHeight.IsZero() { + timeout.Block = &wasmvmtypes.IBCTimeoutBlock{ + Height: packet.TimeoutHeight.RevisionHeight, + Revision: packet.TimeoutHeight.RevisionNumber, + } + } + return wasmvmtypes.IBCPacket{ Data: packet.Data, Src: wasmvmtypes.IBCEndpoint{ChannelID: packet.SourceChannel, PortID: packet.SourcePort}, Dest: wasmvmtypes.IBCEndpoint{ChannelID: packet.DestinationChannel, PortID: packet.DestinationPort}, Sequence: packet.Sequence, - TimeoutBlock: &wasmvmtypes.IBCTimeoutBlock{ - Height: packet.TimeoutHeight.RevisionHeight, - Revision: packet.TimeoutHeight.RevisionNumber, - }, - TimeoutTimestamp: &packet.TimeoutTimestamp, + Timeout: timeout, } } @@ -266,7 +273,7 @@ func ValidateChannelParams(channelID string) error { return err } if channelSequence > math.MaxUint32 { - return sdkerrors.Wrapf(wasmTypes.ErrMaxIBCChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, math.MaxUint32) + return sdkerrors.Wrapf(types.ErrMaxIBCChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, math.MaxUint32) } return nil } diff --git a/x/wasm/internal/keeper/handler_plugin_test.go b/x/wasm/internal/keeper/handler_plugin_test.go deleted file mode 100644 index 9e067afece..0000000000 --- a/x/wasm/internal/keeper/handler_plugin_test.go +++ /dev/null @@ -1,507 +0,0 @@ -package keeper - -import ( - "encoding/json" - "github.com/golang/protobuf/proto" - codectypes "github.com/line/lfb-sdk/codec/types" - capabilitytypes "github.com/line/lfb-sdk/x/capability/types" - govtypes "github.com/line/lfb-sdk/x/gov/types" - ibctransfertypes "github.com/line/lfb-sdk/x/ibc/applications/transfer/types" - clienttypes "github.com/line/lfb-sdk/x/ibc/core/02-client/types" - channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" - ibcexported "github.com/line/lfb-sdk/x/ibc/core/exported" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" - "testing" - - sdk "github.com/line/lfb-sdk/types" - banktypes "github.com/line/lfb-sdk/x/bank/types" - distributiontypes "github.com/line/lfb-sdk/x/distribution/types" - stakingtypes "github.com/line/lfb-sdk/x/staking/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" - wasmvmtypes "github.com/line/wasmvm/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestEncoding(t *testing.T) { - addr1 := RandomAccountAddress(t) - addr2 := RandomAccountAddress(t) - invalidAddr := "xrnd1d02kd90n38qvr3qb9qof83fn2d2" - valAddr := make(sdk.ValAddress, sdk.AddrLen) - valAddr[0] = 12 - valAddr2 := make(sdk.ValAddress, sdk.AddrLen) - valAddr2[1] = 123 - var timeoutVal uint64 = 100 - - jsonMsg := json.RawMessage(`{"foo": 123}`) - - bankMsg := &banktypes.MsgSend{ - FromAddress: addr2.String(), - ToAddress: addr1.String(), - Amount: sdk.Coins{ - sdk.NewInt64Coin("uatom", 12345), - sdk.NewInt64Coin("utgd", 54321), - }, - } - bankMsgBin, err := proto.Marshal(bankMsg) - require.NoError(t, err) - - content, err := codectypes.NewAnyWithValue(types.StoreCodeProposalFixture()) - require.NoError(t, err) - - proposalMsg := &govtypes.MsgSubmitProposal{ - Proposer: addr1.String(), - InitialDeposit: sdk.NewCoins(sdk.NewInt64Coin("uatom", 12345)), - Content: content, - } - proposalMsgBin, err := proto.Marshal(proposalMsg) - require.NoError(t, err) - - cases := map[string]struct { - sender sdk.AccAddress - srcMsg wasmvmtypes.CosmosMsg - srcIBCPort string - // set if valid - output []sdk.Msg - // set if invalid - isError bool - }{ - "simple send": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Bank: &wasmvmtypes.BankMsg{ - Send: &wasmvmtypes.SendMsg{ - ToAddress: addr2.String(), - Amount: []wasmvmtypes.Coin{ - { - Denom: "uatom", - Amount: "12345", - }, - { - Denom: "usdt", - Amount: "54321", - }, - }, - }, - }, - }, - output: []sdk.Msg{ - &banktypes.MsgSend{ - FromAddress: addr1.String(), - ToAddress: addr2.String(), - Amount: sdk.Coins{ - sdk.NewInt64Coin("uatom", 12345), - sdk.NewInt64Coin("usdt", 54321), - }, - }, - }, - }, - "invalid send amount": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Bank: &wasmvmtypes.BankMsg{ - Send: &wasmvmtypes.SendMsg{ - ToAddress: addr2.String(), - Amount: []wasmvmtypes.Coin{ - { - Denom: "uatom", - Amount: "123.456", - }, - }, - }, - }, - }, - isError: true, - }, - "invalid address": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Bank: &wasmvmtypes.BankMsg{ - Send: &wasmvmtypes.SendMsg{ - ToAddress: invalidAddr, - Amount: []wasmvmtypes.Coin{ - { - Denom: "uatom", - Amount: "7890", - }, - }, - }, - }, - }, - isError: false, // addresses are checked in the handler - output: []sdk.Msg{ - &banktypes.MsgSend{ - FromAddress: addr1.String(), - ToAddress: invalidAddr, - Amount: sdk.Coins{ - sdk.NewInt64Coin("uatom", 7890), - }, - }, - }, - }, - "wasm execute": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Wasm: &wasmvmtypes.WasmMsg{ - Execute: &wasmvmtypes.ExecuteMsg{ - ContractAddr: addr2.String(), - Msg: jsonMsg, - Send: []wasmvmtypes.Coin{ - wasmvmtypes.NewCoin(12, "eth"), - }, - }, - }, - }, - output: []sdk.Msg{ - &types.MsgExecuteContract{ - Sender: addr1.String(), - Contract: addr2.String(), - Msg: jsonMsg, - Funds: sdk.NewCoins(sdk.NewInt64Coin("eth", 12)), - }, - }, - }, - "wasm instantiate": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Wasm: &wasmvmtypes.WasmMsg{ - Instantiate: &wasmvmtypes.InstantiateMsg{ - CodeID: 7, - Msg: jsonMsg, - Send: []wasmvmtypes.Coin{ - wasmvmtypes.NewCoin(123, "eth"), - }, - Label: "myLabel", - }, - }, - }, - output: []sdk.Msg{ - &types.MsgInstantiateContract{ - Sender: addr1.String(), - CodeID: 7, - Label: "myLabel", - InitMsg: jsonMsg, - Funds: sdk.NewCoins(sdk.NewInt64Coin("eth", 123)), - }, - }, - }, - "wasm migrate": { - sender: addr2, - srcMsg: wasmvmtypes.CosmosMsg{ - Wasm: &wasmvmtypes.WasmMsg{ - Migrate: &wasmvmtypes.MigrateMsg{ - ContractAddr: addr1.String(), - NewCodeID: 12, - Msg: jsonMsg, - }, - }, - }, - output: []sdk.Msg{ - &types.MsgMigrateContract{ - Sender: addr2.String(), - Contract: addr1.String(), - CodeID: 12, - MigrateMsg: jsonMsg, - }, - }, - }, - "staking delegate": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Delegate: &wasmvmtypes.DelegateMsg{ - Validator: valAddr.String(), - Amount: wasmvmtypes.NewCoin(777, "stake"), - }, - }, - }, - output: []sdk.Msg{ - &stakingtypes.MsgDelegate{ - DelegatorAddress: addr1.String(), - ValidatorAddress: valAddr.String(), - Amount: sdk.NewInt64Coin("stake", 777), - }, - }, - }, - "staking delegate to non-validator": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Delegate: &wasmvmtypes.DelegateMsg{ - Validator: addr2.String(), - Amount: wasmvmtypes.NewCoin(777, "stake"), - }, - }, - }, - isError: false, // fails in the handler - output: []sdk.Msg{ - &stakingtypes.MsgDelegate{ - DelegatorAddress: addr1.String(), - ValidatorAddress: addr2.String(), - Amount: sdk.NewInt64Coin("stake", 777), - }, - }, - }, - "staking undelegate": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Undelegate: &wasmvmtypes.UndelegateMsg{ - Validator: valAddr.String(), - Amount: wasmvmtypes.NewCoin(555, "stake"), - }, - }, - }, - output: []sdk.Msg{ - &stakingtypes.MsgUndelegate{ - DelegatorAddress: addr1.String(), - ValidatorAddress: valAddr.String(), - Amount: sdk.NewInt64Coin("stake", 555), - }, - }, - }, - "staking redelegate": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Redelegate: &wasmvmtypes.RedelegateMsg{ - SrcValidator: valAddr.String(), - DstValidator: valAddr2.String(), - Amount: wasmvmtypes.NewCoin(222, "stake"), - }, - }, - }, - output: []sdk.Msg{ - &stakingtypes.MsgBeginRedelegate{ - DelegatorAddress: addr1.String(), - ValidatorSrcAddress: valAddr.String(), - ValidatorDstAddress: valAddr2.String(), - Amount: sdk.NewInt64Coin("stake", 222), - }, - }, - }, - "staking withdraw (implicit recipient)": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Withdraw: &wasmvmtypes.WithdrawMsg{ - Validator: valAddr2.String(), - }, - }, - }, - output: []sdk.Msg{ - &distributiontypes.MsgSetWithdrawAddress{ - DelegatorAddress: addr1.String(), - WithdrawAddress: addr1.String(), - }, - &distributiontypes.MsgWithdrawDelegatorReward{ - DelegatorAddress: addr1.String(), - ValidatorAddress: valAddr2.String(), - }, - }, - }, - "staking withdraw (explicit recipient)": { - sender: addr1, - srcMsg: wasmvmtypes.CosmosMsg{ - Staking: &wasmvmtypes.StakingMsg{ - Withdraw: &wasmvmtypes.WithdrawMsg{ - Validator: valAddr2.String(), - Recipient: addr2.String(), - }, - }, - }, - output: []sdk.Msg{ - &distributiontypes.MsgSetWithdrawAddress{ - DelegatorAddress: addr1.String(), - WithdrawAddress: addr2.String(), - }, - &distributiontypes.MsgWithdrawDelegatorReward{ - DelegatorAddress: addr1.String(), - ValidatorAddress: valAddr2.String(), - }, - }, - }, - "stargate encoded bank msg": { - sender: addr2, - srcMsg: wasmvmtypes.CosmosMsg{ - Stargate: &wasmvmtypes.StargateMsg{ - TypeURL: "/lfb.bank.v1beta1.MsgSend", - Value: bankMsgBin, - }, - }, - output: []sdk.Msg{bankMsg}, - }, - "stargate encoded msg with any type": { - sender: addr2, - srcMsg: wasmvmtypes.CosmosMsg{ - Stargate: &wasmvmtypes.StargateMsg{ - TypeURL: "/lfb.gov.v1beta1.MsgSubmitProposal", - Value: proposalMsgBin, - }, - }, - output: []sdk.Msg{proposalMsg}, - }, - "stargate encoded invalid typeUrl": { - sender: addr2, - srcMsg: wasmvmtypes.CosmosMsg{ - Stargate: &wasmvmtypes.StargateMsg{ - TypeURL: "/lfb.bank.v2.MsgSend", - Value: bankMsgBin, - }, - }, - isError: true, - }, - "IBC transfer with block timeout": { - sender: addr1, - srcIBCPort: "myIBCPort", - srcMsg: wasmvmtypes.CosmosMsg{ - IBC: &wasmvmtypes.IBCMsg{ - Transfer: &wasmvmtypes.TransferMsg{ - ChannelID: "myChanID", - ToAddress: addr2.String(), - Amount: wasmvmtypes.Coin{ - Denom: "ALX", - Amount: "1", - }, - TimeoutBlock: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}, - }, - }, - }, - output: []sdk.Msg{ - &ibctransfertypes.MsgTransfer{ - SourcePort: "transfer", - SourceChannel: "myChanID", - Token: sdk.Coin{ - Denom: "ALX", - Amount: sdk.NewInt(1), - }, - Sender: addr1.String(), - Receiver: addr2.String(), - TimeoutHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 2}, - }, - }, - }, - "IBC transfer with time timeout": { - sender: addr1, - srcIBCPort: "myIBCPort", - srcMsg: wasmvmtypes.CosmosMsg{ - IBC: &wasmvmtypes.IBCMsg{ - Transfer: &wasmvmtypes.TransferMsg{ - ChannelID: "myChanID", - ToAddress: addr2.String(), - Amount: wasmvmtypes.Coin{ - Denom: "ALX", - Amount: "1", - }, - TimeoutTimestamp: &timeoutVal, - }, - }, - }, - output: []sdk.Msg{ - &ibctransfertypes.MsgTransfer{ - SourcePort: "transfer", - SourceChannel: "myChanID", - Token: sdk.Coin{ - Denom: "ALX", - Amount: sdk.NewInt(1), - }, - Sender: addr1.String(), - Receiver: addr2.String(), - TimeoutTimestamp: 100, - }, - }, - }, - "IBC close channel": { - sender: addr1, - srcIBCPort: "myIBCPort", - srcMsg: wasmvmtypes.CosmosMsg{ - IBC: &wasmvmtypes.IBCMsg{ - CloseChannel: &wasmvmtypes.CloseChannelMsg{ - ChannelID: "channel-1", - }, - }, - }, - output: []sdk.Msg{ - &channeltypes.MsgChannelCloseInit{ - PortId: "wasm." + addr1.String(), - ChannelId: "channel-1", - Signer: addr1.String(), - }, - }, - }, - } - encodingConfig := MakeEncodingConfig(t) - encoder := DefaultEncoders(nil, nil, encodingConfig.Marshaler) - for name, tc := range cases { - tc := tc - t.Run(name, func(t *testing.T) { - var ctx sdk.Context - res, err := encoder.Encode(ctx, tc.sender, tc.srcIBCPort, tc.srcMsg, nil) - if tc.isError { - require.Error(t, err) - } else { - require.NoError(t, err) - assert.Equal(t, tc.output, res) - } - }) - } -} - -func TestEncodeIBCSendPacket(t *testing.T) { - ibcPort := "contractsIBCPort" - var ctx sdk.Context - specs := map[string]struct { - srcMsg wasmvmtypes.SendPacketMsg - expPacketSent channeltypes.Packet - }{ - "all good": { - srcMsg: wasmvmtypes.SendPacketMsg{ - ChannelID: "channel-1", - Data: []byte("myData"), - TimeoutBlock: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}, - }, - expPacketSent: channeltypes.Packet{ - Sequence: 1, - SourcePort: ibcPort, - SourceChannel: "channel-1", - DestinationPort: "other-port", - DestinationChannel: "other-channel-1", - Data: []byte("myData"), - TimeoutHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 2}, - }, - }, - } - for name, spec := range specs { - t.Run(name, func(t *testing.T) { - var gotPacket ibcexported.PacketI - - var chanKeeper types.ChannelKeeper = &wasmtesting.MockChannelKeeper{ - GetNextSequenceSendFn: func(ctx sdk.Context, portID, channelID string) (uint64, bool) { - return 1, true - }, - GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channeltypes.Channel, bool) { - return channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty( - "other-port", - "other-channel-1", - )}, true - }, - SendPacketFn: func(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { - gotPacket = packet - return nil - }, - } - var capKeeper types.CapabilityKeeper = &wasmtesting.MockCapabilityKeeper{ - GetCapabilityFn: func(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) { - return &capabilitytypes.Capability{}, true - }, - } - sender := RandomAccountAddress(t) - res, err := EncodeIBCMsg(chanKeeper, capKeeper)(ctx, sender, ibcPort, &wasmvmtypes.IBCMsg{SendPacket: &spec.srcMsg}) - - require.NoError(t, err) - assert.Nil(t, res) - assert.Equal(t, spec.expPacketSent, gotPacket) - }) - } -} diff --git a/x/wasm/internal/keeper/options.go b/x/wasm/internal/keeper/options.go deleted file mode 100644 index d4d9736b69..0000000000 --- a/x/wasm/internal/keeper/options.go +++ /dev/null @@ -1,31 +0,0 @@ -package keeper - -import "github.com/line/lfb-sdk/x/wasm/internal/types" - -type optsFn func(*Keeper) - -func (f optsFn) apply(keeper *Keeper) { - f(keeper) -} - -// WithMessageHandler is an optional constructor parameter to replace the default wasm vm engine with the -// given one. -func WithWasmEngine(x types.WasmerEngine) Option { - return optsFn(func(k *Keeper) { - k.wasmer = x - }) -} - -// WithMessageHandler is an optional constructor parameter to set a custom message handler. -func WithMessageHandler(x messenger) Option { - return optsFn(func(k *Keeper) { - k.messenger = x - }) -} - -// WithCoinTransferrer is an optional constructor parameter to set a custom coin transferrer -func WithCoinTransferrer(x coinTransferrer) Option { - return optsFn(func(k *Keeper) { - k.bank = x - }) -} diff --git a/x/wasm/internal/keeper/testdata/burner.wasm b/x/wasm/internal/keeper/testdata/burner.wasm deleted file mode 100644 index 8a16e6eab7..0000000000 Binary files a/x/wasm/internal/keeper/testdata/burner.wasm and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/hackatom.wasm b/x/wasm/internal/keeper/testdata/hackatom.wasm deleted file mode 100644 index fc5a53ddb3..0000000000 Binary files a/x/wasm/internal/keeper/testdata/hackatom.wasm and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/hackatom.wasm.gzip b/x/wasm/internal/keeper/testdata/hackatom.wasm.gzip deleted file mode 100644 index 33c0ab9250..0000000000 Binary files a/x/wasm/internal/keeper/testdata/hackatom.wasm.gzip and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/ibc_reflect.wasm b/x/wasm/internal/keeper/testdata/ibc_reflect.wasm deleted file mode 100644 index 76802272c2..0000000000 Binary files a/x/wasm/internal/keeper/testdata/ibc_reflect.wasm and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/ibc_reflect_send.wasm b/x/wasm/internal/keeper/testdata/ibc_reflect_send.wasm deleted file mode 100644 index fcb0ce69f0..0000000000 Binary files a/x/wasm/internal/keeper/testdata/ibc_reflect_send.wasm and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/reflect.wasm b/x/wasm/internal/keeper/testdata/reflect.wasm deleted file mode 100644 index 7e4fa531b1..0000000000 Binary files a/x/wasm/internal/keeper/testdata/reflect.wasm and /dev/null differ diff --git a/x/wasm/internal/keeper/testdata/staking.wasm b/x/wasm/internal/keeper/testdata/staking.wasm deleted file mode 100644 index 43f7445e33..0000000000 Binary files a/x/wasm/internal/keeper/testdata/staking.wasm and /dev/null differ diff --git a/x/wasm/internal/types/types_test.go b/x/wasm/internal/types/types_test.go deleted file mode 100644 index 86da8de7df..0000000000 --- a/x/wasm/internal/types/types_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package types - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestContractInfoValidateBasic(t *testing.T) { - specs := map[string]struct { - srcMutator func(*ContractInfo) - expError bool - }{ - "all good": {srcMutator: func(_ *ContractInfo) {}}, - "code id empty": { - srcMutator: func(c *ContractInfo) { c.CodeID = 0 }, - expError: true, - }, - "creator empty": { - srcMutator: func(c *ContractInfo) { c.Creator = "" }, - expError: true, - }, - "creator not an address": { - srcMutator: func(c *ContractInfo) { c.Creator = "invalid address" }, - expError: true, - }, - "admin empty": { - srcMutator: func(c *ContractInfo) { c.Admin = "" }, - expError: false, - }, - "admin not an address": { - srcMutator: func(c *ContractInfo) { c.Admin = "invalid address" }, - expError: true, - }, - "label empty": { - srcMutator: func(c *ContractInfo) { c.Label = "" }, - expError: true, - }, - "label exceeds limit": { - srcMutator: func(c *ContractInfo) { c.Label = strings.Repeat("a", MaxLabelSize+1) }, - expError: true, - }, - "empty status": { - srcMutator: func(c *ContractInfo) { c.Status = 0 }, - expError: true, - }, - "invalid status": { - srcMutator: func(c *ContractInfo) { c.Status = 3 }, - expError: true, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - state := ContractInfoFixture(spec.srcMutator) - got := state.ValidateBasic() - if spec.expError { - require.Error(t, got) - return - } - require.NoError(t, got) - }) - } -} - -func TestCodeInfoValidateBasic(t *testing.T) { - specs := map[string]struct { - srcMutator func(*CodeInfo) - expError bool - }{ - "all good": {srcMutator: func(_ *CodeInfo) {}}, - "code hash empty": { - srcMutator: func(c *CodeInfo) { c.CodeHash = []byte{} }, - expError: true, - }, - "code hash nil": { - srcMutator: func(c *CodeInfo) { c.CodeHash = nil }, - expError: true, - }, - "creator empty": { - srcMutator: func(c *CodeInfo) { c.Creator = "" }, - expError: true, - }, - "creator not an address": { - srcMutator: func(c *CodeInfo) { c.Creator = "invalid address" }, - expError: true, - }, - "source empty": { - srcMutator: func(c *CodeInfo) { c.Source = "" }, - }, - "source not an url": { - srcMutator: func(c *CodeInfo) { c.Source = "invalid" }, - expError: true, - }, - "source not an absolute url": { - srcMutator: func(c *CodeInfo) { c.Source = "../bar.txt" }, - expError: true, - }, - "source not https schema url": { - srcMutator: func(c *CodeInfo) { c.Source = "http://example.com" }, - expError: true, - }, - "builder tag exceeds limit": { - srcMutator: func(c *CodeInfo) { c.Builder = strings.Repeat("a", MaxBuildTagSize+1) }, - expError: true, - }, - "builder tag does not match pattern": { - srcMutator: func(c *CodeInfo) { c.Builder = "invalid" }, - expError: true, - }, - "Instantiate config invalid": { - srcMutator: func(c *CodeInfo) { c.InstantiateConfig = AccessConfig{} }, - expError: true, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - state := CodeInfoFixture(spec.srcMutator) - got := state.ValidateBasic() - if spec.expError { - require.Error(t, got) - return - } - require.NoError(t, got) - }) - } -} diff --git a/x/wasm/internal/keeper/api.go b/x/wasm/keeper/api.go similarity index 100% rename from x/wasm/internal/keeper/api.go rename to x/wasm/keeper/api.go diff --git a/x/wasm/internal/keeper/authz_policy.go b/x/wasm/keeper/authz_policy.go similarity index 97% rename from x/wasm/internal/keeper/authz_policy.go rename to x/wasm/keeper/authz_policy.go index ff158365b7..ab690d52ad 100644 --- a/x/wasm/internal/keeper/authz_policy.go +++ b/x/wasm/keeper/authz_policy.go @@ -2,7 +2,7 @@ package keeper import ( sdk "github.com/line/lfb-sdk/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) type AuthorizationPolicy interface { diff --git a/x/wasm/internal/keeper/bench_test.go b/x/wasm/keeper/bench_test.go similarity index 90% rename from x/wasm/internal/keeper/bench_test.go rename to x/wasm/keeper/bench_test.go index 4b88ef1482..51522138a1 100644 --- a/x/wasm/internal/keeper/bench_test.go +++ b/x/wasm/keeper/bench_test.go @@ -1,13 +1,14 @@ package keeper import ( - "github.com/line/lfb-sdk/x/wasm/internal/types" + "testing" + + "github.com/line/lfb-sdk/x/wasm/types" dbm "github.com/line/tm-db/v2" "github.com/line/tm-db/v2/goleveldb" "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb/opt" - "testing" ) func BenchmarkExecution(b *testing.B) { @@ -42,10 +43,10 @@ func BenchmarkExecution(b *testing.B) { for name, spec := range specs { b.Run(name, func(b *testing.B) { wasmConfig := types.WasmConfig{MemoryCacheSize: 0} - ctx, keepers := createTestInput(b, false, SupportedFeatures, nil, nil, wasmConfig, spec.db()) + ctx, keepers := createTestInput(b, false, SupportedFeatures, wasmConfig, spec.db()) example := InstantiateHackatomExampleContract(b, ctx, keepers) if spec.pinned { - require.NoError(b, keepers.WasmKeeper.PinCode(ctx, example.CodeID)) + require.NoError(b, keepers.ContractKeeper.PinCode(ctx, example.CodeID)) } b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/x/wasm/keeper/contract_keeper.go b/x/wasm/keeper/contract_keeper.go new file mode 100644 index 0000000000..bd87d6608c --- /dev/null +++ b/x/wasm/keeper/contract_keeper.go @@ -0,0 +1,74 @@ +package keeper + +import ( + sdk "github.com/line/lfb-sdk/types" + "github.com/line/lfb-sdk/x/wasm/types" +) + +var _ types.ContractOpsKeeper = PermissionedKeeper{} + +// decoratedKeeper contains a subset of the wasm keeper that are already or can be guarded by an authorization policy in the future +type decoratedKeeper interface { + create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, err error) + instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.AccAddress, []byte, error) + migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) (*sdk.Result, error) + setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ AuthorizationPolicy) error + pinCode(ctx sdk.Context, codeID uint64) error + unpinCode(ctx sdk.Context, codeID uint64) error + execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) + setContractInfoExtension(ctx sdk.Context, contract sdk.AccAddress, extra types.ContractInfoExtension) error +} + +type PermissionedKeeper struct { + authZPolicy AuthorizationPolicy + nested decoratedKeeper +} + +func NewPermissionedKeeper(nested decoratedKeeper, authZPolicy AuthorizationPolicy) *PermissionedKeeper { + return &PermissionedKeeper{authZPolicy: authZPolicy, nested: nested} +} + +func NewGovPermissionKeeper(nested decoratedKeeper) *PermissionedKeeper { + return NewPermissionedKeeper(nested, GovAuthorizationPolicy{}) +} + +func NewDefaultPermissionKeeper(nested decoratedKeeper) *PermissionedKeeper { + return NewPermissionedKeeper(nested, DefaultAuthorizationPolicy{}) +} + +func (p PermissionedKeeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig) (codeID uint64, err error) { + return p.nested.create(ctx, creator, wasmCode, source, builder, instantiateAccess, p.authZPolicy) +} + +func (p PermissionedKeeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, []byte, error) { + return p.nested.instantiate(ctx, codeID, creator, admin, initMsg, label, deposit, p.authZPolicy) +} + +func (p PermissionedKeeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { + return p.nested.execute(ctx, contractAddress, caller, msg, coins) +} + +func (p PermissionedKeeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) { + return p.nested.migrate(ctx, contractAddress, caller, newCodeID, msg, p.authZPolicy) +} + +func (p PermissionedKeeper) UpdateContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newAdmin sdk.AccAddress) error { + return p.nested.setContractAdmin(ctx, contractAddress, caller, newAdmin, p.authZPolicy) +} + +func (p PermissionedKeeper) ClearContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress) error { + return p.nested.setContractAdmin(ctx, contractAddress, caller, nil, p.authZPolicy) +} + +func (p PermissionedKeeper) PinCode(ctx sdk.Context, codeID uint64) error { + return p.nested.pinCode(ctx, codeID) +} + +func (p PermissionedKeeper) UnpinCode(ctx sdk.Context, codeID uint64) error { + return p.nested.unpinCode(ctx, codeID) +} + +// SetExtraContractAttributes updates the extra attributes that can be stored with the contract info +func (p PermissionedKeeper) SetContractInfoExtension(ctx sdk.Context, contract sdk.AccAddress, extra types.ContractInfoExtension) error { + return p.nested.setContractInfoExtension(ctx, contract, extra) +} diff --git a/x/wasm/internal/keeper/genesis.go b/x/wasm/keeper/genesis.go similarity index 96% rename from x/wasm/internal/keeper/genesis.go rename to x/wasm/keeper/genesis.go index 48f1744bd4..7691cc7c85 100644 --- a/x/wasm/internal/keeper/genesis.go +++ b/x/wasm/keeper/genesis.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" ) @@ -16,8 +16,8 @@ type ValidatorSetSource interface { // // CONTRACT: all types of accounts must have been already initialized/created func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, stakingKeeper ValidatorSetSource, msgHandler sdk.Handler) ([]abci.ValidatorUpdate, error) { + contractKeeper := NewGovPermissionKeeper(keeper) keeper.setParams(ctx, data.Params) - var maxCodeID uint64 for i, code := range data.Codes { err := keeper.importCode(ctx, code.CodeID, code.CodeInfo, code.CodeBytes) @@ -28,7 +28,7 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki maxCodeID = code.CodeID } if code.Pinned { - if err := keeper.PinCode(ctx, code.CodeID); err != nil { + if err := contractKeeper.PinCode(ctx, code.CodeID); err != nil { return nil, sdkerrors.Wrapf(err, "contract number %d", i) } } diff --git a/x/wasm/internal/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go similarity index 86% rename from x/wasm/internal/keeper/genesis_test.go rename to x/wasm/keeper/genesis_test.go index abd3db9640..f1bb98cbdb 100644 --- a/x/wasm/internal/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -4,7 +4,6 @@ import ( "bytes" "crypto/sha256" "encoding/base64" - "encoding/json" "errors" "fmt" "io/ioutil" @@ -15,14 +14,15 @@ import ( fuzz "github.com/google/gofuzz" "github.com/line/lfb-sdk/store" + "github.com/line/lfb-sdk/store/prefix" sdk "github.com/line/lfb-sdk/types" authkeeper "github.com/line/lfb-sdk/x/auth/keeper" distributionkeeper "github.com/line/lfb-sdk/x/distribution/keeper" paramskeeper "github.com/line/lfb-sdk/x/params/keeper" paramtypes "github.com/line/lfb-sdk/x/params/types" stakingkeeper "github.com/line/lfb-sdk/x/staking/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" - wasmTypes "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" + wasmTypes "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/libs/log" "github.com/line/ostracon/proto/ostracon/crypto" @@ -35,7 +35,8 @@ import ( const firstCodeID = 1 func TestGenesisExportImport(t *testing.T) { - srcKeeper, srcCtx, srcStoreKeys := setupKeeper(t) + wasmKeeper, srcCtx, srcStoreKeys := setupKeeper(t) + contractKeeper := NewGovPermissionKeeper(wasmKeeper) wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) @@ -43,41 +44,52 @@ func TestGenesisExportImport(t *testing.T) { // store some test data f := fuzz.New().Funcs(ModelFuzzers...) - srcKeeper.setParams(srcCtx, types.DefaultParams()) + wasmKeeper.setParams(srcCtx, types.DefaultParams()) for i := 0; i < 25; i++ { var ( - codeInfo types.CodeInfo - contract types.ContractInfo - stateModels []types.Model - history []types.ContractCodeHistoryEntry - pinned bool + codeInfo types.CodeInfo + contract types.ContractInfo + stateModels []types.Model + history []types.ContractCodeHistoryEntry + pinned bool + contractExtension bool ) f.Fuzz(&codeInfo) f.Fuzz(&contract) f.Fuzz(&stateModels) f.NilChance(0).Fuzz(&history) f.Fuzz(&pinned) + f.Fuzz(&contractExtension) + creatorAddr, err := sdk.AccAddressFromBech32(codeInfo.Creator) require.NoError(t, err) - codeID, err := srcKeeper.Create(srcCtx, creatorAddr, wasmCode, codeInfo.Source, codeInfo.Builder, &codeInfo.InstantiateConfig) + codeID, err := contractKeeper.Create(srcCtx, creatorAddr, wasmCode, codeInfo.Source, codeInfo.Builder, &codeInfo.InstantiateConfig) require.NoError(t, err) if pinned { - srcKeeper.PinCode(srcCtx, codeID) + contractKeeper.PinCode(srcCtx, codeID) + } + if contractExtension { + anyTime := time.Now().UTC() + var nestedType govtypes.TextProposal + f.NilChance(0).Fuzz(&nestedType) + myExtension, err := govtypes.NewProposal(&nestedType, 1, anyTime, anyTime) + require.NoError(t, err) + contract.SetExtension(&myExtension) } contract.CodeID = codeID - contractAddr := srcKeeper.generateContractAddress(srcCtx, codeID) - srcKeeper.storeContractInfo(srcCtx, contractAddr, &contract) - srcKeeper.appendToContractHistory(srcCtx, contractAddr, history...) - srcKeeper.importContractState(srcCtx, contractAddr, stateModels) + contractAddr := wasmKeeper.generateContractAddress(srcCtx, codeID) + wasmKeeper.storeContractInfo(srcCtx, contractAddr, &contract) + wasmKeeper.appendToContractHistory(srcCtx, contractAddr, history...) + wasmKeeper.importContractState(srcCtx, contractAddr, stateModels) } var wasmParams types.Params f.NilChance(0).Fuzz(&wasmParams) - srcKeeper.setParams(srcCtx, wasmParams) + wasmKeeper.setParams(srcCtx, wasmParams) // export - exportedState := ExportGenesis(srcCtx, srcKeeper) + exportedState := ExportGenesis(srcCtx, wasmKeeper) // order should not matter rand.Shuffle(len(exportedState.Codes), func(i, j int) { exportedState.Codes[i], exportedState.Codes[j] = exportedState.Codes[j], exportedState.Codes[i] @@ -88,24 +100,32 @@ func TestGenesisExportImport(t *testing.T) { rand.Shuffle(len(exportedState.Sequences), func(i, j int) { exportedState.Sequences[i], exportedState.Sequences[j] = exportedState.Sequences[j], exportedState.Sequences[i] }) - exportedGenesis, err := json.Marshal(exportedState) + exportedGenesis, err := wasmKeeper.cdc.MarshalJSON(exportedState) require.NoError(t, err) - // reset ContractInfo in source DB for comparison with dest DB - srcKeeper.IterateContractInfo(srcCtx, func(address sdk.AccAddress, info wasmTypes.ContractInfo) bool { - srcKeeper.deleteContractSecondIndex(srcCtx, address, &info) - info.ResetFromGenesis(srcCtx) - srcKeeper.storeContractInfo(srcCtx, address, &info) + // setup new instances + dstKeeper, dstCtx, dstStoreKeys := setupKeeper(t) + + // reset contract code index in source DB for comparison with dest DB + wasmKeeper.IterateContractInfo(srcCtx, func(address sdk.AccAddress, info wasmTypes.ContractInfo) bool { + wasmKeeper.removeFromContractCodeSecondaryIndex(srcCtx, address, wasmKeeper.getLastContractHistoryEntry(srcCtx, address)) + prefixStore := prefix.NewStore(srcCtx.KVStore(wasmKeeper.storeKey), types.GetContractCodeHistoryElementPrefix(address)) + for iter := prefixStore.Iterator(nil, nil); iter.Valid(); iter.Next() { + prefixStore.Delete(iter.Key()) + } + x := &info + newHistory := x.ResetFromGenesis(dstCtx) + wasmKeeper.storeContractInfo(srcCtx, address, x) + wasmKeeper.addToContractCodeSecondaryIndex(srcCtx, address, newHistory) + wasmKeeper.appendToContractHistory(srcCtx, address, newHistory) return false }) // re-import - dstKeeper, dstCtx, dstStoreKeys := setupKeeper(t) - var importState wasmTypes.GenesisState - err = json.Unmarshal(exportedGenesis, &importState) + err = dstKeeper.cdc.UnmarshalJSON(exportedGenesis, &importState) require.NoError(t, err) - InitGenesis(dstCtx, dstKeeper, importState, &StakingKeeperMock{}, TestHandler(dstKeeper)) + InitGenesis(dstCtx, dstKeeper, importState, &StakingKeeperMock{}, TestHandler(contractKeeper)) // compare whole DB for j := range srcStoreKeys { @@ -113,16 +133,6 @@ func TestGenesisExportImport(t *testing.T) { dstIT := dstCtx.KVStore(dstStoreKeys[j]).Iterator(nil, nil) for i := 0; srcIT.Valid(); i++ { - isContractHistory := srcStoreKeys[j].Name() == types.StoreKey && bytes.HasPrefix(srcIT.Key(), types.ContractCodeHistoryElementPrefix) - if isContractHistory { - // only skip history entries because we know they are different - // from genesis they are merged into 1 single entry - srcIT.Next() - if bytes.HasPrefix(dstIT.Key(), types.ContractCodeHistoryElementPrefix) { - dstIT.Next() - } - continue - } require.True(t, dstIT.Valid(), "[%s] destination DB has less elements than source. Missing: %x", srcStoreKeys[j].Name(), srcIT.Key()) require.Equal(t, srcIT.Key(), dstIT.Key(), i) require.Equal(t, srcIT.Value(), dstIT.Value(), "[%s] element (%d): %X", srcStoreKeys[j].Name(), i, srcIT.Key()) @@ -486,6 +496,7 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) { ] }` keeper, ctx, _ := setupKeeper(t) + contractKeeper := NewGovPermissionKeeper(keeper) wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) @@ -504,7 +515,7 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) { ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter()) // when - _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keeper)) + _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(contractKeeper)) require.NoError(t, err) // verify wasm code @@ -605,7 +616,7 @@ func TestSupportedGenMsgTypes(t *testing.T) { ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter()) fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, myAddress, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(100)))) // when - _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keeper)) + _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keepers.ContractKeeper)) require.NoError(t, err) // verify code stored @@ -630,8 +641,8 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) { require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(tempDir) }) var ( - keyParams = sdk.NewKVStoreKey(paramtypes.StoreKey) - keyWasm = sdk.NewKVStoreKey(wasmTypes.StoreKey) + keyParams = sdk.NewKVStoreKey(paramtypes.StoreKey) + keyWasm = sdk.NewKVStoreKey(wasmTypes.StoreKey) ) db := memdb.NewDB() @@ -646,10 +657,18 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) { }, false, log.NewNopLogger()) encodingConfig := MakeEncodingConfig(t) + // register an example extension. must be protobuf + encodingConfig.InterfaceRegistry.RegisterImplementations( + (*types.ContractInfoExtension)(nil), + &govtypes.Proposal{}, + ) + // also registering gov interfaces for nested Any type + govtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + wasmConfig := wasmTypes.DefaultWasmConfig() pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams) - srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures, nil, nil) + srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures) return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams} } diff --git a/x/wasm/internal/keeper/handler_plugin.go b/x/wasm/keeper/handler_plugin.go similarity index 51% rename from x/wasm/internal/keeper/handler_plugin.go rename to x/wasm/keeper/handler_plugin.go index 3a61bfd184..f2ee9d366d 100644 --- a/x/wasm/internal/keeper/handler_plugin.go +++ b/x/wasm/keeper/handler_plugin.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/json" + "errors" "fmt" codectypes "github.com/line/lfb-sdk/codec/types" @@ -14,49 +15,79 @@ import ( channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" host "github.com/line/lfb-sdk/x/ibc/core/24-host" stakingtypes "github.com/line/lfb-sdk/x/staking/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" wasmvmtypes "github.com/line/wasmvm/types" ) -type DefaultMessageHandler struct { +// msgEncoder is an extension point to customize encodings +type msgEncoder interface { + // Encode converts wasmvm message to n cosmos message types + Encode(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Msg, error) +} + +// SDKMessageHandler can handles messages that can be encoded into sdk.Message types and routed. +type SDKMessageHandler struct { router sdk.Router encodeRouter types.Router encoders MessageEncoders } -func NewDefaultMessageHandler(router sdk.Router, encodeRouter types.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, customEncoders *MessageEncoders) DefaultMessageHandler { - encoders := DefaultEncoders(channelKeeper, capabilityKeeper, unpacker).Merge(customEncoders) - return DefaultMessageHandler{ - router: router, - encodeRouter: encodeRouter, - encoders: encoders, - } -} - type BankEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.BankMsg) ([]sdk.Msg, error) type CustomEncoder func(sender sdk.AccAddress, msg json.RawMessage, customEncodeRouter types.Router) ([]sdk.Msg, error) +type DistributionEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.DistributionMsg) ([]sdk.Msg, error) type StakingEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk.Msg, error) type StargateEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.StargateMsg) ([]sdk.Msg, error) type WasmEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error) type IBCEncoder func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) type MessageEncoders struct { - Bank BankEncoder - Custom CustomEncoder - IBC IBCEncoder - Staking StakingEncoder - Stargate StargateEncoder - Wasm WasmEncoder + Bank func(sender sdk.AccAddress, msg *wasmvmtypes.BankMsg) ([]sdk.Msg, error) + Custom func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) + Distribution func(sender sdk.AccAddress, msg *wasmvmtypes.DistributionMsg) ([]sdk.Msg, error) + IBC func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) + Staking func(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk.Msg, error) + Stargate func(sender sdk.AccAddress, msg *wasmvmtypes.StargateMsg) ([]sdk.Msg, error) + Wasm func(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error) } -func DefaultEncoders(channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker) MessageEncoders { +func DefaultEncoders(unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource) MessageEncoders { return MessageEncoders{ - Bank: EncodeBankMsg, - Custom: CustomMsg, - IBC: EncodeIBCMsg(channelKeeper, capabilityKeeper), - Staking: EncodeStakingMsg, - Stargate: EncodeStargateMsg(unpacker), - Wasm: EncodeWasmMsg, + Bank: EncodeBankMsg, + Custom: CustomMsg, + Distribution: EncodeDistributionMsg, + IBC: EncodeIBCMsg(portSource), + Staking: EncodeStakingMsg, + Stargate: EncodeStargateMsg(unpacker), + Wasm: EncodeWasmMsg, + } +} + +func NewDefaultMessageHandler( + router sdk.Router, + encodeRouter types.Router, + channelKeeper types.ChannelKeeper, + capabilityKeeper types.CapabilityKeeper, + bankKeeper types.Burner, + unpacker codectypes.AnyUnpacker, + portSource types.ICS20TransferPortSource, + customEncoders ...*MessageEncoders, +) Messenger { + encoders := DefaultEncoders(unpacker, portSource) + for _, e := range customEncoders { + encoders = encoders.Merge(e) + } + return NewMessageHandlerChain( + NewSDKMessageHandler(router, encodeRouter, encoders), + NewIBCRawPacketHandler(channelKeeper, capabilityKeeper), + NewBurnCoinMessageHandler(bankKeeper), + ) +} + +func NewSDKMessageHandler(router sdk.Router, encodeRouter types.Router, encoders msgEncoder) SDKMessageHandler { + return SDKMessageHandler{ + router: router, + encodeRouter: encodeRouter, + encoders: encoders, } } @@ -70,6 +101,9 @@ func (e MessageEncoders) Merge(o *MessageEncoders) MessageEncoders { if o.Custom != nil { e.Custom = o.Custom } + if o.Distribution != nil { + e.Distribution = o.Distribution + } if o.IBC != nil { e.IBC = o.IBC } @@ -91,6 +125,8 @@ func (e MessageEncoders) Encode(ctx sdk.Context, contractAddr sdk.AccAddress, co return e.Bank(contractAddr, msg.Bank) case msg.Custom != nil: return e.Custom(contractAddr, msg.Custom, customRouter) + case msg.Distribution != nil: + return e.Distribution(contractAddr, msg.Distribution) case msg.IBC != nil: return e.IBC(ctx, contractAddr, contractIBCPortID, msg.IBC) case msg.Staking != nil: @@ -100,12 +136,12 @@ func (e MessageEncoders) Encode(ctx sdk.Context, contractAddr sdk.AccAddress, co case msg.Wasm != nil: return e.Wasm(contractAddr, msg.Wasm) } - return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Wasm") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Wasm") } func EncodeBankMsg(sender sdk.AccAddress, msg *wasmvmtypes.BankMsg) ([]sdk.Msg, error) { if msg.Send == nil { - return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Bank") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Bank") } if len(msg.Send.Amount) == 0 { return nil, nil @@ -135,6 +171,25 @@ func CustomMsg(sender sdk.AccAddress, jsonMsg json.RawMessage, router types.Rout return handler(linkMsgWrapper.MsgData) } +func EncodeDistributionMsg(sender sdk.AccAddress, msg *wasmvmtypes.DistributionMsg) ([]sdk.Msg, error) { + switch { + case msg.SetWithdrawAddress != nil: + setMsg := distributiontypes.MsgSetWithdrawAddress{ + DelegatorAddress: sender.String(), + WithdrawAddress: msg.SetWithdrawAddress.Address, + } + return []sdk.Msg{&setMsg}, nil + case msg.WithdrawDelegatorReward != nil: + withdrawMsg := distributiontypes.MsgWithdrawDelegatorReward{ + DelegatorAddress: sender.String(), + ValidatorAddress: msg.WithdrawDelegatorReward.Validator, + } + return []sdk.Msg{&withdrawMsg}, nil + default: + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Distribution") + } +} + func EncodeStakingMsg(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk.Msg, error) { switch { case msg.Delegate != nil: @@ -172,23 +227,8 @@ func EncodeStakingMsg(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk Amount: coin, } return []sdk.Msg{&sdkMsg}, nil - case msg.Withdraw != nil: - senderAddr := sender.String() - rcpt := senderAddr - if len(msg.Withdraw.Recipient) != 0 { - rcpt = msg.Withdraw.Recipient - } - setMsg := distributiontypes.MsgSetWithdrawAddress{ - DelegatorAddress: senderAddr, - WithdrawAddress: rcpt, - } - withdrawMsg := distributiontypes.MsgWithdrawDelegatorReward{ - DelegatorAddress: senderAddr, - ValidatorAddress: msg.Withdraw.Validator, - } - return []sdk.Msg{&setMsg, &withdrawMsg}, nil default: - return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Staking") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Staking") } } @@ -235,6 +275,7 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, CodeID: msg.Instantiate.CodeID, Label: msg.Instantiate.Label, InitMsg: msg.Instantiate.Msg, + Admin: msg.Instantiate.Admin, Funds: coins, } return []sdk.Msg{&sdkMsg}, nil @@ -246,50 +287,27 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, MigrateMsg: msg.Migrate.Msg, } return []sdk.Msg{&sdkMsg}, nil + case msg.ClearAdmin != nil: + sdkMsg := types.MsgClearAdmin{ + Sender: sender.String(), + Contract: msg.ClearAdmin.ContractAddr, + } + return []sdk.Msg{&sdkMsg}, nil + case msg.UpdateAdmin != nil: + sdkMsg := types.MsgUpdateAdmin{ + Sender: sender.String(), + Contract: msg.UpdateAdmin.ContractAddr, + NewAdmin: msg.UpdateAdmin.Admin, + } + return []sdk.Msg{&sdkMsg}, nil default: - return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Wasm") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Wasm") } } -func EncodeIBCMsg(channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper) IBCEncoder { +func EncodeIBCMsg(portSource types.ICS20TransferPortSource) func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) { return func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) { switch { - case msg.SendPacket != nil: - if contractIBCPortID == "" { - return nil, sdkerrors.Wrapf(types.ErrUnsupportedForContract, "ibc not supported") - } - contractIBCChannelID := msg.SendPacket.ChannelID - if contractIBCChannelID == "" { - return nil, sdkerrors.Wrapf(types.ErrEmpty, "ibc channel") - } - - sequence, found := channelKeeper.GetNextSequenceSend(ctx, contractIBCPortID, contractIBCChannelID) - if !found { - return nil, sdkerrors.Wrapf( - channeltypes.ErrSequenceSendNotFound, - "source port: %s, source channel: %s", contractIBCPortID, contractIBCChannelID, - ) - } - - channelInfo, ok := channelKeeper.GetChannel(ctx, contractIBCPortID, contractIBCChannelID) - if !ok { - return nil, sdkerrors.Wrap(channeltypes.ErrInvalidChannel, "not found") - } - channelCap, ok := capabilityKeeper.GetCapability(ctx, host.ChannelCapabilityPath(contractIBCPortID, contractIBCChannelID)) - if !ok { - return nil, sdkerrors.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") - } - packet := channeltypes.NewPacket( - msg.SendPacket.Data, - sequence, - contractIBCPortID, - contractIBCChannelID, - channelInfo.Counterparty.PortId, - channelInfo.Counterparty.ChannelId, - convertWasmIBCTimeoutHeightToCosmosHeight(msg.SendPacket.TimeoutBlock), - convertWasmIBCTimeoutTimestampToCosmosTimestamp(msg.SendPacket.TimeoutTimestamp), - ) - return nil, channelKeeper.SendPacket(ctx, channelCap, packet) case msg.CloseChannel != nil: return []sdk.Msg{&channeltypes.MsgChannelCloseInit{ PortId: PortIDForContract(sender), @@ -301,19 +319,18 @@ func EncodeIBCMsg(channelKeeper types.ChannelKeeper, capabilityKeeper types.Capa if err != nil { return nil, sdkerrors.Wrap(err, "amount") } - portID := ibctransfertypes.ModuleName //todo: port can be customized in genesis. make this more flexible msg := &ibctransfertypes.MsgTransfer{ - SourcePort: portID, + SourcePort: portSource.GetPort(ctx), SourceChannel: msg.Transfer.ChannelID, Token: amount, Sender: sender.String(), Receiver: msg.Transfer.ToAddress, - TimeoutHeight: convertWasmIBCTimeoutHeightToCosmosHeight(msg.Transfer.TimeoutBlock), - TimeoutTimestamp: convertWasmIBCTimeoutTimestampToCosmosTimestamp(msg.Transfer.TimeoutTimestamp), + TimeoutHeight: convertWasmIBCTimeoutHeightToCosmosHeight(msg.Transfer.Timeout.Block), + TimeoutTimestamp: msg.Transfer.Timeout.Timestamp, } return []sdk.Msg{msg}, nil default: - return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of IBC") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "Unknown variant of IBC") } } } @@ -325,14 +342,30 @@ func convertWasmIBCTimeoutHeightToCosmosHeight(ibcTimeoutBlock *wasmvmtypes.IBCT return ibcclienttypes.NewHeight(ibcTimeoutBlock.Revision, ibcTimeoutBlock.Height) } -func convertWasmIBCTimeoutTimestampToCosmosTimestamp(timestamp *uint64) uint64 { - if timestamp == nil { - return 0 +func convertWasmCoinsToSdkCoins(coins []wasmvmtypes.Coin) (sdk.Coins, error) { + var toSend sdk.Coins + for _, coin := range coins { + c, err := convertWasmCoinToSdkCoin(coin) + if err != nil { + return nil, err + } + toSend = append(toSend, c) + } + return toSend, nil +} + +func convertWasmCoinToSdkCoin(coin wasmvmtypes.Coin) (sdk.Coin, error) { + amount, ok := sdk.NewIntFromString(coin.Amount) + if !ok { + return sdk.Coin{}, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, coin.Amount+coin.Denom) } - return *timestamp + return sdk.Coin{ + Denom: coin.Denom, + Amount: amount, + }, nil } -func (h DefaultMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { +func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { sdkMsgs, err := h.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg, h.encodeRouter) if err != nil { return nil, nil, err @@ -354,7 +387,7 @@ func (h DefaultMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.Acc return } -func (h DefaultMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Address, msg sdk.Msg) (*sdk.Result, error) { +func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Address, msg sdk.Msg) (*sdk.Result, error) { if err := msg.ValidateBasic(); err != nil { return nil, err } @@ -377,25 +410,114 @@ func (h DefaultMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sd return res, nil } -func convertWasmCoinsToSdkCoins(coins []wasmvmtypes.Coin) (sdk.Coins, error) { - var toSend sdk.Coins - for _, coin := range coins { - c, err := convertWasmCoinToSdkCoin(coin) - if err != nil { - return nil, err +// MessageHandlerChain defines a chain of handlers that are called one by one until it can be handled. +type MessageHandlerChain struct { + handlers []Messenger +} + +func NewMessageHandlerChain(first Messenger, others ...Messenger) *MessageHandlerChain { + r := &MessageHandlerChain{handlers: append([]Messenger{first}, others...)} + for i := range r.handlers { + if r.handlers[i] == nil { + panic(fmt.Sprintf("handler must not be nil at position : %d", i)) } - toSend = append(toSend, c) } - return toSend, nil + return r } -func convertWasmCoinToSdkCoin(coin wasmvmtypes.Coin) (sdk.Coin, error) { - amount, ok := sdk.NewIntFromString(coin.Amount) +// DispatchMsg dispatch message to handlers. +func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, error) { + for _, h := range m.handlers { + events, data, err := h.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) + switch { + case err == nil: + return events, data, err + case errors.Is(err, types.ErrUnknownMsg): + continue + default: + return events, data, err + } + } + return nil, nil, sdkerrors.Wrap(types.ErrUnknownMsg, "no handler found") +} + +// IBCRawPacketHandler handels IBC.SendPacket messages which are published to an IBC channel. +type IBCRawPacketHandler struct { + channelKeeper types.ChannelKeeper + capabilityKeeper types.CapabilityKeeper +} + +func NewIBCRawPacketHandler(chk types.ChannelKeeper, cak types.CapabilityKeeper) *IBCRawPacketHandler { + return &IBCRawPacketHandler{channelKeeper: chk, capabilityKeeper: cak} +} + +// DispatchMsg publishes a raw IBC packet onto the channel. +func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + if msg.IBC == nil || msg.IBC.SendPacket == nil { + return nil, nil, types.ErrUnknownMsg + } + if contractIBCPortID == "" { + return nil, nil, sdkerrors.Wrapf(types.ErrUnsupportedForContract, "ibc not supported") + } + contractIBCChannelID := msg.IBC.SendPacket.ChannelID + if contractIBCChannelID == "" { + return nil, nil, sdkerrors.Wrapf(types.ErrEmpty, "ibc channel") + } + + sequence, found := h.channelKeeper.GetNextSequenceSend(ctx, contractIBCPortID, contractIBCChannelID) + if !found { + return nil, nil, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, + "source port: %s, source channel: %s", contractIBCPortID, contractIBCChannelID, + ) + } + + channelInfo, ok := h.channelKeeper.GetChannel(ctx, contractIBCPortID, contractIBCChannelID) if !ok { - return sdk.Coin{}, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, coin.Amount+coin.Denom) + return nil, nil, sdkerrors.Wrap(channeltypes.ErrInvalidChannel, "not found") + } + channelCap, ok := h.capabilityKeeper.GetCapability(ctx, host.ChannelCapabilityPath(contractIBCPortID, contractIBCChannelID)) + if !ok { + return nil, nil, sdkerrors.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") + } + packet := channeltypes.NewPacket( + msg.IBC.SendPacket.Data, + sequence, + contractIBCPortID, + contractIBCChannelID, + channelInfo.Counterparty.PortId, + channelInfo.Counterparty.ChannelId, + convertWasmIBCTimeoutHeightToCosmosHeight(msg.IBC.SendPacket.Timeout.Block), + msg.IBC.SendPacket.Timeout.Timestamp, + ) + return nil, nil, h.channelKeeper.SendPacket(ctx, channelCap, packet) +} + +var _ Messenger = MessageHandlerFunc(nil) + +// MessageHandlerFunc is a helper to construct simple function based message handler +type MessageHandlerFunc func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) + +func (m MessageHandlerFunc) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return m(ctx, contractAddr, contractIBCPortID, msg) +} + +// NewBurnCoinMessageHandler handles wasmvm.BurnMsg messages +func NewBurnCoinMessageHandler(burner types.Burner) MessageHandlerFunc { + return func(ctx sdk.Context, contractAddr sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + if msg.Bank != nil && msg.Bank.Burn != nil { + coins, err := convertWasmCoinsToSdkCoins(msg.Bank.Burn.Amount) + if err != nil { + return nil, nil, err + } + if err := burner.SendCoinsFromAccountToModule(ctx, contractAddr, types.ModuleName, coins); err != nil { + return nil, nil, sdkerrors.Wrap(err, "transfer to module") + } + if err := burner.BurnCoins(ctx, types.ModuleName, coins); err != nil { + return nil, nil, sdkerrors.Wrap(err, "burn coins") + } + moduleLogger(ctx).Info("Burned", "amount", coins) + return nil, nil, nil + } + return nil, nil, types.ErrUnknownMsg } - return sdk.Coin{ - Denom: coin.Denom, - Amount: amount, - }, nil } diff --git a/x/wasm/keeper/handler_plugin_test.go b/x/wasm/keeper/handler_plugin_test.go new file mode 100644 index 0000000000..093d470fe9 --- /dev/null +++ b/x/wasm/keeper/handler_plugin_test.go @@ -0,0 +1,395 @@ +package keeper + +import ( + "encoding/json" + "testing" + + "github.com/line/lfb-sdk/baseapp" + sdk "github.com/line/lfb-sdk/types" + sdkerrors "github.com/line/lfb-sdk/types/errors" + banktypes "github.com/line/lfb-sdk/x/bank/types" + capabilitytypes "github.com/line/lfb-sdk/x/capability/types" + clienttypes "github.com/line/lfb-sdk/x/ibc/core/02-client/types" + channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" + ibcexported "github.com/line/lfb-sdk/x/ibc/core/exported" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" + wasmvm "github.com/line/wasmvm" + wasmvmtypes "github.com/line/wasmvm/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMessageHandlerChainDispatch(t *testing.T) { + capturingHandler, gotMsgs := wasmtesting.NewCapturingMessageHandler() + + alwaysUnknownMsgHandler := &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, types.ErrUnknownMsg + }} + + assertNotCalledHandler := &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + t.Fatal("not expected to be called") + return + }} + + myMsg := wasmvmtypes.CosmosMsg{Custom: []byte(`{}`)} + specs := map[string]struct { + handlers []Messenger + expErr *sdkerrors.Error + expEvents []sdk.Event + }{ + "single handler": { + handlers: []Messenger{capturingHandler}, + }, + "passed to next handler": { + handlers: []Messenger{alwaysUnknownMsgHandler, capturingHandler}, + }, + "stops iteration when handled": { + handlers: []Messenger{capturingHandler, assertNotCalledHandler}, + }, + "stops iteration on handler error": { + handlers: []Messenger{&wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, types.ErrInvalidMsg + }}, assertNotCalledHandler}, + expErr: types.ErrInvalidMsg, + }, + "return events when handle": { + handlers: []Messenger{&wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + _, data, _ = capturingHandler.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) + return []sdk.Event{sdk.NewEvent("myEvent", sdk.NewAttribute("foo", "bar"))}, data, nil + }}, + }, + expEvents: []sdk.Event{sdk.NewEvent("myEvent", sdk.NewAttribute("foo", "bar"))}, + }, + "return error when none can handle": { + handlers: []Messenger{alwaysUnknownMsgHandler}, + expErr: types.ErrUnknownMsg, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + *gotMsgs = make([]wasmvmtypes.CosmosMsg, 0) + + // when + h := MessageHandlerChain{spec.handlers} + gotEvents, gotData, gotErr := h.DispatchMsg(sdk.Context{}, RandomAccountAddress(t), "anyPort", myMsg) + + // then + require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr) + if spec.expErr != nil { + return + } + assert.Equal(t, []wasmvmtypes.CosmosMsg{myMsg}, *gotMsgs) + assert.Equal(t, [][]byte{{1}}, gotData) // {1} is default in capturing handler + assert.Equal(t, spec.expEvents, gotEvents) + }) + } +} + +func TestSDKMessageHandlerDispatch(t *testing.T) { + myEvent := sdk.NewEvent("myEvent", sdk.NewAttribute("foo", "bar")) + const myData = "myData" + myRouterResult := sdk.Result{ + Data: []byte(myData), + Events: sdk.Events{myEvent}.ToABCIEvents(), + } + + var gotMsg []sdk.Msg + capturingRouteFn := func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + gotMsg = append(gotMsg, msg) + return &myRouterResult, nil + } + + myContractAddr := RandomAccountAddress(t) + myContractMessage := wasmvmtypes.CosmosMsg{Custom: []byte("{}")} + + specs := map[string]struct { + srcRoute sdk.Route + srcEncoder CustomEncoder + expErr *sdkerrors.Error + expMsgDispatched int + }{ + "all good": { + srcRoute: sdk.NewRoute(types.RouterKey, capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + myMsg := types.MsgExecuteContract{ + Sender: myContractAddr.String(), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("{}"), + } + return []sdk.Msg{&myMsg}, nil + }, + expMsgDispatched: 1, + }, + "multiple output msgs": { + srcRoute: sdk.NewRoute(types.RouterKey, capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + first := &types.MsgExecuteContract{ + Sender: myContractAddr.String(), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("{}"), + } + second := &types.MsgExecuteContract{ + Sender: myContractAddr.String(), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("{}"), + } + return []sdk.Msg{first, second}, nil + }, + expMsgDispatched: 2, + }, + "invalid sdk message rejected": { + srcRoute: sdk.NewRoute(types.RouterKey, capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + invalidMsg := types.MsgExecuteContract{ + Sender: myContractAddr.String(), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("INVALID_JSON"), + } + return []sdk.Msg{&invalidMsg}, nil + }, + expErr: types.ErrInvalid, + }, + "invalid sender rejected": { + srcRoute: sdk.NewRoute(types.RouterKey, capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + invalidMsg := types.MsgExecuteContract{ + Sender: RandomBech32AccountAddress(t), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("{}"), + } + return []sdk.Msg{&invalidMsg}, nil + }, + expErr: sdkerrors.ErrUnauthorized, + }, + "unroutable message rejected": { + srcRoute: sdk.NewRoute("nothing", capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + myMsg := types.MsgExecuteContract{ + Sender: myContractAddr.String(), + Contract: RandomBech32AccountAddress(t), + Msg: []byte("{}"), + } + return []sdk.Msg{&myMsg}, nil + }, + expErr: sdkerrors.ErrUnknownRequest, + }, + "encoding error passed": { + srcRoute: sdk.NewRoute("nothing", capturingRouteFn), + srcEncoder: func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { + myErr := types.ErrUnpinContractFailed + return nil, myErr + }, + expErr: types.ErrUnpinContractFailed, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotMsg = make([]sdk.Msg, 0) + router := baseapp.NewRouter() + router.AddRoute(spec.srcRoute) + + // when + ctx := sdk.Context{} + h := NewSDKMessageHandler(router, MessageEncoders{Custom: spec.srcEncoder}) + gotEvents, gotData, gotErr := h.DispatchMsg(ctx, myContractAddr, "myPort", myContractMessage) + + // then + require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr) + if spec.expErr != nil { + require.Len(t, gotMsg, 0) + return + } + assert.Len(t, gotMsg, spec.expMsgDispatched) + for i := 0; i < spec.expMsgDispatched; i++ { + assert.Equal(t, myEvent, gotEvents[i]) + assert.Equal(t, []byte(myData), gotData[i]) + } + }) + } +} + +func TestIBCRawPacketHandler(t *testing.T) { + ibcPort := "contractsIBCPort" + var ctx sdk.Context + + var capturedPacket ibcexported.PacketI + + chanKeeper := &wasmtesting.MockChannelKeeper{ + GetNextSequenceSendFn: func(ctx sdk.Context, portID, channelID string) (uint64, bool) { + return 1, true + }, + GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channeltypes.Channel, bool) { + return channeltypes.Channel{ + Counterparty: channeltypes.NewCounterparty( + "other-port", + "other-channel-1", + )}, true + }, + SendPacketFn: func(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { + capturedPacket = packet + return nil + }, + } + capKeeper := &wasmtesting.MockCapabilityKeeper{ + GetCapabilityFn: func(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) { + return &capabilitytypes.Capability{}, true + }, + } + + specs := map[string]struct { + srcMsg wasmvmtypes.SendPacketMsg + chanKeeper types.ChannelKeeper + capKeeper types.CapabilityKeeper + expPacketSent channeltypes.Packet + expErr *sdkerrors.Error + }{ + "all good": { + srcMsg: wasmvmtypes.SendPacketMsg{ + ChannelID: "channel-1", + Data: []byte("myData"), + Timeout: wasmvmtypes.IBCTimeout{Block: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}}, + }, + chanKeeper: chanKeeper, + capKeeper: capKeeper, + expPacketSent: channeltypes.Packet{ + Sequence: 1, + SourcePort: ibcPort, + SourceChannel: "channel-1", + DestinationPort: "other-port", + DestinationChannel: "other-channel-1", + Data: []byte("myData"), + TimeoutHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 2}, + }, + }, + "sequence not found returns error": { + srcMsg: wasmvmtypes.SendPacketMsg{ + ChannelID: "channel-1", + Data: []byte("myData"), + Timeout: wasmvmtypes.IBCTimeout{Block: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}}, + }, + chanKeeper: &wasmtesting.MockChannelKeeper{ + GetNextSequenceSendFn: func(ctx sdk.Context, portID, channelID string) (uint64, bool) { + return 0, false + }}, + expErr: channeltypes.ErrSequenceSendNotFound, + }, + "capability not found returns error": { + srcMsg: wasmvmtypes.SendPacketMsg{ + ChannelID: "channel-1", + Data: []byte("myData"), + Timeout: wasmvmtypes.IBCTimeout{Block: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}}, + }, + chanKeeper: chanKeeper, + capKeeper: wasmtesting.MockCapabilityKeeper{ + GetCapabilityFn: func(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) { + return nil, false + }}, + expErr: channeltypes.ErrChannelCapabilityNotFound, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + capturedPacket = nil + // when + h := NewIBCRawPacketHandler(spec.chanKeeper, spec.capKeeper) + data, evts, gotErr := h.DispatchMsg(ctx, RandomAccountAddress(t), ibcPort, wasmvmtypes.CosmosMsg{IBC: &wasmvmtypes.IBCMsg{SendPacket: &spec.srcMsg}}) + // then + require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr) + if spec.expErr != nil { + return + } + assert.Nil(t, data) + assert.Nil(t, evts) + assert.Equal(t, spec.expPacketSent, capturedPacket) + }) + } +} + +func TestBurnCoinMessageHandlerIntegration(t *testing.T) { + // testing via full keeper setup so that we are confident the + // module permissions are set correct and no other handler + // picks the message in the default handler chain + ctx, keepers := CreateDefaultTestInput(t) + k := keepers.WasmKeeper + + before, err := keepers.BankKeeper.TotalSupply(sdk.WrapSDKContext(ctx), &banktypes.QueryTotalSupplyRequest{}) + require.NoError(t, err) + example := InstantiateHackatomExampleContract(t, ctx, keepers) // with deposit of 100 stake + + specs := map[string]struct { + msg wasmvmtypes.BurnMsg + expErr bool + }{ + "all good": { + msg: wasmvmtypes.BurnMsg{ + Amount: wasmvmtypes.Coins{{ + Denom: "denom", + Amount: "100", + }}, + }, + }, + "not enough funds in contract": { + msg: wasmvmtypes.BurnMsg{ + Amount: wasmvmtypes.Coins{{ + Denom: "denom", + Amount: "101", + }}, + }, + expErr: true, + }, + "zero amount rejected": { + msg: wasmvmtypes.BurnMsg{ + Amount: wasmvmtypes.Coins{{ + Denom: "denom", + Amount: "0", + }}, + }, + expErr: true, + }, + "unknown denom - insufficient funds": { + msg: wasmvmtypes.BurnMsg{ + Amount: wasmvmtypes.Coins{{ + Denom: "unknown", + Amount: "1", + }}, + }, + expErr: true, + }, + } + parentCtx := ctx + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, _ = parentCtx.CacheContext() + k.wasmVM = &wasmtesting.MockWasmer{ExecuteFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) { + return &wasmvmtypes.Response{Messages: []wasmvmtypes.CosmosMsg{ + {Bank: &wasmvmtypes.BankMsg{Burn: &spec.msg}}, + }, + }, 0, nil + }} + + // when + _, err = k.execute(ctx, example.Contract, example.CreatorAddr, nil, nil) + + // then + if spec.expErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + // and total supply reduced by burned amount + after, err := keepers.BankKeeper.TotalSupply(sdk.WrapSDKContext(ctx), &banktypes.QueryTotalSupplyRequest{}) + require.NoError(t, err) + diff := before.Supply.Sub(after.Supply) + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(100))), diff) + }) + } + + // test cases: + // not enough money to burn +} diff --git a/x/wasm/internal/keeper/ibc.go b/x/wasm/keeper/ibc.go similarity index 97% rename from x/wasm/internal/keeper/ibc.go rename to x/wasm/keeper/ibc.go index e29761e522..fd5cc3ac43 100644 --- a/x/wasm/internal/keeper/ibc.go +++ b/x/wasm/keeper/ibc.go @@ -7,7 +7,7 @@ import ( sdkerrors "github.com/line/lfb-sdk/types/errors" capabilitytypes "github.com/line/lfb-sdk/x/capability/types" host "github.com/line/lfb-sdk/x/ibc/core/24-host" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) // bindIbcPort will reserve the port. diff --git a/x/wasm/internal/keeper/ibc_test.go b/x/wasm/keeper/ibc_test.go similarity index 89% rename from x/wasm/internal/keeper/ibc_test.go rename to x/wasm/keeper/ibc_test.go index 9d1e2610dc..ae27cd8b5f 100644 --- a/x/wasm/internal/keeper/ibc_test.go +++ b/x/wasm/keeper/ibc_test.go @@ -10,14 +10,14 @@ import ( ) func TestDontBindPortNonIBCContract(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) example := InstantiateHackatomExampleContract(t, ctx, keepers) // ensure we bound the port _, _, err := keepers.IBCKeeper.PortKeeper.LookupModuleByPort(ctx, keepers.WasmKeeper.GetContractInfo(ctx, example.Contract).IBCPortID) require.Error(t, err) } func TestBindingPortForIBCContractOnInstantiate(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) example := InstantiateIBCReflectContract(t, ctx, keepers) // ensure we bound the port owner, _, err := keepers.IBCKeeper.PortKeeper.LookupModuleByPort(ctx, keepers.WasmKeeper.GetContractInfo(ctx, example.Contract).IBCPortID) require.NoError(t, err) @@ -29,7 +29,7 @@ func TestBindingPortForIBCContractOnInstantiate(t *testing.T) { // create a second contract should give yet another portID (and different address) creator := RandomAccountAddress(t) - addr, _, err := keepers.WasmKeeper.Instantiate(ctx, example.CodeID, creator, nil, initMsgBz, "ibc-reflect-2", nil) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, example.CodeID, creator, nil, initMsgBz, "ibc-reflect-2", nil) require.NoError(t, err) require.NotEqual(t, example.Contract, addr) diff --git a/x/wasm/internal/keeper/ioutil.go b/x/wasm/keeper/ioutil.go similarity index 96% rename from x/wasm/internal/keeper/ioutil.go rename to x/wasm/keeper/ioutil.go index 641e768815..012270da6d 100644 --- a/x/wasm/internal/keeper/ioutil.go +++ b/x/wasm/keeper/ioutil.go @@ -6,7 +6,7 @@ import ( "io" "io/ioutil" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) // magic bytes to identify gzip. diff --git a/x/wasm/internal/keeper/ioutil_test.go b/x/wasm/keeper/ioutil_test.go similarity index 97% rename from x/wasm/internal/keeper/ioutil_test.go rename to x/wasm/keeper/ioutil_test.go index 2d23db0cc5..15ac46ffaf 100644 --- a/x/wasm/internal/keeper/ioutil_test.go +++ b/x/wasm/keeper/ioutil_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/x/wasm/internal/keeper/keeper.go b/x/wasm/keeper/keeper.go similarity index 73% rename from x/wasm/internal/keeper/keeper.go rename to x/wasm/keeper/keeper.go index 9b76a7242d..aec01903dd 100644 --- a/x/wasm/internal/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -5,15 +5,16 @@ import ( "encoding/binary" "fmt" "path/filepath" + "time" "github.com/line/lfb-sdk/codec" "github.com/line/lfb-sdk/store/prefix" + "github.com/line/lfb-sdk/telemetry" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" authkeeper "github.com/line/lfb-sdk/x/auth/keeper" paramtypes "github.com/line/lfb-sdk/x/params/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" - abci "github.com/line/ostracon/abci/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/crypto" "github.com/line/ostracon/libs/log" wasmvm "github.com/line/wasmvm" @@ -34,28 +35,42 @@ type Option interface { apply(*Keeper) } -type messenger interface { - DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) +// WasmVMQueryHandler is an extension point for custom query handler implementations +type WasmVMQueryHandler interface { + // HandleQuery executes the requested query + HandleQuery(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) } -type coinTransferrer interface { +type CoinTransferrer interface { // TransferCoins sends the coin amounts from the source to the destination with rules applied. TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error } +// WasmVMResponseHandler is an extension point to handles the response data returned by a contract call. +type WasmVMResponseHandler interface { + // Handle processes the data returned by a contract invocation. + Handle( + ctx sdk.Context, + contractAddr sdk.AccAddress, + ibcPort string, + submessages []wasmvmtypes.SubMsg, + messages []wasmvmtypes.CosmosMsg, + origRspData []byte, + ) ([]byte, error) +} + // Keeper will have a reference to Wasmer with it's own data directory. type Keeper struct { - storeKey sdk.StoreKey - cdc codec.Marshaler - accountKeeper types.AccountKeeper - bank coinTransferrer - ChannelKeeper types.ChannelKeeper - portKeeper types.PortKeeper - capabilityKeeper types.CapabilityKeeper - - wasmer types.WasmerEngine - queryPlugins QueryPlugins - messenger messenger + storeKey sdk.StoreKey + cdc codec.Marshaler + accountKeeper types.AccountKeeper + bank CoinTransferrer + portKeeper types.PortKeeper + capabilityKeeper types.CapabilityKeeper + wasmVM types.WasmerEngine + wasmVMQueryHandler WasmVMQueryHandler + wasmVMResponseHandler WasmVMResponseHandler + messenger Messenger // queryGasLimit is the max wasmvm gas that can be spent on executing a query with a contract queryGasLimit uint64 authZPolicy AuthorizationPolicy @@ -75,6 +90,7 @@ func NewKeeper( channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, capabilityKeeper types.CapabilityKeeper, + portSource types.ICS20TransferPortSource, router sdk.Router, encodeRouter types.Router, queryRouter GRPCQueryRouter, @@ -94,25 +110,26 @@ func NewKeeper( paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) } - keeper := Keeper{ + keeper := &Keeper{ storeKey: storeKey, cdc: cdc, - wasmer: wasmer, + wasmVM: wasmer, accountKeeper: accountKeeper, bank: NewBankCoinTransferrer(bankKeeper), - ChannelKeeper: channelKeeper, portKeeper: portKeeper, capabilityKeeper: capabilityKeeper, - messenger: NewDefaultMessageHandler(router, encodeRouter, channelKeeper, capabilityKeeper, cdc, customEncoders), + messenger: NewDefaultMessageHandler(router, encodeRouter, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource, customEncoders), queryGasLimit: wasmConfig.SmartQueryGasLimit, - authZPolicy: DefaultAuthorizationPolicy{}, paramSpace: paramSpace, } - keeper.queryPlugins = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, queryRouter, &keeper).Merge(customPlugins) + + keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, queryRouter, keeper).Merge(customPlugins) for _, o := range opts { - o.apply(&keeper) + o.apply(keeper) } - return keeper + // not updateable, yet + keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper)) + return *keeper } func (k Keeper) getUploadAccessConfig(ctx sdk.Context) types.AccessConfig { @@ -168,11 +185,6 @@ func (k Keeper) setParams(ctx sdk.Context, ps types.Params) { k.paramSpace.SetParamSet(ctx, &ps) } -// Create uploads and compiles a WASM contract, returning a short identifier for the contract -func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig) (codeID uint64, err error) { - return k.create(ctx, creator, wasmCode, source, builder, instantiateAccess, k.authZPolicy) -} - func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, err error) { if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) { return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") @@ -183,7 +195,7 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, } ctx.GasMeter().ConsumeGas(k.getCompileCost(ctx)*uint64(len(wasmCode)), "Compiling WASM Bytecode") - codeHash, err := k.wasmer.Create(wasmCode) + codeHash, err := k.wasmVM.Create(wasmCode) if err != nil { return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } @@ -208,7 +220,7 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn if err != nil { return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } - newCodeHash, err := k.wasmer.Create(wasmCode) + newCodeHash, err := k.wasmVM.Create(wasmCode) if err != nil { return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } @@ -226,12 +238,8 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn return nil } -// Instantiate creates an instance of a WASM contract -func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, []byte, error) { - return k.instantiate(ctx, codeID, creator, admin, initMsg, label, deposit, k.authZPolicy) -} - func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.AccAddress, []byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "instantiate") if !k.IsPinnedCode(ctx, codeID) { ctx.GasMeter().ConsumeGas(k.getInstanceCost(ctx), "Loading CosmWasm module: instantiate") } @@ -280,11 +288,11 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A wasmStore := types.NewWasmStore(prefixStore) // prepare querier - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddress, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddress, k.getGasMultiplier(ctx)) // instantiate wasm contract gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - res, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, info, initMsg, wasmStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) + res, gasUsed, err := k.wasmVM.Instantiate(codeInfo.CodeHash, env, info, initMsg, prefixStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) k.consumeGas(ctx, gasUsed) if err != nil { return contractAddress, nil, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error()) @@ -299,7 +307,7 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt, types.ContractStatusActive) // check for IBC flag - report, err := k.wasmer.AnalyzeCode(codeInfo.CodeHash) + report, err := k.wasmVM.AnalyzeCode(codeInfo.CodeHash) if err != nil { return contractAddress, nil, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error()) } @@ -313,20 +321,23 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A } // store contract before dispatch so that contract could be called back + historyEntry := contractInfo.InitialHistory(initMsg) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + k.appendToContractHistory(ctx, contractAddress, historyEntry) k.storeContractInfo(ctx, contractAddress, &contractInfo) - k.appendToContractHistory(ctx, contractAddress, contractInfo.InitialHistory(initMsg)) // dispatch submessages then messages - err = k.dispatchAll(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res) if err != nil { return nil, nil, sdkerrors.Wrap(err, "dispatch") } - return contractAddress, res.Data, nil + return contractAddress, data, nil } // Execute executes the contract instance -func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { +func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "execute") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err @@ -350,10 +361,9 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller info := types.NewInfo(caller, coins) // prepare querier - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddress, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddress, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, env, info, msg, wasmStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) + res, gasUsed, execErr := k.wasmVM.Execute(codeInfo.CodeHash, env, info, msg, prefixStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -364,22 +374,18 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller ctx.EventManager().EmitEvents(events) // dispatch submessages then messages - err = k.dispatchAll(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } return &sdk.Result{ - Data: res.Data, + Data: data, }, nil } -// Migrate allows to upgrade a contract to a new code with data migration. -func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) { - return k.migrate(ctx, contractAddress, caller, newCodeID, msg, k.authZPolicy) -} - func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "migrate") if !k.IsPinnedCode(ctx, newCodeID) { ctx.GasMeter().ConsumeGas(k.getInstanceCost(ctx), "Loading CosmWasm module: migrate") } @@ -401,7 +407,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller } // check for IBC flag - switch report, err := k.wasmer.AnalyzeCode(newCodeInfo.CodeHash); { + switch report, err := k.wasmVM.AnalyzeCode(newCodeInfo.CodeHash); { case err != nil: return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) case !report.HasIBCEntryPoints && contractInfo.IBCPortID != "": @@ -419,13 +425,12 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller env := types.NewEnv(ctx, contractAddress) // prepare querier - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddress, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddress, k.getGasMultiplier(ctx)) prefixStoreKey := types.GetContractStorePrefix(contractAddress) prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey) - wasmStore := types.NewWasmStore(prefixStore) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - res, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, &wasmStore, k.cosmwasmAPI(ctx), &querier, k.gasMeter(ctx), gas) + res, gasUsed, err := k.wasmVM.Migrate(newCodeInfo.CodeHash, env, msg, &prefixStore, k.cosmwasmAPI(ctx), &querier, k.gasMeter(ctx), gas) k.consumeGas(ctx, gasUsed) if err != nil { return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) @@ -436,20 +441,21 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller ctx.EventManager().EmitEvents(events) // delete old secondary index entry - k.deleteContractSecondIndex(ctx, contractAddress, contractInfo) + k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) // persist migration updates historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) k.appendToContractHistory(ctx, contractAddress, historyEntry) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) k.storeContractInfo(ctx, contractAddress, contractInfo) // dispatch submessages then messages - err = k.dispatchAll(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } return &sdk.Result{ - Data: res.Data, + Data: data, }, nil } @@ -457,6 +463,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // another native Go module directly. Thus, the keeper doesn't place any access controls on it, that is the // responsibility or the app developer (who passes the wasm.Keeper in app.go) func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "sudo") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err @@ -469,10 +476,9 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte env := types.NewEnv(ctx, contractAddress) // prepare querier - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddress, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddress, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.Sudo(codeInfo.CodeHash, env, msg, wasmStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) + res, gasUsed, execErr := k.wasmVM.Sudo(codeInfo.CodeHash, env, msg, prefixStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -483,13 +489,13 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte ctx.EventManager().EmitEvents(events) // dispatch submessages then messages - err = k.dispatchAll(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } return &sdk.Result{ - Data: res.Data, + Data: data, }, nil } @@ -511,12 +517,11 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply was // prepare querier querier := QueryHandler{ Ctx: ctx, - Plugins: k.queryPlugins, + Plugins: k.wasmVMQueryHandler, GasMultiplier: k.getGasMultiplier(ctx), } gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.Reply(codeInfo.CodeHash, env, reply, wasmStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) + res, gasUsed, execErr := k.wasmVM.Reply(codeInfo.CodeHash, env, reply, prefixStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -527,28 +532,35 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply was ctx.EventManager().EmitEvents(events) // dispatch submessages then messages - err = k.dispatchAll(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } - return &sdk.Result{ - Data: res.Data, + Data: data, }, nil } -func (k Keeper) deleteContractSecondIndex(ctx sdk.Context, contractAddress sdk.AccAddress, contractInfo *types.ContractInfo) { - ctx.KVStore(k.storeKey).Delete(types.GetContractByCreatedSecondaryIndexKey(contractAddress, contractInfo)) +// addToContractCodeSecondaryIndex adds element to the index for contracts-by-codeid queries +func (k Keeper) addToContractCodeSecondaryIndex(ctx sdk.Context, contractAddress sdk.AccAddress, entry types.ContractCodeHistoryEntry) { + store := ctx.KVStore(k.storeKey) + store.Set(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry), []byte{}) } -// UpdateContractAdmin sets the admin value on the ContractInfo. It must be a valid address (use ClearContractAdmin to remove it) -func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newAdmin sdk.AccAddress) error { - return k.setContractAdmin(ctx, contractAddress, caller, newAdmin, k.authZPolicy) +// removeFromContractCodeSecondaryIndex removes element to the index for contracts-by-codeid queries +func (k Keeper) removeFromContractCodeSecondaryIndex(ctx sdk.Context, contractAddress sdk.AccAddress, entry types.ContractCodeHistoryEntry) { + ctx.KVStore(k.storeKey).Delete(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry)) } -// ClearContractAdmin sets the admin value on the ContractInfo to nil, to disable further migrations/ updates. -func (k Keeper) ClearContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress) error { - return k.setContractAdmin(ctx, contractAddress, caller, nil, k.authZPolicy) +// IterateContractsByCode iterates over all contracts with given codeID ASC on code update time. +func (k Keeper) IterateContractsByCode(ctx sdk.Context, codeID uint64, cb func(address sdk.AccAddress) bool) { + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractByCodeIDSecondaryIndexPrefix(codeID)) + for iter := prefixStore.Iterator(nil, nil); iter.Valid(); iter.Next() { + key := iter.Key() + if cb(key[types.AbsoluteTxPositionLen:]) { + return + } + } } // UpdateContractStatus sets a new status of the contract on the ContractInfo. @@ -616,8 +628,22 @@ func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) return r } +// getLastContractHistoryEntry returns the last element from history. To be used internally only as it panics when none exists +func (k Keeper) getLastContractHistoryEntry(ctx sdk.Context, contractAddr sdk.AccAddress) types.ContractCodeHistoryEntry { + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr)) + iter := prefixStore.ReverseIterator(nil, nil) + var r types.ContractCodeHistoryEntry + if !iter.Valid() { + // all contracts have a history + panic(fmt.Sprintf("no history for %s", contractAddr.String())) + } + k.cdc.MustUnmarshalBinaryBare(iter.Value(), &r) + return r +} + // QuerySmart queries the smart contract itself. func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-smart") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return nil, err @@ -627,11 +653,10 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b } // prepare querier - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) env := types.NewEnv(ctx, contractAddr) - wasmStore := types.NewWasmStore(prefixStore) - queryResult, gasUsed, qErr := k.wasmer.Query(codeInfo.CodeHash, env, req, wasmStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gasForContract(ctx, k.getGasMultiplier(ctx))) + queryResult, gasUsed, qErr := k.wasmVM.Query(codeInfo.CodeHash, env, req, prefixStore, k.cosmwasmAPI(ctx), querier, k.gasMeter(ctx), gasForContract(ctx, k.getGasMultiplier(ctx))) k.consumeGas(ctx, gasUsed) if qErr != nil { return nil, sdkerrors.Wrap(types.ErrQueryFailed, qErr.Error()) @@ -641,6 +666,7 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b // QueryRaw returns the contract's state for give key. Returns `nil` when key is `nil`. func (k Keeper) QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-raw") if key == nil { return nil } @@ -681,15 +707,15 @@ func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) return &contract } -func (k Keeper) containsContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool { +func (k Keeper) HasContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool { store := ctx.KVStore(k.storeKey) return store.Has(types.GetContractAddressKey(contractAddress)) } +// storeContractInfo persists the ContractInfo. No secondary index updated here. func (k Keeper) storeContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, contract *types.ContractInfo) { store := ctx.KVStore(k.storeKey) store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshalBinaryBare(contract)) - store.Set(types.GetContractByCreatedSecondaryIndexKey(contractAddress, contract), []byte{}) } func (k Keeper) IterateContractInfo(ctx sdk.Context, cb func(sdk.AccAddress, types.ContractInfo) bool) { @@ -763,17 +789,17 @@ func (k Keeper) GetByteCode(ctx sdk.Context, codeID uint64) ([]byte, error) { return nil, nil } k.cdc.MustUnmarshalBinaryBare(codeInfoBz, &codeInfo) - return k.wasmer.GetCode(codeInfo.CodeHash) + return k.wasmVM.GetCode(codeInfo.CodeHash) } // PinCode pins the wasm contract in wasmvm cache -func (k Keeper) PinCode(ctx sdk.Context, codeID uint64) error { +func (k Keeper) pinCode(ctx sdk.Context, codeID uint64) error { codeInfo := k.GetCodeInfo(ctx, codeID) if codeInfo == nil { return sdkerrors.Wrap(types.ErrNotFound, "code info") } - if err := k.wasmer.Pin(codeInfo.CodeHash); err != nil { + if err := k.wasmVM.Pin(codeInfo.CodeHash); err != nil { return sdkerrors.Wrap(types.ErrPinContractFailed, err.Error()) } store := ctx.KVStore(k.storeKey) @@ -783,12 +809,12 @@ func (k Keeper) PinCode(ctx sdk.Context, codeID uint64) error { } // UnpinCode removes the wasm contract from wasmvm cache -func (k Keeper) UnpinCode(ctx sdk.Context, codeID uint64) error { +func (k Keeper) unpinCode(ctx sdk.Context, codeID uint64) error { codeInfo := k.GetCodeInfo(ctx, codeID) if codeInfo == nil { return sdkerrors.Wrap(types.ErrNotFound, "code info") } - if err := k.wasmer.Unpin(codeInfo.CodeHash); err != nil { + if err := k.wasmVM.Unpin(codeInfo.CodeHash); err != nil { return sdkerrors.Wrap(types.ErrUnpinContractFailed, err.Error()) } @@ -808,148 +834,33 @@ func (k Keeper) InitializePinnedCodes(ctx sdk.Context) error { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PinnedCodeIndexPrefix) iter := store.Iterator(nil, nil) for ; iter.Valid(); iter.Next() { - codeInfo := k.GetCodeInfo(ctx, types.ParsePinnedCodeIndex(iter.Value())) + codeInfo := k.GetCodeInfo(ctx, types.ParsePinnedCodeIndex(iter.Key())) if codeInfo == nil { return sdkerrors.Wrap(types.ErrNotFound, "code info") } - if err := k.wasmer.Pin(codeInfo.CodeHash); err != nil { + if err := k.wasmVM.Pin(codeInfo.CodeHash); err != nil { return sdkerrors.Wrap(types.ErrPinContractFailed, err.Error()) } } return nil } -func (k Keeper) dispatchAll(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, subMsgs []wasmvmtypes.SubMsg, msgs []wasmvmtypes.CosmosMsg) error { - // first dispatch all submessages (and the replies). - err := k.dispatchSubmessages(ctx, contractAddr, ibcPort, subMsgs) - if err != nil { - return err +// setContractInfoExtension updates the extension point data that is stored with the contract info +func (k Keeper) setContractInfoExtension(ctx sdk.Context, contractAddr sdk.AccAddress, ext types.ContractInfoExtension) error { + info := k.GetContractInfo(ctx, contractAddr) + if info == nil { + return sdkerrors.Wrap(types.ErrNotFound, "contract info") } - // then dispatch all the normal messages - return k.dispatchMessages(ctx, contractAddr, ibcPort, msgs) -} - -func (k Keeper) dispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error { - for _, msg := range msgs { - events, _, err := k.messenger.DispatchMsg(ctx, contractAddr, ibcPort, msg) - if err != nil { - return err - } - // redispatch all events, (type sdk.EventTypeMessage will be filtered out in the handler) - ctx.EventManager().EmitEvents(events) - } - return nil -} - -func (k Keeper) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg wasmvmtypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data [][]byte, err error) { - limitedMeter := sdk.NewGasMeter(gasLimit) - subCtx := ctx.WithGasMeter(limitedMeter) - - // catch out of gas panic and just charge the entire gas limit - defer func() { - if r := recover(); r != nil { - // if it's not an OutOfGas error, raise it again - if _, ok := r.(sdk.ErrorOutOfGas); !ok { - // log it to get the original stack trace somewhere (as panic(r) keeps message but stacktrace to here - k.Logger(ctx).Info("SubMsg rethrowing panic: %#v", r) - panic(r) - } - ctx.GasMeter().ConsumeGas(gasLimit, "Sub-Message OutOfGas panic") - err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "SubMsg hit gas limit") - } - }() - events, data, err = k.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg) - - // make sure we charge the parent what was spent - spent := subCtx.GasMeter().GasConsumed() - ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message") - - return events, data, err -} - -// dispatchSubmessages builds a sandbox to execute these messages and returns the execution result to the contract -// that dispatched them, both on success as well as failure -func (k Keeper) dispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) error { - for _, msg := range msgs { - // first, we build a sub-context which we can use inside the submessages - subCtx, commit := ctx.CacheContext() - - // check how much gas left locally, optionally wrap the gas meter - gasRemaining := ctx.GasMeter().Limit() - ctx.GasMeter().GasConsumed() - limitGas := msg.GasLimit != nil && (*msg.GasLimit < gasRemaining) - - var err error - var events []sdk.Event - var data [][]byte - if limitGas { - events, data, err = k.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit) - } else { - events, data, err = k.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg) - } - - // if it succeeds, commit state changes from submessage, and pass on events to Event Manager - if err == nil { - commit() - ctx.EventManager().EmitEvents(events) - } - // on failure, revert state from sandbox, and ignore events (just skip doing the above) - - var result wasmvmtypes.SubcallResult - if err == nil { - // just take the first one for now if there are multiple sub-sdk messages - // and safely return nothing if no data - var responseData []byte - if len(data) > 0 { - responseData = data[0] - } - result = wasmvmtypes.SubcallResult{ - Ok: &wasmvmtypes.SubcallResponse{ - Events: sdkEventsToWasmVMEvents(events), - Data: responseData, - }, - } - } else { - result = wasmvmtypes.SubcallResult{ - Err: err.Error(), - } - } - - // now handle the reply, we use the parent context, and abort on error - reply := wasmvmtypes.Reply{ - ID: msg.ID, - Result: result, - } - - // we can ignore any result returned as there is nothing to do with the data - // and the events are already in the ctx.EventManager() - _, err = k.reply(ctx, contractAddr, reply) - if err != nil { - return err - } + if err := info.SetExtension(ext); err != nil { + return err } + k.storeContractInfo(ctx, contractAddr, info) return nil } -func sdkEventsToWasmVMEvents(events []sdk.Event) []wasmvmtypes.Event { - res := make([]wasmvmtypes.Event, len(events)) - for i, ev := range events { - res[i] = wasmvmtypes.Event{ - Type: ev.Type, - Attributes: sdkAttributesToWasmVMAttributes(ev.Attributes), - } - } - return res -} - -func sdkAttributesToWasmVMAttributes(attrs []abci.EventAttribute) []wasmvmtypes.EventAttribute { - res := make([]wasmvmtypes.EventAttribute, len(attrs)) - for i, attr := range attrs { - res[i] = wasmvmtypes.EventAttribute{ - Key: string(attr.Key), - Value: string(attr.Value), - } - } - return res +// handleContractResponse processes the contract response +func (k *Keeper) handleContractResponse(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, res *wasmvmtypes.Response) ([]byte, error) { + return k.wasmVMResponseHandler.Handle(ctx, contractAddr, ibcPort, res.Submessages, res.Messages, res.Data) } func gasForContract(ctx sdk.Context, gasMultiplier uint64) uint64 { @@ -1037,13 +948,14 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c * if !k.containsCodeInfo(ctx, c.CodeID) { return sdkerrors.Wrapf(types.ErrNotFound, "code id: %d", c.CodeID) } - if k.containsContractInfo(ctx, contractAddr) { + if k.HasContractInfo(ctx, contractAddr) { return sdkerrors.Wrapf(types.ErrDuplicate, "contract: %s", contractAddr) } historyEntry := c.ResetFromGenesis(ctx) k.appendToContractHistory(ctx, contractAddr, historyEntry) k.storeContractInfo(ctx, contractAddr, c) + k.addToContractCodeSecondaryIndex(ctx, contractAddr, historyEntry) return k.importContractState(ctx, contractAddr, state) } @@ -1075,24 +987,38 @@ func (k Keeper) gasMeter(ctx sdk.Context) MultipliedGasMeter { // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return moduleLogger(ctx) +} + +func moduleLogger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } -// CoinTransferrer replicates the cosmos-sdk behaviour as in +// Querier creates a new grpc querier instance +func Querier(k *Keeper) *GrpcQuerier { + return NewGrpcQuerier(k.cdc, k.storeKey, k, k.queryGasLimit) +} + +// QueryGasLimit returns the gas limit for smart queries. +func (k Keeper) QueryGasLimit() sdk.Gas { + return k.queryGasLimit +} + +// BankCoinTransferrer replicates the cosmos-sdk behaviour as in // https://github.com/cosmos/cosmos-sdk/blob/v0.41.4/x/bank/keeper/msg_server.go#L26 -type CoinTransferrer struct { +type BankCoinTransferrer struct { keeper types.BankKeeper } -func NewBankCoinTransferrer(keeper types.BankKeeper) CoinTransferrer { - return CoinTransferrer{ +func NewBankCoinTransferrer(keeper types.BankKeeper) BankCoinTransferrer { + return BankCoinTransferrer{ keeper: keeper, } } // TransferCoins transfers coins from source to destination account when coin send was enabled for them and the recipient // is not in the blocked address list. -func (c CoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { +func (c BankCoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { if err := c.keeper.SendEnabledCoins(ctx, amt...); err != nil { return err } @@ -1105,3 +1031,39 @@ func (c CoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, } return nil } + +type msgDispatcher interface { + DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error + DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) +} + +// DefaultWasmVMContractResponseHandler default implementation that first dispatches submessage then normal messages. +// The Submessage execution may include an success/failure response handling by the contract that can overwrite the +// original +type DefaultWasmVMContractResponseHandler struct { + md msgDispatcher +} + +func NewDefaultWasmVMContractResponseHandler(md msgDispatcher) *DefaultWasmVMContractResponseHandler { + return &DefaultWasmVMContractResponseHandler{md: md} +} + +// Handle processes the data returned by a contract invocation. +func (h DefaultWasmVMContractResponseHandler) Handle( + ctx sdk.Context, + contractAddr sdk.AccAddress, + ibcPort string, + submessages []wasmvmtypes.SubMsg, + messages []wasmvmtypes.CosmosMsg, + origRspData []byte, +) ([]byte, error) { + result := origRspData + switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, submessages); { + case err != nil: + return nil, sdkerrors.Wrap(err, "submessages") + case rsp != nil: + result = rsp + } + // then dispatch all the normal messages + return result, sdkerrors.Wrap(h.md.DispatchMessages(ctx, contractAddr, ibcPort, messages), "messages") +} diff --git a/x/wasm/internal/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go similarity index 78% rename from x/wasm/internal/keeper/keeper_test.go rename to x/wasm/keeper/keeper_test.go index 30a6c49ad1..ecf5b81faa 100644 --- a/x/wasm/internal/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -13,8 +13,8 @@ import ( sdkerrors "github.com/line/lfb-sdk/types/errors" authtypes "github.com/line/lfb-sdk/x/auth/types" banktypes "github.com/line/lfb-sdk/x/bank/types" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" tmproto "github.com/line/ostracon/proto/ostracon/types" wasmvm "github.com/line/wasmvm" wasmvmtypes "github.com/line/wasmvm/types" @@ -25,13 +25,13 @@ import ( const SupportedFeatures = "staking,stargate" func TestNewKeeper(t *testing.T) { - _, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - require.NotNil(t, keepers.WasmKeeper) + _, keepers := CreateTestInput(t, false, SupportedFeatures) + require.NotNil(t, keepers.ContractKeeper) } func TestCreate(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -43,7 +43,7 @@ func TestCreate(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(1), contractID) // and verify content - storedCode, err := keeper.GetByteCode(ctx, contractID) + storedCode, err := keepers.WasmKeeper.GetByteCode(ctx, contractID) require.NoError(t, err) require.Equal(t, wasmCode, storedCode) } @@ -79,9 +79,9 @@ func TestCreateStoresInstantiatePermission(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper - keeper.setParams(ctx, types.Params{ + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper + keepers.WasmKeeper.setParams(ctx, types.Params{ CodeUploadAccess: types.AllowEverybody, InstantiateDefaultPermission: spec.srcPermission, ContractStatusAccess: types.DefaultContractStatusAccess, @@ -95,7 +95,7 @@ func TestCreateStoresInstantiatePermission(t *testing.T) { codeID, err := keeper.Create(ctx, myAddr, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag", nil) require.NoError(t, err) - codeInfo := keeper.GetCodeInfo(ctx, codeID) + codeInfo := keepers.WasmKeeper.GetCodeInfo(ctx, codeID) require.NotNil(t, codeInfo) assert.True(t, spec.expInstConf.Equals(codeInfo.InstantiateConfig), "got %#v", codeInfo.InstantiateConfig) }) @@ -103,8 +103,8 @@ func TestCreateStoresInstantiatePermission(t *testing.T) { } func TestCreateWithParamPermissions(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.WasmKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.ContractKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -139,7 +139,7 @@ func TestCreateWithParamPermissions(t *testing.T) { t.Run(msg, func(t *testing.T) { params := types.DefaultParams() params.CodeUploadAccess = spec.srcPermission - keeper.setParams(ctx, params) + keepers.WasmKeeper.setParams(ctx, params) _, err := keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag", nil) require.True(t, spec.expError.Is(err), err) if spec.expError != nil { @@ -150,8 +150,8 @@ func TestCreateWithParamPermissions(t *testing.T) { } func TestCreateDuplicate(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -170,17 +170,17 @@ func TestCreateDuplicate(t *testing.T) { require.Equal(t, uint64(2), duplicateID) // and verify both content is proper - storedCode, err := keeper.GetByteCode(ctx, contractID) + storedCode, err := keepers.WasmKeeper.GetByteCode(ctx, contractID) require.NoError(t, err) require.Equal(t, wasmCode, storedCode) - storedCode, err = keeper.GetByteCode(ctx, duplicateID) + storedCode, err = keepers.WasmKeeper.GetByteCode(ctx, duplicateID) require.NoError(t, err) require.Equal(t, wasmCode, storedCode) } func TestCreateWithSimulation(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper ctx = ctx.WithBlockHeader(tmproto.Header{Height: 1}). WithGasMeter(stypes.NewInfiniteGasMeter()) @@ -197,14 +197,14 @@ func TestCreateWithSimulation(t *testing.T) { require.Equal(t, uint64(1), contractID) // then try to create it in non-simulation mode (should not fail) - ctx, keepers = CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper = keepers.AccountKeeper, keepers.WasmKeeper + ctx, keepers = CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper = keepers.AccountKeeper, keepers.ContractKeeper contractID, err = keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag", nil) require.NoError(t, err) require.Equal(t, uint64(1), contractID) // and verify content - code, err := keeper.GetByteCode(ctx, contractID) + code, err := keepers.WasmKeeper.GetByteCode(ctx, contractID) require.NoError(t, err) require.Equal(t, code, wasmCode) } @@ -235,8 +235,8 @@ func TestIsSimulationMode(t *testing.T) { } func TestCreateWithGzippedPayload(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -248,7 +248,7 @@ func TestCreateWithGzippedPayload(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(1), contractID) // and verify content - storedCode, err := keeper.GetByteCode(ctx, contractID) + storedCode, err := keepers.WasmKeeper.GetByteCode(ctx, contractID) require.NoError(t, err) rawCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) @@ -256,8 +256,8 @@ func TestCreateWithGzippedPayload(t *testing.T) { } func TestInstantiate(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -281,17 +281,17 @@ func TestInstantiate(t *testing.T) { gasBefore := ctx.GasMeter().GasConsumed() // create with no balance is also legal - gotContractAddr, _, err := keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, "demo contract 1", nil) + gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, "demo contract 1", nil) require.NoError(t, err) require.Equal(t, "link18vd8fpwxzck93qlwghaj6arh4p7c5n89fvcmzu", gotContractAddr.String()) gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x11b90), gasAfter-gasBefore) + require.Equal(t, uint64(0x122a0), gasAfter-gasBefore) } // ensure it is stored properly - info := keeper.GetContractInfo(ctx, gotContractAddr) + info := keepers.WasmKeeper.GetContractInfo(ctx, gotContractAddr) require.NotNil(t, info) assert.Equal(t, creator.String(), info.Creator) assert.Equal(t, codeID, info.CodeID) @@ -304,7 +304,7 @@ func TestInstantiate(t *testing.T) { Updated: types.NewAbsoluteTxPosition(ctx), Msg: json.RawMessage(initMsgBz), }} - assert.Equal(t, exp, keeper.GetContractHistory(ctx, gotContractAddr)) + assert.Equal(t, exp, keepers.WasmKeeper.GetContractHistory(ctx, gotContractAddr)) } func TestInstantiateWithDeposit(t *testing.T) { @@ -343,8 +343,8 @@ func TestInstantiateWithDeposit(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.WasmKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.ContractKeeper if spec.fundAddr { fundAccounts(t, ctx, accKeeper, bankKeeper, spec.srcActor, sdk.NewCoins(sdk.NewInt64Coin("denom", 200))) @@ -353,7 +353,7 @@ func TestInstantiateWithDeposit(t *testing.T) { require.NoError(t, err) // when - addr, _, err := keeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "my label", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "my label", deposit) // then if spec.expError { require.Error(t, err) @@ -413,22 +413,22 @@ func TestInstantiateWithPermissions(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.WasmKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.ContractKeeper fundAccounts(t, ctx, accKeeper, bankKeeper, spec.srcActor, deposit) contractID, err := keeper.Create(ctx, myAddr, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "", &spec.srcPermission) require.NoError(t, err) - _, _, err = keeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "demo contract 1", nil) + _, _, err = keepers.ContractKeeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "demo contract 1", nil) assert.True(t, spec.expError.Is(err), "got %+v", err) }) } } func TestInstantiateWithNonExistingCodeID(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, bankKeeper := keepers.AccountKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -438,13 +438,13 @@ func TestInstantiateWithNonExistingCodeID(t *testing.T) { require.NoError(t, err) const nonExistingCodeID = 9999 - addr, _, err := keeper.Instantiate(ctx, nonExistingCodeID, creator, nil, initMsgBz, "demo contract 2", nil) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, nonExistingCodeID, creator, nil, initMsgBz, "demo contract 2", nil) require.True(t, types.ErrNotFound.Is(err), err) require.Nil(t, addr) } func TestInstantiateWithContractDataResponse(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) wasmerMock := &wasmtesting.MockWasmer{ InstantiateFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) { @@ -455,14 +455,14 @@ func TestInstantiateWithContractDataResponse(t *testing.T) { } example := StoreRandomContract(t, ctx, keepers, wasmerMock) - _, data, err := keepers.WasmKeeper.Instantiate(ctx, example.CodeID, example.CreatorAddr, nil, nil, "test", nil) + _, data, err := keepers.ContractKeeper.Instantiate(ctx, example.CodeID, example.CreatorAddr, nil, nil, "test", nil) require.NoError(t, err) assert.Equal(t, []byte("my-response-data"), data) } func TestExecute(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -483,7 +483,7 @@ func TestExecute(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit) require.NoError(t, err) require.Equal(t, "link18vd8fpwxzck93qlwghaj6arh4p7c5n89fvcmzu", addr.String()) @@ -504,7 +504,7 @@ func TestExecute(t *testing.T) { // unauthorized - trialCtx so we don't change state trialCtx := ctx.WithMultiStore(ctx.MultiStore().CacheWrap().(sdk.MultiStore)) - res, err := keeper.Execute(trialCtx, addr, creator, []byte(`{"release":{}}`), nil) + res, err := keepers.ContractKeeper.Execute(trialCtx, addr, creator, []byte(`{"release":{}}`), nil) require.Error(t, err) require.True(t, errors.Is(err, types.ErrExecuteFailed)) require.Equal(t, "Unauthorized: execute wasm contract failed", err.Error()) @@ -513,7 +513,7 @@ func TestExecute(t *testing.T) { start := time.Now() gasBefore := ctx.GasMeter().GasConsumed() - res, err = keeper.Execute(ctx, addr, fred, []byte(`{"release":{}}`), topUp) + res, err = keepers.ContractKeeper.Execute(ctx, addr, fred, []byte(`{"release":{}}`), topUp) diff := time.Now().Sub(start) require.NoError(t, err) require.NotNil(t, res) @@ -521,7 +521,7 @@ func TestExecute(t *testing.T) { // make sure gas is properly deducted from ctx gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x1180c), gasAfter-gasBefore) + require.Equal(t, uint64(0x12917), gasAfter-gasBefore) } // ensure bob now exists and got both payments released bobAcct = accKeeper.GetAccount(ctx, bob) @@ -597,8 +597,8 @@ func TestExecuteWithDeposit(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.WasmKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.ContractKeeper if spec.newBankParams != nil { bankKeeper.SetParams(ctx, *spec.newBankParams) } @@ -612,11 +612,11 @@ func TestExecuteWithDeposit(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - contractAddr, _, err := keeper.Instantiate(ctx, codeID, spec.srcActor, nil, initMsgBz, "my label", nil) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, spec.srcActor, nil, initMsgBz, "my label", nil) require.NoError(t, err) // when - _, err = keeper.Execute(ctx, contractAddr, spec.srcActor, []byte(`{"release":{}}`), deposit) + _, err = keepers.ContractKeeper.Execute(ctx, contractAddr, spec.srcActor, []byte(`{"release":{}}`), deposit) // then if spec.expError { @@ -631,8 +631,8 @@ func TestExecuteWithDeposit(t *testing.T) { } func TestExecuteWithNonExistingAddress(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit.Add(deposit...)) @@ -644,8 +644,8 @@ func TestExecuteWithNonExistingAddress(t *testing.T) { } func TestExecuteWithPanic(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -666,11 +666,11 @@ func TestExecuteWithPanic(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 4", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 4", deposit) require.NoError(t, err) // let's make sure we get a reasonable error, no panic/crash - _, err = keeper.Execute(ctx, addr, fred, []byte(`{"panic":{}}`), topUp) + _, err = keepers.ContractKeeper.Execute(ctx, addr, fred, []byte(`{"panic":{}}`), topUp) require.Error(t, err) require.True(t, errors.Is(err, types.ErrExecuteFailed)) // test with contains as "Display" implementation of the Wasmer "RuntimeError" is different for Mac and Linux @@ -678,8 +678,8 @@ func TestExecuteWithPanic(t *testing.T) { } func TestExecuteWithCpuLoop(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -700,7 +700,7 @@ func TestExecuteWithCpuLoop(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 5", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 5", deposit) require.NoError(t, err) // make sure we set a limit before calling @@ -717,14 +717,14 @@ func TestExecuteWithCpuLoop(t *testing.T) { }() // this should throw out of gas exception (panic) - _, err = keeper.Execute(ctx, addr, fred, []byte(`{"cpu_loop":{}}`), nil) + _, err = keepers.ContractKeeper.Execute(ctx, addr, fred, []byte(`{"cpu_loop":{}}`), nil) require.True(t, false, "We must panic before this line") } func TestExecuteWithStorageLoop(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -745,7 +745,7 @@ func TestExecuteWithStorageLoop(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 6", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 6", deposit) require.NoError(t, err) // make sure we set a limit before calling @@ -762,7 +762,7 @@ func TestExecuteWithStorageLoop(t *testing.T) { }() // this should throw out of gas exception (panic) - _, err = keeper.Execute(ctx, addr, fred, []byte(`{"storage_loop":{}}`), nil) + _, err = keepers.ContractKeeper.Execute(ctx, addr, fred, []byte(`{"storage_loop":{}}`), nil) require.True(t, false, "We must panic before this line") } @@ -804,8 +804,8 @@ func TestExecuteInactiveContract(t *testing.T) { } func TestMigrate(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -943,7 +943,7 @@ func TestMigrate(t *testing.T) { t.Run(msg, func(t *testing.T) { // given a contract instance ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) - contractAddr, _, err := keeper.Instantiate(ctx, spec.fromCodeID, creator, spec.admin, spec.initMsg, "demo contract", nil) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, spec.fromCodeID, creator, spec.admin, spec.initMsg, "demo contract", nil) require.NoError(t, err) if spec.overrideContractAddr != nil { contractAddr = spec.overrideContractAddr @@ -956,7 +956,7 @@ func TestMigrate(t *testing.T) { if spec.expErr != nil { return } - cInfo := keeper.GetContractInfo(ctx, contractAddr) + cInfo := keepers.WasmKeeper.GetContractInfo(ctx, contractAddr) assert.Equal(t, spec.toCodeID, cInfo.CodeID) assert.Equal(t, spec.expIBCPort, cInfo.IBCPortID != "", cInfo.IBCPortID) @@ -971,47 +971,56 @@ func TestMigrate(t *testing.T) { Updated: types.NewAbsoluteTxPosition(ctx), Msg: spec.migrateMsg, }} - assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr)) + assert.Equal(t, expHistory, keepers.WasmKeeper.GetContractHistory(ctx, contractAddr)) // and verify contract state - raw := keeper.QueryRaw(ctx, contractAddr, []byte("config")) - var stored map[string][]byte + raw := keepers.WasmKeeper.QueryRaw(ctx, contractAddr, []byte("config")) + var stored map[string]string require.NoError(t, json.Unmarshal(raw, &stored)) require.Contains(t, stored, "verifier") require.NoError(t, err) - assert.Equal(t, spec.expVerifier, sdk.AccAddress(stored["verifier"])) + assert.Equal(t, spec.expVerifier.String(), stored["verifier"]) }) } } func TestMigrateReplacesTheSecondIndex(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) example := InstantiateHackatomExampleContract(t, ctx, keepers) // then assert a second index exists store := ctx.KVStore(keepers.WasmKeeper.storeKey) oldContractInfo := keepers.WasmKeeper.GetContractInfo(ctx, example.Contract) require.NotNil(t, oldContractInfo) - exists := store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, oldContractInfo)) + createHistoryEntry := types.ContractCodeHistoryEntry{ + CodeID: example.CodeID, + Updated: types.NewAbsoluteTxPosition(ctx), + } + exists := store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, createHistoryEntry)) require.True(t, exists) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // increment for different block // when do migrate newCodeExample := StoreBurnerExampleContract(t, ctx, keepers) migMsgBz := BurnerExampleInitMsg{Payout: example.CreatorAddr}.GetBytes(t) - _, err := keepers.WasmKeeper.Migrate(ctx, example.Contract, example.CreatorAddr, newCodeExample.CodeID, migMsgBz) + _, err := keepers.ContractKeeper.Migrate(ctx, example.Contract, example.CreatorAddr, newCodeExample.CodeID, migMsgBz) require.NoError(t, err) + // then the new index exists - newContractInfo := keepers.WasmKeeper.GetContractInfo(ctx, example.Contract) - exists = store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, newContractInfo)) + migrateHistoryEntry := types.ContractCodeHistoryEntry{ + CodeID: newCodeExample.CodeID, + Updated: types.NewAbsoluteTxPosition(ctx), + } + exists = store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, migrateHistoryEntry)) require.True(t, exists) // and the old index was removed - exists = store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, oldContractInfo)) + exists = store.Has(types.GetContractByCreatedSecondaryIndexKey(example.Contract, createHistoryEntry)) require.False(t, exists) } func TestMigrateWithDispatchedMessage(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit.Add(deposit...)) @@ -1036,7 +1045,7 @@ func TestMigrateWithDispatchedMessage(t *testing.T) { initMsgBz := initMsg.GetBytes(t) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) - contractAddr, _, err := keeper.Instantiate(ctx, originalContractID, creator, fred, initMsgBz, "demo contract", deposit) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, originalContractID, creator, fred, initMsgBz, "demo contract", deposit) require.NoError(t, err) migMsgBz := BurnerExampleInitMsg{Payout: myPayoutAddr}.GetBytes(t) @@ -1080,7 +1089,7 @@ func TestMigrateWithDispatchedMessage(t *testing.T) { assert.JSONEq(t, expJSONEvts, prettyEvents(t, ctx.EventManager().Events())) // all persistent data cleared - m := keeper.QueryRaw(ctx, contractAddr, []byte("config")) + m := keepers.WasmKeeper.QueryRaw(ctx, contractAddr, []byte("config")) require.Len(t, m, 0) // and all deposit tokens sent to myPayoutAddr @@ -1123,6 +1132,74 @@ func TestMigrateInactiveContract(t *testing.T) { require.True(t, types.ErrInvalid.Is(err), "expected %v but got %+v", types.ErrInvalid, err) } +func TestIterateContractsByCode(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + k, c := keepers.WasmKeeper, keepers.ContractKeeper + example1 := InstantiateHackatomExampleContract(t, ctx, keepers) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + example2 := InstantiateIBCReflectContract(t, ctx, keepers) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + initMsg := HackatomExampleInitMsg{ + Verifier: RandomAccountAddress(t), + Beneficiary: RandomAccountAddress(t), + }.GetBytes(t) + contractAddr3, _, err := c.Instantiate(ctx, example1.CodeID, example1.CreatorAddr, nil, initMsg, "foo", nil) + require.NoError(t, err) + specs := map[string]struct { + codeID uint64 + exp []sdk.AccAddress + }{ + "multiple results": { + codeID: example1.CodeID, + exp: []sdk.AccAddress{example1.Contract, contractAddr3}, + }, + "single results": { + codeID: example2.CodeID, + exp: []sdk.AccAddress{example2.Contract}, + }, + "empty results": { + codeID: 99999, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var gotAddr []sdk.AccAddress + k.IterateContractsByCode(ctx, spec.codeID, func(address sdk.AccAddress) bool { + gotAddr = append(gotAddr, address) + return false + }) + assert.Equal(t, spec.exp, gotAddr) + }) + } +} + +func TestIterateContractsByCodeWithMigration(t *testing.T) { + // mock migration so that it does not fail when migrate example1 to example2.codeID + mockWasmVM := wasmtesting.MockWasmer{MigrateFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) { + return &wasmvmtypes.Response{}, 1, nil + }} + wasmtesting.MakeInstantiable(&mockWasmVM) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures, WithWasmEngine(&mockWasmVM)) + k, c := keepers.WasmKeeper, keepers.ContractKeeper + example1 := InstantiateHackatomExampleContract(t, ctx, keepers) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + example2 := InstantiateIBCReflectContract(t, ctx, keepers) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + _, err := c.Migrate(ctx, example1.Contract, example1.CreatorAddr, example2.CodeID, []byte("{}")) + require.NoError(t, err) + + // when + var gotAddr []sdk.AccAddress + k.IterateContractsByCode(ctx, example2.CodeID, func(address sdk.AccAddress) bool { + gotAddr = append(gotAddr, address) + return false + }) + + // then + exp := []sdk.AccAddress{example2.Contract, example1.Contract} + assert.Equal(t, exp, gotAddr) +} + type sudoMsg struct { // This is a tongue-in-check demo command. This is not the intended purpose of Sudo. // Here we show that some priviledged Go module can make a call that should never be exposed @@ -1141,8 +1218,8 @@ type stealFundsMsg struct { } func TestSudo(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit.Add(deposit...)) @@ -1161,7 +1238,7 @@ func TestSudo(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit) require.NoError(t, err) require.Equal(t, "link18vd8fpwxzck93qlwghaj6arh4p7c5n89fvcmzu", addr.String()) @@ -1183,7 +1260,7 @@ func TestSudo(t *testing.T) { sudoMsg, err := json.Marshal(msg) require.NoError(t, err) - res, err := keeper.Sudo(ctx, addr, sudoMsg) + res, err := keepers.WasmKeeper.Sudo(ctx, addr, sudoMsg) require.NoError(t, err) require.NotNil(t, res) @@ -1220,8 +1297,8 @@ func mustMarshal(t *testing.T, r interface{}) []byte { } func TestUpdateContractAdmin(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -1274,7 +1351,7 @@ func TestUpdateContractAdmin(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - addr, _, err := keeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil) require.NoError(t, err) if spec.overrideContractAddr != nil { addr = spec.overrideContractAddr @@ -1284,7 +1361,7 @@ func TestUpdateContractAdmin(t *testing.T) { if spec.expErr != nil { return } - cInfo := keeper.GetContractInfo(ctx, addr) + cInfo := keepers.WasmKeeper.GetContractInfo(ctx, addr) assert.Equal(t, spec.newAdmin.String(), cInfo.Admin) }) } @@ -1327,8 +1404,8 @@ func TestUpdateContractAdminInactiveContract(t *testing.T) { } func TestClearContractAdmin(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) @@ -1376,7 +1453,7 @@ func TestClearContractAdmin(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - addr, _, err := keeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil) require.NoError(t, err) if spec.overrideContractAddr != nil { addr = spec.overrideContractAddr @@ -1386,7 +1463,7 @@ func TestClearContractAdmin(t *testing.T) { if spec.expErr != nil { return } - cInfo := keeper.GetContractInfo(ctx, addr) + cInfo := keepers.WasmKeeper.GetContractInfo(ctx, addr) assert.Empty(t, cInfo.Admin) }) } @@ -1533,3 +1610,121 @@ func runUpdateStatusSpec(t *testing.T, msg string, keeper *Keeper, ctx sdk.Conte assert.Equal(t, spec.newStatus, cInfo.Status) }) } + +func TestInitializePinnedCodes(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + k := keepers.WasmKeeper + + var capturedChecksums []wasmvm.Checksum + mock := wasmtesting.MockWasmer{PinFn: func(checksum wasmvm.Checksum) error { + capturedChecksums = append(capturedChecksums, checksum) + return nil + }} + wasmtesting.MakeIBCInstantiable(&mock) + + const testItems = 3 + myCodeIDs := make([]uint64, testItems) + for i := 0; i < testItems; i++ { + myCodeIDs[i] = StoreRandomContract(t, ctx, keepers, &mock).CodeID + require.NoError(t, k.pinCode(ctx, myCodeIDs[i])) + } + capturedChecksums = nil + + // when + gotErr := k.InitializePinnedCodes(ctx) + + // then + require.NoError(t, gotErr) + require.Len(t, capturedChecksums, testItems) + for i, c := range myCodeIDs { + var exp wasmvm.Checksum = k.GetCodeInfo(ctx, c).CodeHash + assert.Equal(t, exp, capturedChecksums[i]) + } +} + +func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) { + noopDMsgs := func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error { + return nil + } + + specs := map[string]struct { + srcData []byte + setup func(m *wasmtesting.MockMsgDispatcher) + expErr bool + expData []byte + }{ + "submessage overwrites result when set": { + srcData: []byte("otherData"), + setup: func(m *wasmtesting.MockMsgDispatcher) { + m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + return []byte("mySubMsgData"), nil + } + m.DispatchMessagesFn = noopDMsgs + }, + expErr: false, + expData: []byte("mySubMsgData"), + }, + "submessage overwrites result when empty": { + srcData: []byte("otherData"), + setup: func(m *wasmtesting.MockMsgDispatcher) { + m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + return []byte(""), nil + } + m.DispatchMessagesFn = noopDMsgs + }, + expErr: false, + expData: []byte(""), + }, + "submessage do not overwrite result when nil": { + srcData: []byte("otherData"), + setup: func(m *wasmtesting.MockMsgDispatcher) { + m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + return nil, nil + } + m.DispatchMessagesFn = noopDMsgs + }, + expErr: false, + expData: []byte("otherData"), + }, + "submessage error aborts process": { + setup: func(m *wasmtesting.MockMsgDispatcher) { + m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + return nil, errors.New("test - ignore") + } + }, + expErr: true, + }, + "message error aborts process": { + setup: func(m *wasmtesting.MockMsgDispatcher) { + m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + return []byte("mySubMsgData"), nil + } + m.DispatchMessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error { + return errors.New("test - ignore") + } + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var ( + subMsgs []wasmvmtypes.SubMsg + msgs []wasmvmtypes.CosmosMsg + ) + var mock wasmtesting.MockMsgDispatcher + spec.setup(&mock) + d := NewDefaultWasmVMContractResponseHandler(&mock) + // when + + gotData, gotErr := d.Handle(sdk.Context{}, RandomAccountAddress(t), "ibc-port", subMsgs, msgs, spec.srcData) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expData, gotData) + }) + } + +} diff --git a/x/wasm/internal/keeper/legacy_querier.go b/x/wasm/keeper/legacy_querier.go similarity index 73% rename from x/wasm/internal/keeper/legacy_querier.go rename to x/wasm/keeper/legacy_querier.go index f4de06b6fb..300427d1b3 100644 --- a/x/wasm/internal/keeper/legacy_querier.go +++ b/x/wasm/keeper/legacy_querier.go @@ -3,13 +3,11 @@ package keeper import ( "encoding/json" "reflect" - "sort" "strconv" - "strings" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" ) @@ -29,7 +27,7 @@ const ( ) // NewLegacyQuerier creates a new querier -func NewLegacyQuerier(keeper *Keeper) sdk.Querier { +func NewLegacyQuerier(keeper types.ViewKeeper, gasLimit sdk.Gas) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { var ( rsp interface{} @@ -42,19 +40,19 @@ func NewLegacyQuerier(keeper *Keeper) sdk.Querier { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } //nolint:staticcheck - rsp, err = queryContractInfo(ctx, addr, *keeper) + rsp, err = queryContractInfo(ctx, addr, keeper) case QueryListContractByCode: codeID, err := strconv.ParseUint(path[1], 10, 64) if err != nil { return nil, sdkerrors.Wrapf(types.ErrInvalid, "code id: %s", err.Error()) } //nolint:staticcheck - rsp, err = queryContractListByCode(ctx, codeID, *keeper) + rsp = queryContractListByCode(ctx, codeID, keeper) case QueryGetContractState: if len(path) < 3 { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint") } - return queryContractState(ctx, path[1], path[2], req.Data, keeper) + return queryContractState(ctx, path[1], path[2], req.Data, gasLimit, keeper) case QueryGetCode: codeID, err := strconv.ParseUint(path[1], 10, 64) if err != nil { @@ -64,14 +62,14 @@ func NewLegacyQuerier(keeper *Keeper) sdk.Querier { rsp, err = queryCode(ctx, codeID, keeper) case QueryListCode: //nolint:staticcheck - rsp, err = queryCodeList(ctx, *keeper) + rsp, err = queryCodeList(ctx, keeper) case QueryContractHistory: contractAddr, err := sdk.AccAddressFromBech32(path[1]) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } //nolint:staticcheck - rsp, err = queryContractHistory(ctx, contractAddr, *keeper) + rsp, err = queryContractHistory(ctx, contractAddr, keeper) default: return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint") } @@ -89,7 +87,7 @@ func NewLegacyQuerier(keeper *Keeper) sdk.Querier { } } -func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, keeper *Keeper) (json.RawMessage, error) { +func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, gasLimit sdk.Gas, keeper types.ViewKeeper) (json.RawMessage, error) { contractAddr, err := sdk.AccAddressFromBech32(bech) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, bech) @@ -113,7 +111,7 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, return keeper.QueryRaw(ctx, contractAddr, data), nil case QueryMethodContractStateSmart: // we enforce a subjective gas limit on all queries to avoid infinite loops - ctx = ctx.WithGasMeter(sdk.NewGasMeter(keeper.queryGasLimit)) + ctx = ctx.WithGasMeter(sdk.NewGasMeter(gasLimit)) // this returns raw bytes (must be base64-encoded) return keeper.QuerySmart(ctx, contractAddr, data) default: @@ -127,7 +125,7 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, } //nolint:unparam -func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, error) { +func queryCodeList(ctx sdk.Context, keeper types.ViewKeeper) ([]types.CodeInfoResponse, error) { var info []types.CodeInfoResponse keeper.IterateCodeInfos(ctx, func(i uint64, res types.CodeInfo) bool { info = append(info, types.CodeInfoResponse{ @@ -143,7 +141,7 @@ func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, er } //nolint:unparam -func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper Keeper) ([]types.ContractCodeHistoryEntry, error) { +func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper types.ViewKeeper) ([]types.ContractCodeHistoryEntry, error) { history := keeper.GetContractHistory(ctx, contractAddr) // redact response for i := range history { @@ -153,32 +151,11 @@ func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper K } //nolint:unparam -func queryContractListByCode(ctx sdk.Context, codeID uint64, keeper Keeper) ([]types.ContractInfoWithAddress, error) { - var contracts []types.ContractInfoWithAddress - keeper.IterateContractInfo(ctx, func(addr sdk.AccAddress, info types.ContractInfo) bool { - if info.CodeID == codeID { - // and add the address - infoWithAddress := types.ContractInfoWithAddress{ - Address: addr.String(), - ContractInfo: &info, - } - contracts = append(contracts, infoWithAddress) - } +func queryContractListByCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) []string { + var contracts []string + keeper.IterateContractsByCode(ctx, codeID, func(addr sdk.AccAddress) bool { + contracts = append(contracts, addr.String()) return false }) - - // now we sort them by AbsoluteTxPosition - sort.Slice(contracts, func(i, j int) bool { - this := contracts[i].ContractInfo.Created - other := contracts[j].ContractInfo.Created - if this.Equal(other) { - return strings.Compare(contracts[i].Address, contracts[j].Address) < 0 - } - return this.LessThan(other) - }) - - for i := range contracts { - contracts[i].Created = nil - } - return contracts, nil + return contracts } diff --git a/x/wasm/internal/keeper/legacy_querier_test.go b/x/wasm/keeper/legacy_querier_test.go similarity index 89% rename from x/wasm/internal/keeper/legacy_querier_test.go rename to x/wasm/keeper/legacy_querier_test.go index 15d400b900..ccc8733481 100644 --- a/x/wasm/internal/keeper/legacy_querier_test.go +++ b/x/wasm/keeper/legacy_querier_test.go @@ -9,14 +9,14 @@ import ( sdk "github.com/line/lfb-sdk/types" sdkErrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLegacyQueryContractState(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -27,7 +27,7 @@ func TestLegacyQueryContractState(t *testing.T) { wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - contractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil) + contractID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, "", "", nil) require.NoError(t, err) _, _, bob := keyPubAddr() @@ -38,7 +38,7 @@ func TestLegacyQueryContractState(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract to query", deposit) + addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract to query", deposit) require.NoError(t, err) contractModel := []types.Model{ @@ -48,7 +48,9 @@ func TestLegacyQueryContractState(t *testing.T) { keeper.importContractState(ctx, addr, contractModel) // this gets us full error, not redacted sdk.Error - q := NewLegacyQuerier(keeper) + var defaultQueryGasLimit sdk.Gas = 3000000 + q := NewLegacyQuerier(keeper, defaultQueryGasLimit) + specs := map[string]struct { srcPath []string srcReq abci.RequestQuery @@ -151,7 +153,7 @@ func TestLegacyQueryContractState(t *testing.T) { } func TestLegacyQueryContractListByCodeOrdering(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000)) @@ -162,7 +164,7 @@ func TestLegacyQueryContractListByCodeOrdering(t *testing.T) { wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, "", "", nil) require.NoError(t, err) _, _, bob := keyPubAddr() @@ -190,33 +192,32 @@ func TestLegacyQueryContractListByCodeOrdering(t *testing.T) { ctx = setBlock(ctx, h) h++ } - _, _, err = keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp) + _, _, err = keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp) require.NoError(t, err) } // query and check the results are properly sorted - q := NewLegacyQuerier(keeper) + var defaultQueryGasLimit sdk.Gas = 3000000 + q := NewLegacyQuerier(keeper, defaultQueryGasLimit) + query := []string{QueryListContractByCode, fmt.Sprintf("%d", codeID)} data := abci.RequestQuery{} res, err := q(ctx, query, data) require.NoError(t, err) - var contracts []map[string]interface{} + var contracts []string err = json.Unmarshal(res, &contracts) require.NoError(t, err) require.Equal(t, 10, len(contracts)) - for i, contract := range contracts { - assert.Equal(t, fmt.Sprintf("contract %d", i), contract["label"]) - assert.NotEmpty(t, contract["address"]) - // ensure these are not shown - assert.Nil(t, contract["created"]) + for _, contract := range contracts { + assert.NotEmpty(t, contract) } } func TestLegacyQueryContractHistory(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper var ( @@ -287,7 +288,9 @@ func TestLegacyQueryContractHistory(t *testing.T) { t.Run(msg, func(t *testing.T) { _, _, myContractAddr := keyPubAddr() keeper.appendToContractHistory(ctx, myContractAddr, spec.srcHistory...) - q := NewLegacyQuerier(keeper) + + var defaultQueryGasLimit sdk.Gas = 3000000 + q := NewLegacyQuerier(keeper, defaultQueryGasLimit) queryContractAddr := spec.srcQueryAddr if queryContractAddr == nil { queryContractAddr = myContractAddr @@ -327,7 +330,7 @@ func TestLegacyQueryCodeList(t *testing.T) { for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper for _, codeID := range spec.codeIDs { @@ -336,7 +339,8 @@ func TestLegacyQueryCodeList(t *testing.T) { wasmCode), ) } - q := NewLegacyQuerier(keeper) + var defaultQueryGasLimit sdk.Gas = 3000000 + q := NewLegacyQuerier(keeper, defaultQueryGasLimit) // when query := []string{QueryListCode} data := abci.RequestQuery{} diff --git a/x/wasm/keeper/metrics.go b/x/wasm/keeper/metrics.go new file mode 100644 index 0000000000..5cf96cda70 --- /dev/null +++ b/x/wasm/keeper/metrics.go @@ -0,0 +1,72 @@ +package keeper + +import ( + wasmvmtypes "github.com/line/wasmvm/types" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + labelPinned = "pinned" + labelMemory = "memory" + labelFs = "fs" +) + +// metricSource source of wasmvm metrics +type metricSource interface { + GetMetrics() (*wasmvmtypes.Metrics, error) +} + +var _ prometheus.Collector = (*WasmVMMetricsCollector)(nil) + +// WasmVMMetricsCollector custom metrics collector to be used with Prometheus +type WasmVMMetricsCollector struct { + source metricSource + CacheHitsDescr *prometheus.Desc + CacheMissesDescr *prometheus.Desc + CacheElementsDescr *prometheus.Desc + CacheSizeDescr *prometheus.Desc +} + +//NewWasmVMMetricsCollector constructor +func NewWasmVMMetricsCollector(s metricSource) *WasmVMMetricsCollector { + return &WasmVMMetricsCollector{ + source: s, + CacheHitsDescr: prometheus.NewDesc("wasmvm_cache_hits_total", "Total number of cache hits", []string{"type"}, nil), + CacheMissesDescr: prometheus.NewDesc("wasmvm_cache_misses_total", "Total number of cache misses", nil, nil), + CacheElementsDescr: prometheus.NewDesc("wasmvm_cache_elements_total", "Total number of elements in the cache", []string{"type"}, nil), + CacheSizeDescr: prometheus.NewDesc("wasmvm_cache_size_bytes", "Total number of elements in the cache", []string{"type"}, nil), + } +} + +// Register registers all metrics +func (p *WasmVMMetricsCollector) Register(r prometheus.Registerer) { + r.MustRegister(p) +} + +// Describe sends the super-set of all possible descriptors of metrics +func (p *WasmVMMetricsCollector) Describe(descs chan<- *prometheus.Desc) { + descs <- p.CacheHitsDescr + descs <- p.CacheMissesDescr + descs <- p.CacheElementsDescr + descs <- p.CacheSizeDescr +} + +// Collect is called by the Prometheus registry when collecting metrics. +func (p *WasmVMMetricsCollector) Collect(c chan<- prometheus.Metric) { + m, err := p.source.GetMetrics() + if err != nil { + return + } + c <- prometheus.MustNewConstMetric(p.CacheHitsDescr, prometheus.CounterValue, float64(m.HitsPinnedMemoryCache), labelPinned) + c <- prometheus.MustNewConstMetric(p.CacheHitsDescr, prometheus.CounterValue, float64(m.HitsMemoryCache), labelMemory) + c <- prometheus.MustNewConstMetric(p.CacheHitsDescr, prometheus.CounterValue, float64(m.HitsFsCache), labelFs) + c <- prometheus.MustNewConstMetric(p.CacheMissesDescr, prometheus.CounterValue, float64(m.Misses)) + c <- prometheus.MustNewConstMetric(p.CacheElementsDescr, prometheus.GaugeValue, float64(m.ElementsPinnedMemoryCache), labelPinned) + c <- prometheus.MustNewConstMetric(p.CacheElementsDescr, prometheus.GaugeValue, float64(m.ElementsMemoryCache), labelMemory) + c <- prometheus.MustNewConstMetric(p.CacheSizeDescr, prometheus.GaugeValue, float64(m.SizeMemoryCache), labelMemory) + c <- prometheus.MustNewConstMetric(p.CacheSizeDescr, prometheus.GaugeValue, float64(m.SizePinnedMemoryCache), labelPinned) + // Node about fs metrics: + // The number of elements and the size of elements in the file system cache cannot easily be obtained. + // We had to either scan the whole directory of potentially thousands of files or track the values when files are added or removed. + // Such a tracking would need to be on disk such that the values are not cleared when the node is restarted. +} diff --git a/x/wasm/keeper/msg_dispatcher.go b/x/wasm/keeper/msg_dispatcher.go new file mode 100644 index 0000000000..341a884777 --- /dev/null +++ b/x/wasm/keeper/msg_dispatcher.go @@ -0,0 +1,174 @@ +package keeper + +import ( + sdk "github.com/line/lfb-sdk/types" + sdkerrors "github.com/line/lfb-sdk/types/errors" + "github.com/line/lfb-sdk/x/wasm/types" + abci "github.com/line/ostracon/abci/types" + wasmvmtypes "github.com/line/wasmvm/types" +) + +// Messenger is an extension point for custom wasmd message handling +type Messenger interface { + // DispatchMsg encodes the wasmVM message and dispatches it. + DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) +} + +// replyer is a subset of keeper that can handle replies to submessages +type replyer interface { + reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) +} + +// MessageDispatcher coordinates message sending and submessage reply/ state commits +type MessageDispatcher struct { + messenger Messenger + keeper replyer +} + +// NewMessageDispatcher constructor +func NewMessageDispatcher(messenger Messenger, keeper replyer) *MessageDispatcher { + return &MessageDispatcher{messenger: messenger, keeper: keeper} +} + +// DispatchMessages sends all messages. +func (d MessageDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error { + for _, msg := range msgs { + events, _, err := d.messenger.DispatchMsg(ctx, contractAddr, ibcPort, msg) + if err != nil { + return err + } + // redispatch all events, (type sdk.EventTypeMessage will be filtered out in the handler) + ctx.EventManager().EmitEvents(events) + } + return nil +} + +// dispatchMsgWithGasLimit sends a message with gas limit applied +func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg wasmvmtypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data [][]byte, err error) { + limitedMeter := sdk.NewGasMeter(gasLimit) + subCtx := ctx.WithGasMeter(limitedMeter) + + // catch out of gas panic and just charge the entire gas limit + defer func() { + if r := recover(); r != nil { + // if it's not an OutOfGas error, raise it again + if _, ok := r.(sdk.ErrorOutOfGas); !ok { + // log it to get the original stack trace somewhere (as panic(r) keeps message but stacktrace to here + moduleLogger(ctx).Info("SubMsg rethrowing panic: %#v", r) + panic(r) + } + ctx.GasMeter().ConsumeGas(gasLimit, "Sub-Message OutOfGas panic") + err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "SubMsg hit gas limit") + } + }() + events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg) + + // make sure we charge the parent what was spent + spent := subCtx.GasMeter().GasConsumed() + ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message") + + return events, data, err +} + +// DispatchSubmessages builds a sandbox to execute these messages and returns the execution result to the contract +// that dispatched them, both on success as well as failure +func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + var rsp []byte + for _, msg := range msgs { + switch msg.ReplyOn { + case wasmvmtypes.ReplySuccess, wasmvmtypes.ReplyError, wasmvmtypes.ReplyAlways: + default: + return nil, sdkerrors.Wrap(types.ErrInvalid, "replyOn") + } + // first, we build a sub-context which we can use inside the submessages + subCtx, commit := ctx.CacheContext() + + // check how much gas left locally, optionally wrap the gas meter + gasRemaining := ctx.GasMeter().Limit() - ctx.GasMeter().GasConsumed() + limitGas := msg.GasLimit != nil && (*msg.GasLimit < gasRemaining) + + var err error + var events []sdk.Event + var data [][]byte + if limitGas { + events, data, err = d.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit) + } else { + events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg) + } + + // if it succeeds, commit state changes from submessage, and pass on events to Event Manager + if err == nil { + commit() + ctx.EventManager().EmitEvents(events) + } + // on failure, revert state from sandbox, and ignore events (just skip doing the above) + + // we only callback if requested. Short-circuit here the two cases we don't want to + if msg.ReplyOn == wasmvmtypes.ReplySuccess && err != nil { + return nil, err + } + if msg.ReplyOn == wasmvmtypes.ReplyError && err == nil { + continue + } + + // otherwise, we create a SubcallResult and pass it into the calling contract + var result wasmvmtypes.SubcallResult + if err == nil { + // just take the first one for now if there are multiple sub-sdk messages + // and safely return nothing if no data + var responseData []byte + if len(data) > 0 { + responseData = data[0] + } + result = wasmvmtypes.SubcallResult{ + Ok: &wasmvmtypes.SubcallResponse{ + Events: sdkEventsToWasmVmEvents(events), + Data: responseData, + }, + } + } else { + result = wasmvmtypes.SubcallResult{ + Err: err.Error(), + } + } + + // now handle the reply, we use the parent context, and abort on error + reply := wasmvmtypes.Reply{ + ID: msg.ID, + Result: result, + } + + // we can ignore any result returned as there is nothing to do with the data + // and the events are already in the ctx.EventManager() + rData, err := d.keeper.reply(ctx, contractAddr, reply) + switch { + case err != nil: + return nil, sdkerrors.Wrap(err, "reply") + case rData.Data != nil: + rsp = rData.Data + } + } + return rsp, nil +} + +func sdkEventsToWasmVmEvents(events []sdk.Event) []wasmvmtypes.Event { + res := make([]wasmvmtypes.Event, len(events)) + for i, ev := range events { + res[i] = wasmvmtypes.Event{ + Type: ev.Type, + Attributes: sdkAttributesToWasmVmAttributes(ev.Attributes), + } + } + return res +} + +func sdkAttributesToWasmVmAttributes(attrs []abci.EventAttribute) []wasmvmtypes.EventAttribute { + res := make([]wasmvmtypes.EventAttribute, len(attrs)) + for i, attr := range attrs { + res[i] = wasmvmtypes.EventAttribute{ + Key: string(attr.Key), + Value: string(attr.Value), + } + } + return res +} diff --git a/x/wasm/keeper/msg_dispatcher_test.go b/x/wasm/keeper/msg_dispatcher_test.go new file mode 100644 index 0000000000..77f0fba33a --- /dev/null +++ b/x/wasm/keeper/msg_dispatcher_test.go @@ -0,0 +1,237 @@ +package keeper + +import ( + "errors" + "fmt" + "testing" + + sdk "github.com/line/lfb-sdk/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + abci "github.com/line/ostracon/abci/types" + wasmvmtypes "github.com/line/wasmvm/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDispatchSubmessages(t *testing.T) { + noReplyCalled := &mockReplyer{} + var anyGasLimit uint64 = 1 + specs := map[string]struct { + msgs []wasmvmtypes.SubMsg + replyer *mockReplyer + msgHandler *wasmtesting.MockMessageHandler + expErr bool + expData []byte + expCommits []bool + expEvents sdk.Events + }{ + "no reply on error without error": { + msgs: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyError}}, + replyer: noReplyCalled, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, [][]byte{[]byte("myData")}, nil + }, + }, + expCommits: []bool{true}, + }, + "no reply on success without success": { + msgs: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplySuccess}}, + replyer: noReplyCalled, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, errors.New("test, ignore") + }, + }, + expCommits: []bool{false}, + expErr: true, + }, + "reply on success - received": { + msgs: []wasmvmtypes.SubMsg{{ + ReplyOn: wasmvmtypes.ReplySuccess, + }}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return &sdk.Result{Data: []byte("myReplyData")}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, [][]byte{[]byte("myData")}, nil + }, + }, + expData: []byte("myReplyData"), + expCommits: []bool{true}, + }, + "reply on error - handled": { + msgs: []wasmvmtypes.SubMsg{{ + ReplyOn: wasmvmtypes.ReplyError, + }}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return &sdk.Result{Data: []byte("myReplyData")}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, errors.New("my error") + }, + }, + expData: []byte("myReplyData"), + expCommits: []bool{false}, + }, + "with reply events": { + msgs: []wasmvmtypes.SubMsg{{ + ReplyOn: wasmvmtypes.ReplySuccess, + }}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return &sdk.Result{Data: []byte("myReplyData")}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + myEvents := []sdk.Event{{Type: "myEvent", Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}}} + return myEvents, [][]byte{[]byte("myData")}, nil + }, + }, + expData: []byte("myReplyData"), + expCommits: []bool{true}, + expEvents: []sdk.Event{{ + Type: "myEvent", + Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, + }}, + }, + "reply returns error": { + msgs: []wasmvmtypes.SubMsg{{ + ReplyOn: wasmvmtypes.ReplySuccess, + }}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return nil, errors.New("reply failed") + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, nil + }, + }, + expCommits: []bool{false}, + expErr: true, + }, + "with gas limit - out of gas": { + msgs: []wasmvmtypes.SubMsg{{ + GasLimit: &anyGasLimit, + ReplyOn: wasmvmtypes.ReplyError, + }}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return &sdk.Result{Data: []byte("myReplyData")}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + ctx.GasMeter().ConsumeGas(sdk.Gas(101), "testing") + return nil, [][]byte{[]byte("someData")}, nil + }, + }, + expData: []byte("myReplyData"), + expCommits: []bool{false}, + }, + "with gas limit - within limit no error": { + msgs: []wasmvmtypes.SubMsg{{ + GasLimit: &anyGasLimit, + ReplyOn: wasmvmtypes.ReplyError, + }}, + replyer: &mockReplyer{}, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + ctx.GasMeter().ConsumeGas(sdk.Gas(1), "testing") + return nil, [][]byte{[]byte("someData")}, nil + }, + }, + expCommits: []bool{true}, + }, + "multiple msg - last reply": { + msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + return &sdk.Result{Data: []byte(fmt.Sprintf("myReplyData:%d", reply.ID))}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, errors.New("my error") + }, + }, + expData: []byte("myReplyData:2"), + expCommits: []bool{false, false}, + }, + "multiple msg - last reply with non nil": { + msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + if reply.ID == 2 { + return &sdk.Result{}, nil + } + return &sdk.Result{Data: []byte("myReplyData:1")}, nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, errors.New("my error") + }, + }, + expData: []byte("myReplyData:1"), + expCommits: []bool{false, false}, + }, + "empty replyOn rejected": { + msgs: []wasmvmtypes.SubMsg{{}}, + replyer: noReplyCalled, + msgHandler: &wasmtesting.MockMessageHandler{}, + expErr: true, + }, + "invalid replyOn rejected": { + msgs: []wasmvmtypes.SubMsg{{ReplyOn: "invalid"}}, + replyer: noReplyCalled, + msgHandler: &wasmtesting.MockMessageHandler{}, + expCommits: []bool{false}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var mockStore wasmtesting.MockCommitMultiStore + em := sdk.NewEventManager() + ctx := sdk.Context{}.WithMultiStore(&mockStore). + WithGasMeter(sdk.NewGasMeter(100)). + WithEventManager(em) + d := NewMessageDispatcher(spec.msgHandler, spec.replyer) + gotData, gotErr := d.DispatchSubmessages(ctx, RandomAccountAddress(t), "any_port", spec.msgs) + if spec.expErr { + require.Error(t, gotErr) + return + } else { + require.NoError(t, gotErr) + assert.Equal(t, spec.expData, gotData) + } + assert.Equal(t, spec.expCommits, mockStore.Committed) + if len(spec.expEvents) == 0 { + assert.Empty(t, em.Events()) + } else { + assert.Equal(t, spec.expEvents, em.Events()) + } + }) + } +} + +type mockReplyer struct { + replyFn func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) +} + +func (m mockReplyer) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + if m.replyFn == nil { + panic("not expected to be called") + } + return m.replyFn(ctx, contractAddress, reply) +} diff --git a/x/wasm/internal/keeper/msg_server.go b/x/wasm/keeper/msg_server.go similarity index 98% rename from x/wasm/internal/keeper/msg_server.go rename to x/wasm/keeper/msg_server.go index 1882934cc1..733244296d 100644 --- a/x/wasm/internal/keeper/msg_server.go +++ b/x/wasm/keeper/msg_server.go @@ -6,16 +6,16 @@ import ( sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) var _ types.MsgServer = msgServer{} type msgServer struct { - keeper *Keeper + keeper types.ContractOpsKeeper } -func NewMsgServerImpl(k *Keeper) types.MsgServer { +func NewMsgServerImpl(k types.ContractOpsKeeper) types.MsgServer { return &msgServer{keeper: k} } diff --git a/x/wasm/keeper/options.go b/x/wasm/keeper/options.go new file mode 100644 index 0000000000..bb65ace0a1 --- /dev/null +++ b/x/wasm/keeper/options.go @@ -0,0 +1,84 @@ +package keeper + +import ( + "fmt" + + "github.com/line/lfb-sdk/x/wasm/types" + "github.com/prometheus/client_golang/prometheus" +) + +type optsFn func(*Keeper) + +func (f optsFn) apply(keeper *Keeper) { + f(keeper) +} + +// WithWasmEngine is an optional constructor parameter to replace the default wasmVM engine with the +// given one. +func WithWasmEngine(x types.WasmerEngine) Option { + return optsFn(func(k *Keeper) { + k.wasmVM = x + }) +} + +// WithMessageHandler is an optional constructor parameter to set a custom handler for wasmVM messages. +// This option should not be combined with Option `WithMessageEncoders`. +func WithMessageHandler(x Messenger) Option { + return optsFn(func(k *Keeper) { + k.messenger = x + }) +} + +// WithQueryHandler is an optional constructor parameter to set custom query handler for wasmVM requests. +// This option should not be combined with Option `WithQueryPlugins`. +func WithQueryHandler(x WasmVMQueryHandler) Option { + return optsFn(func(k *Keeper) { + k.wasmVMQueryHandler = x + }) +} + +// WithQueryPlugins is an optional constructor parameter to pass custom query plugins for wasmVM requests. +// This option expects the default `QueryHandler` set an should not be combined with Option `WithQueryHandler`. +func WithQueryPlugins(x *QueryPlugins) Option { + return optsFn(func(k *Keeper) { + q, ok := k.wasmVMQueryHandler.(QueryPlugins) + if !ok { + panic(fmt.Sprintf("Unsupported query handler type: %T", k.wasmVMQueryHandler)) + } + k.wasmVMQueryHandler = q.Merge(x) + }) +} + +// WithMessageEncoders is an optional constructor parameter to pass custom message encoder to the default wasm message handler. +// This option expects the `DefaultMessageHandler` set an should not be combined with Option `WithMessageHandler`. +func WithMessageEncoders(x *MessageEncoders) Option { + return optsFn(func(k *Keeper) { + q, ok := k.messenger.(*MessageHandlerChain) + if !ok { + panic(fmt.Sprintf("Unsupported message handler type: %T", k.messenger)) + } + s, ok := q.handlers[0].(SDKMessageHandler) + if !ok { + panic(fmt.Sprintf("Unexpected message handler type: %T", q.handlers[0])) + } + e, ok := s.encoders.(MessageEncoders) + if !ok { + panic(fmt.Sprintf("Unsupported encoder type: %T", s.encoders)) + } + s.encoders = e.Merge(x) + q.handlers[0] = s + }) +} + +// WithCoinTransferrer is an optional constructor parameter to set a custom coin transferrer +func WithCoinTransferrer(x CoinTransferrer) Option { + return optsFn(func(k *Keeper) { + k.bank = x + }) +} + +func WithVMCacheMetrics(r prometheus.Registerer) Option { + return optsFn(func(k *Keeper) { + NewWasmVMMetricsCollector(k.wasmVM).Register(r) + }) +} diff --git a/x/wasm/internal/keeper/options_test.go b/x/wasm/keeper/options_test.go similarity index 62% rename from x/wasm/internal/keeper/options_test.go rename to x/wasm/keeper/options_test.go index f54ca314e3..3effa62810 100644 --- a/x/wasm/internal/keeper/options_test.go +++ b/x/wasm/keeper/options_test.go @@ -1,14 +1,15 @@ package keeper import ( + "testing" + authkeeper "github.com/line/lfb-sdk/x/auth/keeper" distributionkeeper "github.com/line/lfb-sdk/x/distribution/keeper" paramtypes "github.com/line/lfb-sdk/x/params/types" stakingkeeper "github.com/line/lfb-sdk/x/staking/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/stretchr/testify/assert" - "testing" ) func TestConstructorOptions(t *testing.T) { @@ -19,7 +20,7 @@ func TestConstructorOptions(t *testing.T) { "wasm engine": { srcOpt: WithWasmEngine(&wasmtesting.MockWasmer{}), verify: func(k Keeper) { - assert.IsType(t, k.wasmer, &wasmtesting.MockWasmer{}) + assert.IsType(t, k.wasmVM, &wasmtesting.MockWasmer{}) }, }, "message handler": { @@ -28,6 +29,12 @@ func TestConstructorOptions(t *testing.T) { assert.IsType(t, k.messenger, &wasmtesting.MockMessageHandler{}) }, }, + "query plugins": { + srcOpt: WithQueryHandler(&wasmtesting.MockQueryHandler{}), + verify: func(k Keeper) { + assert.IsType(t, k.wasmVMQueryHandler, &wasmtesting.MockQueryHandler{}) + }, + }, "coin transferrer": { srcOpt: WithCoinTransferrer(&wasmtesting.MockCoinTransferrer{}), verify: func(k Keeper) { @@ -37,27 +44,7 @@ func TestConstructorOptions(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - k := NewKeeper( - nil, - nil, - paramtypes.NewSubspace(nil, nil, nil, ""), - authkeeper.AccountKeeper{}, - nil, - stakingkeeper.Keeper{}, - distributionkeeper.Keeper{}, - nil, - nil, - nil, - nil, - nil, - nil, - "tempDir", - types.DefaultWasmConfig(), - SupportedFeatures, - nil, - nil, - spec.srcOpt, - ) + k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), SupportedFeatures, spec.srcOpt) spec.verify(k) }) } diff --git a/x/wasm/internal/keeper/proposal_handler.go b/x/wasm/keeper/proposal_handler.go similarity index 75% rename from x/wasm/internal/keeper/proposal_handler.go rename to x/wasm/keeper/proposal_handler.go index 82aeb4cbe3..975b9333b8 100644 --- a/x/wasm/internal/keeper/proposal_handler.go +++ b/x/wasm/keeper/proposal_handler.go @@ -8,7 +8,7 @@ import ( sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" govtypes "github.com/line/lfb-sdk/x/gov/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) // governing contains a subset of the wasm keeper used by gov processes @@ -23,7 +23,12 @@ type governing interface { } // NewWasmProposalHandler creates a new governance Handler for wasm proposals -func NewWasmProposalHandler(k governing, enabledProposalTypes []types.ProposalType) govtypes.Handler { +func NewWasmProposalHandler(k decoratedKeeper, enabledProposalTypes []types.ProposalType) govtypes.Handler { + return NewWasmProposalHandlerX(NewGovPermissionKeeper(k), enabledProposalTypes) +} + +// NewWasmProposalHandlerX creates a new governance Handler for wasm proposals +func NewWasmProposalHandlerX(k types.ContractOpsKeeper, enabledProposalTypes []types.ProposalType) govtypes.Handler { enabledTypes := make(map[string]struct{}, len(enabledProposalTypes)) for i := range enabledProposalTypes { enabledTypes[string(enabledProposalTypes[i])] = struct{}{} @@ -58,7 +63,7 @@ func NewWasmProposalHandler(k governing, enabledProposalTypes []types.ProposalTy } } -func handleStoreCodeProposal(ctx sdk.Context, k governing, p types.StoreCodeProposal) error { +func handleStoreCodeProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.StoreCodeProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -67,7 +72,7 @@ func handleStoreCodeProposal(ctx sdk.Context, k governing, p types.StoreCodeProp if err != nil { return sdkerrors.Wrap(err, "run as address") } - codeID, err := k.create(ctx, runAsAddr, p.WASMByteCode, p.Source, p.Builder, p.InstantiatePermission, GovAuthorizationPolicy{}) + codeID, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.Source, p.Builder, p.InstantiatePermission) if err != nil { return err } @@ -80,7 +85,7 @@ func handleStoreCodeProposal(ctx sdk.Context, k governing, p types.StoreCodeProp return nil } -func handleInstantiateProposal(ctx sdk.Context, k governing, p types.InstantiateContractProposal) error { +func handleInstantiateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.InstantiateContractProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -93,7 +98,7 @@ func handleInstantiateProposal(ctx sdk.Context, k governing, p types.Instantiate return sdkerrors.Wrap(err, "admin") } - contractAddr, _, err := k.instantiate(ctx, p.CodeID, runAsAddr, adminAddr, p.InitMsg, p.Label, p.Funds, GovAuthorizationPolicy{}) + contractAddr, _, err := k.Instantiate(ctx, p.CodeID, runAsAddr, adminAddr, p.InitMsg, p.Label, p.Funds) if err != nil { return err } @@ -107,7 +112,7 @@ func handleInstantiateProposal(ctx sdk.Context, k governing, p types.Instantiate return nil } -func handleMigrateProposal(ctx sdk.Context, k governing, p types.MigrateContractProposal) error { +func handleMigrateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.MigrateContractProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -120,7 +125,7 @@ func handleMigrateProposal(ctx sdk.Context, k governing, p types.MigrateContract if err != nil { return sdkerrors.Wrap(err, "run as address") } - res, err := k.migrate(ctx, contractAddr, runAsAddr, p.CodeID, p.MigrateMsg, GovAuthorizationPolicy{}) + res, err := k.Migrate(ctx, contractAddr, runAsAddr, p.CodeID, p.MigrateMsg) if err != nil { return err } @@ -141,7 +146,7 @@ func handleMigrateProposal(ctx sdk.Context, k governing, p types.MigrateContract return nil } -func handleUpdateAdminProposal(ctx sdk.Context, k governing, p types.UpdateAdminProposal) error { +func handleUpdateAdminProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.UpdateAdminProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -154,7 +159,7 @@ func handleUpdateAdminProposal(ctx sdk.Context, k governing, p types.UpdateAdmin return sdkerrors.Wrap(err, "run as address") } - if err := k.setContractAdmin(ctx, contractAddr, nil, newAdminAddr, GovAuthorizationPolicy{}); err != nil { + if err := k.UpdateContractAdmin(ctx, contractAddr, nil, newAdminAddr); err != nil { return err } @@ -166,7 +171,7 @@ func handleUpdateAdminProposal(ctx sdk.Context, k governing, p types.UpdateAdmin return nil } -func handleClearAdminProposal(ctx sdk.Context, k governing, p types.ClearAdminProposal) error { +func handleClearAdminProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.ClearAdminProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -175,7 +180,7 @@ func handleClearAdminProposal(ctx sdk.Context, k governing, p types.ClearAdminPr if err != nil { return sdkerrors.Wrap(err, "contract") } - if err := k.setContractAdmin(ctx, contractAddr, nil, nil, GovAuthorizationPolicy{}); err != nil { + if err := k.ClearContractAdmin(ctx, contractAddr, nil); err != nil { return err } @@ -187,7 +192,7 @@ func handleClearAdminProposal(ctx sdk.Context, k governing, p types.ClearAdminPr return nil } -func handlePinCodesProposal(ctx sdk.Context, k governing, p types.PinCodesProposal) error { +func handlePinCodesProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.PinCodesProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -197,8 +202,13 @@ func handlePinCodesProposal(ctx sdk.Context, k governing, p types.PinCodesPropos } } s := make([]string, len(p.CodeIDs)) - for i, v := range p.CodeIDs { - s[i] = strconv.FormatUint(v, 10) + for _, v := range p.CodeIDs { + ourEvent := sdk.NewEvent( + types.EventTypePinCode, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(v, 10)), + ) + ctx.EventManager().EmitEvent(ourEvent) } ourEvent := sdk.NewEvent( @@ -210,7 +220,7 @@ func handlePinCodesProposal(ctx sdk.Context, k governing, p types.PinCodesPropos return nil } -func handleUnpinCodesProposal(ctx sdk.Context, k governing, p types.UnpinCodesProposal) error { +func handleUnpinCodesProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.UnpinCodesProposal) error { if err := p.ValidateBasic(); err != nil { return err } @@ -220,8 +230,13 @@ func handleUnpinCodesProposal(ctx sdk.Context, k governing, p types.UnpinCodesPr } } s := make([]string, len(p.CodeIDs)) - for i, v := range p.CodeIDs { - s[i] = strconv.FormatUint(v, 10) + for _, v := range p.CodeIDs { + ourEvent := sdk.NewEvent( + types.EventTypeUnpinCode, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(v, 10)), + ) + ctx.EventManager().EmitEvent(ourEvent) } ourEvent := sdk.NewEvent( diff --git a/x/wasm/internal/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go similarity index 97% rename from x/wasm/internal/keeper/proposal_integration_test.go rename to x/wasm/keeper/proposal_integration_test.go index 731252b2bf..a62081a8d2 100644 --- a/x/wasm/internal/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -11,15 +11,15 @@ import ( sdk "github.com/line/lfb-sdk/types" govtypes "github.com/line/lfb-sdk/x/gov/types" "github.com/line/lfb-sdk/x/params/types/proposal" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" wasmvm "github.com/line/wasmvm" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestStoreCodeProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper wasmKeeper.setParams(ctx, types.Params{ CodeUploadAccess: types.AllowNobody, @@ -64,7 +64,7 @@ func TestStoreCodeProposal(t *testing.T) { } func TestInstantiateProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper wasmKeeper.setParams(ctx, types.Params{ CodeUploadAccess: types.AllowNobody, @@ -124,7 +124,7 @@ func TestInstantiateProposal(t *testing.T) { } func TestMigrateProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper wasmKeeper.setParams(ctx, types.Params{ CodeUploadAccess: types.AllowNobody, @@ -260,7 +260,7 @@ func TestAdminProposals(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper wasmKeeper.setParams(ctx, types.Params{ CodeUploadAccess: types.AllowNobody, @@ -294,7 +294,7 @@ func TestAdminProposals(t *testing.T) { } func TestUpdateParamsProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper var ( @@ -366,7 +366,7 @@ func TestUpdateParamsProposal(t *testing.T) { } func TestPinCodesProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper mock := wasmtesting.MockWasmer{ @@ -453,7 +453,7 @@ func TestPinCodesProposal(t *testing.T) { } } func TestUnpinCodesProposal(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, "staking", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper mock := wasmtesting.MockWasmer{ diff --git a/x/wasm/internal/keeper/querier.go b/x/wasm/keeper/querier.go similarity index 72% rename from x/wasm/internal/keeper/querier.go rename to x/wasm/keeper/querier.go index bf902f0508..6fcddd3dfd 100644 --- a/x/wasm/internal/keeper/querier.go +++ b/x/wasm/keeper/querier.go @@ -5,42 +5,52 @@ import ( "encoding/binary" "runtime/debug" + "github.com/line/lfb-sdk/codec" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "github.com/line/lfb-sdk/store/prefix" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" "github.com/line/lfb-sdk/types/query" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) var _ types.QueryServer = &GrpcQuerier{} type GrpcQuerier struct { - keeper *Keeper + cdc codec.Marshaler + storeKey sdk.StoreKey + keeper types.ViewKeeper + queryGasLimit sdk.Gas } -func NewQuerier(keeper *Keeper) GrpcQuerier { - return GrpcQuerier{keeper: keeper} +func NewGrpcQuerier(cdc codec.Marshaler, storeKey sdk.StoreKey, keeper types.ViewKeeper, queryGasLimit sdk.Gas) *GrpcQuerier { + return &GrpcQuerier{cdc: cdc, storeKey: storeKey, keeper: keeper, queryGasLimit: queryGasLimit} } func (q GrpcQuerier) ContractInfo(c context.Context, req *types.QueryContractInfoRequest) (*types.QueryContractInfoResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } contractAddr, err := sdk.AccAddressFromBech32(req.Address) if err != nil { return nil, err } - rsp, err := queryContractInfo(sdk.UnwrapSDKContext(c), contractAddr, *q.keeper) + rsp, err := queryContractInfo(sdk.UnwrapSDKContext(c), contractAddr, q.keeper) switch { case err != nil: return nil, err case rsp == nil: return nil, types.ErrNotFound } - return &types.QueryContractInfoResponse{ - Address: rsp.Address, - ContractInfo: rsp.ContractInfo, - }, nil + return rsp, nil } func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } contractAddr, err := sdk.AccAddressFromBech32(req.Address) if err != nil { return nil, err @@ -49,11 +59,11 @@ func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContract ctx := sdk.UnwrapSDKContext(c) r := make([]types.ContractCodeHistoryEntry, 0) - prefixStore := prefix.NewStore(ctx.KVStore(q.keeper.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr)) + prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr)) pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { if accumulate { var e types.ContractCodeHistoryEntry - if err := q.keeper.cdc.UnmarshalBinaryBare(value, &e); err != nil { + if err := q.cdc.UnmarshalBinaryBare(value, &e); err != nil { return false, err } e.Updated = nil // redact @@ -70,26 +80,22 @@ func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContract }, nil } +// ContractsByCode lists all smart contracts for a code id func (q GrpcQuerier) ContractsByCode(c context.Context, req *types.QueryContractsByCodeRequest) (*types.QueryContractsByCodeResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } if req.CodeId == 0 { return nil, sdkerrors.Wrap(types.ErrInvalid, "code id") } ctx := sdk.UnwrapSDKContext(c) - r := make([]types.ContractInfoWithAddress, 0) + r := make([]string, 0) - prefixStore := prefix.NewStore(ctx.KVStore(q.keeper.storeKey), types.GetContractByCodeIDSecondaryIndexPrefix(req.CodeId)) + prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractByCodeIDSecondaryIndexPrefix(req.CodeId)) pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { - var contractAddr sdk.AccAddress = key[types.AbsoluteTxPositionLen:] - c := q.keeper.GetContractInfo(ctx, contractAddr) - if c == nil { - return false, types.ErrNotFound - } - c.Created = nil // redact if accumulate { - r = append(r, types.ContractInfoWithAddress{ - Address: contractAddr.String(), - ContractInfo: c, - }) + var contractAddr sdk.AccAddress = key[types.AbsoluteTxPositionLen:] + r = append(r, contractAddr.String()) } return true, nil }) @@ -97,23 +103,26 @@ func (q GrpcQuerier) ContractsByCode(c context.Context, req *types.QueryContract return nil, err } return &types.QueryContractsByCodeResponse{ - ContractInfos: r, - Pagination: pageRes, + Contracts: r, + Pagination: pageRes, }, nil } func (q GrpcQuerier) AllContractState(c context.Context, req *types.QueryAllContractStateRequest) (*types.QueryAllContractStateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } contractAddr, err := sdk.AccAddressFromBech32(req.Address) if err != nil { return nil, err } ctx := sdk.UnwrapSDKContext(c) - if !q.keeper.containsContractInfo(ctx, contractAddr) { + if !q.keeper.HasContractInfo(ctx, contractAddr) { return nil, types.ErrNotFound } r := make([]types.Model, 0) - prefixStore := prefix.NewStore(ctx.KVStore(q.keeper.storeKey), types.GetContractStorePrefix(contractAddr)) + prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractStorePrefix(contractAddr)) pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { if accumulate { r = append(r, types.Model{ @@ -133,6 +142,9 @@ func (q GrpcQuerier) AllContractState(c context.Context, req *types.QueryAllCont } func (q GrpcQuerier) RawContractState(c context.Context, req *types.QueryRawContractStateRequest) (*types.QueryRawContractStateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } ctx := sdk.UnwrapSDKContext(c) contractAddr, err := sdk.AccAddressFromBech32(req.Address) @@ -140,7 +152,7 @@ func (q GrpcQuerier) RawContractState(c context.Context, req *types.QueryRawCont return nil, err } - if !q.keeper.containsContractInfo(ctx, contractAddr) { + if !q.keeper.HasContractInfo(ctx, contractAddr) { return nil, types.ErrNotFound } rsp := q.keeper.QueryRaw(ctx, contractAddr, req.QueryData) @@ -148,11 +160,14 @@ func (q GrpcQuerier) RawContractState(c context.Context, req *types.QueryRawCont } func (q GrpcQuerier) SmartContractState(c context.Context, req *types.QuerySmartContractStateRequest) (rsp *types.QuerySmartContractStateResponse, err error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } contractAddr, err := sdk.AccAddressFromBech32(req.Address) if err != nil { return nil, err } - ctx := sdk.UnwrapSDKContext(c).WithGasMeter(sdk.NewGasMeter(q.keeper.queryGasLimit)) + ctx := sdk.UnwrapSDKContext(c).WithGasMeter(sdk.NewGasMeter(q.queryGasLimit)) // recover from out-of-gas panic defer func() { if r := recover(); r != nil { @@ -166,7 +181,7 @@ func (q GrpcQuerier) SmartContractState(c context.Context, req *types.QuerySmart err = sdkerrors.ErrPanic } rsp = nil - q.keeper.Logger(ctx). + moduleLogger(ctx). Debug("smart query contract", "error", "recovering panic", "contract-address", req.Address, @@ -186,6 +201,9 @@ func (q GrpcQuerier) SmartContractState(c context.Context, req *types.QuerySmart } func (q GrpcQuerier) Code(c context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } if req.CodeId == 0 { return nil, sdkerrors.Wrap(types.ErrInvalid, "code id") } @@ -203,13 +221,16 @@ func (q GrpcQuerier) Code(c context.Context, req *types.QueryCodeRequest) (*type } func (q GrpcQuerier) Codes(c context.Context, req *types.QueryCodesRequest) (*types.QueryCodesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } ctx := sdk.UnwrapSDKContext(c) r := make([]types.CodeInfoResponse, 0) - prefixStore := prefix.NewStore(ctx.KVStore(q.keeper.storeKey), types.CodeKeyPrefix) + prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.CodeKeyPrefix) pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { if accumulate { var c types.CodeInfo - if err := q.keeper.cdc.UnmarshalBinaryBare(value, &c); err != nil { + if err := q.cdc.UnmarshalBinaryBare(value, &c); err != nil { return false, err } r = append(r, types.CodeInfoResponse{ @@ -228,20 +249,20 @@ func (q GrpcQuerier) Codes(c context.Context, req *types.QueryCodesRequest) (*ty return &types.QueryCodesResponse{CodeInfos: r, Pagination: pageRes}, nil } -func queryContractInfo(ctx sdk.Context, addr sdk.AccAddress, keeper Keeper) (*types.ContractInfoWithAddress, error) { +func queryContractInfo(ctx sdk.Context, addr sdk.AccAddress, keeper types.ViewKeeper) (*types.QueryContractInfoResponse, error) { info := keeper.GetContractInfo(ctx, addr) if info == nil { return nil, types.ErrNotFound } // redact the Created field (just used for sorting, not part of public API) info.Created = nil - return &types.ContractInfoWithAddress{ + return &types.QueryContractInfoResponse{ Address: addr.String(), - ContractInfo: info, + ContractInfo: *info, }, nil } -func queryCode(ctx sdk.Context, codeID uint64, keeper *Keeper) (*types.QueryCodeResponse, error) { +func queryCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) (*types.QueryCodeResponse, error) { if codeID == 0 { return nil, nil } diff --git a/x/wasm/internal/keeper/querier_test.go b/x/wasm/keeper/querier_test.go similarity index 81% rename from x/wasm/internal/keeper/querier_test.go rename to x/wasm/keeper/querier_test.go index ecc47cd44f..8e6ba7a17c 100644 --- a/x/wasm/internal/keeper/querier_test.go +++ b/x/wasm/keeper/querier_test.go @@ -6,13 +6,14 @@ import ( "fmt" "io/ioutil" "testing" + "time" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" sdk "github.com/line/lfb-sdk/types" sdkErrors "github.com/line/lfb-sdk/types/errors" "github.com/line/lfb-sdk/types/query" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/libs/log" cosmwasm "github.com/line/wasmvm" wasmvmtypes "github.com/line/wasmvm/types" @@ -21,7 +22,7 @@ import ( ) func TestQueryAllContractState(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper exampleContract := InstantiateHackatomExampleContract(t, ctx, keepers) @@ -32,7 +33,7 @@ func TestQueryAllContractState(t *testing.T) { } require.NoError(t, keeper.importContractState(ctx, contractAddr, contractModel)) - q := NewQuerier(keeper) + q := Querier(keeper) specs := map[string]struct { srcQuery *types.QueryAllContractStateRequest expModelContains []types.Model @@ -108,13 +109,13 @@ func TestQueryAllContractState(t *testing.T) { } func TestQuerySmartContractState(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper exampleContract := InstantiateHackatomExampleContract(t, ctx, keepers) contractAddr := exampleContract.Contract.String() - q := NewQuerier(keeper) + q := Querier(keeper) specs := map[string]struct { srcAddr sdk.AccAddress srcQuery *types.QuerySmartContractStateRequest @@ -151,7 +152,7 @@ func TestQuerySmartContractState(t *testing.T) { } func TestQuerySmartContractPanics(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) contractAddr := contractAddress(1, 1) keepers.WasmKeeper.storeCodeInfo(ctx, 1, types.CodeInfo{}) keepers.WasmKeeper.storeContractInfo(ctx, contractAddr, &types.ContractInfo{ @@ -179,12 +180,12 @@ func TestQuerySmartContractPanics(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - keepers.WasmKeeper.wasmer = &wasmtesting.MockWasmer{QueryFn: func(checksum cosmwasm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64) ([]byte, uint64, error) { + keepers.WasmKeeper.wasmVM = &wasmtesting.MockWasmer{QueryFn: func(checksum cosmwasm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64) ([]byte, uint64, error) { spec.doInContract() return nil, 0, nil }} // when - q := NewQuerier(keepers.WasmKeeper) + q := Querier(keepers.WasmKeeper) got, err := q.SmartContractState(sdk.WrapSDKContext(ctx), &types.QuerySmartContractStateRequest{ Address: contractAddr.String(), }) @@ -195,7 +196,7 @@ func TestQuerySmartContractPanics(t *testing.T) { } func TestQueryRawContractState(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper exampleContract := InstantiateHackatomExampleContract(t, ctx, keepers) @@ -206,7 +207,7 @@ func TestQueryRawContractState(t *testing.T) { } require.NoError(t, keeper.importContractState(ctx, exampleContract.Contract, contractModel)) - q := NewQuerier(keeper) + q := Querier(keeper) specs := map[string]struct { srcQuery *types.QueryRawContractStateRequest expData []byte @@ -250,7 +251,7 @@ func TestQueryRawContractState(t *testing.T) { } func TestQueryContractListByCodeOrdering(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000)) @@ -261,7 +262,7 @@ func TestQueryContractListByCodeOrdering(t *testing.T) { wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, "", "", nil) require.NoError(t, err) _, _, bob := keyPubAddr() @@ -283,33 +284,30 @@ func TestQueryContractListByCodeOrdering(t *testing.T) { } // create 10 contracts with real block/gas setup - for i := range [10]int{} { + for i := 0; i < 10; i++ { // 3 tx per block, so we ensure both comparisons work if i%3 == 0 { ctx = setBlock(ctx, h) h++ } - _, _, err = keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp) + _, _, err = keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp) require.NoError(t, err) } // query and check the results are properly sorted - q := NewQuerier(keeper) + q := Querier(keeper) res, err := q.ContractsByCode(sdk.WrapSDKContext(ctx), &types.QueryContractsByCodeRequest{CodeId: codeID}) require.NoError(t, err) - require.Equal(t, 10, len(res.ContractInfos)) + require.Equal(t, 10, len(res.Contracts)) - for i, contract := range res.ContractInfos { - assert.Equal(t, fmt.Sprintf("contract %d", i), contract.Label) - assert.NotEmpty(t, contract.Address) - // ensure these are not shown - assert.Nil(t, contract.Created) + for _, contractAddr := range res.Contracts { + assert.NotEmpty(t, contractAddr) } } func TestQueryContractHistory(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper var ( @@ -435,7 +433,7 @@ func TestQueryContractHistory(t *testing.T) { keeper.appendToContractHistory(xCtx, cAddr, spec.srcHistory...) // when - q := NewQuerier(keeper) + q := Querier(keeper) got, err := q.ContractHistory(sdk.WrapSDKContext(xCtx), &spec.req) // then @@ -453,7 +451,7 @@ func TestQueryCodeList(t *testing.T) { wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) keeper := keepers.WasmKeeper specs := map[string]struct { @@ -510,7 +508,7 @@ func TestQueryCodeList(t *testing.T) { ) } // when - q := NewQuerier(keeper) + q := Querier(keeper) got, err := q.Codes(sdk.WrapSDKContext(xCtx), &spec.req) // then @@ -524,6 +522,77 @@ func TestQueryCodeList(t *testing.T) { } } +func TestQueryContractInfo(t *testing.T) { + var ( + contractAddr = RandomAccountAddress(t) + anyDate = time.Now().UTC() + ) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures) + // register an example extension. must be protobuf + keepers.EncodingConfig.InterfaceRegistry.RegisterImplementations( + (*types.ContractInfoExtension)(nil), + &govtypes.Proposal{}, + ) + govtypes.RegisterInterfaces(keepers.EncodingConfig.InterfaceRegistry) + + k := keepers.WasmKeeper + querier := NewGrpcQuerier(k.cdc, k.storeKey, k, k.queryGasLimit) + myExtension := func(info *types.ContractInfo) { + // abuse gov proposal as a random protobuf extension with an Any type + myExt, err := govtypes.NewProposal(&govtypes.TextProposal{Title: "foo", Description: "bar"}, 1, anyDate, anyDate) + require.NoError(t, err) + myExt.TotalDeposit = nil + info.SetExtension(&myExt) + } + specs := map[string]struct { + src *types.QueryContractInfoRequest + stored types.ContractInfo + expRsp *types.QueryContractInfoResponse + expErr bool + }{ + "found": { + src: &types.QueryContractInfoRequest{Address: contractAddr.String()}, + stored: types.ContractInfoFixture(), + expRsp: &types.QueryContractInfoResponse{ + Address: contractAddr.String(), + ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { + info.Created = nil // not returned on queries + }), + }, + }, + "with extension": { + src: &types.QueryContractInfoRequest{Address: contractAddr.String()}, + stored: types.ContractInfoFixture(myExtension), + expRsp: &types.QueryContractInfoResponse{ + Address: contractAddr.String(), + ContractInfo: types.ContractInfoFixture(myExtension, func(info *types.ContractInfo) { + info.Created = nil // not returned on queries + }), + }, + }, + "not found": { + src: &types.QueryContractInfoRequest{Address: RandomBech32AccountAddress(t)}, + stored: types.ContractInfoFixture(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + xCtx, _ := ctx.CacheContext() + k.storeContractInfo(xCtx, contractAddr, &spec.stored) + // when + gotRsp, gotErr := querier.ContractInfo(sdk.WrapSDKContext(xCtx), spec.src) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expRsp, gotRsp) + }) + } + +} + func fromBase64(s string) []byte { r, err := base64.StdEncoding.DecodeString(s) if err != nil { diff --git a/x/wasm/internal/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go similarity index 87% rename from x/wasm/internal/keeper/query_plugins.go rename to x/wasm/keeper/query_plugins.go index c05bdc6c46..99288da44a 100644 --- a/x/wasm/internal/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -5,7 +5,7 @@ import ( "fmt" channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" @@ -17,15 +17,15 @@ import ( type QueryHandler struct { Ctx sdk.Context - Plugins QueryPlugins + Plugins WasmVMQueryHandler Caller sdk.AccAddress GasMultiplier uint64 } -func NewQueryHandler(ctx sdk.Context, plugins QueryPlugins, caller sdk.AccAddress, gasMultiplier uint64) QueryHandler { +func NewQueryHandler(ctx sdk.Context, vmQueryHandler WasmVMQueryHandler, caller sdk.AccAddress, gasMultiplier uint64) QueryHandler { return QueryHandler{ Ctx: ctx, - Plugins: plugins, + Plugins: vmQueryHandler, Caller: caller, GasMultiplier: gasMultiplier, } @@ -54,27 +54,7 @@ func (q QueryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) ( defer func() { q.Ctx.GasMeter().ConsumeGas(subctx.GasMeter().GasConsumed(), "contract sub-query") }() - - // do the query - if request.Bank != nil { - return q.Plugins.Bank(subctx, request.Bank) - } - if request.Custom != nil { - return q.Plugins.Custom(subctx, request.Custom) - } - if request.IBC != nil { - return q.Plugins.IBC(subctx, q.Caller, request.IBC) - } - if request.Staking != nil { - return q.Plugins.Staking(subctx, request.Staking) - } - if request.Stargate != nil { - return q.Plugins.Stargate(subctx, request.Stargate) - } - if request.Wasm != nil { - return q.Plugins.Wasm(subctx, request.Wasm) - } - return nil, wasmvmtypes.Unknown{} + return q.Plugins.HandleQuery(subctx, q.Caller, request) } func (q QueryHandler) GasConsumed() uint64 { @@ -92,7 +72,24 @@ type QueryPlugins struct { Wasm func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) } -func DefaultQueryPlugins(bank types.BankViewKeeper, staking types.StakingKeeper, distKeeper types.DistributionKeeper, channelKeeper types.ChannelKeeper, queryRouter GRPCQueryRouter, wasm *Keeper) QueryPlugins { +type contractMetaDataSource interface { + GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo +} + +type wasmQueryKeeper interface { + contractMetaDataSource + QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte + QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) +} + +func DefaultQueryPlugins( + bank types.BankViewKeeper, + staking types.StakingKeeper, + distKeeper types.DistributionKeeper, + channelKeeper types.ChannelKeeper, + queryRouter GRPCQueryRouter, + wasm wasmQueryKeeper, +) QueryPlugins { return QueryPlugins{ Bank: BankQuerier(bank), Custom: CustomQuerierImpl(queryRouter), @@ -129,6 +126,30 @@ func (e QueryPlugins) Merge(o *QueryPlugins) QueryPlugins { return e } +// HandleQuery executes the requested query +func (e QueryPlugins) HandleQuery(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) { + // do the query + if request.Bank != nil { + return e.Bank(ctx, request.Bank) + } + if request.Custom != nil { + return e.Custom(ctx, request.Custom) + } + if request.IBC != nil { + return e.IBC(ctx, caller, request.IBC) + } + if request.Staking != nil { + return e.Staking(ctx, request.Staking) + } + if request.Stargate != nil { + return e.Stargate(ctx, request.Stargate) + } + if request.Wasm != nil { + return e.Wasm(ctx, request.Wasm) + } + return nil, wasmvmtypes.Unknown{} +} + func BankQuerier(bankKeeper types.BankViewKeeper) func(ctx sdk.Context, request *wasmvmtypes.BankQuery) ([]byte, error) { return func(ctx sdk.Context, request *wasmvmtypes.BankQuery) ([]byte, error) { if request.AllBalances != nil { @@ -184,7 +205,7 @@ func CustomQuerierImpl(queryRouter GRPCQueryRouter) func(ctx sdk.Context, querie } } -func IBCQuerier(wasm *Keeper, channelKeeper types.ChannelKeeper) func(ctx sdk.Context, caller sdk.AccAddress, request *wasmvmtypes.IBCQuery) ([]byte, error) { +func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper) func(ctx sdk.Context, caller sdk.AccAddress, request *wasmvmtypes.IBCQuery) ([]byte, error) { return func(ctx sdk.Context, caller sdk.AccAddress, request *wasmvmtypes.IBCQuery) ([]byte, error) { if request.PortID != nil { contractInfo := wasm.GetContractInfo(ctx, caller) @@ -281,7 +302,7 @@ func StakingQuerier(keeper types.StakingKeeper, distKeeper types.DistributionKee } return json.Marshal(res) } - if request.Validators != nil { + if request.AllValidators != nil { validators := keeper.GetBondedValidatorsByPower(ctx) //validators := keeper.GetAllValidators(ctx) wasmVals := make([]wasmvmtypes.Validator, len(validators)) @@ -293,11 +314,28 @@ func StakingQuerier(keeper types.StakingKeeper, distKeeper types.DistributionKee MaxChangeRate: v.Commission.MaxChangeRate.String(), } } - res := wasmvmtypes.ValidatorsResponse{ + res := wasmvmtypes.AllValidatorsResponse{ Validators: wasmVals, } return json.Marshal(res) } + if request.Validator != nil { + valAddr, err := sdk.ValAddressFromBech32(request.Validator.Address) + if err != nil { + return nil, err + } + v, found := keeper.GetValidator(ctx, valAddr) + res := wasmvmtypes.ValidatorResponse{} + if found { + res.Validator = &wasmvmtypes.Validator{ + Address: v.OperatorAddress, + Commission: v.Commission.Rate.String(), + MaxCommission: v.Commission.MaxRate.String(), + MaxChangeRate: v.Commission.MaxChangeRate.String(), + } + } + return json.Marshal(res) + } if request.AllDelegations != nil { delegator, err := sdk.AccAddressFromBech32(request.AllDelegations.Delegator) if err != nil { @@ -439,7 +477,7 @@ func getAccumulatedRewards(ctx sdk.Context, distKeeper types.DistributionKeeper, return rewards, nil } -func WasmQuerier(wasm *Keeper) func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) { +func WasmQuerier(wasm wasmQueryKeeper) func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) { return func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) { if request.Smart != nil { addr, err := sdk.AccAddressFromBech32(request.Smart.ContractAddr) diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go new file mode 100644 index 0000000000..82d1786642 --- /dev/null +++ b/x/wasm/keeper/query_plugins_test.go @@ -0,0 +1,256 @@ +package keeper + +import ( + "testing" + + sdk "github.com/line/lfb-sdk/types" + sdkerrors "github.com/line/lfb-sdk/types/errors" + channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" + wasmvmtypes "github.com/line/wasmvm/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIBCQuerier(t *testing.T) { + myExampleChannels := []channeltypes.IdentifiedChannel{ + { + State: channeltypes.OPEN, + Ordering: channeltypes.ORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "counterPartyPortID", + ChannelId: "counterPartyChannelID", + }, + ConnectionHops: []string{"one"}, + Version: "v1", + PortId: "myPortID", + ChannelId: "myChannelID", + }, + { + State: channeltypes.INIT, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "otherCounterPartyPortID", + ChannelId: "otherCounterPartyChannelID", + }, + ConnectionHops: []string{"other", "second"}, + Version: "otherVersion", + PortId: "otherPortID", + ChannelId: "otherChannelID", + }, + } + specs := map[string]struct { + srcQuery *wasmvmtypes.IBCQuery + wasmKeeper *wasmKeeperMock + channelKeeper *wasmtesting.MockChannelKeeper + expJsonResult string + expErr *sdkerrors.Error + }{ + "query port id": { + srcQuery: &wasmvmtypes.IBCQuery{ + PortID: &wasmvmtypes.PortIDQuery{}, + }, + wasmKeeper: newWasmKeeperMock( + func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { + return &types.ContractInfo{IBCPortID: "myIBCPortID"} + }, + ), + channelKeeper: &wasmtesting.MockChannelKeeper{}, + expJsonResult: `{"port_id":"myIBCPortID"}`, + }, + "query list channels - all": { + srcQuery: &wasmvmtypes.IBCQuery{ + ListChannels: &wasmvmtypes.ListChannelsQuery{}, + }, + channelKeeper: &wasmtesting.MockChannelKeeper{ + IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), + }, + expJsonResult: `{ + "channels": [ + { + "endpoint": { + "port_id": "myPortID", + "channel_id": "myChannelID" + }, + "counterparty_endpoint": { + "port_id": "counterPartyPortID", + "channel_id": "counterPartyChannelID" + }, + "order": "ORDER_ORDERED", + "version": "v1", + "connection_id": "one" + }, + { + "endpoint": { + "port_id": "otherPortID", + "channel_id": "otherChannelID" + }, + "counterparty_endpoint": { + "port_id": "otherCounterPartyPortID", + "channel_id": "otherCounterPartyChannelID" + }, + "order": "ORDER_UNORDERED", + "version": "otherVersion", + "connection_id": "other" + } + ] +}`, + }, + "query list channels - filtered": { + srcQuery: &wasmvmtypes.IBCQuery{ + ListChannels: &wasmvmtypes.ListChannelsQuery{ + PortID: "otherPortID", + }, + }, + channelKeeper: &wasmtesting.MockChannelKeeper{ + IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), + }, + expJsonResult: `{ + "channels": [ + { + "endpoint": { + "port_id": "otherPortID", + "channel_id": "otherChannelID" + }, + "counterparty_endpoint": { + "port_id": "otherCounterPartyPortID", + "channel_id": "otherCounterPartyChannelID" + }, + "order": "ORDER_UNORDERED", + "version": "otherVersion", + "connection_id": "other" + } + ] +}`, + }, + "query list channels - filtered empty": { + srcQuery: &wasmvmtypes.IBCQuery{ + ListChannels: &wasmvmtypes.ListChannelsQuery{ + PortID: "none-existing", + }, + }, + channelKeeper: &wasmtesting.MockChannelKeeper{ + IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), + }, + expJsonResult: `{"channels": []}`, + }, + "query channel": { + srcQuery: &wasmvmtypes.IBCQuery{ + Channel: &wasmvmtypes.ChannelQuery{ + PortID: "myQueryPortID", + ChannelID: "myQueryChannelID", + }, + }, + channelKeeper: &wasmtesting.MockChannelKeeper{ + GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) { + return channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "counterPartyPortID", + ChannelId: "otherCounterPartyChannelID", + }, + ConnectionHops: []string{"one"}, + Version: "version", + }, true + }, + }, + expJsonResult: `{ + "channel": { + "endpoint": { + "port_id": "myQueryPortID", + "channel_id": "myQueryChannelID" + }, + "counterparty_endpoint": { + "port_id": "counterPartyPortID", + "channel_id": "otherCounterPartyChannelID" + }, + "order": "ORDER_UNORDERED", + "version": "version", + "connection_id": "one" + } +}`, + }, + "query channel - without port set": { + srcQuery: &wasmvmtypes.IBCQuery{ + Channel: &wasmvmtypes.ChannelQuery{ + ChannelID: "myQueryChannelID", + }, + }, + wasmKeeper: newWasmKeeperMock(func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { + return &types.ContractInfo{IBCPortID: "myLoadedPortID"} + }), + channelKeeper: &wasmtesting.MockChannelKeeper{ + GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) { + return channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "counterPartyPortID", + ChannelId: "otherCounterPartyChannelID", + }, + ConnectionHops: []string{"one"}, + Version: "version", + }, true + }, + }, + expJsonResult: `{ + "channel": { + "endpoint": { + "port_id": "myLoadedPortID", + "channel_id": "myQueryChannelID" + }, + "counterparty_endpoint": { + "port_id": "counterPartyPortID", + "channel_id": "otherCounterPartyChannelID" + }, + "order": "ORDER_UNORDERED", + "version": "version", + "connection_id": "one" + } +}`, + }, + "query channel - empty result": { + srcQuery: &wasmvmtypes.IBCQuery{ + Channel: &wasmvmtypes.ChannelQuery{ + PortID: "myQueryPortID", + ChannelID: "myQueryChannelID", + }, + }, + channelKeeper: &wasmtesting.MockChannelKeeper{ + GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) { + return channeltypes.Channel{}, false + }, + }, + expJsonResult: "{}", + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + h := IBCQuerier(spec.wasmKeeper, spec.channelKeeper) + gotResult, gotErr := h(sdk.Context{}, RandomAccountAddress(t), spec.srcQuery) + require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr) + if spec.expErr != nil { + return + } + assert.JSONEq(t, spec.expJsonResult, string(gotResult), string(gotResult)) + }) + } + +} + +type wasmKeeperMock struct { + GetContractInfoFn func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo +} + +func newWasmKeeperMock(f func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo) *wasmKeeperMock { + return &wasmKeeperMock{GetContractInfoFn: f} +} + +func (m wasmKeeperMock) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { + if m.GetContractInfoFn == nil { + panic("not expected to be called") + } + return m.GetContractInfoFn(ctx, contractAddress) +} diff --git a/x/wasm/internal/keeper/recurse_test.go b/x/wasm/keeper/recurse_test.go similarity index 88% rename from x/wasm/internal/keeper/recurse_test.go rename to x/wasm/keeper/recurse_test.go index 4289a5c74d..80bab54274 100644 --- a/x/wasm/internal/keeper/recurse_test.go +++ b/x/wasm/keeper/recurse_test.go @@ -4,7 +4,8 @@ import ( "encoding/json" "testing" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" wasmvmtypes "github.com/line/wasmvm/types" "github.com/stretchr/testify/assert" @@ -41,14 +42,13 @@ var totalWasmQueryCounter int func initRecurseContract(t *testing.T) (contract sdk.AccAddress, creator sdk.AccAddress, ctx sdk.Context, keeper *Keeper) { // we do one basic setup before all test cases (which are read-only and don't change state) var realWasmQuerier func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) - countingQuerier := &QueryPlugins{ - Wasm: func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) { + countingQuerier := &wasmtesting.MockQueryHandler{ + HandleQueryFn: func(ctx sdk.Context, request wasmvmtypes.QueryRequest, caller sdk.AccAddress) ([]byte, error) { totalWasmQueryCounter++ - return realWasmQuerier(ctx, request) - }, - } + return realWasmQuerier(ctx, request.Wasm) + }} - ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, countingQuerier) + ctx, keepers := CreateTestInput(t, false, SupportedFeatures, WithQueryHandler(countingQuerier)) keeper = keepers.WasmKeeper realWasmQuerier = WasmQuerier(keeper) @@ -58,12 +58,12 @@ func initRecurseContract(t *testing.T) (contract sdk.AccAddress, creator sdk.Acc func TestGasCostOnQuery(t *testing.T) { const ( - GasNoWork uint64 = 44_059 + GasNoWork uint64 = 44_072 // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 - GasWork50 uint64 = 49_728 // this is a little shy of 50k gas - to keep an eye on the limit + GasWork50 uint64 = 49_764 // this is a little shy of 50k gas - to keep an eye on the limit - GasReturnUnhashed uint64 = 287 - GasReturnHashed uint64 = 262 + GasReturnUnhashed uint64 = 283 + GasReturnHashed uint64 = 257 ) cases := map[string]struct { @@ -81,14 +81,14 @@ func TestGasCostOnQuery(t *testing.T) { msg: Recurse{ Work: 50, // 50 rounds of sha256 inside the contract }, - expectedGas: GasWork50 + 1, + expectedGas: GasWork50, }, "recursion 1, no work": { gasLimit: 400_000, msg: Recurse{ Depth: 1, }, - expectedGas: 2*GasNoWork + GasReturnUnhashed - 2, + expectedGas: 2*GasNoWork + GasReturnUnhashed, }, "recursion 1, some work": { gasLimit: 400_000, @@ -190,9 +190,6 @@ func TestGasOnExternalQuery(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { - // set the external gas limit (normally from config file) - keeper.queryGasLimit = tc.gasLimit - recurse := tc.msg recurse.Contract = contractAddr msg := buildRecurseQuery(t, recurse) @@ -203,12 +200,12 @@ func TestGasOnExternalQuery(t *testing.T) { if tc.expectPanic { require.Panics(t, func() { // this should run out of gas - _, err := NewLegacyQuerier(keeper)(ctx, path, req) + _, err := NewLegacyQuerier(keeper, tc.gasLimit)(ctx, path, req) t.Logf("%v", err) }) } else { // otherwise, make sure we get a good success - _, err := NewLegacyQuerier(keeper)(ctx, path, req) + _, err := NewLegacyQuerier(keeper, tc.gasLimit)(ctx, path, req) require.NoError(t, err) } }) @@ -225,9 +222,9 @@ func TestLimitRecursiveQueryGas(t *testing.T) { const ( // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 - GasWork2k uint64 = 272_782 // = InstanceCost + x // we have 6x gas used in cpu than in the instance + GasWork2k uint64 = 273_567 // = InstanceCost + x // we have 6x gas used in cpu than in the instance // This is overhead for calling into a sub-contract - GasReturnHashed uint64 = 265 + GasReturnHashed uint64 = 262 ) cases := map[string]struct { @@ -253,8 +250,8 @@ func TestLimitRecursiveQueryGas(t *testing.T) { Work: 2000, }, expectQueriesFromContract: 5, - // FIXME: why -9 ... confused a bit by calculations, seems like rounding issues - expectedGas: GasWork2k + 5*(GasWork2k+GasReturnHashed) - 9, + // FIXME: why -3 ... confused a bit by calculations, seems like rounding issues + expectedGas: GasWork2k + 5*(GasWork2k+GasReturnHashed) - 3, }, // this is where we expect an error... // it has enough gas to run 4 times and die on the 5th (4th time dispatching to sub-contract) diff --git a/x/wasm/internal/keeper/reflect_test.go b/x/wasm/keeper/reflect_test.go similarity index 90% rename from x/wasm/internal/keeper/reflect_test.go rename to x/wasm/keeper/reflect_test.go index 0babcb2944..2845311ed0 100644 --- a/x/wasm/internal/keeper/reflect_test.go +++ b/x/wasm/keeper/reflect_test.go @@ -2,11 +2,12 @@ package keeper import ( "encoding/json" - "github.com/golang/protobuf/proto" "io/ioutil" "strings" "testing" + "github.com/golang/protobuf/proto" + "github.com/line/lfb-sdk/codec" codectypes "github.com/line/lfb-sdk/codec/types" sdk "github.com/line/lfb-sdk/types" @@ -14,7 +15,7 @@ import ( authkeeper "github.com/line/lfb-sdk/x/auth/keeper" bankkeeper "github.com/line/lfb-sdk/x/bank/keeper" banktypes "github.com/line/lfb-sdk/x/bank/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" wasmvmtypes "github.com/line/wasmvm/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -83,9 +84,9 @@ func mustParse(t *testing.T, data []byte, res interface{}) { const ReflectFeatures = "staking,mask,stargate" func TestReflectContractSend(t *testing.T) { - cdc := MakeTestCodec(t) - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(cdc), nil) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc))) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -165,9 +166,9 @@ func TestReflectContractSend(t *testing.T) { } func TestReflectCustomMsg(t *testing.T) { - cdc := MakeTestCodec(t) - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(cdc), reflectPlugins()) - accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) @@ -258,8 +259,8 @@ func TestReflectCustomMsg(t *testing.T) { } func TestMaskReflectCustomQuery(t *testing.T) { - cdc := MakeTestCodec(t) - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(cdc), reflectPlugins()) + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -268,13 +269,13 @@ func TestMaskReflectCustomQuery(t *testing.T) { // upload code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), codeID) // creator instantiates a contract and gives it tokens contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000)) - contractAddr, _, err := keeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) require.NoError(t, err) require.NotEmpty(t, contractAddr) @@ -308,8 +309,8 @@ func TestMaskReflectCustomQuery(t *testing.T) { } func TestReflectStargateQuery(t *testing.T) { - cdc := MakeTestCodec(t) - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(cdc), reflectPlugins()) + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper funds := sdk.NewCoins(sdk.NewInt64Coin("denom", 320000)) @@ -320,12 +321,12 @@ func TestReflectStargateQuery(t *testing.T) { // upload code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), codeID) // creator instantiates a contract and gives it tokens - contractAddr, _, err := keeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) require.NoError(t, err) require.NotEmpty(t, contractAddr) @@ -381,11 +382,12 @@ func TestReflectStargateQuery(t *testing.T) { } type reflectState struct { - Owner []byte `json:"owner"` + Owner string `json:"owner"` } func TestMaskReflectWasmQueries(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(MakeTestCodec(t)), nil) + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -394,13 +396,13 @@ func TestMaskReflectWasmQueries(t *testing.T) { // upload reflect code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - reflectID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), reflectID) // creator instantiates a contract and gives it tokens reflectStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000)) - reflectAddr, _, err := keeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), "reflect contract 2", reflectStart) + reflectAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), "reflect contract 2", reflectStart) require.NoError(t, err) require.NotEmpty(t, reflectAddr) @@ -417,7 +419,7 @@ func TestMaskReflectWasmQueries(t *testing.T) { raw := keeper.QueryRaw(ctx, reflectAddr, configKey) var stateRes reflectState mustParse(t, raw, &stateRes) - require.Equal(t, stateRes.Owner, []byte(creator)) + require.Equal(t, stateRes.Owner, creator.String()) // now, let's reflect a smart query into the x/wasm handlers and see if we get the same result reflectOwnerQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{ @@ -452,11 +454,12 @@ func TestMaskReflectWasmQueries(t *testing.T) { // now, with the raw data, we can parse it into state var reflectStateRes reflectState mustParse(t, reflectRawRes.Data, &reflectStateRes) - require.Equal(t, reflectStateRes.Owner, []byte(creator)) + require.Equal(t, reflectStateRes.Owner, creator.String()) } func TestWasmRawQueryWithNil(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, reflectEncoders(MakeTestCodec(t)), nil) + cdc := MakeEncodingConfig(t).Marshaler + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -465,13 +468,13 @@ func TestWasmRawQueryWithNil(t *testing.T) { // upload reflect code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - reflectID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), reflectID) // creator instantiates a contract and gives it tokens reflectStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000)) - reflectAddr, _, err := keeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), "reflect contract 2", reflectStart) + reflectAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), "reflect contract 2", reflectStart) require.NoError(t, err) require.NotEmpty(t, reflectAddr) diff --git a/x/wasm/internal/keeper/relay.go b/x/wasm/keeper/relay.go similarity index 71% rename from x/wasm/internal/keeper/relay.go rename to x/wasm/keeper/relay.go index 45e93acf18..7f0727c58d 100644 --- a/x/wasm/internal/keeper/relay.go +++ b/x/wasm/keeper/relay.go @@ -1,9 +1,12 @@ package keeper import ( + "time" + + "github.com/line/lfb-sdk/telemetry" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" wasmvmtypes "github.com/line/wasmvm/types" ) @@ -17,17 +20,18 @@ func (k Keeper) OnOpenChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-open-channel") + _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err } env := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - gasUsed, execErr := k.wasmer.IBCChannelOpen(codeInfo.CodeHash, env, channel, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, channel, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -48,17 +52,17 @@ func (k Keeper) OnConnectChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-connect-channel") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err } env := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.IBCChannelConnect(codeInfo.CodeHash, env, channel, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, channel, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -68,7 +72,7 @@ func (k Keeper) OnConnectChannel( events := types.ParseEvents(res.Attributes, contractAddr) ctx.EventManager().EmitEvents(events) - if err := k.dispatchAll(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages); err != nil { + if _, err := k.wasmVMResponseHandler.Handle(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, nil); err != nil { return err } return nil @@ -85,17 +89,18 @@ func (k Keeper) OnCloseChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-close-channel") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err } params := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.IBCChannelClose(codeInfo.CodeHash, params, channel, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, channel, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -105,7 +110,7 @@ func (k Keeper) OnCloseChannel( events := types.ParseEvents(res.Attributes, contractAddr) ctx.EventManager().EmitEvents(events) - if err := k.dispatchAll(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages); err != nil { + if _, err := k.wasmVMResponseHandler.Handle(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, nil); err != nil { return err } return nil @@ -122,17 +127,17 @@ func (k Keeper) OnRecvPacket( contractAddr sdk.AccAddress, packet wasmvmtypes.IBCPacket, ) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-recv-packet") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return nil, err } env := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.IBCPacketReceive(codeInfo.CodeHash, env, packet, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, packet, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -141,11 +146,7 @@ func (k Keeper) OnRecvPacket( // emit all events from this contract itself events := types.ParseEvents(res.Attributes, contractAddr) ctx.EventManager().EmitEvents(events) - - if err := k.dispatchAll(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages); err != nil { - return nil, err - } - return res.Acknowledgement, nil + return k.wasmVMResponseHandler.Handle(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Acknowledgement) } // OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet @@ -160,17 +161,17 @@ func (k Keeper) OnAckPacket( contractAddr sdk.AccAddress, acknowledgement wasmvmtypes.IBCAcknowledgement, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-ack-packet") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err } env := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.IBCPacketAck(codeInfo.CodeHash, env, acknowledgement, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, acknowledgement, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -180,7 +181,7 @@ func (k Keeper) OnAckPacket( events := types.ParseEvents(res.Attributes, contractAddr) ctx.EventManager().EmitEvents(events) - if err := k.dispatchAll(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages); err != nil { + if _, err := k.wasmVMResponseHandler.Handle(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, nil); err != nil { return err } return nil @@ -194,17 +195,18 @@ func (k Keeper) OnTimeoutPacket( contractAddr sdk.AccAddress, packet wasmvmtypes.IBCPacket, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-timeout-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err } env := types.NewEnv(ctx, contractAddr) - querier := NewQueryHandler(ctx, k.queryPlugins, contractAddr, k.getGasMultiplier(ctx)) + querier := NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddr, k.getGasMultiplier(ctx)) gas := gasForContract(ctx, k.getGasMultiplier(ctx)) - wasmStore := types.NewWasmStore(prefixStore) - res, gasUsed, execErr := k.wasmer.IBCPacketTimeout(codeInfo.CodeHash, env, packet, wasmStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) + res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, packet, prefixStore, k.cosmwasmAPI(ctx), querier, ctx.GasMeter(), gas) k.consumeGas(ctx, gasUsed) if execErr != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) @@ -214,7 +216,7 @@ func (k Keeper) OnTimeoutPacket( events := types.ParseEvents(res.Attributes, contractAddr) ctx.EventManager().EmitEvents(events) - if err := k.dispatchAll(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages); err != nil { + if _, err := k.wasmVMResponseHandler.Handle(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, nil); err != nil { return err } return nil diff --git a/x/wasm/internal/keeper/relay_test.go b/x/wasm/keeper/relay_test.go similarity index 94% rename from x/wasm/internal/keeper/relay_test.go rename to x/wasm/keeper/relay_test.go index fa7a4b74b9..98b7c7baa3 100644 --- a/x/wasm/internal/keeper/relay_test.go +++ b/x/wasm/keeper/relay_test.go @@ -6,8 +6,8 @@ import ( "testing" sdk "github.com/line/lfb-sdk/types" - "github.com/line/lfb-sdk/x/wasm/internal/keeper/wasmtesting" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" wasmvm "github.com/line/wasmvm" wasmvmtypes "github.com/line/wasmvm/types" "github.com/stretchr/testify/assert" @@ -17,7 +17,8 @@ import ( func TestOnOpenChannel(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -76,7 +77,8 @@ func TestOnOpenChannel(t *testing.T) { func TestOnConnectChannel(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -84,7 +86,7 @@ func TestOnConnectChannel(t *testing.T) { contractGas sdk.Gas contractResp *wasmvmtypes.IBCBasicResponse contractErr error - overwriteMessenger messenger + overwriteMessenger *wasmtesting.MockMessageHandler expErr bool expContractEventAttrs int expNoEvents bool @@ -150,10 +152,9 @@ func TestOnConnectChannel(t *testing.T) { defer cancel() before := ctx.GasMeter().GasConsumed() msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler() - keepers.WasmKeeper.messenger = msger - + *messenger = *msger if spec.overwriteMessenger != nil { - keepers.WasmKeeper.messenger = spec.overwriteMessenger + *messenger = *spec.overwriteMessenger } // when @@ -186,7 +187,8 @@ func TestOnConnectChannel(t *testing.T) { func TestOnCloseChannel(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -194,7 +196,7 @@ func TestOnCloseChannel(t *testing.T) { contractGas sdk.Gas contractResp *wasmvmtypes.IBCBasicResponse contractErr error - overwriteMessenger messenger + overwriteMessenger *wasmtesting.MockMessageHandler expErr bool expContractEventAttrs int expNoEvents bool @@ -259,10 +261,10 @@ func TestOnCloseChannel(t *testing.T) { defer cancel() before := ctx.GasMeter().GasConsumed() msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler() - keepers.WasmKeeper.messenger = msger + *messenger = *msger if spec.overwriteMessenger != nil { - keepers.WasmKeeper.messenger = spec.overwriteMessenger + *messenger = *spec.overwriteMessenger } // when @@ -296,7 +298,8 @@ func TestOnCloseChannel(t *testing.T) { func TestOnRecvPacket(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -304,7 +307,7 @@ func TestOnRecvPacket(t *testing.T) { contractGas sdk.Gas contractResp *wasmvmtypes.IBCReceiveResponse contractErr error - overwriteMessenger messenger + overwriteMessenger *wasmtesting.MockMessageHandler expErr bool expContractEventAttrs int expNoEvents bool @@ -382,10 +385,10 @@ func TestOnRecvPacket(t *testing.T) { before := ctx.GasMeter().GasConsumed() msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler() - keepers.WasmKeeper.messenger = msger + *messenger = *msger if spec.overwriteMessenger != nil { - keepers.WasmKeeper.messenger = spec.overwriteMessenger + *messenger = *spec.overwriteMessenger } // when @@ -421,7 +424,8 @@ func TestOnRecvPacket(t *testing.T) { func TestOnAckPacket(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -429,7 +433,7 @@ func TestOnAckPacket(t *testing.T) { contractGas sdk.Gas contractResp *wasmvmtypes.IBCBasicResponse contractErr error - overwriteMessenger messenger + overwriteMessenger *wasmtesting.MockMessageHandler expErr bool expContractEventAttrs int expNoEvents bool @@ -495,10 +499,10 @@ func TestOnAckPacket(t *testing.T) { defer cancel() before := ctx.GasMeter().GasConsumed() msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler() - keepers.WasmKeeper.messenger = msger + *messenger = *msger if spec.overwriteMessenger != nil { - keepers.WasmKeeper.messenger = spec.overwriteMessenger + *messenger = *spec.overwriteMessenger } // when @@ -532,7 +536,8 @@ func TestOnAckPacket(t *testing.T) { func TestOnTimeoutPacket(t *testing.T) { var m wasmtesting.MockWasmer wasmtesting.MakeIBCInstantiable(&m) - parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil) + var messenger = &wasmtesting.MockMessageHandler{} + parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, WithMessageHandler(messenger)) example := SeedNewContractInstance(t, parentCtx, keepers, &m) specs := map[string]struct { @@ -540,7 +545,7 @@ func TestOnTimeoutPacket(t *testing.T) { contractGas sdk.Gas contractResp *wasmvmtypes.IBCBasicResponse contractErr error - overwriteMessenger messenger + overwriteMessenger *wasmtesting.MockMessageHandler expErr bool expContractEventAttrs int expNoEvents bool @@ -605,10 +610,10 @@ func TestOnTimeoutPacket(t *testing.T) { defer cancel() before := ctx.GasMeter().GasConsumed() msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler() - keepers.WasmKeeper.messenger = msger + *messenger = *msger if spec.overwriteMessenger != nil { - keepers.WasmKeeper.messenger = spec.overwriteMessenger + *messenger = *spec.overwriteMessenger } // when diff --git a/x/wasm/internal/keeper/staking_test.go b/x/wasm/keeper/staking_test.go similarity index 85% rename from x/wasm/internal/keeper/staking_test.go rename to x/wasm/keeper/staking_test.go index c4d0f74e37..d530b28976 100644 --- a/x/wasm/internal/keeper/staking_test.go +++ b/x/wasm/keeper/staking_test.go @@ -5,6 +5,8 @@ import ( "io/ioutil" "testing" + wasmtypes "github.com/line/lfb-sdk/x/wasm/types" + codectypes "github.com/line/lfb-sdk/codec/types" "github.com/line/lfb-sdk/crypto/keys/secp256k1" sdk "github.com/line/lfb-sdk/types" @@ -90,8 +92,8 @@ type InvestmentResponse struct { } func TestInitializeStaking(t *testing.T) { - ctx, k := CreateTestInput(t, false, SupportedFeatures, nil, nil) - accKeeper, stakingKeeper, keeper, bankKeeper := k.AccountKeeper, k.StakingKeeper, k.WasmKeeper, k.BankKeeper + ctx, k := CreateTestInput(t, false, SupportedFeatures) + accKeeper, stakingKeeper, keeper, bankKeeper := k.AccountKeeper, k.StakingKeeper, k.ContractKeeper, k.BankKeeper valAddr := addValidator(t, ctx, stakingKeeper, accKeeper, bankKeeper, sdk.NewInt64Coin("stake", 1234567)) ctx = nextBlock(ctx, stakingKeeper) @@ -121,7 +123,7 @@ func TestInitializeStaking(t *testing.T) { initBz, err := json.Marshal(&initMsg) require.NoError(t, err) - stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil) + stakingAddr, _, err := k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) @@ -141,7 +143,7 @@ func TestInitializeStaking(t *testing.T) { badBz, err := json.Marshal(&badInitMsg) require.NoError(t, err) - _, _, err = keeper.Instantiate(ctx, stakingID, creator, nil, badBz, "missing validator", nil) + _, _, err = k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, badBz, "missing validator", nil) require.Error(t, err) // no changes to bonding shares @@ -154,16 +156,17 @@ type initInfo struct { creator sdk.AccAddress contractAddr sdk.AccAddress - ctx sdk.Context - accKeeper authkeeper.AccountKeeper - stakingKeeper stakingkeeper.Keeper - distKeeper distributionkeeper.Keeper - wasmKeeper Keeper - bankKeeper bankkeeper.Keeper + ctx sdk.Context + accKeeper authkeeper.AccountKeeper + stakingKeeper stakingkeeper.Keeper + distKeeper distributionkeeper.Keeper + wasmKeeper Keeper + contractKeeper wasmtypes.ContractOpsKeeper + bankKeeper bankkeeper.Keeper } func initializeStaking(t *testing.T) initInfo { - ctx, k := CreateTestInput(t, false, SupportedFeatures, nil, nil) + ctx, k := CreateTestInput(t, false, SupportedFeatures) accKeeper, stakingKeeper, keeper, bankKeeper := k.AccountKeeper, k.StakingKeeper, k.WasmKeeper, k.BankKeeper valAddr := addValidator(t, ctx, stakingKeeper, accKeeper, bankKeeper, sdk.NewInt64Coin("stake", 1000000)) @@ -186,7 +189,7 @@ func initializeStaking(t *testing.T) initInfo { // upload staking derivates code stakingCode, err := ioutil.ReadFile("./testdata/staking.wasm") require.NoError(t, err) - stakingID, err := keeper.Create(ctx, creator, stakingCode, "", "", nil) + stakingID, err := k.ContractKeeper.Create(ctx, creator, stakingCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), stakingID) @@ -202,20 +205,21 @@ func initializeStaking(t *testing.T) initInfo { initBz, err := json.Marshal(&initMsg) require.NoError(t, err) - stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil) + stakingAddr, _, err := k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) return initInfo{ - valAddr: valAddr, - creator: creator, - contractAddr: stakingAddr, - ctx: ctx, - accKeeper: accKeeper, - stakingKeeper: stakingKeeper, - wasmKeeper: *keeper, - distKeeper: k.DistKeeper, - bankKeeper: bankKeeper, + valAddr: valAddr, + creator: creator, + contractAddr: stakingAddr, + ctx: ctx, + accKeeper: accKeeper, + stakingKeeper: stakingKeeper, + wasmKeeper: *keeper, + distKeeper: k.DistKeeper, + bankKeeper: bankKeeper, + contractKeeper: k.ContractKeeper, } } @@ -244,7 +248,7 @@ func TestBonding(t *testing.T) { } bondBz, err := json.Marshal(bond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, bondBz, funds) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds) require.NoError(t, err) // check some account values - the money is on neither account (cuz it is bonded) @@ -287,7 +291,7 @@ func TestUnbonding(t *testing.T) { } bondBz, err := json.Marshal(bond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, bondBz, funds) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds) require.NoError(t, err) // update height a bit @@ -301,7 +305,7 @@ func TestUnbonding(t *testing.T) { } unbondBz, err := json.Marshal(unbond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, unbondBz, nil) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, unbondBz, nil) require.NoError(t, err) // check some account values - the money is on neither account (cuz it is bonded) @@ -356,7 +360,7 @@ func TestReinvest(t *testing.T) { } bondBz, err := json.Marshal(bond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, bondBz, funds) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds) require.NoError(t, err) // update height a bit to solidify the delegation @@ -370,7 +374,7 @@ func TestReinvest(t *testing.T) { } reinvestBz, err := json.Marshal(reinvest) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, reinvestBz, nil) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, reinvestBz, nil) require.NoError(t, err) // check some account values - the money is on neither account (cuz it is bonded) @@ -424,7 +428,7 @@ func TestQueryStakingInfo(t *testing.T) { } bondBz, err := json.Marshal(bond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, bondBz, funds) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds) require.NoError(t, err) // update height a bit to solidify the delegation @@ -442,12 +446,12 @@ func TestQueryStakingInfo(t *testing.T) { // upload mask code maskCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - maskID, err := keeper.Create(ctx, creator, maskCode, "", "", nil) + maskID, err := initInfo.contractKeeper.Create(ctx, creator, maskCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(2), maskID) // creator instantiates a contract and gives it tokens - maskAddr, _, err := keeper.Instantiate(ctx, maskID, creator, nil, []byte("{}"), "mask contract 2", nil) + maskAddr, _, err := initInfo.contractKeeper.Instantiate(ctx, maskID, creator, nil, []byte("{}"), "mask contract 2", nil) require.NoError(t, err) require.NotEmpty(t, maskAddr) @@ -467,24 +471,61 @@ func TestQueryStakingInfo(t *testing.T) { assert.Equal(t, "stake", bondedRes.Denom) // now, let's reflect a smart query into the x/wasm handlers and see if we get the same result - reflectValidatorsQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{ - Validators: &wasmvmtypes.ValidatorsQuery{}, + reflectAllValidatorsQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{ + AllValidators: &wasmvmtypes.AllValidatorsQuery{}, }}}} - reflectValidatorsBin := buildReflectQuery(t, &reflectValidatorsQuery) - res, err = keeper.QuerySmart(ctx, maskAddr, reflectValidatorsBin) + reflectAllValidatorsBin := buildReflectQuery(t, &reflectAllValidatorsQuery) + res, err = keeper.QuerySmart(ctx, maskAddr, reflectAllValidatorsBin) require.NoError(t, err) // first we pull out the data from chain response, before parsing the original response mustParse(t, res, &reflectRes) - var validatorRes wasmvmtypes.ValidatorsResponse + var allValidatorsRes wasmvmtypes.AllValidatorsResponse + mustParse(t, reflectRes.Data, &allValidatorsRes) + require.Len(t, allValidatorsRes.Validators, 1) + valInfo := allValidatorsRes.Validators[0] + // Note: this ValAddress not AccAddress, may change with #264 + require.Equal(t, valAddr.String(), valInfo.Address) + require.Contains(t, valInfo.Commission, "0.100") + require.Contains(t, valInfo.MaxCommission, "0.200") + require.Contains(t, valInfo.MaxChangeRate, "0.010") + + // find a validator + reflectValidatorQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{ + Validator: &wasmvmtypes.ValidatorQuery{ + Address: valAddr.String(), + }, + }}}} + reflectValidatorBin := buildReflectQuery(t, &reflectValidatorQuery) + res, err = keeper.QuerySmart(ctx, maskAddr, reflectValidatorBin) + require.NoError(t, err) + // first we pull out the data from chain response, before parsing the original response + mustParse(t, res, &reflectRes) + var validatorRes wasmvmtypes.ValidatorResponse mustParse(t, reflectRes.Data, &validatorRes) - require.Len(t, validatorRes.Validators, 1) - valInfo := validatorRes.Validators[0] + require.NotNil(t, validatorRes.Validator) + valInfo = *validatorRes.Validator // Note: this ValAddress not AccAddress, may change with #264 require.Equal(t, valAddr.String(), valInfo.Address) require.Contains(t, valInfo.Commission, "0.100") require.Contains(t, valInfo.MaxCommission, "0.200") require.Contains(t, valInfo.MaxChangeRate, "0.010") + // missing validator + noVal := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()) + reflectNoValidatorQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{ + Validator: &wasmvmtypes.ValidatorQuery{ + Address: noVal.String(), + }, + }}}} + reflectNoValidatorBin := buildReflectQuery(t, &reflectNoValidatorQuery) + res, err = keeper.QuerySmart(ctx, maskAddr, reflectNoValidatorBin) + require.NoError(t, err) + // first we pull out the data from chain response, before parsing the original response + mustParse(t, res, &reflectRes) + var noValidatorRes wasmvmtypes.ValidatorResponse + mustParse(t, reflectRes.Data, &noValidatorRes) + require.Nil(t, noValidatorRes.Validator) + // test to get all my delegations reflectAllDelegationsQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{ AllDelegations: &wasmvmtypes.AllDelegationsQuery{ @@ -546,7 +587,7 @@ func TestQueryStakingPlugin(t *testing.T) { // STEP 1: take a lot of setup from TestReinvest so we have non-zero info initInfo := initializeStaking(t) ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr - keeper, stakingKeeper, accKeeper := initInfo.wasmKeeper, initInfo.stakingKeeper, initInfo.accKeeper + stakingKeeper, accKeeper := initInfo.stakingKeeper, initInfo.accKeeper distKeeper := initInfo.distKeeper // initial checks of bonding state @@ -566,7 +607,7 @@ func TestQueryStakingPlugin(t *testing.T) { } bondBz, err := json.Marshal(bond) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, bob, bondBz, funds) + _, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds) require.NoError(t, err) // update height a bit to solidify the delegation diff --git a/x/wasm/internal/keeper/submsg_test.go b/x/wasm/keeper/submsg_test.go similarity index 71% rename from x/wasm/internal/keeper/submsg_test.go rename to x/wasm/keeper/submsg_test.go index 919ce1ce7c..fc28c8091a 100644 --- a/x/wasm/internal/keeper/submsg_test.go +++ b/x/wasm/keeper/submsg_test.go @@ -18,7 +18,7 @@ import ( // Try a simple send, no gas limit to for a sanity check before trying table tests func TestDispatchSubMsgSuccessCase(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, ReflectFeatures) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -31,12 +31,12 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) { // upload code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) require.Equal(t, uint64(1), codeID) // creator instantiates a contract and gives it tokens - contractAddr, _, err := keeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) require.NoError(t, err) require.NotEmpty(t, contractAddr) @@ -60,14 +60,15 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) { reflectSend := ReflectHandleMsg{ ReflectSubCall: &reflectSubPayload{ Msgs: []wasmvmtypes.SubMsg{{ - ID: 7, - Msg: msg, + ID: 7, + Msg: msg, + ReplyOn: wasmvmtypes.ReplyAlways, }}, }, } reflectSendBz, err := json.Marshal(reflectSend) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, creator, reflectSendBz, nil) + _, err = keepers.ContractKeeper.Execute(ctx, contractAddr, creator, reflectSendBz, nil) require.NoError(t, err) // fred got coins @@ -126,7 +127,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { subGasLimit := uint64(300_000) // prep - create one chain and upload the code - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, nil, nil) + ctx, keepers := CreateTestInput(t, false, ReflectFeatures) ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) ctx = ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper @@ -136,13 +137,13 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { // upload code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - reflectID, err := keeper.Create(ctx, uploader, reflectCode, "", "", nil) + reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, reflectCode, "", "", nil) require.NoError(t, err) // create hackatom contract for testing (for infinite loop) hackatomCode, err := ioutil.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - hackatomID, err := keeper.Create(ctx, uploader, hackatomCode, "", "", nil) + hackatomID, err := keepers.ContractKeeper.Create(ctx, uploader, hackatomCode, "", "", nil) require.NoError(t, err) _, _, bob := keyPubAddr() _, _, fred := keyPubAddr() @@ -152,7 +153,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { } initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - hackatomAddr, _, err := keeper.Instantiate(ctx, hackatomID, uploader, nil, initMsgBz, "hackatom demo", contractStart) + hackatomAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, hackatomID, uploader, nil, initMsgBz, "hackatom demo", contractStart) require.NoError(t, err) validBankSend := func(contract, emptyAccount string) wasmvmtypes.CosmosMsg { @@ -313,7 +314,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, contractStart) _, _, empty := keyPubAddr() - contractAddr, _, err := keeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), fmt.Sprintf("contract %s", name), contractStart) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), fmt.Sprintf("contract %s", name), contractStart) require.NoError(t, err) msg := tc.msg(contractAddr.String(), empty.String()) @@ -323,6 +324,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { ID: tc.submsgID, Msg: msg, GasLimit: tc.gasLimit, + ReplyOn: wasmvmtypes.ReplyAlways, }}, }, } @@ -339,7 +341,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { } } }() - _, err = keeper.Execute(execCtx, contractAddr, creator, reflectSendBz, nil) + _, err = keepers.ContractKeeper.Execute(execCtx, contractAddr, creator, reflectSendBz, nil) if tc.executeError { require.Error(t, err) @@ -387,7 +389,7 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) { Bank: nilEncoder, } - ctx, keepers := CreateTestInput(t, false, ReflectFeatures, customEncoders, nil) + ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageHandler(NewSDKMessageHandler(nil, customEncoders))) accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) @@ -399,11 +401,11 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) { // upload code reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") require.NoError(t, err) - codeID, err := keeper.Create(ctx, creator, reflectCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) require.NoError(t, err) // creator instantiates a contract and gives it tokens - contractAddr, _, err := keeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) require.NoError(t, err) require.NotEmpty(t, contractAddr) @@ -422,14 +424,15 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) { reflectSend := ReflectHandleMsg{ ReflectSubCall: &reflectSubPayload{ Msgs: []wasmvmtypes.SubMsg{{ - ID: 7, - Msg: msg, + ID: 7, + Msg: msg, + ReplyOn: wasmvmtypes.ReplyAlways, }}, }, } reflectSendBz, err := json.Marshal(reflectSend) require.NoError(t, err) - _, err = keeper.Execute(ctx, contractAddr, creator, reflectSendBz, nil) + _, err = keepers.ContractKeeper.Execute(ctx, contractAddr, creator, reflectSendBz, nil) require.NoError(t, err) // query the reflect state to ensure the result was stored @@ -451,3 +454,132 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) { assert.Empty(t, sub.Data) require.Len(t, sub.Events, 0) } + +// Try a simple send, no gas limit to for a sanity check before trying table tests +func TestDispatchSubMsgConditionalReplyOn(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, ReflectFeatures) + accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000)) + + creator := createFakeFundedAccount(t, ctx, accKeeper, bankKeeper, deposit) + _, _, fred := keyPubAddr() + + // upload code + reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm") + require.NoError(t, err) + codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, "", "", nil) + require.NoError(t, err) + + // creator instantiates a contract and gives it tokens + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart) + require.NoError(t, err) + + goodSend := wasmvmtypes.CosmosMsg{ + Bank: &wasmvmtypes.BankMsg{ + Send: &wasmvmtypes.SendMsg{ + ToAddress: fred.String(), + Amount: []wasmvmtypes.Coin{{ + Denom: "denom", + Amount: "1000", + }}, + }, + }, + } + failSend := wasmvmtypes.CosmosMsg{ + Bank: &wasmvmtypes.BankMsg{ + Send: &wasmvmtypes.SendMsg{ + ToAddress: fred.String(), + Amount: []wasmvmtypes.Coin{{ + Denom: "no-such-token", + Amount: "777777", + }}, + }, + }, + } + + cases := map[string]struct { + // true for wasmvmtypes.ReplySuccess, false for wasmvmtypes.ReplyError + replyOnSuccess bool + msg wasmvmtypes.CosmosMsg + // true if the call should return an error (it wasn't handled) + expectError bool + // true if the reflect contract wrote the response (success or error) - it was captured + writeResult bool + }{ + "all good, reply success": { + replyOnSuccess: true, + msg: goodSend, + expectError: false, + writeResult: true, + }, + "all good, reply error": { + replyOnSuccess: false, + msg: goodSend, + expectError: false, + writeResult: false, + }, + "bad msg, reply success": { + replyOnSuccess: true, + msg: failSend, + expectError: true, + writeResult: false, + }, + "bad msg, reply error": { + replyOnSuccess: false, + msg: failSend, + expectError: false, + writeResult: true, + }, + } + + var id uint64 = 0 + for name, tc := range cases { + id++ + t.Run(name, func(t *testing.T) { + subMsg := wasmvmtypes.SubMsg{ + ID: id, + Msg: tc.msg, + ReplyOn: wasmvmtypes.ReplySuccess, + } + if !tc.replyOnSuccess { + subMsg.ReplyOn = wasmvmtypes.ReplyError + } + + reflectSend := ReflectHandleMsg{ + ReflectSubCall: &reflectSubPayload{ + Msgs: []wasmvmtypes.SubMsg{subMsg}, + }, + } + reflectSendBz, err := json.Marshal(reflectSend) + require.NoError(t, err) + _, err = keepers.ContractKeeper.Execute(ctx, contractAddr, creator, reflectSendBz, nil) + + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + + // query the reflect state to check if the result was stored + query := ReflectQueryMsg{ + SubCallResult: &SubCall{ID: id}, + } + queryBz, err := json.Marshal(query) + require.NoError(t, err) + queryRes, err := keeper.QuerySmart(ctx, contractAddr, queryBz) + if tc.writeResult { + // we got some data for this call + require.NoError(t, err) + var res wasmvmtypes.Reply + err = json.Unmarshal(queryRes, &res) + require.NoError(t, err) + require.Equal(t, id, res.ID) + } else { + // nothing should be there -> error + require.Error(t, err) + } + }) + } +} diff --git a/x/wasm/internal/keeper/test_common.go b/x/wasm/keeper/test_common.go similarity index 89% rename from x/wasm/internal/keeper/test_common.go rename to x/wasm/keeper/test_common.go index c23527275a..2e61f07f17 100644 --- a/x/wasm/internal/keeper/test_common.go +++ b/x/wasm/keeper/test_common.go @@ -56,7 +56,8 @@ import ( stakingtypes "github.com/line/lfb-sdk/x/staking/types" "github.com/line/lfb-sdk/x/upgrade" upgradeclient "github.com/line/lfb-sdk/x/upgrade/client" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper/wasmtesting" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/crypto" "github.com/line/ostracon/crypto/ed25519" "github.com/line/ostracon/libs/log" @@ -128,13 +129,16 @@ var TestingStakeParams = stakingtypes.Params{ } type TestKeepers struct { - AccountKeeper authkeeper.AccountKeeper - StakingKeeper stakingkeeper.Keeper - DistKeeper distributionkeeper.Keeper - BankKeeper bankkeeper.Keeper - GovKeeper govkeeper.Keeper - WasmKeeper *Keeper - IBCKeeper *ibckeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + StakingKeeper stakingkeeper.Keeper + DistKeeper distributionkeeper.Keeper + BankKeeper bankkeeper.Keeper + GovKeeper govkeeper.Keeper + ContractKeeper types.ContractOpsKeeper + WasmKeeper *Keeper + IBCKeeper *ibckeeper.Keeper + Router *baseapp.Router + EncodingConfig params2.EncodingConfig } // CreateDefaultTestInput common settings for CreateTestInput @@ -143,11 +147,9 @@ func CreateDefaultTestInput(t TestingT) (sdk.Context, TestKeepers) { } // encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default) -func CreateTestInput(t TestingT, isCheckTx bool, supportedFeatures string, encoders *MessageEncoders, queriers *QueryPlugins) (sdk.Context, TestKeepers) { +func CreateTestInput(t TestingT, isCheckTx bool, supportedFeatures string, encoders *MessageEncoders, queriers *QueryPlugins, opts ...Option) (sdk.Context, TestKeepers) { // Load default wasm config - wasmConfig := types.DefaultWasmConfig() - db := memdb.NewDB() - return createTestInput(t, isCheckTx, supportedFeatures, encoders, queriers, wasmConfig, db) + return createTestInput(t, isCheckTx, supportedFeatures, encoders, queriers, types.DefaultWasmConfig(), memdb.NewDB(), opts...) } // encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default) @@ -159,6 +161,7 @@ func createTestInput( queriers *QueryPlugins, wasmConfig types.WasmConfig, db dbm.DB, + opts ...Option, ) (sdk.Context, TestKeepers) { tempDir := t.TempDir() @@ -213,6 +216,7 @@ func createTestInput( stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.ModuleName: {authtypes.Burner}, } authSubsp, _ := paramsKeeper.GetSubspace(authtypes.ModuleName) authKeeper := authkeeper.NewAccountKeeper( @@ -237,9 +241,10 @@ func createTestInput( blockedAddrs, ) bankParams := banktypes.DefaultParams() - bankParams = bankParams.SetSendEnabledParam("stake", true) bankKeeper.SetParams(ctx, bankParams) - + bankKeeper.SetSupply(ctx, banktypes.NewSupply(sdk.NewCoins( + sdk.NewCoin("denom", sdk.NewInt(10000)), + ))) stakingSubsp, _ := paramsKeeper.GetSubspace(stakingtypes.ModuleName) stakingKeeper := stakingkeeper.NewKeeper(appCodec, keyStaking, authKeeper, bankKeeper, stakingSubsp) stakingKeeper.SetParams(ctx, TestingStakeParams) @@ -294,6 +299,7 @@ func createTestInput( ibcKeeper.ChannelKeeper, &ibcKeeper.PortKeeper, scopedWasmKeeper, + wasmtesting.MockIBCTransferKeeper{}, router, nil, querier, @@ -302,10 +308,12 @@ func createTestInput( supportedFeatures, encoders, queriers, + opts..., ) keeper.setParams(ctx, types.DefaultParams()) // add wasm handler so we can loop-back (contracts calling contracts) - router.AddRoute(sdk.NewRoute(types.RouterKey, TestHandler(&keeper))) + contractKeeper := NewDefaultPermissionKeeper(&keeper) + router.AddRoute(sdk.NewRoute(types.RouterKey, TestHandler(contractKeeper))) govRouter := govtypes.NewRouter(). AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). @@ -323,19 +331,22 @@ func createTestInput( govKeeper.SetTallyParams(ctx, govtypes.DefaultTallyParams()) keepers := TestKeepers{ - AccountKeeper: authKeeper, - StakingKeeper: stakingKeeper, - DistKeeper: distKeeper, - WasmKeeper: &keeper, - BankKeeper: bankKeeper, - GovKeeper: govKeeper, - IBCKeeper: ibcKeeper, + AccountKeeper: authKeeper, + StakingKeeper: stakingKeeper, + DistKeeper: distKeeper, + ContractKeeper: contractKeeper, + WasmKeeper: &keeper, + BankKeeper: bankKeeper, + GovKeeper: govKeeper, + IBCKeeper: ibcKeeper, + Router: router, + EncodingConfig: encodingConfig, } return ctx, keepers } // TestHandler returns a wasm handler for tests (to avoid circular imports) -func TestHandler(k *Keeper) sdk.Handler { +func TestHandler(k types.ContractOpsKeeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -352,7 +363,7 @@ func TestHandler(k *Keeper) sdk.Handler { } } -func handleStoreCode(ctx sdk.Context, k *Keeper, msg *types.MsgStoreCode) (*sdk.Result, error) { +func handleStoreCode(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgStoreCode) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") @@ -368,7 +379,7 @@ func handleStoreCode(ctx sdk.Context, k *Keeper, msg *types.MsgStoreCode) (*sdk. }, nil } -func handleInstantiate(ctx sdk.Context, k *Keeper, msg *types.MsgInstantiateContract) (*sdk.Result, error) { +func handleInstantiate(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgInstantiateContract) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") @@ -391,7 +402,7 @@ func handleInstantiate(ctx sdk.Context, k *Keeper, msg *types.MsgInstantiateCont }, nil } -func handleExecute(ctx sdk.Context, k *Keeper, msg *types.MsgExecuteContract) (*sdk.Result, error) { +func handleExecute(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgExecuteContract) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") @@ -442,7 +453,7 @@ func StoreReflectContract(t TestingT, ctx sdk.Context, keepers TestKeepers) uint require.NoError(t, err) _, _, creatorAddr := keyPubAddr() - codeID, err := keepers.WasmKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) require.NoError(t, err) return codeID } @@ -455,7 +466,7 @@ func StoreExampleContract(t TestingT, ctx sdk.Context, keepers TestKeepers, wasm wasmCode, err := ioutil.ReadFile(wasmFile) require.NoError(t, err) - codeID, err := keepers.WasmKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) require.NoError(t, err) return ExampleContract{anyAmount, creator, creatorAddr, codeID} } @@ -471,7 +482,7 @@ type ExampleContractInstance struct { func SeedNewContractInstance(t TestingT, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContractInstance { t.Helper() exampleContract := StoreRandomContract(t, ctx, keepers, mock) - contractAddr, _, err := keepers.WasmKeeper.Instantiate(ctx, exampleContract.CodeID, exampleContract.CreatorAddr, exampleContract.CreatorAddr, []byte(`{}`), "", nil) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, exampleContract.CodeID, exampleContract.CreatorAddr, exampleContract.CreatorAddr, []byte(`{}`), "", nil) require.NoError(t, err) return ExampleContractInstance{ ExampleContract: exampleContract, @@ -485,9 +496,9 @@ func StoreRandomContract(t TestingT, ctx sdk.Context, keepers TestKeepers, mock anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)) creator, _, creatorAddr := keyPubAddr() fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, creatorAddr, anyAmount) - keepers.WasmKeeper.wasmer = mock + keepers.WasmKeeper.wasmVM = mock wasmCode := append(wasmIdent, rand.Bytes(10)...) - codeID, err := keepers.WasmKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) + codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil) require.NoError(t, err) exampleContract := ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID} return exampleContract @@ -517,7 +528,7 @@ func InstantiateHackatomExampleContract(t TestingT, ctx sdk.Context, keepers Tes initialAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 100)) adminAddr := contract.CreatorAddr - contractAddr, _, err := keepers.WasmKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, "demo contract to query", initialAmount) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, "demo contract to query", initialAmount) require.NoError(t, err) return HackatomExampleInstance{ ExampleContract: contract, @@ -557,7 +568,7 @@ func InstantiateIBCReflectContract(t TestingT, ctx sdk.Context, keepers TestKeep }.GetBytes(t) adminAddr := RandomAccountAddress(t) - contractAddr, _, err := keepers.WasmKeeper.Instantiate(ctx, ibcReflectID, adminAddr, adminAddr, initMsgBz, "ibc-reflect-factory", nil) + contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, ibcReflectID, adminAddr, adminAddr, initMsgBz, "ibc-reflect-factory", nil) require.NoError(t, err) return IBCReflectExampleInstance{ Admin: adminAddr, diff --git a/x/wasm/internal/keeper/test_fuzz.go b/x/wasm/keeper/test_fuzz.go similarity index 97% rename from x/wasm/internal/keeper/test_fuzz.go rename to x/wasm/keeper/test_fuzz.go index 98740dcabe..0cc209d0da 100644 --- a/x/wasm/internal/keeper/test_fuzz.go +++ b/x/wasm/keeper/test_fuzz.go @@ -5,7 +5,7 @@ import ( fuzz "github.com/google/gofuzz" sdk "github.com/line/lfb-sdk/types" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" tmBytes "github.com/line/ostracon/libs/bytes" ) diff --git a/x/wasm/keeper/testdata/burner.wasm b/x/wasm/keeper/testdata/burner.wasm new file mode 100644 index 0000000000..a060cb5a64 Binary files /dev/null and b/x/wasm/keeper/testdata/burner.wasm differ diff --git a/x/wasm/internal/keeper/testdata/download_releases.sh b/x/wasm/keeper/testdata/download_releases.sh similarity index 100% rename from x/wasm/internal/keeper/testdata/download_releases.sh rename to x/wasm/keeper/testdata/download_releases.sh diff --git a/x/wasm/internal/keeper/testdata/genesis.json b/x/wasm/keeper/testdata/genesis.json similarity index 100% rename from x/wasm/internal/keeper/testdata/genesis.json rename to x/wasm/keeper/testdata/genesis.json diff --git a/x/wasm/keeper/testdata/hackatom.wasm b/x/wasm/keeper/testdata/hackatom.wasm new file mode 100644 index 0000000000..e9f0b90503 Binary files /dev/null and b/x/wasm/keeper/testdata/hackatom.wasm differ diff --git a/x/wasm/keeper/testdata/hackatom.wasm.gzip b/x/wasm/keeper/testdata/hackatom.wasm.gzip new file mode 100644 index 0000000000..8ce63272f4 Binary files /dev/null and b/x/wasm/keeper/testdata/hackatom.wasm.gzip differ diff --git a/x/wasm/keeper/testdata/ibc_reflect.wasm b/x/wasm/keeper/testdata/ibc_reflect.wasm new file mode 100644 index 0000000000..33f49b33e0 Binary files /dev/null and b/x/wasm/keeper/testdata/ibc_reflect.wasm differ diff --git a/x/wasm/keeper/testdata/ibc_reflect_send.wasm b/x/wasm/keeper/testdata/ibc_reflect_send.wasm new file mode 100644 index 0000000000..dca7f5f0d2 Binary files /dev/null and b/x/wasm/keeper/testdata/ibc_reflect_send.wasm differ diff --git a/x/wasm/keeper/testdata/reflect.wasm b/x/wasm/keeper/testdata/reflect.wasm new file mode 100644 index 0000000000..4606c4a8df Binary files /dev/null and b/x/wasm/keeper/testdata/reflect.wasm differ diff --git a/x/wasm/keeper/testdata/staking.wasm b/x/wasm/keeper/testdata/staking.wasm new file mode 100644 index 0000000000..93c7cb4564 Binary files /dev/null and b/x/wasm/keeper/testdata/staking.wasm differ diff --git a/x/wasm/internal/keeper/wasmtesting/coin_transferrer.go b/x/wasm/keeper/wasmtesting/coin_transferrer.go similarity index 100% rename from x/wasm/internal/keeper/wasmtesting/coin_transferrer.go rename to x/wasm/keeper/wasmtesting/coin_transferrer.go diff --git a/x/wasm/internal/keeper/wasmtesting/messenger.go b/x/wasm/keeper/wasmtesting/messenger.go similarity index 100% rename from x/wasm/internal/keeper/wasmtesting/messenger.go rename to x/wasm/keeper/wasmtesting/messenger.go diff --git a/x/wasm/internal/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go similarity index 96% rename from x/wasm/internal/keeper/wasmtesting/mock_engine.go rename to x/wasm/keeper/wasmtesting/mock_engine.go index b41ac83627..d1159ed40c 100644 --- a/x/wasm/internal/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -5,7 +5,7 @@ import ( "crypto/sha256" sdkerrors "github.com/line/lfb-sdk/types/errors" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" "github.com/line/ostracon/libs/rand" wasmvm "github.com/line/wasmvm" wasmvmtypes "github.com/line/wasmvm/types" @@ -34,6 +34,7 @@ type MockWasmer struct { IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) PinFn func(checksum wasmvm.Checksum) error UnpinFn func(checksum wasmvm.Checksum) error + GetMetricsFn func() (*wasmvmtypes.Metrics, error) } func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error) { @@ -163,9 +164,16 @@ func (m *MockWasmer) Unpin(checksum wasmvm.Checksum) error { return m.UnpinFn(checksum) } +func (m *MockWasmer) GetMetrics() (*wasmvmtypes.Metrics, error) { + if m.GetMetricsFn == nil { + panic("not expected to be called") + } + return m.GetMetricsFn() +} + var AlwaysPanicMockWasmer = &MockWasmer{} -// selfCallingInstMockWasmer prepares a Wasmer mock that calls itself on instantiation. +// SelfCallingInstMockWasmer prepares a Wasmer mock that calls itself on instantiation. func SelfCallingInstMockWasmer(executeCalled *bool) *MockWasmer { return &MockWasmer{ @@ -272,10 +280,16 @@ type contractExecutable interface { ) (*wasmvmtypes.Response, uint64, error) } -//MakeIBCInstantiable adds some noop functions to not fail when contract is used for instantiation -func MakeIBCInstantiable(m *MockWasmer) { +//MakeInstantiable adds some noop functions to not fail when contract is used for instantiation +func MakeInstantiable(m *MockWasmer) { m.CreateFn = HashOnlyCreateFn m.InstantiateFn = NoOpInstantiateFn + m.AnalyzeCodeFn = WithoutIBCAnalyzeFn +} + +//MakeIBCInstantiable adds some noop functions to not fail when contract is used for instantiation +func MakeIBCInstantiable(m *MockWasmer) { + MakeInstantiable(m) m.AnalyzeCodeFn = HasIBCAnalyzeFn } diff --git a/x/wasm/internal/keeper/wasmtesting/mock_keepers.go b/x/wasm/keeper/wasmtesting/mock_keepers.go similarity index 79% rename from x/wasm/internal/keeper/wasmtesting/mock_keepers.go rename to x/wasm/keeper/wasmtesting/mock_keepers.go index e43a3b45cc..a68cc3d371 100644 --- a/x/wasm/internal/keeper/wasmtesting/mock_keepers.go +++ b/x/wasm/keeper/wasmtesting/mock_keepers.go @@ -5,6 +5,7 @@ import ( capabilitytypes "github.com/line/lfb-sdk/x/capability/types" channeltypes "github.com/line/lfb-sdk/x/ibc/core/04-channel/types" ibcexported "github.com/line/lfb-sdk/x/ibc/core/exported" + "github.com/line/lfb-sdk/x/wasm/types" ) type MockChannelKeeper struct { @@ -13,6 +14,7 @@ type MockChannelKeeper struct { SendPacketFn func(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error ChanCloseInitFn func(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error GetAllChannelsFn func(ctx sdk.Context) []channeltypes.IdentifiedChannel + IterateChannelsFn func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) } func (m *MockChannelKeeper) GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) { @@ -29,17 +31,6 @@ func (m *MockChannelKeeper) GetAllChannels(ctx sdk.Context) []channeltypes.Ident return m.GetAllChannelsFn(ctx) } -// Auto-implemented from GetAllChannels data -func (m *MockChannelKeeper) IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) { - channels := m.GetAllChannels(ctx) - for _, channel := range channels { - stop := cb(channel) - if stop { - break - } - } -} - func (m *MockChannelKeeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { if m.GetNextSequenceSendFn == nil { panic("not supposed to be called!") @@ -61,6 +52,24 @@ func (m *MockChannelKeeper) ChanCloseInit(ctx sdk.Context, portID, channelID str return m.ChanCloseInitFn(ctx, portID, channelID, chanCap) } +func (m *MockChannelKeeper) IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) { + if m.IterateChannelsFn == nil { + panic("not expected to be called") + } + m.IterateChannelsFn(ctx, cb) +} + +func MockChannelKeeperIterator(s []channeltypes.IdentifiedChannel) func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) { + return func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) { + for _, channel := range s { + stop := cb(channel) + if stop { + break + } + } + } +} + type MockCapabilityKeeper struct { GetCapabilityFn func(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) ClaimCapabilityFn func(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error @@ -79,7 +88,6 @@ func (m MockCapabilityKeeper) ClaimCapability(ctx sdk.Context, cap *capabilityty panic("not supposed to be called!") } return m.ClaimCapabilityFn(ctx, cap, name) - } func (m MockCapabilityKeeper) AuthenticateCapability(ctx sdk.Context, capability *capabilitytypes.Capability, name string) bool { @@ -87,5 +95,17 @@ func (m MockCapabilityKeeper) AuthenticateCapability(ctx sdk.Context, capability panic("not supposed to be called!") } return m.AuthenticateCapabilityFn(ctx, capability, name) +} +var _ types.ICS20TransferPortSource = &MockIBCTransferKeeper{} + +type MockIBCTransferKeeper struct { + GetPortFn func(ctx sdk.Context) string +} + +func (m MockIBCTransferKeeper) GetPort(ctx sdk.Context) string { + if m.GetPortFn == nil { + panic("not expected to be called") + } + return m.GetPortFn(ctx) } diff --git a/x/wasm/keeper/wasmtesting/msg_dispatcher.go b/x/wasm/keeper/wasmtesting/msg_dispatcher.go new file mode 100644 index 0000000000..0c2c7dd40e --- /dev/null +++ b/x/wasm/keeper/wasmtesting/msg_dispatcher.go @@ -0,0 +1,25 @@ +package wasmtesting + +import ( + sdk "github.com/line/lfb-sdk/types" + wasmvmtypes "github.com/line/wasmvm/types" +) + +type MockMsgDispatcher struct { + DispatchMessagesFn func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error + DispatchSubmessagesFn func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) +} + +func (m MockMsgDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error { + if m.DispatchMessagesFn == nil { + panic("not expected to be called") + } + return m.DispatchMessagesFn(ctx, contractAddr, ibcPort, msgs) +} + +func (m MockMsgDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) { + if m.DispatchSubmessagesFn == nil { + panic("not expected to be called") + } + return m.DispatchSubmessagesFn(ctx, contractAddr, ibcPort, msgs) +} diff --git a/x/wasm/keeper/wasmtesting/query_handler.go b/x/wasm/keeper/wasmtesting/query_handler.go new file mode 100644 index 0000000000..b4faa369a6 --- /dev/null +++ b/x/wasm/keeper/wasmtesting/query_handler.go @@ -0,0 +1,17 @@ +package wasmtesting + +import ( + sdk "github.com/line/lfb-sdk/types" + wasmvmtypes "github.com/line/wasmvm/types" +) + +type MockQueryHandler struct { + HandleQueryFn func(ctx sdk.Context, request wasmvmtypes.QueryRequest, caller sdk.AccAddress) ([]byte, error) +} + +func (m *MockQueryHandler) HandleQuery(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) { + if m.HandleQueryFn == nil { + panic("not expected to be called") + } + return m.HandleQueryFn(ctx, request, caller) +} diff --git a/x/wasm/keeper/wasmtesting/store.go b/x/wasm/keeper/wasmtesting/store.go new file mode 100644 index 0000000000..a5a3b4744e --- /dev/null +++ b/x/wasm/keeper/wasmtesting/store.go @@ -0,0 +1,26 @@ +package wasmtesting + +import ( + storetypes "github.com/line/lfb-sdk/store/types" + sdk "github.com/line/lfb-sdk/types" +) + +// MockCommitMultiStore mock with a CacheMultiStore to capture commits +type MockCommitMultiStore struct { + sdk.CommitMultiStore + Committed []bool +} + +func (m *MockCommitMultiStore) CacheMultiStore() storetypes.CacheMultiStore { + m.Committed = append(m.Committed, false) + return &mockCMS{m, &m.Committed[len(m.Committed)-1]} +} + +type mockCMS struct { + sdk.CommitMultiStore + committed *bool +} + +func (m *mockCMS) Write() { + *m.committed = true +} diff --git a/x/wasm/linkwasmd/app/app.go b/x/wasm/linkwasmd/app/app.go index 944012c242..8955cb6408 100644 --- a/x/wasm/linkwasmd/app/app.go +++ b/x/wasm/linkwasmd/app/app.go @@ -88,7 +88,7 @@ import ( upgradetypes "github.com/line/lfb-sdk/x/upgrade/types" "github.com/line/lfb-sdk/x/wasm" wasmclient "github.com/line/lfb-sdk/x/wasm/client" - wasmtypes "github.com/line/lfb-sdk/x/wasm/internal/types" + wasmtypes "github.com/line/lfb-sdk/x/wasm/types" appparams "github.com/line/lfb-sdk/x/wasm/linkwasmd/app/params" diff --git a/x/wasm/linkwasmd/app/app_test.go b/x/wasm/linkwasmd/app/app_test.go index e1497b074d..586c5cb5ba 100644 --- a/x/wasm/linkwasmd/app/app_test.go +++ b/x/wasm/linkwasmd/app/app_test.go @@ -45,7 +45,11 @@ func TestBlacklistedAddrs(t *testing.T) { gapp := NewLinkApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, MakeEncodingConfig(), wasm.EnableAllProposals, EmptyBaseAppOptions{}, emptyWasmOpts) for acc := range maccPerms { - require.Equal(t, !allowedReceivingModAcc[acc], gapp.BankKeeper.BlockedAddr(gapp.AccountKeeper.GetModuleAddress(acc))) + t.Run(acc, func(t *testing.T) { + require.True(t, gapp.bankKeeper.BlockedAddr(gapp.accountKeeper.GetModuleAddress(acc)), + "ensure that blocked addresses are properly set in bank keeper", + ) + }) } } diff --git a/x/wasm/linkwasmd/cmd/linkwasmd/cmd/root.go b/x/wasm/linkwasmd/cmd/linkwasmd/cmd/root.go index 4d05d583cd..9daa174e89 100644 --- a/x/wasm/linkwasmd/cmd/linkwasmd/cmd/root.go +++ b/x/wasm/linkwasmd/cmd/linkwasmd/cmd/root.go @@ -48,7 +48,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { encodingConfig := app.MakeEncodingConfig() initClientCtx := client.Context{}. - WithJSONMarshaler(encodingConfig.Marshaler). + WithJSONMarshaler(clientcodec.NewProtoCodec(encodingConfig.Marshaler, encodingConfig.InterfaceRegistry)). WithInterfaceRegistry(encodingConfig.InterfaceRegistry). WithTxConfig(encodingConfig.TxConfig). WithLegacyAmino(encodingConfig.Amino). @@ -187,15 +187,17 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts serverty if err != nil { panic(err) } - var emptyWasmOpts []wasm.Option - return app.NewLinkApp( - logger, db, traceStore, true, skipUpgradeHeights, + var wasmOpts []wasm.Option + if cast.ToBool(appOpts.Get("telemetry.enabled")) { + wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) + + return app.NewWasmApp(logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), app.MakeEncodingConfig(), // Ideally, we would reuse the one created by NewRootCmd. wasm.EnableAllProposals, appOpts, - emptyWasmOpts, + wasmOpts, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), diff --git a/x/wasm/module.go b/x/wasm/module.go index 0552102be4..8f8f12cca5 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -17,9 +17,9 @@ import ( simtypes "github.com/line/lfb-sdk/types/simulation" "github.com/line/lfb-sdk/x/wasm/client/cli" "github.com/line/lfb-sdk/x/wasm/client/rest" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" "github.com/line/lfb-sdk/x/wasm/simulation" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -111,12 +111,12 @@ func NewAppModule(cdc codec.Marshaler, keeper *Keeper, validatorSetSource keeper } func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(keeper.NewDefaultPermissionKeeper(am.keeper))) types.RegisterQueryServer(cfg.QueryServer(), NewQuerier(am.keeper)) } func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { - return keeper.NewLegacyQuerier(am.keeper) + return keeper.NewLegacyQuerier(am.keeper, am.keeper.QueryGasLimit()) } // RegisterInvariants registers the wasm module invariants. @@ -124,7 +124,7 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} // Route returns the message routing key for the wasm module. func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(RouterKey, NewHandler(am.keeper)) + return sdk.NewRoute(RouterKey, NewHandler(keeper.NewDefaultPermissionKeeper(am.keeper))) } // QuerierRoute returns the wasm module's querier route name. diff --git a/x/wasm/module_test.go b/x/wasm/module_test.go index 8bbeb69ee4..65e15200e7 100644 --- a/x/wasm/module_test.go +++ b/x/wasm/module_test.go @@ -12,8 +12,8 @@ import ( authkeeper "github.com/line/lfb-sdk/x/auth/keeper" bankkeeper "github.com/line/lfb-sdk/x/bank/keeper" stakingkeeper "github.com/line/lfb-sdk/x/staking/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/keeper" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/keeper" + "github.com/line/lfb-sdk/x/wasm/types" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/crypto" "github.com/line/ostracon/crypto/ed25519" @@ -33,7 +33,7 @@ type testData struct { // returns a cleanup function, which must be defered on func setupTest(t *testing.T) testData { - ctx, keepers := CreateTestInput(t, false, "staking,stargate", nil, nil) + ctx, keepers := CreateTestInput(t, false, "staking,stargate") cdc := keeper.MakeTestCodec(t) data := testData{ module: NewAppModule(cdc, keepers.WasmKeeper, keepers.StakingKeeper), @@ -64,8 +64,8 @@ func mustLoad(path string) []byte { var ( _, _, addrAcc1 = keyPubAddr() addr1 = addrAcc1.String() - testContract = mustLoad("./internal/keeper/testdata/hackatom.wasm") - maskContract = mustLoad("./internal/keeper/testdata/reflect.wasm") + testContract = mustLoad("./keeper/testdata/hackatom.wasm") + maskContract = mustLoad("./keeper/testdata/reflect.wasm") oldContract = mustLoad("./testdata/escrow_0.7.wasm") ) @@ -137,9 +137,9 @@ type initMsg struct { type emptyMsg struct{} type state struct { - Verifier wasmvmtypes.CanonicalAddress `json:"verifier"` - Beneficiary wasmvmtypes.CanonicalAddress `json:"beneficiary"` - Funder wasmvmtypes.CanonicalAddress `json:"funder"` + Verifier string `json:"verifier"` + Beneficiary string `json:"beneficiary"` + Funder string `json:"funder"` } func TestHandleInstantiate(t *testing.T) { @@ -195,9 +195,9 @@ func TestHandleInstantiate(t *testing.T) { assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}) assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator) assertContractState(t, q, data.ctx, contractBech32Addr, state{ - Verifier: []byte(fred), - Beneficiary: []byte(bob), - Funder: []byte(creator), + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), }) } @@ -492,9 +492,9 @@ func TestHandleExecute(t *testing.T) { assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}) assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator) assertContractState(t, q, data.ctx, contractBech32Addr, state{ - Verifier: []byte(fred), - Beneficiary: []byte(bob), - Funder: []byte(creator), + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), }) } @@ -691,25 +691,25 @@ func assertCodeBytes(t *testing.T, q sdk.Querier, ctx sdk.Context, codeID uint64 assert.EqualValues(t, codeID, res["id"]) } -func assertContractList(t *testing.T, q sdk.Querier, ctx sdk.Context, codeID uint64, addrs []string) { +func assertContractList(t *testing.T, q sdk.Querier, ctx sdk.Context, codeID uint64, expContractAddrs []string) { bz, sdkerr := q(ctx, []string{QueryListContractByCode, fmt.Sprintf("%d", codeID)}, abci.RequestQuery{}) require.NoError(t, sdkerr) if len(bz) == 0 { - require.Equal(t, len(addrs), 0) + require.Equal(t, len(expContractAddrs), 0) return } - var res []ContractInfoWithAddress + var res []string err := json.Unmarshal(bz, &res) require.NoError(t, err) var hasAddrs = make([]string, len(res)) for i, r := range res { - hasAddrs[i] = r.Address + hasAddrs[i] = r } - assert.Equal(t, hasAddrs, addrs) + assert.Equal(t, expContractAddrs, hasAddrs) } func assertContractState(t *testing.T, q sdk.Querier, ctx sdk.Context, contractBech32Addr string, expected state) { diff --git a/x/wasm/simulation/genesis.go b/x/wasm/simulation/genesis.go index cc96d7de5c..e95f10d68e 100644 --- a/x/wasm/simulation/genesis.go +++ b/x/wasm/simulation/genesis.go @@ -2,7 +2,7 @@ package simulation import ( "github.com/line/lfb-sdk/types/module" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) // RandomizeGenState generates a random GenesisState for wasm diff --git a/x/wasm/simulation/params.go b/x/wasm/simulation/params.go index e59d39e200..c76a105fc7 100644 --- a/x/wasm/simulation/params.go +++ b/x/wasm/simulation/params.go @@ -7,7 +7,7 @@ import ( "github.com/line/lfb-sdk/codec" simtypes "github.com/line/lfb-sdk/types/simulation" "github.com/line/lfb-sdk/x/simulation" - "github.com/line/lfb-sdk/x/wasm/internal/types" + "github.com/line/lfb-sdk/x/wasm/types" ) func ParamChanges(r *rand.Rand, cdc codec.Marshaler) []simtypes.ParamChange { diff --git a/x/wasm/internal/types/codec.go b/x/wasm/types/codec.go similarity index 96% rename from x/wasm/internal/types/codec.go rename to x/wasm/types/codec.go index 277aaef2d9..cf690a1e1a 100644 --- a/x/wasm/internal/types/codec.go +++ b/x/wasm/types/codec.go @@ -50,6 +50,8 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &UnpinCodesProposal{}, ) + registry.RegisterInterface("ContractInfoExtension", (*ContractInfoExtension)(nil)) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/wasm/internal/types/encoder.go b/x/wasm/types/encoder.go similarity index 100% rename from x/wasm/internal/types/encoder.go rename to x/wasm/types/encoder.go diff --git a/x/wasm/internal/types/errors.go b/x/wasm/types/errors.go similarity index 93% rename from x/wasm/internal/types/errors.go rename to x/wasm/types/errors.go index c65916ddee..fc84b014c9 100644 --- a/x/wasm/internal/types/errors.go +++ b/x/wasm/types/errors.go @@ -63,4 +63,7 @@ var ( // ErrUnpinContractFailed error for unpinning contract failures ErrUnpinContractFailed = sdkErrors.Register(DefaultCodespace, 19, "unpinning contract failed") + + // ErrUnknownMsg error by a message handler to show that it is not responsible for this message type + ErrUnknownMsg = sdkErrors.Register(DefaultCodespace, 20, "unknown message from the contract") ) diff --git a/x/wasm/internal/types/events.go b/x/wasm/types/events.go similarity index 94% rename from x/wasm/internal/types/events.go rename to x/wasm/types/events.go index 538637ff1f..8007cd978b 100644 --- a/x/wasm/internal/types/events.go +++ b/x/wasm/types/events.go @@ -14,6 +14,7 @@ const ( const ( // event attributes AttributeKeyContract = "contract_address" AttributeKeyCodeID = "code_id" + AttributeKeySigner = "signer" AttributeKeyCodeIDs = "code_ids" AttributeKeyContractStatus = "contract_status" ) diff --git a/x/wasm/internal/types/expected_keepers.go b/x/wasm/types/expected_keepers.go similarity index 89% rename from x/wasm/internal/types/expected_keepers.go rename to x/wasm/types/expected_keepers.go index b66a041080..4c73591552 100644 --- a/x/wasm/internal/types/expected_keepers.go +++ b/x/wasm/types/expected_keepers.go @@ -13,14 +13,21 @@ import ( stakingtypes "github.com/line/lfb-sdk/x/staking/types" ) -// BankKeeper defines a subset of methods implemented by the cosmos-sdk bank keeper +// BankViewKeeper defines a subset of methods implemented by the cosmos-sdk bank keeper type BankViewKeeper interface { GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins } +// Burner is a subset of the sdk bank keeper methods +type Burner interface { + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error +} + // BankKeeper defines a subset of methods implemented by the cosmos-sdk bank keeper type BankKeeper interface { BankViewKeeper + Burner SendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error BlockedAddr(addr sdk.AccAddress) bool SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error @@ -89,3 +96,8 @@ type CapabilityKeeper interface { ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error AuthenticateCapability(ctx sdk.Context, capability *capabilitytypes.Capability, name string) bool } + +// ICS20TransferPortSource is a subset of the ibc transfer keeper. +type ICS20TransferPortSource interface { + GetPort(ctx sdk.Context) string +} diff --git a/x/wasm/types/exported_keepers.go b/x/wasm/types/exported_keepers.go new file mode 100644 index 0000000000..ad747a7981 --- /dev/null +++ b/x/wasm/types/exported_keepers.go @@ -0,0 +1,93 @@ +package types + +import ( + "github.com/line/lfb-sdk/types" + sdk "github.com/line/lfb-sdk/types" + capabilitytypes "github.com/line/lfb-sdk/x/capability/types" + types2 "github.com/line/wasmvm/types" +) + +// ViewKeeper provides read only operations +type ViewKeeper interface { + GetContractHistory(ctx types.Context, contractAddr types.AccAddress) []ContractCodeHistoryEntry + QuerySmart(ctx types.Context, contractAddr types.AccAddress, req []byte) ([]byte, error) + QueryRaw(ctx types.Context, contractAddress types.AccAddress, key []byte) []byte + HasContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool + GetContractInfo(ctx types.Context, contractAddress types.AccAddress) *ContractInfo + IterateContractInfo(ctx types.Context, cb func(types.AccAddress, ContractInfo) bool) + IterateContractsByCode(ctx sdk.Context, codeID uint64, cb func(address sdk.AccAddress) bool) + GetContractState(ctx types.Context, contractAddress types.AccAddress) types.Iterator + GetCodeInfo(ctx types.Context, codeID uint64) *CodeInfo + IterateCodeInfos(ctx types.Context, cb func(uint64, CodeInfo) bool) + GetByteCode(ctx types.Context, codeID uint64) ([]byte, error) + IsPinnedCode(ctx types.Context, codeID uint64) bool +} + +// ContractOpsKeeper contains mutable operations on a contract. +type ContractOpsKeeper interface { + // Create uploads and compiles a WASM contract, returning a short identifier for the contract + Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *AccessConfig) (codeID uint64, err error) + + // Instantiate creates an instance of a WASM contract + Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, []byte, error) + + // Execute executes the contract instance + Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) + + // Migrate allows to upgrade a contract to a new code with data migration. + Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) + + // UpdateContractAdmin sets the admin value on the ContractInfo. It must be a valid address (use ClearContractAdmin to remove it) + UpdateContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newAdmin sdk.AccAddress) error + + // ClearContractAdmin sets the admin value on the ContractInfo to nil, to disable further migrations/ updates. + ClearContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress) error + + // PinCode pins the wasm contract in wasmvm cache + PinCode(ctx sdk.Context, codeID uint64) error + + // UnpinCode removes the wasm contract from wasmvm cache + UnpinCode(ctx sdk.Context, codeID uint64) error + + // SetContractInfoExtension updates the extension point data that is stored with the contract info + SetContractInfoExtension(ctx sdk.Context, contract sdk.AccAddress, extra ContractInfoExtension) error +} + +// IBCContractKeeper IBC lifecycle event handler +type IBCContractKeeper interface { + OnOpenChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + channel types2.IBCChannel, + ) error + OnConnectChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + channel types2.IBCChannel, + ) error + OnCloseChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + channel types2.IBCChannel, + ) error + OnRecvPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + packet types2.IBCPacket, + ) ([]byte, error) + OnAckPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + acknowledgement types2.IBCAcknowledgement, + ) error + OnTimeoutPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + packet types2.IBCPacket, + ) error + // ClaimCapability allows the transfer module to claim a capability + //that IBC module passes to it + ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error + // AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function + AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool +} diff --git a/x/wasm/internal/types/feature_flag.go b/x/wasm/types/feature_flag.go similarity index 100% rename from x/wasm/internal/types/feature_flag.go rename to x/wasm/types/feature_flag.go diff --git a/x/wasm/internal/types/genesis.go b/x/wasm/types/genesis.go similarity index 100% rename from x/wasm/internal/types/genesis.go rename to x/wasm/types/genesis.go diff --git a/x/wasm/internal/types/genesis.pb.go b/x/wasm/types/genesis.pb.go similarity index 91% rename from x/wasm/internal/types/genesis.pb.go rename to x/wasm/types/genesis.pb.go index 63896c12bb..2e5e223be9 100644 --- a/x/wasm/internal/types/genesis.pb.go +++ b/x/wasm/types/genesis.pb.go @@ -397,48 +397,48 @@ func init() { func init() { proto.RegisterFile("genesis.proto", fileDescriptor_14205810582f3203) } var fileDescriptor_14205810582f3203 = []byte{ - // 648 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xcf, 0x4e, 0xdb, 0x4a, - 0x14, 0xc6, 0x63, 0x12, 0x87, 0xe4, 0x10, 0x2e, 0x68, 0xe0, 0xde, 0x6b, 0x85, 0x92, 0x44, 0x61, - 0x03, 0x6a, 0x89, 0x05, 0x5d, 0x76, 0x55, 0x97, 0x0a, 0x52, 0x44, 0x55, 0x19, 0xa9, 0x0b, 0x36, - 0x91, 0xff, 0x1c, 0x5c, 0x8b, 0x78, 0x26, 0xcd, 0x4c, 0x28, 0x79, 0x8b, 0xaa, 0x0f, 0xd1, 0x67, - 0x61, 0xc9, 0xb2, 0xab, 0xa8, 0x0a, 0xbb, 0x3e, 0x45, 0x35, 0xe3, 0x89, 0x71, 0xd5, 0x9a, 0x6e, - 0x2c, 0x9f, 0xe3, 0xef, 0xfb, 0xcd, 0x9c, 0x33, 0x67, 0x0c, 0xab, 0x11, 0x52, 0xe4, 0x31, 0xef, - 0x8d, 0xc6, 0x4c, 0x30, 0xf2, 0x6f, 0xc0, 0x78, 0xf2, 0xc9, 0xe3, 0x49, 0x4f, 0x3d, 0xae, 0x0f, - 0x7c, 0x14, 0xde, 0x41, 0x73, 0x33, 0x62, 0x11, 0x53, 0x0a, 0x5b, 0xbe, 0xa5, 0xe2, 0xe6, 0x8a, - 0x98, 0x8e, 0x50, 0x3b, 0x9b, 0x35, 0x71, 0x93, 0xbe, 0x75, 0x6f, 0x4d, 0x68, 0x1c, 0xa7, 0xd4, - 0x73, 0xe1, 0x09, 0x24, 0x2f, 0xa0, 0x3a, 0xf2, 0xc6, 0x5e, 0xc2, 0x2d, 0xa3, 0x63, 0xec, 0xae, - 0x1c, 0x6e, 0xf7, 0xfe, 0xb8, 0x4a, 0xef, 0x9d, 0x12, 0x39, 0x95, 0xdb, 0x59, 0xbb, 0xe4, 0x6a, - 0x0b, 0x79, 0x03, 0x66, 0xc0, 0x42, 0xe4, 0xd6, 0x52, 0xa7, 0xbc, 0xbb, 0x72, 0xb8, 0x55, 0xe0, - 0x7d, 0xc5, 0x42, 0x74, 0xfe, 0x97, 0xce, 0x1f, 0xb3, 0xf6, 0x9a, 0x72, 0x3c, 0x63, 0x49, 0x2c, - 0x30, 0x19, 0x89, 0xa9, 0x9b, 0x22, 0xc8, 0x05, 0xd4, 0x03, 0x46, 0xc5, 0xd8, 0x0b, 0x04, 0xb7, - 0xca, 0x8a, 0xd7, 0x2e, 0xe4, 0xa5, 0x3a, 0x67, 0x4b, 0x33, 0x37, 0x32, 0x67, 0x8e, 0xfb, 0x80, - 0x93, 0x6c, 0x8e, 0x1f, 0x27, 0x48, 0x03, 0xe4, 0x56, 0xe5, 0x51, 0xf6, 0xb9, 0xd6, 0x3d, 0xb0, - 0x33, 0x67, 0x9e, 0x9d, 0x25, 0x89, 0x0f, 0xb5, 0x08, 0xe9, 0x20, 0xe1, 0x11, 0xb7, 0x4c, 0x85, - 0x7e, 0x5a, 0x80, 0xce, 0xf7, 0x5d, 0x06, 0x67, 0x3c, 0xe2, 0x4e, 0x53, 0x2f, 0x43, 0x16, 0x90, - 0xdc, 0x2a, 0xcb, 0x51, 0x2a, 0x6a, 0x7e, 0x59, 0x82, 0x65, 0x6d, 0x20, 0x47, 0x00, 0x5c, 0xb0, - 0x31, 0x0e, 0x64, 0xdb, 0xf4, 0xa1, 0xed, 0x14, 0xac, 0x78, 0xc6, 0xa3, 0x73, 0xa9, 0x95, 0x07, - 0x70, 0x52, 0x72, 0xeb, 0x7c, 0x11, 0x10, 0x1f, 0x36, 0x63, 0xca, 0x85, 0x47, 0x45, 0xec, 0x09, - 0xc9, 0x4a, 0x5b, 0x65, 0x2d, 0x29, 0xde, 0x7e, 0x31, 0xaf, 0xff, 0xe0, 0x5a, 0x1c, 0xc3, 0x49, - 0xc9, 0xdd, 0x88, 0x7f, 0x4f, 0x93, 0xf7, 0xb0, 0x8e, 0x37, 0x18, 0x4c, 0xf2, 0xfc, 0xb2, 0xe2, - 0xef, 0x15, 0xf3, 0x5f, 0xa7, 0x8e, 0x1c, 0x7b, 0x0d, 0x7f, 0x4d, 0x39, 0x26, 0x94, 0xf9, 0x24, - 0xe9, 0x7e, 0x35, 0xa0, 0xa2, 0x6a, 0xd9, 0x81, 0x65, 0xd9, 0x8b, 0x41, 0x1c, 0xaa, 0x76, 0x54, - 0x1c, 0x98, 0xcf, 0xda, 0x55, 0xf9, 0xa9, 0x7f, 0xe4, 0x56, 0xe5, 0xa7, 0x7e, 0x48, 0x1c, 0x39, - 0x5e, 0x52, 0x44, 0x2f, 0x99, 0xae, 0xb2, 0xfd, 0xc8, 0xb8, 0xf6, 0xe9, 0x25, 0xd3, 0xc3, 0x5e, - 0x0b, 0x74, 0x4c, 0xb6, 0x01, 0x14, 0xc3, 0x9f, 0x0a, 0xe4, 0xaa, 0x94, 0x86, 0xab, 0xa8, 0x8e, - 0x4c, 0x90, 0xff, 0xa0, 0x3a, 0x8a, 0x29, 0xc5, 0xd0, 0xaa, 0x74, 0x8c, 0xdd, 0x9a, 0xab, 0xa3, - 0xee, 0x9d, 0x01, 0xb5, 0xac, 0x29, 0x7b, 0xb0, 0xbe, 0x68, 0xc6, 0xc0, 0x0b, 0xc3, 0x31, 0xf2, - 0xf4, 0xe6, 0xd5, 0xdd, 0xb5, 0x45, 0xfe, 0x65, 0x9a, 0x26, 0x6f, 0x61, 0x35, 0x93, 0xe6, 0xb6, - 0xbd, 0xf3, 0x97, 0x5b, 0x91, 0xdb, 0x7a, 0x23, 0xc8, 0xe5, 0x48, 0x1f, 0xfe, 0xc9, 0x78, 0x5c, - 0x0e, 0xa1, 0xbe, 0x66, 0x4f, 0x8a, 0x4e, 0x83, 0x85, 0x38, 0xd4, 0xa4, 0x6c, 0x27, 0x6a, 0x7a, - 0xbb, 0x0e, 0xd4, 0x16, 0x17, 0x85, 0x74, 0xa0, 0x1a, 0x87, 0x83, 0x2b, 0x9c, 0xaa, 0x3a, 0x1a, - 0x4e, 0x7d, 0x3e, 0x6b, 0x9b, 0xfd, 0xa3, 0x53, 0x9c, 0xba, 0x66, 0x1c, 0x9e, 0xe2, 0x94, 0x6c, - 0x82, 0x79, 0xed, 0x0d, 0x27, 0xa8, 0x0a, 0xa8, 0xb8, 0x69, 0xe0, 0x1c, 0xdf, 0xce, 0x5b, 0xc6, - 0xdd, 0xbc, 0x65, 0x7c, 0x9f, 0xb7, 0x8c, 0xcf, 0xf7, 0xad, 0xd2, 0xdd, 0x7d, 0xab, 0xf4, 0xed, - 0xbe, 0x55, 0xba, 0xd8, 0x8f, 0x62, 0xf1, 0x61, 0xe2, 0xf7, 0x02, 0x96, 0xd8, 0xc3, 0x98, 0xa2, - 0x3d, 0xbc, 0xf4, 0xf7, 0x79, 0x78, 0x65, 0xdf, 0xd8, 0x72, 0x83, 0x76, 0x4c, 0x05, 0x8e, 0xa9, - 0x37, 0xb4, 0xd5, 0x3f, 0xce, 0xaf, 0xaa, 0x5f, 0xdb, 0xf3, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x32, 0x7c, 0x89, 0xdb, 0x2f, 0x05, 0x00, 0x00, + // 643 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xcf, 0x6e, 0xd3, 0x4e, + 0x10, 0xc7, 0xe3, 0x26, 0x4e, 0x93, 0x69, 0xfa, 0x6b, 0xb5, 0xed, 0x0f, 0xac, 0x94, 0x26, 0x51, + 0xca, 0xa1, 0x15, 0x34, 0x51, 0xcb, 0x11, 0x09, 0x09, 0x53, 0x44, 0x43, 0x55, 0x84, 0x5c, 0x89, + 0x43, 0x2f, 0x91, 0xff, 0x4c, 0x8d, 0xd5, 0xd8, 0x1b, 0xb2, 0x9b, 0x52, 0xbf, 0x05, 0xe2, 0x21, + 0x78, 0x96, 0x1e, 0x7b, 0xe4, 0x14, 0xa1, 0xf4, 0xc6, 0x53, 0xa0, 0x5d, 0xaf, 0x1d, 0x23, 0x70, + 0xb9, 0x58, 0x9e, 0xf1, 0xf7, 0xfb, 0xd9, 0x9d, 0xd9, 0x59, 0xc3, 0xaa, 0x8f, 0x11, 0xb2, 0x80, + 0xf5, 0xc6, 0x13, 0xca, 0x29, 0xf9, 0xdf, 0xa5, 0x2c, 0xfc, 0x6c, 0xb3, 0xb0, 0x27, 0x1f, 0x57, + 0x07, 0x0e, 0x72, 0xfb, 0xa0, 0xb9, 0xe9, 0x53, 0x9f, 0x4a, 0x45, 0x5f, 0xbc, 0x25, 0xe2, 0xe6, + 0x0a, 0x8f, 0xc7, 0xa8, 0x9c, 0xcd, 0x1a, 0xbf, 0x4e, 0xde, 0xba, 0x37, 0x3a, 0x34, 0xde, 0x24, + 0xd4, 0x33, 0x6e, 0x73, 0x24, 0xcf, 0xa1, 0x3a, 0xb6, 0x27, 0x76, 0xc8, 0x0c, 0xad, 0xa3, 0xed, + 0xae, 0x1c, 0x6e, 0xf7, 0xfe, 0xba, 0x4a, 0xef, 0xbd, 0x14, 0x99, 0x95, 0x9b, 0x59, 0xbb, 0x64, + 0x29, 0x0b, 0x79, 0x0b, 0xba, 0x4b, 0x3d, 0x64, 0xc6, 0x52, 0xa7, 0xbc, 0xbb, 0x72, 0xb8, 0x55, + 0xe0, 0x7d, 0x45, 0x3d, 0x34, 0x1f, 0x0a, 0xe7, 0xcf, 0x59, 0x7b, 0x4d, 0x3a, 0x9e, 0xd2, 0x30, + 0xe0, 0x18, 0x8e, 0x79, 0x6c, 0x25, 0x08, 0x72, 0x0e, 0x75, 0x97, 0x46, 0x7c, 0x62, 0xbb, 0x9c, + 0x19, 0x65, 0xc9, 0x6b, 0x17, 0xf2, 0x12, 0x9d, 0xb9, 0xa5, 0x98, 0x1b, 0x99, 0x33, 0xc7, 0x5d, + 0xe0, 0x04, 0x9b, 0xe1, 0xa7, 0x29, 0x46, 0x2e, 0x32, 0xa3, 0x72, 0x2f, 0xfb, 0x4c, 0xe9, 0x16, + 0xec, 0xcc, 0x99, 0x67, 0x67, 0x49, 0xe2, 0x40, 0xcd, 0xc7, 0x68, 0x18, 0x32, 0x9f, 0x19, 0xba, + 0x44, 0x3f, 0x29, 0x40, 0xe7, 0xfb, 0x2e, 0x82, 0x53, 0xe6, 0x33, 0xb3, 0xa9, 0x96, 0x21, 0x29, + 0x24, 0xb7, 0xca, 0xb2, 0x9f, 0x88, 0x9a, 0x5f, 0x97, 0x60, 0x59, 0x19, 0xc8, 0x11, 0x00, 0xe3, + 0x74, 0x82, 0x43, 0xd1, 0x36, 0x75, 0x68, 0x3b, 0x05, 0x2b, 0x9e, 0x32, 0xff, 0x4c, 0x68, 0xc5, + 0x01, 0x1c, 0x97, 0xac, 0x3a, 0x4b, 0x03, 0xe2, 0xc0, 0x66, 0x10, 0x31, 0x6e, 0x47, 0x3c, 0xb0, + 0xb9, 0x60, 0x25, 0xad, 0x32, 0x96, 0x24, 0x6f, 0xbf, 0x98, 0x37, 0x58, 0xb8, 0xd2, 0x63, 0x38, + 0x2e, 0x59, 0x1b, 0xc1, 0x9f, 0x69, 0xf2, 0x01, 0xd6, 0xf1, 0x1a, 0xdd, 0x69, 0x9e, 0x5f, 0x96, + 0xfc, 0xbd, 0x62, 0xfe, 0xeb, 0xc4, 0x91, 0x63, 0xaf, 0xe1, 0xef, 0x29, 0x53, 0x87, 0x32, 0x9b, + 0x86, 0xdd, 0x6f, 0x1a, 0x54, 0x64, 0x2d, 0x3b, 0xb0, 0x2c, 0x7a, 0x31, 0x0c, 0x3c, 0xd9, 0x8e, + 0x8a, 0x09, 0xf3, 0x59, 0xbb, 0x2a, 0x3e, 0x0d, 0x8e, 0xac, 0xaa, 0xf8, 0x34, 0xf0, 0x88, 0x29, + 0xc6, 0x4b, 0x88, 0xa2, 0x0b, 0xaa, 0xaa, 0x6c, 0xdf, 0x33, 0xae, 0x83, 0xe8, 0x82, 0xaa, 0x61, + 0xaf, 0xb9, 0x2a, 0x26, 0xdb, 0x00, 0x92, 0xe1, 0xc4, 0x1c, 0x99, 0x2c, 0xa5, 0x61, 0x49, 0xaa, + 0x29, 0x12, 0xe4, 0x01, 0x54, 0xc7, 0x41, 0x14, 0xa1, 0x67, 0x54, 0x3a, 0xda, 0x6e, 0xcd, 0x52, + 0x51, 0xf7, 0x56, 0x83, 0x5a, 0xd6, 0x94, 0x3d, 0x58, 0x4f, 0x9b, 0x31, 0xb4, 0x3d, 0x6f, 0x82, + 0x2c, 0xb9, 0x79, 0x75, 0x6b, 0x2d, 0xcd, 0xbf, 0x4c, 0xd2, 0xe4, 0x1d, 0xac, 0x66, 0xd2, 0xdc, + 0xb6, 0x77, 0xfe, 0x71, 0x2b, 0x72, 0x5b, 0x6f, 0xb8, 0xb9, 0x1c, 0x19, 0xc0, 0x7f, 0x19, 0x8f, + 0x89, 0x21, 0x54, 0xd7, 0xec, 0x51, 0xd1, 0x69, 0x50, 0x0f, 0x47, 0x8a, 0x94, 0xed, 0x44, 0x4e, + 0x6f, 0xd7, 0x84, 0x5a, 0x7a, 0x51, 0x48, 0x07, 0xaa, 0x81, 0x37, 0xbc, 0xc4, 0x58, 0xd6, 0xd1, + 0x30, 0xeb, 0xf3, 0x59, 0x5b, 0x1f, 0x1c, 0x9d, 0x60, 0x6c, 0xe9, 0x81, 0x77, 0x82, 0x31, 0xd9, + 0x04, 0xfd, 0xca, 0x1e, 0x4d, 0x51, 0x16, 0x50, 0xb1, 0x92, 0xc0, 0x7c, 0x71, 0x33, 0x6f, 0x69, + 0xb7, 0xf3, 0x96, 0xf6, 0x63, 0xde, 0xd2, 0xbe, 0xdc, 0xb5, 0x4a, 0xb7, 0x77, 0xad, 0xd2, 0xf7, + 0xbb, 0x56, 0xe9, 0xfc, 0xb1, 0x1f, 0xf0, 0x8f, 0x53, 0xa7, 0xe7, 0xd2, 0xb0, 0x3f, 0x0a, 0x22, + 0xec, 0x8f, 0x2e, 0x9c, 0x7d, 0xe6, 0x5d, 0xf6, 0xaf, 0xfb, 0x62, 0x83, 0x7d, 0xf9, 0x6b, 0x73, + 0xaa, 0xf2, 0x8f, 0xf6, 0xec, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xc3, 0x78, 0x56, 0x26, + 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/wasm/internal/types/genesis.proto b/x/wasm/types/genesis.proto similarity index 96% rename from x/wasm/internal/types/genesis.proto rename to x/wasm/types/genesis.proto index 3302bb57ad..56a794821e 100644 --- a/x/wasm/internal/types/genesis.proto +++ b/x/wasm/types/genesis.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "types.proto"; import "tx.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; // GenesisState - genesis state of x/wasm message GenesisState { diff --git a/x/wasm/internal/types/genesis_test.go b/x/wasm/types/genesis_test.go similarity index 100% rename from x/wasm/internal/types/genesis_test.go rename to x/wasm/types/genesis_test.go diff --git a/x/wasm/internal/types/iavl_range_test.go b/x/wasm/types/iavl_range_test.go similarity index 100% rename from x/wasm/internal/types/iavl_range_test.go rename to x/wasm/types/iavl_range_test.go diff --git a/x/wasm/internal/types/ibc.pb.go b/x/wasm/types/ibc.pb.go similarity index 87% rename from x/wasm/internal/types/ibc.pb.go rename to x/wasm/types/ibc.pb.go index d77294b0b9..f3e44edd33 100644 --- a/x/wasm/internal/types/ibc.pb.go +++ b/x/wasm/types/ibc.pb.go @@ -117,29 +117,28 @@ func init() { func init() { proto.RegisterFile("ibc.proto", fileDescriptor_a85b3c622f5831ad) } var fileDescriptor_a85b3c622f5831ad = []byte{ - // 337 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0x3f, 0x4f, 0xfa, 0x40, - 0x1c, 0xc6, 0x5b, 0xc2, 0x8f, 0x5f, 0xb8, 0xa8, 0xd1, 0x46, 0x92, 0x6a, 0xc8, 0x41, 0x3a, 0xb1, - 0xd0, 0x93, 0xb0, 0x39, 0x99, 0xb2, 0x48, 0x0c, 0x4b, 0x75, 0x72, 0x21, 0xd7, 0xf6, 0xeb, 0xf5, - 0xb4, 0xbd, 0x23, 0xdc, 0x21, 0xb2, 0xf9, 0x12, 0x7c, 0x59, 0x8c, 0x8c, 0x4e, 0x44, 0xe1, 0x1d, - 0x30, 0x3a, 0x19, 0x4a, 0x6b, 0x64, 0x75, 0xb9, 0x3f, 0xcf, 0xf7, 0x73, 0x4f, 0x72, 0xcf, 0x83, - 0xaa, 0x3c, 0x08, 0xdd, 0xd1, 0x58, 0x6a, 0x69, 0xd5, 0x42, 0xa9, 0xd2, 0x29, 0x55, 0xa9, 0x9b, - 0x2d, 0xcf, 0x9d, 0x00, 0x34, 0xed, 0x9c, 0x9f, 0x32, 0xc9, 0x64, 0x46, 0x90, 0xed, 0x69, 0x07, - 0x3b, 0xaf, 0x25, 0x84, 0x06, 0x8a, 0xf5, 0xbd, 0xde, 0x2d, 0x88, 0xc8, 0xea, 0xa2, 0xff, 0x61, - 0x4c, 0x85, 0x80, 0xc4, 0x2e, 0x35, 0xcd, 0x56, 0xd5, 0x3b, 0xdb, 0x2c, 0x1b, 0xb5, 0x19, 0x4d, - 0x93, 0x4b, 0x47, 0xc9, 0xc9, 0x38, 0x84, 0x61, 0x3e, 0x77, 0xfc, 0x82, 0xb4, 0xae, 0xd0, 0x91, - 0xe6, 0x29, 0xc8, 0x89, 0x1e, 0xc6, 0xc0, 0x59, 0xac, 0xed, 0x72, 0xd3, 0x6c, 0x95, 0x7f, 0xbf, - 0xdd, 0x9f, 0x3b, 0xfe, 0x61, 0x2e, 0x5c, 0x67, 0x77, 0xab, 0x8f, 0x4e, 0x0a, 0x62, 0xbb, 0x2b, - 0x4d, 0xd3, 0x91, 0xfd, 0x2f, 0x33, 0xa9, 0x6f, 0x96, 0x0d, 0x7b, 0xdf, 0xe4, 0x07, 0x71, 0xfc, - 0xe3, 0x5c, 0xbb, 0x2b, 0x24, 0xeb, 0x02, 0x95, 0x23, 0xaa, 0xa9, 0x5d, 0x69, 0x9a, 0xad, 0x03, - 0xaf, 0xfe, 0xb5, 0x6c, 0xd8, 0x20, 0x42, 0x19, 0x71, 0xc1, 0xc8, 0xa3, 0x92, 0xc2, 0xf5, 0xe9, - 0x74, 0x00, 0x4a, 0x51, 0x06, 0x7e, 0x46, 0x3a, 0x7d, 0x64, 0xed, 0x12, 0xe8, 0x25, 0x52, 0x41, - 0x2f, 0xff, 0xd4, 0x5f, 0x92, 0xf0, 0x6e, 0xe6, 0x9f, 0xd8, 0x98, 0xaf, 0xb0, 0xb9, 0x58, 0x61, - 0xf3, 0x63, 0x85, 0xcd, 0xb7, 0x35, 0x36, 0x16, 0x6b, 0x6c, 0xbc, 0xaf, 0xb1, 0x71, 0xdf, 0x66, - 0x5c, 0xc7, 0x93, 0xc0, 0x0d, 0x65, 0x4a, 0x12, 0x2e, 0x80, 0x24, 0x0f, 0x41, 0x5b, 0x45, 0x4f, - 0xe4, 0x85, 0x6c, 0x9b, 0x22, 0x5c, 0x68, 0x18, 0x0b, 0x9a, 0x10, 0x3d, 0x1b, 0x81, 0x0a, 0x2a, - 0x59, 0x43, 0xdd, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc5, 0xb2, 0x3e, 0x48, 0xdb, 0x01, 0x00, - 0x00, + // 329 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0x3f, 0x4f, 0xc2, 0x40, + 0x18, 0xc6, 0x5b, 0x82, 0x18, 0x2e, 0x6a, 0xb4, 0x91, 0xa4, 0x1a, 0x72, 0x90, 0xc6, 0x81, 0xc5, + 0x9e, 0x84, 0xcd, 0xc9, 0x94, 0x45, 0x06, 0x96, 0xea, 0xe4, 0x42, 0xae, 0xed, 0xeb, 0xb5, 0xda, + 0xde, 0x11, 0xee, 0x10, 0xd9, 0xfc, 0x08, 0x7e, 0x2c, 0x46, 0x46, 0x27, 0xa2, 0xf0, 0x0d, 0x18, + 0x9d, 0x0c, 0x47, 0x6b, 0x64, 0x75, 0xb9, 0x3f, 0xcf, 0xfb, 0xbb, 0x27, 0xb9, 0xe7, 0x41, 0xd5, + 0x24, 0x08, 0xdd, 0xe1, 0x48, 0x28, 0x61, 0xd5, 0x42, 0x21, 0xb3, 0x09, 0x95, 0x99, 0xab, 0x97, + 0x97, 0x76, 0x00, 0x8a, 0xb6, 0xcf, 0x4f, 0x99, 0x60, 0x42, 0x13, 0x64, 0x73, 0xda, 0xc2, 0xce, + 0x5b, 0x09, 0xa1, 0xbe, 0x64, 0x3d, 0xaf, 0x7b, 0x07, 0x3c, 0xb2, 0x3a, 0x68, 0x3f, 0x8c, 0x29, + 0xe7, 0x90, 0xda, 0xa5, 0xa6, 0xd9, 0xaa, 0x7a, 0x67, 0xeb, 0x45, 0xa3, 0x36, 0xa5, 0x59, 0x7a, + 0xed, 0x48, 0x31, 0x1e, 0x85, 0x30, 0xc8, 0xe7, 0x8e, 0x5f, 0x90, 0xd6, 0x0d, 0x3a, 0x52, 0x49, + 0x06, 0x62, 0xac, 0x06, 0x31, 0x24, 0x2c, 0x56, 0x76, 0xb9, 0x69, 0xb6, 0xca, 0x7f, 0xdf, 0xee, + 0xce, 0x1d, 0xff, 0x30, 0x17, 0x6e, 0xf5, 0xdd, 0xea, 0xa1, 0x93, 0x82, 0xd8, 0xec, 0x52, 0xd1, + 0x6c, 0x68, 0xef, 0x69, 0x93, 0xfa, 0x7a, 0xd1, 0xb0, 0x77, 0x4d, 0x7e, 0x11, 0xc7, 0x3f, 0xce, + 0xb5, 0xfb, 0x42, 0xb2, 0xae, 0x50, 0x39, 0xa2, 0x8a, 0xda, 0x95, 0xa6, 0xd9, 0x3a, 0xf0, 0xea, + 0xdf, 0x8b, 0x86, 0x0d, 0x3c, 0x14, 0x51, 0xc2, 0x19, 0x79, 0x92, 0x82, 0xbb, 0x3e, 0x9d, 0xf4, + 0x41, 0x4a, 0xca, 0xc0, 0xd7, 0xa4, 0xd3, 0x43, 0xd6, 0x36, 0x81, 0x6e, 0x2a, 0x24, 0x74, 0xf3, + 0x4f, 0xfd, 0x27, 0x09, 0xcf, 0x9b, 0x7d, 0x61, 0x63, 0xb6, 0xc4, 0xe6, 0x7c, 0x89, 0xcd, 0xcf, + 0x25, 0x36, 0xdf, 0x57, 0xd8, 0x98, 0xaf, 0xb0, 0xf1, 0xb1, 0xc2, 0xc6, 0xc3, 0x05, 0x4b, 0x54, + 0x3c, 0x0e, 0xdc, 0x50, 0x64, 0x24, 0x4d, 0x38, 0x90, 0xf4, 0x31, 0xb8, 0x94, 0xd1, 0x33, 0x79, + 0x25, 0x9b, 0xa6, 0x88, 0x9a, 0x0e, 0x41, 0x06, 0x15, 0x5d, 0x4c, 0xe7, 0x27, 0x00, 0x00, 0xff, + 0xff, 0xa8, 0xb3, 0xb0, 0xdf, 0xd2, 0x01, 0x00, 0x00, } func (m *MsgIBCSend) Marshal() (dAtA []byte, err error) { diff --git a/x/wasm/internal/types/ibc.proto b/x/wasm/types/ibc.proto similarity index 97% rename from x/wasm/internal/types/ibc.proto rename to x/wasm/types/ibc.proto index af20031d9a..986ea6903d 100644 --- a/x/wasm/internal/types/ibc.proto +++ b/x/wasm/types/ibc.proto @@ -3,7 +3,7 @@ package cosmwasm.wasm.v1beta1; import "gogoproto/gogo.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; option (gogoproto.goproto_getters_all) = false; // MsgIBCSend diff --git a/x/wasm/internal/types/keys.go b/x/wasm/types/keys.go similarity index 93% rename from x/wasm/internal/types/keys.go rename to x/wasm/types/keys.go index 373905065f..56f6cdea61 100644 --- a/x/wasm/internal/types/keys.go +++ b/x/wasm/types/keys.go @@ -14,10 +14,10 @@ const ( // TStoreKey is the string transient store representation TStoreKey = "transient_" + ModuleName - // QuerierRoute is the querier route for the staking module + // QuerierRoute is the querier route for the wasm module QuerierRoute = ModuleName - // RouterKey is the msg router key for the staking module + // RouterKey is the msg router key for the wasm module RouterKey = ModuleName ) @@ -52,13 +52,13 @@ func GetContractStorePrefix(addr sdk.AccAddress) []byte { } // GetContractByCreatedSecondaryIndexKey returns the key for the secondary index: -// `` -func GetContractByCreatedSecondaryIndexKey(contractAddr sdk.AccAddress, c *ContractInfo) []byte { +// `` +func GetContractByCreatedSecondaryIndexKey(contractAddr sdk.AccAddress, c ContractCodeHistoryEntry) []byte { prefix := GetContractByCodeIDSecondaryIndexPrefix(c.CodeID) prefixLen := len(prefix) r := make([]byte, prefixLen+AbsoluteTxPositionLen+sdk.AddrLen) copy(r[0:], prefix) - copy(r[prefixLen:], c.Created.Bytes()) + copy(r[prefixLen:], c.Updated.Bytes()) copy(r[prefixLen+AbsoluteTxPositionLen:], contractAddr) return r } diff --git a/x/wasm/internal/types/keys_test.go b/x/wasm/types/keys_test.go similarity index 86% rename from x/wasm/internal/types/keys_test.go rename to x/wasm/types/keys_test.go index f42a2d7f9f..5a271aed6a 100644 --- a/x/wasm/internal/types/keys_test.go +++ b/x/wasm/types/keys_test.go @@ -29,12 +29,12 @@ func TestGetContractByCodeIDSecondaryIndexPrefix(t *testing.T) { } func TestGetContractByCreatedSecondaryIndexKey(t *testing.T) { - c := &ContractInfo{ + e := ContractCodeHistoryEntry{ CodeID: 1, - Created: &AbsoluteTxPosition{2 + 1<<(8*7), 3 + 1<<(8*7)}, + Updated: &AbsoluteTxPosition{2 + 1<<(8*7), 3 + 1<<(8*7)}, } addr := bytes.Repeat([]byte{4}, sdk.AddrLen) - got := GetContractByCreatedSecondaryIndexKey(addr, c) + got := GetContractByCreatedSecondaryIndexKey(addr, e) exp := []byte{6, // prefix 0, 0, 0, 0, 0, 0, 0, 1, // codeID 1, 0, 0, 0, 0, 0, 0, 2, // height diff --git a/x/wasm/internal/types/params.go b/x/wasm/types/params.go similarity index 100% rename from x/wasm/internal/types/params.go rename to x/wasm/types/params.go diff --git a/x/wasm/internal/types/params_test.go b/x/wasm/types/params_test.go similarity index 100% rename from x/wasm/internal/types/params_test.go rename to x/wasm/types/params_test.go diff --git a/x/wasm/internal/types/proposal.go b/x/wasm/types/proposal.go similarity index 95% rename from x/wasm/internal/types/proposal.go rename to x/wasm/types/proposal.go index 48c7093f02..93aea40f3a 100644 --- a/x/wasm/internal/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -2,6 +2,7 @@ package types import ( "encoding/base64" + "encoding/json" "fmt" "strings" @@ -64,14 +65,13 @@ func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypeClearAdmin)) govtypes.RegisterProposalType(string(ProposalTypePinCodes)) govtypes.RegisterProposalType(string(ProposalTypeUnpinCodes)) - govtypes.RegisterProposalType(string(ProposalTypeUpdateContractStatus)) - govtypes.RegisterProposalTypeCodec(StoreCodeProposal{}, "wasm/StoreCodeProposal") - govtypes.RegisterProposalTypeCodec(InstantiateContractProposal{}, "wasm/InstantiateContractProposal") - govtypes.RegisterProposalTypeCodec(MigrateContractProposal{}, "wasm/MigrateContractProposal") - govtypes.RegisterProposalTypeCodec(UpdateAdminProposal{}, "wasm/UpdateAdminProposal") - govtypes.RegisterProposalTypeCodec(ClearAdminProposal{}, "wasm/ClearAdminProposal") - govtypes.RegisterProposalTypeCodec(PinCodesProposal{}, "wasm/PinCodesProposal") - govtypes.RegisterProposalTypeCodec(UnpinCodesProposal{}, "wasm/UnpinCodesProposal") + govtypes.RegisterProposalTypeCodec(&StoreCodeProposal{}, "wasm/StoreCodeProposal") + govtypes.RegisterProposalTypeCodec(&InstantiateContractProposal{}, "wasm/InstantiateContractProposal") + govtypes.RegisterProposalTypeCodec(&MigrateContractProposal{}, "wasm/MigrateContractProposal") + govtypes.RegisterProposalTypeCodec(&UpdateAdminProposal{}, "wasm/UpdateAdminProposal") + govtypes.RegisterProposalTypeCodec(&ClearAdminProposal{}, "wasm/ClearAdminProposal") + govtypes.RegisterProposalTypeCodec(&PinCodesProposal{}, "wasm/PinCodesProposal") + govtypes.RegisterProposalTypeCodec(&UnpinCodesProposal{}, "wasm/UnpinCodesProposal") govtypes.RegisterProposalTypeCodec(UpdateContractStatusProposal{}, "wasm/UpdateContractStatusProposal") } @@ -188,6 +188,10 @@ func (p InstantiateContractProposal) ValidateBasic() error { return err } } + if !json.Valid(p.InitMsg) { + return sdkerrors.Wrap(ErrInvalid, "init msg json") + } + return nil } @@ -254,6 +258,9 @@ func (p MigrateContractProposal) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(p.RunAs); err != nil { return sdkerrors.Wrap(err, "run as") } + if !json.Valid(p.MigrateMsg) { + return sdkerrors.Wrap(ErrInvalid, "migrate msg json") + } return nil } diff --git a/x/wasm/internal/types/proposal.pb.go b/x/wasm/types/proposal.pb.go similarity index 94% rename from x/wasm/internal/types/proposal.pb.go rename to x/wasm/types/proposal.pb.go index b21b571134..a911f34ed9 100644 --- a/x/wasm/internal/types/proposal.pb.go +++ b/x/wasm/types/proposal.pb.go @@ -405,55 +405,55 @@ func init() { func init() { proto.RegisterFile("proposal.proto", fileDescriptor_c3ac5ce23bf32d05) } var fileDescriptor_c3ac5ce23bf32d05 = []byte{ - // 760 bytes of a gzipped FileDescriptorProto + // 754 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0x8f, 0x9b, 0xc6, 0x49, 0x27, 0x51, 0x09, 0x26, 0x0d, 0x56, 0x77, 0x65, 0x47, 0xae, 0x40, - 0x91, 0xd0, 0xda, 0x6a, 0x91, 0xf8, 0x27, 0xed, 0x21, 0x0e, 0x97, 0x1e, 0x22, 0x55, 0x8e, 0x56, - 0x88, 0xbd, 0x44, 0x63, 0x7b, 0xe2, 0x1d, 0xb0, 0x67, 0x2c, 0xcf, 0x84, 0x90, 0x6f, 0xc1, 0x07, - 0xe0, 0x03, 0xac, 0xb8, 0x20, 0xbe, 0x45, 0x8f, 0xcb, 0x6d, 0x4f, 0x86, 0x4d, 0x2f, 0x9c, 0x73, - 0xe4, 0x84, 0x66, 0xc6, 0x09, 0x29, 0xda, 0x45, 0x95, 0xa0, 0x48, 0x5c, 0xa2, 0xbc, 0x79, 0xbf, - 0xf7, 0x7e, 0xbf, 0xf9, 0xbd, 0x97, 0x09, 0x38, 0xce, 0x0b, 0x9a, 0x53, 0x06, 0x53, 0x37, 0x2f, - 0x28, 0xa7, 0xc6, 0x49, 0x44, 0x59, 0xb6, 0x84, 0x2c, 0x73, 0xe5, 0xc7, 0x37, 0xe7, 0x21, 0xe2, - 0xf0, 0xfc, 0xb4, 0x97, 0xd0, 0x84, 0x4a, 0x84, 0x27, 0xbe, 0x29, 0xf0, 0xe9, 0x83, 0x74, 0x1e, - 0x7a, 0x21, 0x64, 0xc8, 0xab, 0x70, 0x5e, 0x44, 0x31, 0xa9, 0x92, 0x6d, 0xbe, 0xca, 0x11, 0x53, - 0x81, 0xf3, 0xfc, 0x00, 0xbc, 0x3d, 0xe5, 0xb4, 0x40, 0x63, 0x1a, 0xa3, 0xab, 0x8a, 0xd2, 0xe8, - 0x81, 0x06, 0xc7, 0x3c, 0x45, 0xa6, 0x36, 0xd0, 0x86, 0x47, 0x81, 0x0a, 0x8c, 0x01, 0x68, 0xc7, - 0x88, 0x45, 0x05, 0xce, 0x39, 0xa6, 0xc4, 0x3c, 0x90, 0xb9, 0xfd, 0x23, 0xe3, 0x04, 0xe8, 0xc5, - 0x82, 0xcc, 0x20, 0x33, 0xeb, 0xaa, 0xb0, 0x58, 0x90, 0x11, 0x33, 0x3e, 0x02, 0xc7, 0x42, 0xf4, - 0x2c, 0x5c, 0x71, 0x34, 0x8b, 0x68, 0x8c, 0xcc, 0xc3, 0x81, 0x36, 0xec, 0xf8, 0xdd, 0x75, 0x69, - 0x77, 0xbe, 0x18, 0x4d, 0x27, 0xfe, 0x8a, 0x4b, 0x01, 0x41, 0x47, 0xe0, 0xb6, 0x91, 0xd1, 0x07, - 0x3a, 0xa3, 0x8b, 0x22, 0x42, 0x66, 0x43, 0xb6, 0xab, 0x22, 0xc3, 0x04, 0xcd, 0x70, 0x81, 0xd3, - 0x18, 0x15, 0xa6, 0x2e, 0x13, 0xdb, 0xd0, 0x78, 0x0a, 0xfa, 0x98, 0x30, 0x0e, 0x09, 0xc7, 0x90, - 0xa3, 0x59, 0x8e, 0x8a, 0x0c, 0x33, 0x26, 0xd4, 0x36, 0x07, 0xda, 0xb0, 0x7d, 0x71, 0xe6, 0xbe, - 0xd6, 0x46, 0x77, 0x14, 0x45, 0x88, 0xb1, 0x31, 0x25, 0x73, 0x9c, 0x04, 0x27, 0x7b, 0x2d, 0xae, - 0x76, 0x1d, 0x9c, 0x9f, 0x0f, 0xc0, 0x83, 0xcb, 0x3f, 0x33, 0x63, 0x4a, 0x78, 0x01, 0x23, 0x7e, - 0x5f, 0xa6, 0xf5, 0x40, 0x03, 0xc6, 0x19, 0x26, 0xd2, 0xab, 0xa3, 0x40, 0x05, 0xc6, 0x19, 0x68, - 0x0a, 0x03, 0x67, 0x38, 0x96, 0x9e, 0x1c, 0xfa, 0x60, 0x5d, 0xda, 0xba, 0x70, 0xeb, 0xf2, 0xf3, - 0x40, 0x17, 0xa9, 0xcb, 0x58, 0x94, 0xa6, 0x30, 0x44, 0x69, 0xe5, 0x8e, 0x0a, 0x8c, 0x8f, 0x41, - 0x0b, 0x13, 0xcc, 0x67, 0x19, 0x4b, 0xa4, 0x1b, 0x1d, 0xff, 0xe1, 0xef, 0xa5, 0x6d, 0x22, 0x12, - 0xd1, 0x18, 0x93, 0xc4, 0xfb, 0x8a, 0x51, 0xe2, 0x06, 0x70, 0x39, 0x41, 0x8c, 0xc1, 0x04, 0x05, - 0x4d, 0x81, 0x9e, 0xb0, 0xc4, 0xf8, 0x12, 0x34, 0xe6, 0x0b, 0x12, 0x33, 0xb3, 0x35, 0xa8, 0x0f, - 0xdb, 0x17, 0x7d, 0x37, 0x9d, 0x87, 0xae, 0xd8, 0xae, 0x9d, 0x7d, 0x63, 0x8a, 0x89, 0xff, 0xc1, - 0x75, 0x69, 0xd7, 0x7e, 0xf8, 0xc5, 0x3e, 0x4b, 0x30, 0x7f, 0xb6, 0x08, 0xdd, 0x88, 0x66, 0x5e, - 0x8a, 0x09, 0xf2, 0xd2, 0x79, 0xf8, 0x88, 0xc5, 0x5f, 0x7b, 0x6a, 0xef, 0x04, 0x96, 0x05, 0xaa, - 0xa3, 0xf3, 0x9b, 0x06, 0xde, 0x9d, 0xe0, 0xa4, 0xf8, 0x0f, 0xfc, 0x3c, 0x05, 0xad, 0xa8, 0xa2, - 0xa8, 0x2c, 0xdd, 0xc5, 0x77, 0x73, 0xf5, 0x31, 0x68, 0x67, 0x4a, 0xaa, 0xb4, 0x50, 0xbf, 0x83, - 0x85, 0xa0, 0x2a, 0x98, 0xb0, 0xc4, 0xf9, 0x5e, 0x03, 0xef, 0x3c, 0xc9, 0x63, 0xc8, 0xd1, 0x48, - 0x4c, 0xf2, 0x1f, 0x5f, 0xf3, 0x1c, 0x1c, 0x11, 0xb4, 0x9c, 0xa9, 0x1d, 0x91, 0x37, 0xf5, 0x7b, - 0x9b, 0xd2, 0xee, 0xae, 0x60, 0x96, 0x7e, 0xe6, 0xec, 0x52, 0x4e, 0xd0, 0x22, 0x68, 0x29, 0x29, - 0xff, 0xce, 0x02, 0xe7, 0x19, 0x30, 0xc6, 0x29, 0x82, 0xc5, 0xbf, 0x23, 0x6e, 0x9f, 0xa9, 0xfe, - 0x17, 0xa6, 0x1f, 0x35, 0xd0, 0xbd, 0xc2, 0x44, 0xb8, 0xcb, 0x76, 0x44, 0xef, 0xdf, 0x22, 0xf2, - 0xbb, 0x9b, 0xd2, 0xee, 0xa8, 0x9b, 0xc8, 0x63, 0x67, 0x4b, 0xfd, 0xc9, 0x6b, 0xa8, 0xfd, 0xfe, - 0xa6, 0xb4, 0x0d, 0x85, 0xde, 0x4b, 0x3a, 0xb7, 0x25, 0x7d, 0x2a, 0x24, 0xc9, 0x19, 0x8b, 0xc5, - 0xa8, 0x0f, 0x0f, 0x7d, 0x6b, 0x5d, 0xda, 0x4d, 0x35, 0x64, 0xb6, 0x29, 0xed, 0xb7, 0x54, 0x87, - 0x2d, 0xc8, 0x09, 0x9a, 0x6a, 0xf0, 0xcc, 0xf9, 0x49, 0x03, 0xc6, 0x13, 0x92, 0xff, 0xdf, 0x34, - 0x3f, 0x54, 0xeb, 0xb6, 0xfd, 0x61, 0x4d, 0x39, 0xe4, 0x0b, 0x76, 0x9f, 0xa3, 0x35, 0x1e, 0x03, - 0x9d, 0x49, 0x16, 0xb9, 0x5e, 0xc7, 0x17, 0xef, 0xbd, 0xe1, 0xb9, 0xbd, 0x2d, 0x29, 0xa8, 0x8a, - 0xfc, 0xe9, 0xf5, 0x2b, 0xab, 0xf6, 0xf2, 0x95, 0x55, 0x7b, 0xbe, 0xb6, 0xb4, 0xeb, 0xb5, 0xa5, - 0xbd, 0x58, 0x5b, 0xda, 0xaf, 0x6b, 0x4b, 0xfb, 0xee, 0xc6, 0xaa, 0xbd, 0xb8, 0xb1, 0x6a, 0x2f, - 0x6f, 0xac, 0xda, 0xd3, 0x47, 0x6f, 0x7a, 0x5f, 0xbe, 0xf5, 0x04, 0x89, 0x87, 0x09, 0x47, 0x05, - 0x81, 0xa9, 0x7a, 0x6f, 0x42, 0x5d, 0xfe, 0xd1, 0x7d, 0xf8, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xca, 0x0e, 0x15, 0xd2, 0x51, 0x07, 0x00, 0x00, + 0x14, 0x8f, 0x9b, 0xc6, 0x49, 0x27, 0x51, 0x09, 0x26, 0x0d, 0x56, 0x77, 0x65, 0x47, 0x2e, 0xa0, + 0x48, 0x08, 0x5b, 0x2d, 0x12, 0xff, 0xa4, 0x3d, 0xc4, 0xe1, 0x52, 0xa4, 0x48, 0x95, 0xab, 0x15, + 0x62, 0x2f, 0xd1, 0xd8, 0x9e, 0x78, 0x07, 0xec, 0x19, 0xcb, 0x33, 0x21, 0xe4, 0x5b, 0xf0, 0x01, + 0xf8, 0x00, 0x2b, 0x2e, 0x88, 0x6f, 0xd1, 0xe3, 0x72, 0xdb, 0x93, 0x61, 0xd3, 0x0b, 0xe7, 0x1c, + 0x39, 0xa1, 0x99, 0x71, 0x42, 0x8a, 0xb6, 0xa8, 0x12, 0x14, 0x69, 0x2f, 0x51, 0xde, 0xbc, 0xdf, + 0x7b, 0xbf, 0xdf, 0xfc, 0xde, 0xcb, 0x04, 0x1c, 0xe6, 0x05, 0xcd, 0x29, 0x83, 0xa9, 0x9b, 0x17, + 0x94, 0x53, 0xe3, 0x28, 0xa2, 0x2c, 0x5b, 0x40, 0x96, 0xb9, 0xf2, 0xe3, 0xdb, 0xd3, 0x10, 0x71, + 0x78, 0x7a, 0xdc, 0x4b, 0x68, 0x42, 0x25, 0xc2, 0x13, 0xdf, 0x14, 0xf8, 0xf8, 0x41, 0x3a, 0x0b, + 0xbd, 0x10, 0x32, 0xe4, 0x55, 0x38, 0x2f, 0xa2, 0x98, 0x54, 0xc9, 0x36, 0x5f, 0xe6, 0x88, 0xa9, + 0xc0, 0x79, 0xb6, 0x07, 0xde, 0xbc, 0xe4, 0xb4, 0x40, 0x63, 0x1a, 0xa3, 0x8b, 0x8a, 0xd2, 0xe8, + 0x81, 0x06, 0xc7, 0x3c, 0x45, 0xa6, 0x36, 0xd0, 0x86, 0x07, 0x81, 0x0a, 0x8c, 0x01, 0x68, 0xc7, + 0x88, 0x45, 0x05, 0xce, 0x39, 0xa6, 0xc4, 0xdc, 0x93, 0xb9, 0xdd, 0x23, 0xe3, 0x08, 0xe8, 0xc5, + 0x9c, 0x4c, 0x21, 0x33, 0xeb, 0xaa, 0xb0, 0x98, 0x93, 0x11, 0x33, 0x3e, 0x02, 0x87, 0x42, 0xf4, + 0x34, 0x5c, 0x72, 0x34, 0x8d, 0x68, 0x8c, 0xcc, 0xfd, 0x81, 0x36, 0xec, 0xf8, 0xdd, 0x55, 0x69, + 0x77, 0xbe, 0x1c, 0x5d, 0x4e, 0xfc, 0x25, 0x97, 0x02, 0x82, 0x8e, 0xc0, 0x6d, 0x22, 0xa3, 0x0f, + 0x74, 0x46, 0xe7, 0x45, 0x84, 0xcc, 0x86, 0x6c, 0x57, 0x45, 0x86, 0x09, 0x9a, 0xe1, 0x1c, 0xa7, + 0x31, 0x2a, 0x4c, 0x5d, 0x26, 0x36, 0xa1, 0xf1, 0x04, 0xf4, 0x31, 0x61, 0x1c, 0x12, 0x8e, 0x21, + 0x47, 0xd3, 0x1c, 0x15, 0x19, 0x66, 0x4c, 0xa8, 0x6d, 0x0e, 0xb4, 0x61, 0xfb, 0xec, 0xc4, 0x7d, + 0xa5, 0x8d, 0xee, 0x28, 0x8a, 0x10, 0x63, 0x63, 0x4a, 0x66, 0x38, 0x09, 0x8e, 0x76, 0x5a, 0x5c, + 0x6c, 0x3b, 0x38, 0xbf, 0xec, 0x81, 0x07, 0xe7, 0x7f, 0x65, 0xc6, 0x94, 0xf0, 0x02, 0x46, 0xfc, + 0xbe, 0x4c, 0xeb, 0x81, 0x06, 0x8c, 0x33, 0x4c, 0xa4, 0x57, 0x07, 0x81, 0x0a, 0x8c, 0x13, 0xd0, + 0x14, 0x06, 0x4e, 0x71, 0x2c, 0x3d, 0xd9, 0xf7, 0xc1, 0xaa, 0xb4, 0x75, 0xe1, 0xd6, 0xf9, 0xe7, + 0x81, 0x2e, 0x52, 0xe7, 0xb1, 0x28, 0x4d, 0x61, 0x88, 0xd2, 0xca, 0x1d, 0x15, 0x18, 0x1f, 0x83, + 0x16, 0x26, 0x98, 0x4f, 0x33, 0x96, 0x48, 0x37, 0x3a, 0xfe, 0xc3, 0x3f, 0x4a, 0xdb, 0x44, 0x24, + 0xa2, 0x31, 0x26, 0x89, 0xf7, 0x35, 0xa3, 0xc4, 0x0d, 0xe0, 0x62, 0x82, 0x18, 0x83, 0x09, 0x0a, + 0x9a, 0x02, 0x3d, 0x61, 0x89, 0xf1, 0x15, 0x68, 0xcc, 0xe6, 0x24, 0x66, 0x66, 0x6b, 0x50, 0x1f, + 0xb6, 0xcf, 0xfa, 0x6e, 0x3a, 0x0b, 0x5d, 0xb1, 0x5d, 0x5b, 0xfb, 0xc6, 0x14, 0x13, 0xff, 0xfd, + 0xab, 0xd2, 0xae, 0xfd, 0xf8, 0xab, 0x7d, 0x92, 0x60, 0xfe, 0x74, 0x1e, 0xba, 0x11, 0xcd, 0xbc, + 0x14, 0x13, 0xe4, 0xa5, 0xb3, 0xf0, 0x03, 0x16, 0x7f, 0xe3, 0xa9, 0xbd, 0x13, 0x58, 0x16, 0xa8, + 0x8e, 0xce, 0xef, 0x1a, 0x78, 0x7b, 0x82, 0x93, 0xe2, 0x7f, 0xf0, 0xf3, 0x18, 0xb4, 0xa2, 0x8a, + 0xa2, 0xb2, 0x74, 0x1b, 0xdf, 0xcd, 0xd5, 0x47, 0xa0, 0x9d, 0x29, 0xa9, 0xd2, 0x42, 0xfd, 0x0e, + 0x16, 0x82, 0xaa, 0x60, 0xc2, 0x12, 0xe7, 0x07, 0x0d, 0xbc, 0xf5, 0x38, 0x8f, 0x21, 0x47, 0x23, + 0x31, 0xc9, 0x7f, 0x7d, 0xcd, 0x53, 0x70, 0x40, 0xd0, 0x62, 0xaa, 0x76, 0x44, 0xde, 0xd4, 0xef, + 0xad, 0x4b, 0xbb, 0xbb, 0x84, 0x59, 0xfa, 0x99, 0xb3, 0x4d, 0x39, 0x41, 0x8b, 0xa0, 0x85, 0xa4, + 0xfc, 0x27, 0x0b, 0x9c, 0xa7, 0xc0, 0x18, 0xa7, 0x08, 0x16, 0xff, 0x8d, 0xb8, 0x5d, 0xa6, 0xfa, + 0xdf, 0x98, 0x7e, 0xd2, 0x40, 0xf7, 0x02, 0x13, 0xe1, 0x2e, 0xdb, 0x12, 0xbd, 0x77, 0x83, 0xc8, + 0xef, 0xae, 0x4b, 0xbb, 0xa3, 0x6e, 0x22, 0x8f, 0x9d, 0x0d, 0xf5, 0x27, 0xaf, 0xa0, 0xf6, 0xfb, + 0xeb, 0xd2, 0x36, 0x14, 0x7a, 0x27, 0xe9, 0xdc, 0x94, 0xf4, 0xa9, 0x90, 0x24, 0x67, 0x2c, 0x16, + 0xa3, 0x3e, 0xdc, 0xf7, 0xad, 0x55, 0x69, 0x37, 0xd5, 0x90, 0xd9, 0xba, 0xb4, 0xdf, 0x50, 0x1d, + 0x36, 0x20, 0x27, 0x68, 0xaa, 0xc1, 0x33, 0xe7, 0x67, 0x0d, 0x18, 0x8f, 0x49, 0xfe, 0xba, 0x69, + 0x7e, 0xa8, 0xd6, 0x6d, 0xf3, 0xc3, 0xba, 0xe4, 0x90, 0xcf, 0xd9, 0x7d, 0x8e, 0xd6, 0x78, 0x04, + 0x74, 0x26, 0x59, 0xe4, 0x7a, 0x1d, 0x9e, 0xbd, 0x7b, 0xcb, 0x73, 0x7b, 0x53, 0x52, 0x50, 0x15, + 0xf9, 0x5f, 0x5c, 0xbd, 0xb4, 0x6a, 0x2f, 0x5e, 0x5a, 0xb5, 0x67, 0x2b, 0x4b, 0xbb, 0x5a, 0x59, + 0xda, 0xf3, 0x95, 0xa5, 0xfd, 0xb6, 0xb2, 0xb4, 0xef, 0xaf, 0xad, 0xda, 0xf3, 0x6b, 0xab, 0xf6, + 0xe2, 0xda, 0xaa, 0x3d, 0x79, 0xe7, 0xb6, 0xf7, 0xe5, 0x3b, 0x4f, 0x90, 0xa8, 0x67, 0x26, 0xd4, + 0xe5, 0xff, 0xdb, 0x87, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xad, 0x0f, 0x3c, 0x92, 0x48, 0x07, + 0x00, 0x00, } func (this *StoreCodeProposal) Equal(that interface{}) bool { diff --git a/x/wasm/internal/types/proposal.proto b/x/wasm/types/proposal.proto similarity index 99% rename from x/wasm/internal/types/proposal.proto rename to x/wasm/types/proposal.proto index 878d27bafb..16746071d1 100644 --- a/x/wasm/internal/types/proposal.proto +++ b/x/wasm/types/proposal.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "lfb/base/v1beta1/coin.proto"; import "types.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; option (gogoproto.goproto_stringer_all) = false; option (gogoproto.goproto_getters_all) = false; option (gogoproto.equal_all) = true; diff --git a/x/wasm/internal/types/proposal_test.go b/x/wasm/types/proposal_test.go similarity index 91% rename from x/wasm/internal/types/proposal_test.go rename to x/wasm/types/proposal_test.go index ee8d1b6203..b18eaf2bb2 100644 --- a/x/wasm/internal/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "encoding/json" "strings" "testing" @@ -199,6 +200,13 @@ func TestValidateInstantiateContractProposal(t *testing.T) { src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) { p.InitMsg = nil }), + expErr: true, + }, + "with invalid init msg": { + src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) { + p.InitMsg = []byte("not a json string") + }), + expErr: true, }, "without init funds": { src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) { @@ -282,6 +290,13 @@ func TestValidateMigrateContractProposal(t *testing.T) { src: MigrateContractProposalFixture(func(p *MigrateContractProposal) { p.MigrateMsg = nil }), + expErr: true, + }, + "migrate msg with invalid json": { + src: MigrateContractProposalFixture(func(p *MigrateContractProposal) { + p.MigrateMsg = []byte("not a json message") + }), + expErr: true, }, "base data missing": { src: MigrateContractProposalFixture(func(p *MigrateContractProposal) { @@ -750,3 +765,63 @@ func TestConvertToProposals(t *testing.T) { }) } } + +func TestUnmarshalContentFromJson(t *testing.T) { + specs := map[string]struct { + src string + got govtypes.Content + exp govtypes.Content + }{ + "instantiate ": { + src: ` +{ + "title": "foo", + "description": "bar", + "admin": "myAdminAddress", + "code_id": 1, + "funds": [{"denom": "ALX", "amount": "2"},{"denom": "BLX","amount": "3"}], + "init_msg": "e30=", + "label": "testing", + "run_as": "myRunAsAddress" +}`, + got: &InstantiateContractProposal{}, + exp: &InstantiateContractProposal{ + Title: "foo", + Description: "bar", + RunAs: "myRunAsAddress", + Admin: "myAdminAddress", + CodeID: 1, + Label: "testing", + InitMsg: []byte("{}"), + Funds: sdk.NewCoins(sdk.NewCoin("ALX", sdk.NewInt(2)), sdk.NewCoin("BLX", sdk.NewInt(3))), + }, + }, + "migrate ": { + src: ` +{ + "title": "foo", + "description": "bar", + "code_id": 1, + "contract": "myContractAddr", + "migrate_msg": "e30=", + "run_as": "myRunAsAddress" +}`, + got: &MigrateContractProposal{}, + exp: &MigrateContractProposal{ + Title: "foo", + Description: "bar", + RunAs: "myRunAsAddress", + Contract: "myContractAddr", + CodeID: 1, + MigrateMsg: []byte("{}"), + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + require.NoError(t, json.Unmarshal([]byte(spec.src), spec.got)) + assert.Equal(t, spec.exp, spec.got) + }) + } + +} diff --git a/x/wasm/internal/types/querier_router.go b/x/wasm/types/querier_router.go similarity index 100% rename from x/wasm/internal/types/querier_router.go rename to x/wasm/types/querier_router.go diff --git a/x/wasm/internal/types/querier_router_test.go b/x/wasm/types/querier_router_test.go similarity index 100% rename from x/wasm/internal/types/querier_router_test.go rename to x/wasm/types/querier_router_test.go diff --git a/x/wasm/internal/types/query.pb.go b/x/wasm/types/query.pb.go similarity index 94% rename from x/wasm/internal/types/query.pb.go rename to x/wasm/types/query.pb.go index 64cf217a22..3bfc9726ca 100644 --- a/x/wasm/internal/types/query.pb.go +++ b/x/wasm/types/query.pb.go @@ -774,76 +774,76 @@ func init() { func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } var fileDescriptor_5c6ac9b241082464 = []byte{ - // 1104 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x97, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0x3d, 0xa9, 0xf3, 0xc3, 0x93, 0x14, 0xc2, 0xa8, 0x50, 0x63, 0xdc, 0x75, 0xb4, 0x54, - 0xc4, 0x05, 0xba, 0x93, 0x1f, 0x2d, 0x12, 0xe5, 0x54, 0x27, 0x48, 0xa9, 0x44, 0x28, 0x6c, 0x0e, - 0xe5, 0xc7, 0x21, 0x9a, 0xdd, 0x9d, 0xd8, 0x0b, 0xeb, 0x1d, 0x77, 0x67, 0x4c, 0x62, 0x85, 0x08, - 0x89, 0x0b, 0x27, 0x04, 0x12, 0x47, 0x2e, 0x70, 0xab, 0x2a, 0x38, 0x22, 0x71, 0x84, 0x5b, 0x8e, - 0x91, 0xb8, 0x70, 0xb2, 0xc0, 0xe1, 0x80, 0xf2, 0x27, 0xf4, 0x84, 0x76, 0x76, 0xd6, 0x59, 0x3b, - 0x59, 0xdb, 0x41, 0x16, 0x5c, 0xac, 0x1d, 0x7b, 0xde, 0x7b, 0x9f, 0xf7, 0x7d, 0x33, 0xef, 0xad, - 0xe1, 0xec, 0xc3, 0x26, 0x0d, 0x5a, 0x46, 0x23, 0x60, 0x82, 0xa1, 0x67, 0x6d, 0xc6, 0xeb, 0xbb, - 0x84, 0xd7, 0x0d, 0xf9, 0xf1, 0xc9, 0xb2, 0x45, 0x05, 0x59, 0x2e, 0x5c, 0xa9, 0xb2, 0x2a, 0x93, - 0x3b, 0x70, 0xf8, 0x14, 0x6d, 0x2e, 0xcc, 0x8a, 0x56, 0x83, 0x72, 0xb5, 0x28, 0x56, 0x19, 0xab, - 0x7a, 0x14, 0x93, 0x86, 0x8b, 0x89, 0xef, 0x33, 0x41, 0x84, 0xcb, 0xfc, 0xf8, 0xd7, 0x45, 0x6f, - 0xc7, 0xc2, 0x16, 0xe1, 0x14, 0xcb, 0x68, 0x58, 0x39, 0xc6, 0x0d, 0x52, 0x75, 0x7d, 0xb9, 0x33, - 0xda, 0xa8, 0xdf, 0x82, 0xf9, 0x77, 0xc3, 0x1d, 0x6b, 0xcc, 0x17, 0x01, 0xb1, 0xc5, 0x3d, 0x7f, - 0x87, 0x99, 0xf4, 0x61, 0x93, 0x72, 0x81, 0xf2, 0x70, 0x9a, 0x38, 0x4e, 0x40, 0x39, 0xcf, 0x83, - 0x05, 0x50, 0xce, 0x99, 0xf1, 0x52, 0xff, 0x0a, 0xc0, 0xe7, 0xcf, 0x31, 0xe3, 0x0d, 0xe6, 0x73, - 0x9a, 0x6e, 0x87, 0x4c, 0x78, 0xd9, 0x56, 0x16, 0xdb, 0xae, 0xbf, 0xc3, 0xf2, 0x13, 0x0b, 0xa0, - 0x3c, 0xbb, 0xf2, 0xa2, 0x71, 0xae, 0x0c, 0x46, 0xd2, 0x7b, 0x65, 0xe6, 0xa8, 0x5d, 0x02, 0x27, - 0xed, 0x52, 0xc6, 0x9c, 0xb3, 0x13, 0xdf, 0xdf, 0xc9, 0xfe, 0xfd, 0x5d, 0x09, 0xe8, 0x9f, 0xc2, - 0x17, 0x7a, 0x80, 0x36, 0x5c, 0x2e, 0x58, 0xd0, 0x1a, 0x9a, 0x0a, 0x5a, 0x83, 0xf0, 0x54, 0x94, - 0x2e, 0x8f, 0xb7, 0x63, 0x19, 0xa1, 0x7c, 0x46, 0x54, 0xac, 0x18, 0xe8, 0x1d, 0x52, 0xa5, 0xca, - 0xa5, 0x99, 0x30, 0xd3, 0x7f, 0x02, 0xb0, 0x78, 0x7e, 0x78, 0x25, 0xc9, 0x7d, 0x38, 0x4d, 0x7d, - 0x11, 0xb8, 0x34, 0x8c, 0x7f, 0xa9, 0x3c, 0xbb, 0x82, 0x87, 0xa4, 0xbc, 0xc6, 0x1c, 0xaa, 0x9c, - 0xbc, 0xe9, 0x8b, 0xa0, 0x55, 0xc9, 0x1e, 0x86, 0xa9, 0xc7, 0x5e, 0xd0, 0xfa, 0x39, 0xd8, 0xd7, - 0x07, 0x63, 0x47, 0x28, 0x3d, 0xdc, 0xfb, 0x7d, 0xaa, 0xf1, 0x4a, 0x2b, 0x0c, 0x1c, 0xab, 0x76, - 0x15, 0x4e, 0xdb, 0xcc, 0xa1, 0xdb, 0xae, 0x23, 0x55, 0xcb, 0x9a, 0x53, 0xe1, 0xf2, 0x9e, 0x33, - 0x1e, 0xd1, 0xbe, 0x04, 0xf0, 0x6a, 0xb2, 0xc2, 0x0f, 0x5c, 0x51, 0xbb, 0xab, 0xaa, 0xf2, 0x7f, - 0x1c, 0xa1, 0x5f, 0xfb, 0x8b, 0xd8, 0x55, 0x43, 0x15, 0xf1, 0x43, 0xf8, 0x54, 0x4f, 0xe8, 0xb8, - 0x96, 0xc6, 0x08, 0xb1, 0x13, 0xc9, 0xa9, 0x52, 0x5e, 0x4e, 0x22, 0x8c, 0xab, 0xa0, 0x07, 0x2a, - 0x85, 0xbb, 0x9e, 0x17, 0x47, 0xdf, 0x12, 0x44, 0xd0, 0xff, 0xe8, 0x1e, 0x7c, 0x0f, 0xe0, 0xb5, - 0x94, 0xf8, 0x4a, 0xc3, 0x3b, 0x70, 0xaa, 0xce, 0x1c, 0xea, 0xc5, 0xda, 0x15, 0x53, 0xb4, 0xdb, - 0x0c, 0x37, 0x29, 0xa5, 0x94, 0xc5, 0x98, 0x24, 0x7a, 0xa0, 0x24, 0x32, 0xc9, 0xee, 0x05, 0x25, - 0xba, 0x06, 0xa1, 0x8c, 0xb1, 0xed, 0x10, 0x41, 0x64, 0xfc, 0x39, 0x33, 0x27, 0xbf, 0x59, 0x27, - 0x82, 0xe8, 0xab, 0x2a, 0xf7, 0xb3, 0x8e, 0x55, 0xee, 0x08, 0x66, 0xa5, 0x25, 0x90, 0x96, 0xf2, - 0x59, 0x7f, 0x1f, 0x6a, 0xd2, 0x68, 0xab, 0x4e, 0x02, 0x31, 0x5e, 0x9e, 0x2d, 0x58, 0x4a, 0x75, - 0xad, 0x88, 0x96, 0x92, 0x44, 0x95, 0xe2, 0x93, 0x76, 0x29, 0x4f, 0x7d, 0x9b, 0x39, 0xae, 0x5f, - 0xc5, 0x1f, 0x71, 0xe6, 0x1b, 0x26, 0xd9, 0xdd, 0xa4, 0x9c, 0x87, 0x5a, 0x46, 0xbc, 0xaf, 0xc0, - 0x79, 0x75, 0x47, 0x86, 0xb7, 0x09, 0xbd, 0x0d, 0xe0, 0x7c, 0xb8, 0xb1, 0x67, 0x3a, 0xdc, 0xe8, - 0xdb, 0x5d, 0x99, 0xef, 0xb4, 0x4b, 0x53, 0x72, 0xdb, 0xfa, 0x49, 0xbb, 0x34, 0xe1, 0x3a, 0xdd, - 0x36, 0x93, 0x87, 0xd3, 0x76, 0x40, 0x89, 0x60, 0x81, 0xcc, 0x2e, 0x67, 0xc6, 0x4b, 0xb4, 0x09, - 0x73, 0x21, 0xce, 0x76, 0x8d, 0xf0, 0x5a, 0xfe, 0x92, 0xa4, 0x5f, 0x7a, 0xd2, 0x2e, 0xbd, 0x5a, - 0x75, 0x45, 0xad, 0x69, 0x19, 0x36, 0xab, 0x63, 0xcf, 0xf5, 0x29, 0x66, 0x3c, 0xcc, 0x9a, 0xf9, - 0xd8, 0x73, 0x2d, 0x8e, 0xad, 0x96, 0xa0, 0xdc, 0xd8, 0xa0, 0x7b, 0x95, 0xf0, 0xc1, 0x9c, 0x09, - 0x5d, 0x6c, 0x10, 0x5e, 0x43, 0xcf, 0xc1, 0x29, 0xce, 0x9a, 0x81, 0x4d, 0xf3, 0x59, 0x19, 0x47, - 0xad, 0x42, 0x00, 0xab, 0xe9, 0x7a, 0x0e, 0x0d, 0xf2, 0x93, 0x11, 0x80, 0x5a, 0xaa, 0x96, 0xf1, - 0x05, 0x80, 0xcf, 0x24, 0xe4, 0x50, 0x19, 0xbe, 0x0d, 0x73, 0x51, 0x86, 0x61, 0x7b, 0x02, 0xf2, - 0x98, 0x2e, 0xa6, 0xb6, 0x88, 0x5e, 0x75, 0x12, 0x2d, 0x6a, 0xc6, 0x56, 0xbf, 0xa1, 0xa2, 0xaa, - 0x92, 0xac, 0x70, 0x65, 0xe6, 0xa4, 0x5d, 0x92, 0xeb, 0xa8, 0x22, 0x8a, 0xe4, 0xbd, 0x04, 0x08, - 0x8f, 0x0b, 0xd3, 0x7b, 0xa7, 0xc1, 0xbf, 0xbb, 0xd3, 0x8f, 0x00, 0x44, 0x49, 0xd7, 0x2a, 0xc9, - 0xb7, 0x20, 0xec, 0x26, 0x19, 0x5f, 0xe6, 0x91, 0xb3, 0x8c, 0xee, 0x75, 0x2e, 0xce, 0x70, 0x4c, - 0x57, 0x7b, 0xe5, 0x31, 0x84, 0x93, 0x12, 0x15, 0x7d, 0x0b, 0xe0, 0x5c, 0xb2, 0xfd, 0xa2, 0xb4, - 0x79, 0x9b, 0xf6, 0xf2, 0x53, 0x58, 0x1a, 0xdd, 0x20, 0x22, 0xd1, 0xcb, 0x9f, 0xff, 0xf6, 0xd7, - 0x37, 0x13, 0x3a, 0x5a, 0xc0, 0xa1, 0x41, 0xf7, 0x95, 0x2b, 0x6e, 0xf3, 0x78, 0x5f, 0xdd, 0xdb, - 0x03, 0xf4, 0x03, 0x80, 0x4f, 0xf7, 0xbd, 0x29, 0xa0, 0x95, 0x51, 0xe2, 0xf5, 0xbe, 0xd5, 0x14, - 0x56, 0x2f, 0x64, 0xa3, 0x30, 0x97, 0x24, 0xe6, 0xcb, 0xa8, 0x3c, 0x0c, 0x13, 0xd7, 0x14, 0xda, - 0xe3, 0x04, 0xae, 0x9a, 0x89, 0xa3, 0xe1, 0xf6, 0xbe, 0x4e, 0x8c, 0x86, 0xdb, 0x37, 0x74, 0x75, - 0x43, 0xe2, 0x96, 0xd1, 0x4b, 0xfd, 0xb8, 0x0e, 0xc5, 0xfb, 0xaa, 0x91, 0x1c, 0x74, 0xe9, 0x39, - 0xfa, 0x11, 0xc0, 0xf9, 0xfe, 0xe9, 0x83, 0x06, 0x46, 0x4e, 0x99, 0x95, 0x85, 0x5b, 0x17, 0x33, - 0x1a, 0xc6, 0x7b, 0x46, 0x5e, 0x2e, 0xd1, 0x7e, 0x06, 0x70, 0xbe, 0x7f, 0x62, 0x0c, 0xe6, 0x4d, - 0x19, 0x5c, 0x83, 0x79, 0xd3, 0x86, 0x92, 0xfe, 0xba, 0xe4, 0x5d, 0x45, 0xcb, 0x43, 0x79, 0x03, - 0xb2, 0x8b, 0xf7, 0x4f, 0x07, 0xce, 0x01, 0xfa, 0x05, 0x40, 0x74, 0x76, 0xb8, 0xa0, 0xdb, 0x83, - 0x38, 0x52, 0xe7, 0x5c, 0xe1, 0xb5, 0x8b, 0x9a, 0xa9, 0x04, 0xde, 0x90, 0x09, 0xdc, 0x46, 0xab, - 0xc3, 0x05, 0x0f, 0x9d, 0xf4, 0xa6, 0xf0, 0x19, 0xcc, 0xca, 0xe3, 0xbc, 0x38, 0xf8, 0x68, 0x9e, - 0x9e, 0xe1, 0xf2, 0xf0, 0x8d, 0x8a, 0xeb, 0xba, 0xe4, 0xd2, 0x50, 0x71, 0xd0, 0xc1, 0x45, 0x7b, - 0x70, 0x52, 0xf6, 0x55, 0x34, 0xd4, 0x71, 0xdc, 0xd5, 0x0b, 0x37, 0x46, 0xd8, 0xa9, 0x18, 0x0a, - 0x92, 0xe1, 0x0a, 0x42, 0x67, 0x19, 0x2a, 0xf7, 0x0f, 0xff, 0xd4, 0x32, 0x8f, 0x3a, 0x5a, 0xe6, - 0xb0, 0xa3, 0x81, 0xa3, 0x8e, 0x06, 0xfe, 0xe8, 0x68, 0xe0, 0xeb, 0x63, 0x2d, 0x73, 0x74, 0xac, - 0x65, 0x7e, 0x3f, 0xd6, 0x32, 0x1f, 0xdc, 0xec, 0x9f, 0xa6, 0xde, 0x8e, 0x75, 0x93, 0x3b, 0x1f, - 0xe3, 0xbd, 0xc8, 0x9d, 0xeb, 0x0b, 0x1a, 0xf8, 0xc4, 0xc3, 0xf2, 0x7f, 0xa9, 0x35, 0x25, 0xff, - 0x51, 0xae, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x7d, 0xd2, 0x6b, 0xca, 0xe1, 0x0e, 0x00, 0x00, + // 1100 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x97, 0xcd, 0x6f, 0xe3, 0xc4, + 0x1b, 0xc7, 0x33, 0xdd, 0x34, 0x6d, 0xa6, 0xdd, 0xdf, 0x2f, 0x8c, 0x16, 0x36, 0x84, 0xac, 0x53, + 0x99, 0x8a, 0x66, 0x79, 0xb1, 0xdb, 0x66, 0x17, 0x89, 0xe5, 0xb4, 0x69, 0x41, 0x5d, 0x89, 0xf2, + 0xe2, 0x1e, 0x96, 0x97, 0x43, 0x35, 0xb6, 0x27, 0x89, 0xc1, 0xf1, 0x64, 0x3d, 0x13, 0xda, 0xa8, + 0x54, 0x48, 0x5c, 0x38, 0x21, 0x90, 0x38, 0x72, 0x81, 0xdb, 0x6a, 0x05, 0x47, 0x24, 0x8e, 0x70, + 0xeb, 0xb1, 0x12, 0x17, 0x4e, 0x11, 0xa4, 0x1c, 0x50, 0xff, 0x84, 0x3d, 0x21, 0x8f, 0xc7, 0xa9, + 0x93, 0xd6, 0x49, 0x8a, 0x22, 0xb8, 0x44, 0x9e, 0x64, 0x9e, 0xe7, 0xf9, 0x3c, 0xdf, 0x67, 0xe6, + 0x79, 0x1c, 0xb8, 0xf0, 0xa0, 0x4d, 0xfc, 0x8e, 0xd6, 0xf2, 0x29, 0xa7, 0xe8, 0x49, 0x8b, 0xb2, + 0xe6, 0x1e, 0x66, 0x4d, 0x4d, 0x7c, 0x7c, 0xbc, 0x66, 0x12, 0x8e, 0xd7, 0x0a, 0xd7, 0xea, 0xb4, + 0x4e, 0xc5, 0x0e, 0x3d, 0x78, 0x0a, 0x37, 0x17, 0x16, 0x78, 0xa7, 0x45, 0x98, 0x5c, 0x14, 0xeb, + 0x94, 0xd6, 0x5d, 0xa2, 0xe3, 0x96, 0xa3, 0x63, 0xcf, 0xa3, 0x1c, 0x73, 0x87, 0x7a, 0xd1, 0xaf, + 0x2b, 0x6e, 0xcd, 0xd4, 0x4d, 0xcc, 0x88, 0x2e, 0xa2, 0xe9, 0xd2, 0xb1, 0xde, 0xc2, 0x75, 0xc7, + 0x13, 0x3b, 0xc3, 0x8d, 0xea, 0x2d, 0x98, 0x7f, 0x27, 0xd8, 0xb1, 0x41, 0x3d, 0xee, 0x63, 0x8b, + 0xdf, 0xf3, 0x6a, 0xd4, 0x20, 0x0f, 0xda, 0x84, 0x71, 0x94, 0x87, 0x73, 0xd8, 0xb6, 0x7d, 0xc2, + 0x58, 0x1e, 0x2c, 0x81, 0x72, 0xd6, 0x88, 0x96, 0xea, 0x97, 0x00, 0x3e, 0x7d, 0x81, 0x19, 0x6b, + 0x51, 0x8f, 0x91, 0x64, 0x3b, 0x64, 0xc0, 0xab, 0x96, 0xb4, 0xd8, 0x75, 0xbc, 0x1a, 0xcd, 0xcf, + 0x2c, 0x81, 0xf2, 0xc2, 0xfa, 0xb3, 0xda, 0x85, 0x32, 0x68, 0x71, 0xef, 0xd5, 0xf9, 0xe3, 0x6e, + 0x09, 0x9c, 0x76, 0x4b, 0x29, 0x63, 0xd1, 0x8a, 0x7d, 0x7f, 0x27, 0xfd, 0xd7, 0xb7, 0x25, 0xa0, + 0x7e, 0x02, 0x9f, 0x19, 0x00, 0xda, 0x72, 0x18, 0xa7, 0x7e, 0x67, 0x6c, 0x2a, 0x68, 0x03, 0xc2, + 0x33, 0x51, 0xfa, 0x3c, 0x6e, 0xcd, 0xd4, 0x02, 0xf9, 0xb4, 0xb0, 0x58, 0x11, 0xd0, 0xdb, 0xb8, + 0x4e, 0xa4, 0x4b, 0x23, 0x66, 0xa6, 0xfe, 0x08, 0x60, 0xf1, 0xe2, 0xf0, 0x52, 0x92, 0xb7, 0xe0, + 0x1c, 0xf1, 0xb8, 0xef, 0x90, 0x20, 0xfe, 0x95, 0xf2, 0xc2, 0xba, 0x3e, 0x26, 0xe5, 0x0d, 0x6a, + 0x13, 0xe9, 0xe4, 0x35, 0x8f, 0xfb, 0x9d, 0x6a, 0xfa, 0x28, 0x48, 0x3d, 0xf2, 0x82, 0x36, 0x2f, + 0xc0, 0x5e, 0x1e, 0x8d, 0x1d, 0xa2, 0x0c, 0x70, 0x1f, 0x0c, 0xa9, 0xc6, 0xaa, 0x9d, 0x20, 0x70, + 0xa4, 0xda, 0x75, 0x38, 0x67, 0x51, 0x9b, 0xec, 0x3a, 0xb6, 0x50, 0x2d, 0x6d, 0x64, 0x82, 0xe5, + 0x3d, 0x7b, 0x3a, 0xa2, 0x7d, 0x01, 0xe0, 0xf5, 0x78, 0x85, 0xef, 0x3b, 0xbc, 0x71, 0x57, 0x56, + 0xe5, 0xbf, 0x38, 0x42, 0xbf, 0x0c, 0x17, 0xb1, 0xaf, 0x86, 0x2c, 0xe2, 0x07, 0xf0, 0x7f, 0x03, + 0xa1, 0xa3, 0x5a, 0x6a, 0x13, 0xc4, 0x8e, 0x25, 0x27, 0x4b, 0x79, 0x35, 0x8e, 0x30, 0xad, 0x82, + 0x1e, 0xca, 0x14, 0xee, 0xba, 0x6e, 0x14, 0x7d, 0x87, 0x63, 0x4e, 0xfe, 0xa5, 0x7b, 0xf0, 0x1d, + 0x80, 0x37, 0x12, 0xe2, 0x4b, 0x0d, 0xef, 0xc0, 0x4c, 0x93, 0xda, 0xc4, 0x8d, 0xb4, 0x2b, 0x26, + 0x68, 0xb7, 0x1d, 0x6c, 0x92, 0x4a, 0x49, 0x8b, 0x29, 0x49, 0x74, 0x5f, 0x4a, 0x64, 0xe0, 0xbd, + 0x4b, 0x4a, 0x74, 0x03, 0x42, 0x11, 0x63, 0xd7, 0xc6, 0x1c, 0x8b, 0xf8, 0x8b, 0x46, 0x56, 0x7c, + 0xb3, 0x89, 0x39, 0x56, 0x2b, 0x32, 0xf7, 0xf3, 0x8e, 0x65, 0xee, 0x08, 0xa6, 0x85, 0x25, 0x10, + 0x96, 0xe2, 0x59, 0x7d, 0x0f, 0x2a, 0xc2, 0x68, 0xa7, 0x89, 0x7d, 0x3e, 0x5d, 0x9e, 0x1d, 0x58, + 0x4a, 0x74, 0x2d, 0x89, 0x56, 0xe3, 0x44, 0xd5, 0xe2, 0xe3, 0x6e, 0x29, 0x4f, 0x3c, 0x8b, 0xda, + 0x8e, 0x57, 0xd7, 0x3f, 0x64, 0xd4, 0xd3, 0x0c, 0xbc, 0xb7, 0x4d, 0x18, 0x0b, 0xb4, 0x0c, 0x79, + 0x5f, 0x80, 0x39, 0x79, 0x47, 0xc6, 0xb7, 0x09, 0xb5, 0x0b, 0x60, 0x2e, 0xd8, 0x38, 0x30, 0x1d, + 0x6e, 0x0e, 0xed, 0xae, 0xe6, 0x7a, 0xdd, 0x52, 0x46, 0x6c, 0xdb, 0x3c, 0xed, 0x96, 0x66, 0x1c, + 0xbb, 0xdf, 0x66, 0xf2, 0x70, 0xce, 0xf2, 0x09, 0xe6, 0xd4, 0x17, 0xd9, 0x65, 0x8d, 0x68, 0x89, + 0xb6, 0x61, 0x36, 0xc0, 0xd9, 0x6d, 0x60, 0xd6, 0xc8, 0x5f, 0x11, 0xf4, 0xab, 0x8f, 0xbb, 0xa5, + 0x17, 0xeb, 0x0e, 0x6f, 0xb4, 0x4d, 0xcd, 0xa2, 0x4d, 0xdd, 0x75, 0x3c, 0xa2, 0x53, 0x16, 0x64, + 0x4d, 0x3d, 0xdd, 0x75, 0x4c, 0xa6, 0x9b, 0x1d, 0x4e, 0x98, 0xb6, 0x45, 0xf6, 0xab, 0xc1, 0x83, + 0x31, 0x1f, 0xb8, 0xd8, 0xc2, 0xac, 0x81, 0x9e, 0x82, 0x19, 0x46, 0xdb, 0xbe, 0x45, 0xf2, 0x69, + 0x11, 0x47, 0xae, 0x02, 0x00, 0xb3, 0xed, 0xb8, 0x36, 0xf1, 0xf3, 0xb3, 0x21, 0x80, 0x5c, 0xca, + 0x96, 0xf1, 0x39, 0x80, 0x4f, 0xc4, 0xe4, 0x90, 0x19, 0xbe, 0x09, 0xb3, 0x61, 0x86, 0x41, 0x7b, + 0x02, 0xe2, 0x98, 0xae, 0x24, 0xb6, 0x88, 0x41, 0x75, 0x62, 0x2d, 0x6a, 0xde, 0x92, 0xbf, 0xa1, + 0xa2, 0xac, 0x92, 0xa8, 0x70, 0x75, 0xfe, 0xb4, 0x5b, 0x12, 0xeb, 0xb0, 0x22, 0x92, 0xe4, 0xdd, + 0x18, 0x08, 0x8b, 0x0a, 0x33, 0x78, 0xa7, 0xc1, 0x3f, 0xbb, 0xd3, 0x0f, 0x01, 0x44, 0x71, 0xd7, + 0x32, 0xc9, 0x37, 0x20, 0xec, 0x27, 0x19, 0x5d, 0xe6, 0x89, 0xb3, 0x0c, 0xef, 0x75, 0x36, 0xca, + 0x70, 0x4a, 0x57, 0x7b, 0xfd, 0x11, 0x84, 0xb3, 0x02, 0x15, 0x7d, 0x03, 0xe0, 0x62, 0xbc, 0xfd, + 0xa2, 0xa4, 0x79, 0x9b, 0xf4, 0xf2, 0x53, 0x58, 0x9d, 0xdc, 0x20, 0x24, 0x51, 0xcb, 0x9f, 0xfd, + 0xfa, 0xe7, 0xd7, 0x33, 0x2a, 0x5a, 0xd2, 0x03, 0x83, 0xfe, 0x2b, 0x57, 0xd4, 0xe6, 0xf5, 0x03, + 0x79, 0x6f, 0x0f, 0xd1, 0xf7, 0x00, 0xfe, 0x7f, 0xe8, 0x4d, 0x01, 0xad, 0x4f, 0x12, 0x6f, 0xf0, + 0xad, 0xa6, 0x50, 0xb9, 0x94, 0x8d, 0xc4, 0x5c, 0x15, 0x98, 0xcf, 0xa3, 0xf2, 0x38, 0x4c, 0xbd, + 0x21, 0xd1, 0x1e, 0xc5, 0x70, 0xe5, 0x4c, 0x9c, 0x0c, 0x77, 0xf0, 0x75, 0x62, 0x32, 0xdc, 0xa1, + 0xa1, 0xab, 0x6a, 0x02, 0xb7, 0x8c, 0x9e, 0x1b, 0xc6, 0xb5, 0x89, 0x7e, 0x20, 0x1b, 0xc9, 0x61, + 0x9f, 0x9e, 0xa1, 0x1f, 0x00, 0xcc, 0x0d, 0x4f, 0x1f, 0x34, 0x32, 0x72, 0xc2, 0xac, 0x2c, 0xdc, + 0xba, 0x9c, 0xd1, 0x38, 0xde, 0x73, 0xf2, 0x32, 0x81, 0xf6, 0x13, 0x80, 0xb9, 0xe1, 0x89, 0x31, + 0x9a, 0x37, 0x61, 0x70, 0x8d, 0xe6, 0x4d, 0x1a, 0x4a, 0xea, 0x2b, 0x82, 0xb7, 0x82, 0xd6, 0xc6, + 0xf2, 0xfa, 0x78, 0x4f, 0x3f, 0x38, 0x1b, 0x38, 0x87, 0xe8, 0x67, 0x00, 0xd1, 0xf9, 0xe1, 0x82, + 0x6e, 0x8f, 0xe2, 0x48, 0x9c, 0x73, 0x85, 0x97, 0x2f, 0x6b, 0x26, 0x13, 0x78, 0x55, 0x24, 0x70, + 0x1b, 0x55, 0xc6, 0x0b, 0x1e, 0x38, 0x19, 0x4c, 0xe1, 0x53, 0x98, 0x16, 0xc7, 0x79, 0x65, 0xf4, + 0xd1, 0x3c, 0x3b, 0xc3, 0xe5, 0xf1, 0x1b, 0x25, 0xd7, 0xb2, 0xe0, 0x52, 0x50, 0x71, 0xd4, 0xc1, + 0x45, 0xfb, 0x70, 0x56, 0xf4, 0x55, 0x34, 0xd6, 0x71, 0xd4, 0xd5, 0x0b, 0x37, 0x27, 0xd8, 0x29, + 0x19, 0x0a, 0x82, 0xe1, 0x1a, 0x42, 0xe7, 0x19, 0xaa, 0xaf, 0x1f, 0xfd, 0xa1, 0xa4, 0x1e, 0xf6, + 0x94, 0xd4, 0x51, 0x4f, 0x01, 0xc7, 0x3d, 0x05, 0xfc, 0xde, 0x53, 0xc0, 0x57, 0x27, 0x4a, 0xea, + 0xf8, 0x44, 0x49, 0xfd, 0x76, 0xa2, 0xa4, 0xde, 0x5f, 0x1e, 0x9e, 0xa6, 0x6e, 0xcd, 0x7c, 0x89, + 0xd9, 0x1f, 0xe9, 0xfb, 0xa1, 0x3b, 0xf1, 0x77, 0xd4, 0xcc, 0x88, 0x3f, 0x92, 0x95, 0xbf, 0x03, + 0x00, 0x00, 0xff, 0xff, 0xcc, 0xbe, 0x15, 0xe4, 0xd8, 0x0e, 0x00, 0x00, } func (this *QueryContractInfoResponse) Equal(that interface{}) bool { diff --git a/x/wasm/internal/types/query.pb.gw.go b/x/wasm/types/query.pb.gw.go similarity index 100% rename from x/wasm/internal/types/query.pb.gw.go rename to x/wasm/types/query.pb.gw.go diff --git a/x/wasm/internal/types/query.proto b/x/wasm/types/query.proto similarity index 99% rename from x/wasm/internal/types/query.proto rename to x/wasm/types/query.proto index d8e1a39c0e..b5d70d240f 100644 --- a/x/wasm/internal/types/query.proto +++ b/x/wasm/types/query.proto @@ -6,7 +6,7 @@ import "types.proto"; import "google/api/annotations.proto"; import "lfb/base/query/v1beta1/pagination.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; option (gogoproto.goproto_getters_all) = false; option (gogoproto.equal_all) = false; diff --git a/x/wasm/internal/types/router.go b/x/wasm/types/router.go similarity index 100% rename from x/wasm/internal/types/router.go rename to x/wasm/types/router.go diff --git a/x/wasm/internal/types/router_test.go b/x/wasm/types/router_test.go similarity index 100% rename from x/wasm/internal/types/router_test.go rename to x/wasm/types/router_test.go diff --git a/x/wasm/internal/types/store.go b/x/wasm/types/store.go similarity index 100% rename from x/wasm/internal/types/store.go rename to x/wasm/types/store.go diff --git a/x/wasm/internal/types/test_fixtures.go b/x/wasm/types/test_fixtures.go similarity index 100% rename from x/wasm/internal/types/test_fixtures.go rename to x/wasm/types/test_fixtures.go diff --git a/x/wasm/internal/types/tx.go b/x/wasm/types/tx.go similarity index 100% rename from x/wasm/internal/types/tx.go rename to x/wasm/types/tx.go diff --git a/x/wasm/internal/types/tx.pb.go b/x/wasm/types/tx.pb.go similarity index 94% rename from x/wasm/internal/types/tx.pb.go rename to x/wasm/types/tx.pb.go index 8f623e5828..923ad8c03e 100644 --- a/x/wasm/internal/types/tx.pb.go +++ b/x/wasm/types/tx.pb.go @@ -37,11 +37,13 @@ type MsgStoreCode struct { Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` // WASMByteCode can be raw or gzip compressed WASMByteCode []byte `protobuf:"bytes,2,opt,name=wasm_byte_code,json=wasmByteCode,proto3" json:"wasm_byte_code,omitempty"` - // Source is a valid absolute HTTPS URI to the contract's source code, optional + // Source is a valid absolute HTTPS URI to the contract's source code, + // optional Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` // Builder is a valid docker image name with tag, optional Builder string `protobuf:"bytes,4,opt,name=builder,proto3" json:"builder,omitempty"` - // InstantiatePermission access control to apply on contract creation, optional + // InstantiatePermission access control to apply on contract creation, + // optional InstantiatePermission *AccessConfig `protobuf:"bytes,5,opt,name=instantiate_permission,json=instantiatePermission,proto3" json:"instantiate_permission,omitempty"` } @@ -117,7 +119,8 @@ func (m *MsgStoreCodeResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgStoreCodeResponse proto.InternalMessageInfo -// MsgInstantiateContract create a new smart contract instance for the given code id. +// MsgInstantiateContract create a new smart contract instance for the given +// code id. type MsgInstantiateContract struct { // Sender is the that actor that signed the messages Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` @@ -128,7 +131,7 @@ type MsgInstantiateContract struct { // Label is optional metadata to be stored with a contract instance. Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` // InitMsg json encoded message to be passed to the contract on instantiation - InitMsg encoding_json.RawMessage `protobuf:"bytes,5,opt,name=init_msg,json=initMsg,proto3,casttype=encoding/json.RawMessage" json:"init_msg,omitempty"` + InitMsg []byte `protobuf:"bytes,5,opt,name=init_msg,json=initMsg,proto3" json:"init_msg,omitempty"` // Funds coins that are transferred to the contract on instantiation Funds github_com_line_lfb_sdk_types.Coins `protobuf:"bytes,6,rep,name=funds,proto3,castrepeated=github.com/line/lfb-sdk/types.Coins" json:"funds"` } @@ -316,9 +319,9 @@ type MsgExecuteContract struct { // Contract is the address of the smart contract Contract string `protobuf:"bytes,2,opt,name=contract,proto3" json:"contract,omitempty"` // Msg json encoded message to be passed to the contract - Msg encoding_json.RawMessage `protobuf:"bytes,3,opt,name=msg,proto3,casttype=encoding/json.RawMessage" json:"msg,omitempty"` + Msg []byte `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` // Funds coins that are transferred to the contract on execution - Funds github_com_line_lfb_sdk_types.Coins `protobuf:"bytes,5,rep,name=funds,proto3,castrepeated=github.com/line/lfb-sdk/types.Coins" json:"funds"` + Funds github_com_line_lfb_sdk_types.Coins `protobuf:"bytes,4,rep,name=funds,proto3,castrepeated=github.com/line/lfb-sdk/types.Coins" json:"funds"` } func (m *MsgExecuteContract) Reset() { *m = MsgExecuteContract{} } @@ -402,7 +405,7 @@ type MsgMigrateContract struct { // CodeID references the new WASM code CodeID uint64 `protobuf:"varint,3,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` // MigrateMsg json encoded message to be passed to the contract on migration - MigrateMsg encoding_json.RawMessage `protobuf:"bytes,4,opt,name=migrate_msg,json=migrateMsg,proto3,casttype=encoding/json.RawMessage" json:"migrate_msg,omitempty"` + MigrateMsg []byte `protobuf:"bytes,4,opt,name=migrate_msg,json=migrateMsg,proto3" json:"migrate_msg,omitempty"` } func (m *MsgMigrateContract) Reset() { *m = MsgMigrateContract{} } @@ -738,66 +741,65 @@ func init() { func init() { proto.RegisterFile("tx.proto", fileDescriptor_0fd2153dc07d3b5c) } var fileDescriptor_0fd2153dc07d3b5c = []byte{ - // 931 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0xcf, 0x6f, 0xe3, 0x44, - 0x14, 0x8e, 0xd7, 0x6d, 0x7e, 0xbc, 0x84, 0x82, 0x4c, 0xdb, 0xb5, 0xbc, 0x28, 0x29, 0x2e, 0x2b, - 0x15, 0x96, 0xda, 0xb4, 0x88, 0x45, 0x08, 0xed, 0x21, 0x09, 0x1c, 0x2a, 0x64, 0x84, 0x5c, 0x21, - 0xc4, 0x4a, 0x28, 0x8c, 0xed, 0x89, 0x19, 0x70, 0x66, 0x22, 0xcf, 0x84, 0xb6, 0x42, 0x82, 0x7f, - 0x80, 0x03, 0x17, 0xce, 0xdc, 0xd1, 0xfe, 0x15, 0x9c, 0x7a, 0x5c, 0x89, 0x0b, 0xa7, 0x02, 0xe9, - 0x95, 0xbf, 0x80, 0x13, 0xf2, 0x8f, 0x38, 0x6e, 0x88, 0x53, 0xb7, 0xec, 0x89, 0x4b, 0xe5, 0x97, - 0x7c, 0xef, 0x7d, 0xef, 0x7d, 0xfe, 0xe6, 0x4d, 0x03, 0x75, 0x71, 0x6a, 0x8c, 0x43, 0x26, 0x98, - 0xb2, 0xe5, 0x32, 0x3e, 0x3a, 0x41, 0x7c, 0x64, 0xc4, 0x7f, 0xbe, 0x3e, 0x70, 0xb0, 0x40, 0x07, - 0xda, 0xbd, 0x60, 0xe8, 0x98, 0x0e, 0xe2, 0xd8, 0x4c, 0x3f, 0x31, 0x5d, 0x46, 0x68, 0x92, 0xa3, - 0x6d, 0xfa, 0xcc, 0x67, 0xf1, 0xa3, 0x19, 0x3d, 0xa5, 0x9f, 0x36, 0xc5, 0xd9, 0x18, 0xf3, 0x24, - 0xd0, 0xff, 0x92, 0xa0, 0x65, 0x71, 0xff, 0x58, 0xb0, 0x10, 0xf7, 0x99, 0x87, 0x95, 0x6d, 0xa8, - 0x72, 0x4c, 0x3d, 0x1c, 0xaa, 0xd2, 0x8e, 0xb4, 0xd7, 0xb0, 0xd3, 0x48, 0x79, 0x08, 0x1b, 0x11, - 0xf1, 0xc0, 0x39, 0x13, 0x78, 0xe0, 0x32, 0x0f, 0xab, 0x77, 0x76, 0xa4, 0xbd, 0x56, 0xef, 0x85, - 0xe9, 0x45, 0xa7, 0xf5, 0x49, 0xf7, 0xd8, 0xea, 0x9d, 0x89, 0xb8, 0x82, 0xdd, 0x8a, 0x70, 0xb3, - 0x28, 0xae, 0xc7, 0x26, 0xa1, 0x8b, 0x55, 0x39, 0xad, 0x17, 0x47, 0x8a, 0x0a, 0x35, 0x67, 0x42, - 0x82, 0x88, 0x68, 0x2d, 0xfe, 0x62, 0x16, 0x2a, 0x8f, 0x61, 0x9b, 0x50, 0x2e, 0x10, 0x15, 0x04, - 0x09, 0x3c, 0x18, 0xe3, 0x70, 0x44, 0x38, 0x27, 0x8c, 0xaa, 0xeb, 0x3b, 0xd2, 0x5e, 0xf3, 0x70, - 0xd7, 0x58, 0x2a, 0x85, 0xd1, 0x75, 0x5d, 0xcc, 0x79, 0x9f, 0xd1, 0x21, 0xf1, 0xed, 0xad, 0x5c, - 0x89, 0x8f, 0xb2, 0x0a, 0xfa, 0xbb, 0xb0, 0x99, 0x9f, 0xd6, 0xc6, 0x7c, 0xcc, 0x28, 0xc7, 0xca, - 0x2e, 0xd4, 0xa2, 0x99, 0x06, 0xc4, 0x8b, 0xc7, 0x5e, 0xeb, 0xc1, 0xf4, 0xa2, 0x53, 0x8d, 0x20, - 0x47, 0xef, 0xd9, 0xd5, 0xe8, 0xab, 0x23, 0x4f, 0xff, 0xf1, 0x0e, 0x6c, 0x5b, 0xdc, 0x3f, 0x9a, - 0x57, 0xee, 0x33, 0x2a, 0x42, 0xe4, 0x8a, 0x42, 0xd5, 0x36, 0x61, 0x1d, 0x79, 0x23, 0x42, 0x63, - 0xb1, 0x1a, 0x76, 0x12, 0xe4, 0xd9, 0xe4, 0x22, 0xb6, 0x28, 0x35, 0x40, 0x0e, 0x0e, 0x52, 0x79, - 0x92, 0x40, 0x79, 0x1b, 0xea, 0x84, 0x12, 0x31, 0x18, 0x71, 0x3f, 0x96, 0xa3, 0xd5, 0x7b, 0xe9, - 0xef, 0x8b, 0x8e, 0x8a, 0xa9, 0xcb, 0x3c, 0x42, 0x7d, 0xf3, 0x4b, 0xce, 0xa8, 0x61, 0xa3, 0x13, - 0x0b, 0x73, 0x8e, 0x7c, 0x6c, 0xd7, 0x22, 0xb4, 0xc5, 0x7d, 0xe5, 0x53, 0x58, 0x1f, 0x4e, 0xa8, - 0xc7, 0xd5, 0xea, 0x8e, 0xbc, 0xd7, 0x3c, 0xdc, 0x36, 0x82, 0xa1, 0x63, 0x44, 0xc6, 0xc9, 0xf4, - 0xeb, 0x33, 0x42, 0x7b, 0x0f, 0xce, 0x2f, 0x3a, 0x95, 0x9f, 0x7f, 0xef, 0xec, 0xfa, 0x44, 0x7c, - 0x31, 0x71, 0x0c, 0x97, 0x8d, 0xcc, 0x80, 0x50, 0x6c, 0x06, 0x43, 0x67, 0x9f, 0x7b, 0x5f, 0x99, - 0x89, 0x79, 0x22, 0x2c, 0xb7, 0x93, 0x8a, 0xfa, 0x87, 0xd0, 0x5e, 0x2e, 0x4b, 0x26, 0xaf, 0x0a, - 0x35, 0xe4, 0x79, 0x21, 0xe6, 0x3c, 0xd5, 0x67, 0x16, 0x2a, 0x0a, 0xac, 0x79, 0x48, 0xa0, 0xc4, - 0x4c, 0x76, 0xfc, 0xac, 0xff, 0x22, 0x83, 0x9e, 0x7f, 0x4b, 0x5d, 0xea, 0xdd, 0x44, 0xf3, 0xff, - 0x85, 0x53, 0xe7, 0xce, 0xa9, 0xe6, 0x9d, 0x93, 0x99, 0xa2, 0x56, 0x64, 0x8a, 0xfa, 0xad, 0x4c, - 0xd1, 0x78, 0xe6, 0xa6, 0xf8, 0x0e, 0x5e, 0xbb, 0xfe, 0x1d, 0xde, 0xe8, 0xfc, 0xe5, 0x5d, 0x74, - 0x67, 0xb9, 0x8b, 0xe4, 0x9c, 0x8b, 0x7e, 0x95, 0x40, 0xb1, 0xb8, 0xff, 0xfe, 0x29, 0x76, 0x27, - 0x25, 0x5c, 0xa3, 0x41, 0xdd, 0x4d, 0x31, 0x69, 0xf5, 0x2c, 0x56, 0x0c, 0x90, 0x23, 0x69, 0xe5, - 0x12, 0xd2, 0x46, 0xc0, 0xb9, 0xac, 0xeb, 0xcf, 0x5c, 0xd6, 0x37, 0x40, 0xfb, 0xf7, 0x50, 0x99, - 0x8c, 0x33, 0x1d, 0xa4, 0x9c, 0x0e, 0x4f, 0x12, 0x1d, 0x2c, 0xe2, 0x87, 0xe8, 0x3f, 0xea, 0x50, - 0x6a, 0x6f, 0x3d, 0x82, 0xe6, 0x28, 0xe1, 0x8a, 0xfd, 0xb8, 0x56, 0x42, 0x34, 0x48, 0x13, 0x2c, - 0xee, 0xa7, 0x03, 0x2e, 0x74, 0xbb, 0x72, 0x40, 0x04, 0x1b, 0x16, 0xf7, 0x3f, 0x1e, 0x7b, 0x48, - 0xe0, 0x6e, 0x7c, 0x4a, 0x8a, 0x66, 0xbb, 0x07, 0x0d, 0x8a, 0x4f, 0x06, 0xf9, 0x8d, 0x5c, 0xa7, - 0xf8, 0x24, 0x49, 0xca, 0x0f, 0x2e, 0x5f, 0x1d, 0x5c, 0x57, 0xe3, 0xc5, 0x9f, 0xa3, 0x98, 0x35, - 0xa4, 0xf7, 0xe1, 0x39, 0x8b, 0xfb, 0xfd, 0x00, 0xa3, 0x70, 0x35, 0xf7, 0xaa, 0xf2, 0x77, 0x61, - 0xeb, 0x4a, 0x91, 0xac, 0xfa, 0xf7, 0x12, 0xdc, 0xcd, 0x88, 0x67, 0x62, 0x1c, 0x0b, 0x24, 0x26, - 0xfc, 0x56, 0x2f, 0xf0, 0x11, 0x54, 0x79, 0x9c, 0x1d, 0xb7, 0xb0, 0x71, 0x78, 0xbf, 0x60, 0x41, - 0x5d, 0xa5, 0xb2, 0xd3, 0x24, 0xfd, 0x65, 0xe8, 0x14, 0x74, 0x33, 0xeb, 0xf8, 0xf0, 0x49, 0x0d, - 0xe4, 0x68, 0xb3, 0x7c, 0x06, 0x8d, 0xf9, 0xff, 0x14, 0x45, 0x7b, 0x30, 0xbf, 0x20, 0xb4, 0x07, - 0x25, 0x40, 0x99, 0x0f, 0xbe, 0x81, 0x17, 0x97, 0x5d, 0x09, 0xfb, 0xc5, 0x35, 0x96, 0xc0, 0xb5, - 0xb7, 0x6e, 0x04, 0xcf, 0xc8, 0x7f, 0x92, 0xa0, 0x73, 0xdd, 0xe5, 0xf4, 0x4e, 0x89, 0x69, 0x96, - 0xa7, 0x6a, 0xdd, 0x5b, 0xa7, 0x66, 0x1d, 0x32, 0x78, 0x7e, 0x71, 0xef, 0xbd, 0x5a, 0x5c, 0x75, - 0x01, 0xaa, 0x1d, 0x94, 0x86, 0xe6, 0x09, 0x17, 0x17, 0xcc, 0x0a, 0xc2, 0x05, 0xe8, 0x2a, 0xc2, - 0xa2, 0x45, 0xe0, 0x42, 0x33, 0x7f, 0xe2, 0xef, 0x17, 0x57, 0xc8, 0xc1, 0xb4, 0xfd, 0x52, 0xb0, - 0x8c, 0xe4, 0x73, 0x80, 0xdc, 0xc9, 0x7e, 0xa5, 0x38, 0x79, 0x8e, 0xd2, 0x5e, 0x2f, 0x83, 0xca, - 0x18, 0xbe, 0x85, 0xcd, 0xa5, 0x87, 0xdb, 0xb8, 0xae, 0xd1, 0xab, 0x78, 0xed, 0xe1, 0xcd, 0xf0, - 0x33, 0xfe, 0xde, 0x07, 0xe7, 0x7f, 0xb6, 0x2b, 0xe7, 0xd3, 0xb6, 0xf4, 0x74, 0xda, 0x96, 0xfe, - 0x98, 0xb6, 0xa5, 0x1f, 0x2e, 0xdb, 0x95, 0xa7, 0x97, 0xed, 0xca, 0x6f, 0x97, 0xed, 0xca, 0xe3, - 0xfd, 0xa2, 0x8b, 0xe9, 0xd4, 0x8c, 0x58, 0x4c, 0x42, 0x05, 0x0e, 0x29, 0x0a, 0x92, 0x8b, 0xca, - 0xa9, 0xc6, 0x3f, 0x29, 0xde, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x12, 0x0b, 0x9c, 0xb5, - 0x0c, 0x00, 0x00, + // 927 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0xcf, 0x6f, 0xe3, 0x44, + 0x14, 0x8e, 0x37, 0x69, 0x7e, 0xbc, 0x84, 0xb2, 0x32, 0x6d, 0xd7, 0x78, 0x51, 0x52, 0xdc, 0x5d, + 0xa9, 0xb0, 0xd4, 0xa6, 0x45, 0x2c, 0x42, 0x88, 0x43, 0x12, 0x38, 0xf4, 0x60, 0x84, 0x5c, 0x21, + 0xc4, 0x4a, 0x28, 0x8c, 0xed, 0x89, 0x31, 0x24, 0x33, 0x91, 0x67, 0x42, 0x5b, 0x21, 0xc1, 0x3f, + 0x80, 0x10, 0xff, 0x01, 0x77, 0xc4, 0x95, 0x7f, 0x80, 0x53, 0x8f, 0x7b, 0xe4, 0x54, 0x20, 0xbd, + 0x72, 0x47, 0xe2, 0x84, 0x3c, 0x76, 0x9c, 0x69, 0x88, 0xd3, 0x64, 0xd9, 0xd3, 0x5e, 0x2a, 0x3f, + 0xe7, 0x7b, 0xdf, 0xf7, 0xde, 0x9b, 0x6f, 0x9e, 0x0b, 0x55, 0x7e, 0x66, 0x8e, 0x22, 0xca, 0xa9, + 0xba, 0xed, 0x51, 0x36, 0x3c, 0x45, 0x6c, 0x68, 0x8a, 0x3f, 0x5f, 0x1d, 0xba, 0x98, 0xa3, 0x43, + 0xfd, 0xee, 0xa0, 0xef, 0x5a, 0x2e, 0x62, 0xd8, 0x4a, 0xdf, 0x58, 0x1e, 0x0d, 0x49, 0x92, 0xa3, + 0x6f, 0x05, 0x34, 0xa0, 0xe2, 0xd1, 0x8a, 0x9f, 0xd2, 0xb7, 0x75, 0x7e, 0x3e, 0xc2, 0x2c, 0x09, + 0x8c, 0xbf, 0x14, 0x68, 0xd8, 0x2c, 0x38, 0xe1, 0x34, 0xc2, 0x5d, 0xea, 0x63, 0x75, 0x07, 0xca, + 0x0c, 0x13, 0x1f, 0x47, 0x9a, 0xb2, 0xab, 0xec, 0xd7, 0x9c, 0x34, 0x52, 0x1f, 0xc2, 0x66, 0x2c, + 0xdc, 0x73, 0xcf, 0x39, 0xee, 0x79, 0xd4, 0xc7, 0xda, 0xad, 0x5d, 0x65, 0xbf, 0xd1, 0xb9, 0x3d, + 0xb9, 0x6c, 0x35, 0x3e, 0x6e, 0x9f, 0xd8, 0x9d, 0x73, 0x2e, 0x18, 0x9c, 0x46, 0x8c, 0x9b, 0x46, + 0x82, 0x8f, 0x8e, 0x23, 0x0f, 0x6b, 0xc5, 0x94, 0x4f, 0x44, 0xaa, 0x06, 0x15, 0x77, 0x1c, 0x0e, + 0x62, 0xa1, 0x92, 0xf8, 0x61, 0x1a, 0xaa, 0x8f, 0x60, 0x27, 0x24, 0x8c, 0x23, 0xc2, 0x43, 0xc4, + 0x71, 0x6f, 0x84, 0xa3, 0x61, 0xc8, 0x58, 0x48, 0x89, 0xb6, 0xb1, 0xab, 0xec, 0xd7, 0x8f, 0xf6, + 0xcc, 0x85, 0xa3, 0x30, 0xdb, 0x9e, 0x87, 0x19, 0xeb, 0x52, 0xd2, 0x0f, 0x03, 0x67, 0x5b, 0xa2, + 0xf8, 0x30, 0x63, 0x30, 0xde, 0x81, 0x2d, 0xb9, 0x5b, 0x07, 0xb3, 0x11, 0x25, 0x0c, 0xab, 0x7b, + 0x50, 0x89, 0x7b, 0xea, 0x85, 0xbe, 0x68, 0xbb, 0xd4, 0x81, 0xc9, 0x65, 0xab, 0x1c, 0x43, 0x8e, + 0xdf, 0x73, 0xca, 0xf1, 0x4f, 0xc7, 0xbe, 0xf1, 0xb7, 0x02, 0x3b, 0x36, 0x0b, 0x8e, 0x67, 0xcc, + 0x5d, 0x4a, 0x78, 0x84, 0x3c, 0x9e, 0x3b, 0xb5, 0x2d, 0xd8, 0x40, 0xfe, 0x30, 0x24, 0x62, 0x58, + 0x35, 0x27, 0x09, 0x64, 0xb5, 0x62, 0x9e, 0x5a, 0x9c, 0x3a, 0x40, 0x2e, 0x1e, 0xa4, 0xe3, 0x49, + 0x02, 0xf5, 0x45, 0xa8, 0x86, 0x24, 0xe4, 0xbd, 0x21, 0x0b, 0xc4, 0x38, 0x1a, 0x4e, 0x25, 0x8e, + 0x6d, 0x16, 0xa8, 0x9f, 0xc0, 0x46, 0x7f, 0x4c, 0x7c, 0xa6, 0x95, 0x77, 0x8b, 0xfb, 0xf5, 0xa3, + 0x1d, 0x73, 0xd0, 0x77, 0xcd, 0xd8, 0x1a, 0xd9, 0x84, 0xba, 0x34, 0x24, 0x9d, 0x07, 0x17, 0x97, + 0xad, 0xc2, 0x4f, 0xbf, 0xb7, 0xf6, 0x82, 0x90, 0x7f, 0x3e, 0x76, 0x4d, 0x8f, 0x0e, 0xad, 0x41, + 0x48, 0xb0, 0x35, 0xe8, 0xbb, 0x07, 0xcc, 0xff, 0xd2, 0x4a, 0xec, 0x11, 0x63, 0x99, 0x93, 0x30, + 0x1a, 0x1f, 0x40, 0x73, 0x71, 0xe3, 0xd9, 0x00, 0x35, 0xa8, 0x20, 0xdf, 0x8f, 0x30, 0x63, 0xe9, + 0x04, 0xa6, 0xa1, 0xaa, 0x42, 0xc9, 0x47, 0x1c, 0x25, 0x76, 0x71, 0xc4, 0xb3, 0xf1, 0x6b, 0x11, + 0x0c, 0xf9, 0x1c, 0xda, 0xc4, 0x5f, 0x67, 0xaa, 0xcf, 0x84, 0x17, 0x67, 0xde, 0x28, 0xcb, 0xde, + 0xc8, 0x8e, 0xbd, 0x22, 0x1f, 0xfb, 0x5b, 0xd2, 0xb1, 0x57, 0x45, 0xaf, 0x2f, 0xfd, 0x73, 0xd9, + 0xd2, 0x30, 0xf1, 0xa8, 0x1f, 0x92, 0xc0, 0xfa, 0x82, 0x51, 0x62, 0x3a, 0xe8, 0xd4, 0xc6, 0x8c, + 0xa1, 0x00, 0x2f, 0x30, 0x45, 0xed, 0xa9, 0x9b, 0xe2, 0x5b, 0x78, 0xf5, 0xe6, 0x33, 0x5c, 0xeb, + 0x86, 0xc9, 0x2e, 0xba, 0xb5, 0xd8, 0x45, 0x45, 0xc9, 0x45, 0xbf, 0x28, 0xa0, 0xda, 0x2c, 0x78, + 0xff, 0x0c, 0x7b, 0xe3, 0x15, 0x5c, 0xa3, 0x43, 0xd5, 0x4b, 0x31, 0x29, 0x7b, 0x16, 0xab, 0xb7, + 0xa1, 0x18, 0x8f, 0x36, 0x61, 0x8f, 0x1f, 0x67, 0x83, 0x2b, 0x3d, 0xf5, 0xc1, 0xbd, 0x0e, 0xfa, + 0x7f, 0xcb, 0xce, 0x06, 0x35, 0xed, 0x54, 0x91, 0x3a, 0xfd, 0x3e, 0xe9, 0xd4, 0x0e, 0x83, 0x08, + 0xfd, 0xcf, 0x4e, 0x57, 0xda, 0x3d, 0x2d, 0xa8, 0x0f, 0x13, 0x2d, 0xe1, 0xb8, 0x92, 0x28, 0x05, + 0xd2, 0x57, 0x36, 0x0b, 0xd2, 0x16, 0xe6, 0xea, 0x59, 0xda, 0x02, 0x82, 0x4d, 0x9b, 0x05, 0x1f, + 0x8d, 0x7c, 0xc4, 0x71, 0x5b, 0x38, 0x3d, 0xaf, 0xfa, 0xbb, 0x50, 0x23, 0xf8, 0xb4, 0x27, 0xef, + 0xcd, 0x2a, 0xc1, 0xa7, 0x49, 0x92, 0xdc, 0x5a, 0xf1, 0x7a, 0x6b, 0x86, 0x26, 0xd6, 0xb3, 0x24, + 0x31, 0x2d, 0xc8, 0xe8, 0xc2, 0x73, 0x36, 0x0b, 0xba, 0x03, 0x8c, 0xa2, 0xe5, 0xda, 0xcb, 0xe8, + 0xef, 0xc0, 0xf6, 0x35, 0x92, 0x8c, 0xfd, 0x3b, 0x05, 0xee, 0x64, 0xc2, 0xd3, 0x61, 0x9c, 0x70, + 0xc4, 0xc7, 0xec, 0x89, 0x8e, 0xe8, 0x5d, 0x28, 0x33, 0x91, 0x2d, 0x4a, 0xd8, 0x3c, 0xba, 0x9f, + 0xb3, 0x64, 0xae, 0x4b, 0x39, 0x69, 0x92, 0xf1, 0x32, 0xb4, 0x72, 0xaa, 0x99, 0x56, 0x7c, 0xf4, + 0x73, 0x05, 0x8a, 0xf1, 0x76, 0xf8, 0x14, 0x6a, 0xb3, 0x2f, 0x7f, 0xde, 0x2e, 0x93, 0x2f, 0xb9, + 0xfe, 0x60, 0x05, 0x50, 0xe6, 0x83, 0xaf, 0xe1, 0x85, 0x45, 0x6b, 0xfd, 0x20, 0x9f, 0x63, 0x01, + 0x5c, 0x7f, 0x73, 0x2d, 0x78, 0x26, 0xfe, 0xa3, 0x02, 0xad, 0x9b, 0x3e, 0x30, 0x6f, 0xaf, 0xd0, + 0xcd, 0xe2, 0x54, 0xbd, 0xfd, 0xc4, 0xa9, 0x59, 0x85, 0x14, 0x9e, 0x9f, 0xdf, 0x5d, 0xaf, 0xe4, + 0xb3, 0xce, 0x41, 0xf5, 0xc3, 0x95, 0xa1, 0xb2, 0xe0, 0xfc, 0x0a, 0x59, 0x22, 0x38, 0x07, 0x5d, + 0x26, 0x98, 0xb7, 0x08, 0x3c, 0xa8, 0xcb, 0x37, 0xfe, 0x7e, 0x3e, 0x83, 0x04, 0xd3, 0x0f, 0x56, + 0x82, 0x65, 0x22, 0x9f, 0x01, 0x48, 0x37, 0xfb, 0x5e, 0x7e, 0xf2, 0x0c, 0xa5, 0xbf, 0xb6, 0x0a, + 0x2a, 0x53, 0xf8, 0x06, 0xb6, 0x16, 0x5e, 0x6e, 0xf3, 0xa6, 0x42, 0xaf, 0xe3, 0xf5, 0x87, 0xeb, + 0xe1, 0xa7, 0xfa, 0x9d, 0xce, 0xc5, 0x9f, 0xcd, 0xc2, 0xc5, 0xa4, 0xa9, 0x3c, 0x9e, 0x34, 0x95, + 0x3f, 0x26, 0x4d, 0xe5, 0x87, 0xab, 0x66, 0xe1, 0xf1, 0x55, 0xb3, 0xf0, 0xdb, 0x55, 0xb3, 0xf0, + 0xe8, 0x5e, 0xde, 0xa7, 0xe7, 0xcc, 0x8a, 0x55, 0x92, 0x2f, 0x90, 0x5b, 0x16, 0xff, 0xef, 0xbf, + 0xf1, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x31, 0x2f, 0x86, 0x4f, 0x52, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -816,7 +818,6 @@ type MsgClient interface { StoreCode(ctx context.Context, in *MsgStoreCode, opts ...grpc.CallOption) (*MsgStoreCodeResponse, error) // Instantiate creates a new smart contract instance for the given code id. InstantiateContract(ctx context.Context, in *MsgInstantiateContract, opts ...grpc.CallOption) (*MsgInstantiateContractResponse, error) - // Store Wasm code and Instantiate a new contract StoreCodeAndInstantiateContract(ctx context.Context, in *MsgStoreCodeAndInstantiateContract, opts ...grpc.CallOption) (*MsgStoreCodeAndInstantiateContractResponse, error) // Execute submits the given message data to a smart contract ExecuteContract(ctx context.Context, in *MsgExecuteContract, opts ...grpc.CallOption) (*MsgExecuteContractResponse, error) @@ -916,7 +917,6 @@ type MsgServer interface { StoreCode(context.Context, *MsgStoreCode) (*MsgStoreCodeResponse, error) // Instantiate creates a new smart contract instance for the given code id. InstantiateContract(context.Context, *MsgInstantiateContract) (*MsgInstantiateContractResponse, error) - // Store Wasm code and Instantiate a new contract StoreCodeAndInstantiateContract(context.Context, *MsgStoreCodeAndInstantiateContract) (*MsgStoreCodeAndInstantiateContractResponse, error) // Execute submits the given message data to a smart contract ExecuteContract(context.Context, *MsgExecuteContract) (*MsgExecuteContractResponse, error) @@ -1517,7 +1517,7 @@ func (m *MsgExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } } if len(m.Msg) > 0 { @@ -3427,7 +3427,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { m.Msg = []byte{} } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Funds", wireType) } diff --git a/x/wasm/internal/types/tx.proto b/x/wasm/types/tx.proto similarity index 94% rename from x/wasm/internal/types/tx.proto rename to x/wasm/types/tx.proto index e39fdcda6b..bc2a48b6e4 100644 --- a/x/wasm/internal/types/tx.proto +++ b/x/wasm/types/tx.proto @@ -5,7 +5,7 @@ import "lfb/base/v1beta1/coin.proto"; import "gogoproto/gogo.proto"; import "types.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; option (gogoproto.goproto_getters_all) = false; // Msg defines the wasm Msg service. @@ -14,7 +14,6 @@ service Msg { rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); // Instantiate creates a new smart contract instance for the given code id. rpc InstantiateContract(MsgInstantiateContract) returns (MsgInstantiateContractResponse); - // Store Wasm code and Instantiate a new contract rpc StoreCodeAndInstantiateContract(MsgStoreCodeAndInstantiateContract) returns (MsgStoreCodeAndInstantiateContractResponse); // Execute submits the given message data to a smart contract @@ -35,11 +34,13 @@ message MsgStoreCode { string sender = 1; // WASMByteCode can be raw or gzip compressed bytes wasm_byte_code = 2 [(gogoproto.customname) = "WASMByteCode"]; - // Source is a valid absolute HTTPS URI to the contract's source code, optional + // Source is a valid absolute HTTPS URI to the contract's source code, + // optional string source = 3; // Builder is a valid docker image name with tag, optional string builder = 4; - // InstantiatePermission access control to apply on contract creation, optional + // InstantiatePermission access control to apply on contract creation, + // optional AccessConfig instantiate_permission = 5; } // MsgStoreCodeResponse returns store result data. @@ -48,7 +49,8 @@ message MsgStoreCodeResponse { uint64 code_id = 1 [(gogoproto.customname) = "CodeID"]; } -// MsgInstantiateContract create a new smart contract instance for the given code id. +// MsgInstantiateContract create a new smart contract instance for the given +// code id. message MsgInstantiateContract { // Sender is the that actor that signed the messages string sender = 1; @@ -59,7 +61,7 @@ message MsgInstantiateContract { // Label is optional metadata to be stored with a contract instance. string label = 4; // InitMsg json encoded message to be passed to the contract on instantiation - bytes init_msg = 5 [(gogoproto.casttype) = "encoding/json.RawMessage"]; + bytes init_msg = 5; // Funds coins that are transferred to the contract on instantiation repeated lfb.base.v1beta1.Coin funds = 6 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/line/lfb-sdk/types.Coins"]; @@ -111,9 +113,9 @@ message MsgExecuteContract { // Contract is the address of the smart contract string contract = 2; // Msg json encoded message to be passed to the contract - bytes msg = 3 [(gogoproto.casttype) = "encoding/json.RawMessage"]; + bytes msg = 3; // Funds coins that are transferred to the contract on execution - repeated lfb.base.v1beta1.Coin funds = 5 + repeated lfb.base.v1beta1.Coin funds = 4 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/line/lfb-sdk/types.Coins"]; } @@ -132,7 +134,7 @@ message MsgMigrateContract { // CodeID references the new WASM code uint64 code_id = 3 [(gogoproto.customname) = "CodeID"]; // MigrateMsg json encoded message to be passed to the contract on migration - bytes migrate_msg = 4 [(gogoproto.casttype) = "encoding/json.RawMessage"]; + bytes migrate_msg = 4; } // MsgMigrateContractResponse returns contract migration result data. diff --git a/x/wasm/internal/types/tx_test.go b/x/wasm/types/tx_test.go similarity index 100% rename from x/wasm/internal/types/tx_test.go rename to x/wasm/types/tx_test.go diff --git a/x/wasm/internal/types/types.go b/x/wasm/types/types.go similarity index 73% rename from x/wasm/internal/types/types.go rename to x/wasm/types/types.go index 0c6a1a9625..2031aaa4f3 100644 --- a/x/wasm/internal/types/types.go +++ b/x/wasm/types/types.go @@ -3,11 +3,14 @@ package types import ( "encoding/json" "fmt" + "reflect" "github.com/gogo/protobuf/jsonpb" + codectypes "github.com/line/lfb-sdk/codec/types" sdk "github.com/line/lfb-sdk/types" sdkerrors "github.com/line/lfb-sdk/types/errors" wasmvmtypes "github.com/line/wasmvm/types" + "google.golang.org/protobuf/proto" ) const ( @@ -108,6 +111,15 @@ func NewContractInfo(codeID uint64, creator, admin sdk.AccAddress, label string, Status: status, } } + +// validatable is an optional interface that can be implemented by an ContractInfoExtension to enable validation +type validatable interface { + ValidateBasic() error +} + +// ValidateBasic does syntax checks on the data. If an extension is set and has the `ValidateBasic() error` method, then +// the method is called as well. It is recommend to implement `ValidateBasic` so that the data is verified in the setter +// but also in the genesis import process. func (c *ContractInfo) ValidateBasic() error { if c.CodeID == 0 { return sdkerrors.Wrap(ErrEmpty, "code id") @@ -133,6 +145,62 @@ func (c *ContractInfo) ValidateBasic() error { if !found || c.Status == ContractStatusUnspecified { return sdkerrors.Wrap(ErrInvalidMsg, "invalid status") } + if c.Extension == nil { + return nil + } + + e, ok := c.Extension.GetCachedValue().(validatable) + if !ok { + return nil + } + if err := e.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "extension") + } + return nil +} + +// SetExtension set new extension data. Calls `ValidateBasic() error` on non nil values when method is implemented by +// the extension. +func (c *ContractInfo) SetExtension(ext ContractInfoExtension) error { + if ext == nil { + c.Extension = nil + return nil + } + if e, ok := ext.(validatable); ok { + if err := e.ValidateBasic(); err != nil { + return err + } + } + any, err := codectypes.NewAnyWithValue(ext) + if err != nil { + return sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error()) + } + + c.Extension = any + return nil +} + +// ReadExtension copies the extension value to the pointer passed as argument so that there is no need to cast +// For example with a custom extension of type `MyContractDetails` it will look as following: +// var d MyContractDetails +// if err := info.ReadExtension(&d); err != nil { +// return nil, sdkerrors.Wrap(err, "extension") +// } +func (c *ContractInfo) ReadExtension(e ContractInfoExtension) error { + rv := reflect.ValueOf(e) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidType, "not a pointer") + } + if c.Extension == nil { + return nil + } + + cached := c.Extension.GetCachedValue() + elem := reflect.ValueOf(cached).Elem() + if !elem.Type().AssignableTo(rv.Elem().Type()) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "extension is of type %s but argument of %s", elem.Type(), rv.Elem().Type()) + } + rv.Elem().Set(elem) return nil } @@ -178,6 +246,23 @@ func (c *ContractInfo) AdminAddr() sdk.AccAddress { return admin } +// ContractInfoExtension defines the extension point for custom data to be stored with a contract info +type ContractInfoExtension interface { + proto.Message + String() string +} + +var _ codectypes.UnpackInterfacesMessage = &ContractInfo{} + +// UnpackInterfaces implements codectypes.UnpackInterfaces +func (m *ContractInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + var details ContractInfoExtension + if err := unpacker.UnpackAny(m.Extension, &details); err != nil { + return err + } + return codectypes.UnpackInterfaces(details, unpacker) +} + // NewAbsoluteTxPosition gets a block position from the context func NewAbsoluteTxPosition(ctx sdk.Context) *AbsoluteTxPosition { // we must safely handle nil gas meters @@ -227,17 +312,15 @@ func NewEnv(ctx sdk.Context, contractAddr sdk.AccAddress) wasmvmtypes.Env { if ctx.BlockHeight() < 0 { panic("Block height must never be negative") } - sec := ctx.BlockTime().Unix() - if sec < 0 { - panic("Block (unix) time must never be negative ") + nano := ctx.BlockTime().UnixNano() + if nano < 1 { + panic("Block (unix) time must never be empty or negative ") } - nano := ctx.BlockTime().Nanosecond() env := wasmvmtypes.Env{ Block: wasmvmtypes.BlockInfo{ - Height: uint64(ctx.BlockHeight()), - Time: uint64(sec), - TimeNanos: uint64(nano), - ChainID: ctx.ChainID(), + Height: uint64(ctx.BlockHeight()), + Time: uint64(nano), + ChainID: ctx.ChainID(), }, Contract: wasmvmtypes.ContractInfo{ Address: contractAddr.String(), diff --git a/x/wasm/internal/types/types.pb.go b/x/wasm/types/types.pb.go similarity index 86% rename from x/wasm/internal/types/types.pb.go rename to x/wasm/types/types.pb.go index 1bd3d925cf..e2a49647b1 100644 --- a/x/wasm/internal/types/types.pb.go +++ b/x/wasm/types/types.pb.go @@ -9,7 +9,9 @@ import ( fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" + types "github.com/line/lfb-sdk/codec/types" github_com_line_ostracon_libs_bytes "github.com/line/ostracon/libs/bytes" + _ "github.com/regen-network/cosmos-proto" io "io" math "math" math_bits "math/bits" @@ -248,7 +250,8 @@ type CodeInfo struct { CodeHash []byte `protobuf:"bytes,1,opt,name=code_hash,json=codeHash,proto3" json:"code_hash,omitempty"` // Creator address who initially stored the code Creator string `protobuf:"bytes,2,opt,name=creator,proto3" json:"creator,omitempty"` - // Source is a valid absolute HTTPS URI to the contract's source code, optional + // Source is a valid absolute HTTPS URI to the contract's source code, + // optional Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` // Builder is a valid docker image name with tag, optional Builder string `protobuf:"bytes,4,opt,name=builder,proto3" json:"builder,omitempty"` @@ -300,11 +303,15 @@ type ContractInfo struct { // Label is optional metadata to be stored with a contract instance. Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` // Created Tx position when the contract was instantiated. - // This data should kept internal and not be exposed via query results. Just use for sorting + // This data should kept internal and not be exposed via query results. Just + // use for sorting Created *AbsoluteTxPosition `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` IBCPortID string `protobuf:"bytes,6,opt,name=ibc_port_id,json=ibcPortId,proto3" json:"ibc_port_id,omitempty"` // Status is a status of a contract Status ContractStatus `protobuf:"varint,7,opt,name=status,proto3,enum=cosmwasm.wasm.v1beta1.ContractStatus" json:"status,omitempty"` + // Extension is an extension point to store custom metadata within the + // persistence model. + Extension *types.Any `protobuf:"bytes,8,opt,name=extension,proto3" json:"extension,omitempty"` } func (m *ContractInfo) Reset() { *m = ContractInfo{} } @@ -383,11 +390,13 @@ func (m *ContractCodeHistoryEntry) XXX_DiscardUnknown() { var xxx_messageInfo_ContractCodeHistoryEntry proto.InternalMessageInfo -// AbsoluteTxPosition is a unique transaction position that allows for global ordering of transactions. +// AbsoluteTxPosition is a unique transaction position that allows for global +// ordering of transactions. type AbsoluteTxPosition struct { // BlockHeight is the block the contract was created at BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` - // TxIndex is a monotonic counter within the block (actual transaction index, or gas consumed) + // TxIndex is a monotonic counter within the block (actual transaction index, + // or gas consumed) TxIndex uint64 `protobuf:"varint,2,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` } @@ -482,92 +491,95 @@ func init() { func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } var fileDescriptor_d938547f84707355 = []byte{ - // 1347 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xf6, 0x3a, 0x89, 0x93, 0x4c, 0xdc, 0xd4, 0x9d, 0x26, 0xa9, 0xe3, 0xb6, 0xb6, 0xbb, 0xa5, - 0x22, 0x6d, 0x53, 0xbb, 0x0d, 0x88, 0x42, 0xa4, 0x22, 0xd9, 0x6b, 0xd3, 0x2c, 0x22, 0x76, 0x34, - 0x76, 0xda, 0x06, 0x09, 0xad, 0xc6, 0xbb, 0x13, 0x67, 0xe8, 0x7a, 0xc7, 0xda, 0x19, 0xa7, 0x76, - 0x4f, 0x1c, 0x91, 0xb9, 0x20, 0x4e, 0x1c, 0x30, 0x42, 0x02, 0xa1, 0x9e, 0xf9, 0x2b, 0x2a, 0x24, - 0xa4, 0x1e, 0x39, 0x59, 0x90, 0x5e, 0xe0, 0x9a, 0x63, 0x4f, 0x68, 0x67, 0xd7, 0xb5, 0x93, 0xfe, - 0x88, 0xb9, 0x58, 0xfb, 0x66, 0xde, 0xf7, 0xbd, 0xfd, 0xbe, 0xf7, 0x66, 0xd6, 0x60, 0x4e, 0x74, - 0x9a, 0x84, 0x67, 0x9a, 0x2e, 0x13, 0x0c, 0x2e, 0x9a, 0x8c, 0x37, 0x1e, 0x61, 0xde, 0xc8, 0xc8, - 0x9f, 0xfd, 0x5b, 0x35, 0x22, 0xf0, 0xad, 0xc4, 0x42, 0x9d, 0xd5, 0x99, 0xcc, 0xc8, 0x7a, 0x4f, - 0x7e, 0xb2, 0x5a, 0x03, 0xa7, 0x73, 0xa6, 0x49, 0x38, 0xaf, 0x76, 0x9a, 0x64, 0x0b, 0xbb, 0xb8, - 0x01, 0x75, 0x30, 0xb5, 0x8f, 0xed, 0x16, 0x89, 0x2b, 0x69, 0x65, 0x65, 0x7e, 0xed, 0x52, 0xe6, - 0xb5, 0x7c, 0x99, 0x21, 0x2c, 0x1f, 0x3b, 0xec, 0xa7, 0xa2, 0x1d, 0xdc, 0xb0, 0xd7, 0x55, 0x89, - 0x54, 0x91, 0xcf, 0xb0, 0x3e, 0xf9, 0xfd, 0x4f, 0x29, 0x45, 0xfd, 0x41, 0x01, 0x51, 0x3f, 0x5b, - 0x63, 0xce, 0x2e, 0xad, 0xc3, 0x07, 0x00, 0x34, 0x89, 0xdb, 0xa0, 0x9c, 0x53, 0xe6, 0x8c, 0x5f, - 0x66, 0xf1, 0xb0, 0x9f, 0x3a, 0xe3, 0x97, 0x19, 0xc2, 0x55, 0x34, 0xc2, 0x05, 0x57, 0xc1, 0x34, - 0xb6, 0x2c, 0x97, 0x70, 0x1e, 0x0f, 0xa7, 0x95, 0x95, 0xd9, 0x3c, 0x3c, 0xec, 0xa7, 0xe6, 0x7d, - 0x4c, 0xb0, 0xa1, 0xa2, 0x41, 0x4a, 0xf0, 0x7a, 0x3f, 0x4e, 0x81, 0x88, 0x54, 0xce, 0xa1, 0x00, - 0xd0, 0x64, 0x16, 0x31, 0x5a, 0x4d, 0x9b, 0x61, 0xcb, 0xc0, 0xb2, 0xb6, 0x7c, 0xc1, 0xb9, 0xb5, - 0xcb, 0x6f, 0x7d, 0x41, 0x5f, 0x59, 0xfe, 0xd2, 0xd3, 0x7e, 0x2a, 0x74, 0xd8, 0x4f, 0x2d, 0xfb, - 0x25, 0x5f, 0x25, 0x53, 0x51, 0xcc, 0x5b, 0xdc, 0x96, 0x6b, 0x3e, 0x14, 0x7e, 0xa7, 0x80, 0x24, - 0x75, 0xb8, 0xc0, 0x8e, 0xa0, 0x58, 0x10, 0xc3, 0x22, 0xbb, 0xb8, 0x65, 0x0b, 0x63, 0xc4, 0xa3, - 0xf0, 0xb8, 0x1e, 0x5d, 0x3d, 0xec, 0xa7, 0xae, 0xf8, 0xc5, 0xdf, 0x4e, 0xa9, 0xa2, 0x0b, 0x23, - 0x09, 0x05, 0x7f, 0x7f, 0x6b, 0xe8, 0xe4, 0x57, 0x0a, 0x58, 0x32, 0x99, 0x23, 0x5c, 0x6c, 0x0a, - 0x83, 0x0b, 0x2c, 0x5a, 0x7c, 0xe0, 0xc7, 0xc4, 0xf8, 0x7e, 0x5c, 0x09, 0xfc, 0xb8, 0x38, 0xf0, - 0xe3, 0x75, 0x84, 0x2a, 0x5a, 0x18, 0x6c, 0x54, 0xe4, 0x7a, 0xe0, 0xcb, 0xa7, 0x00, 0x36, 0x70, - 0xdb, 0xf0, 0xd8, 0x0d, 0xe9, 0x24, 0xa7, 0x8f, 0x49, 0x7c, 0x32, 0xad, 0xac, 0x4c, 0xe6, 0x2f, - 0x0e, 0x4d, 0x7e, 0x35, 0x47, 0x45, 0xa7, 0x1b, 0xb8, 0x7d, 0x1f, 0xf3, 0x86, 0xc6, 0x2c, 0x52, - 0xa1, 0x8f, 0x09, 0xfc, 0x08, 0xcc, 0xd7, 0x31, 0x37, 0x1a, 0x2d, 0x5b, 0xd0, 0xa6, 0x4d, 0x89, - 0x1b, 0x9f, 0x92, 0x3c, 0x23, 0xf3, 0xe1, 0xf1, 0xd4, 0x31, 0x57, 0xd1, 0xa9, 0x3a, 0xe6, 0x9b, - 0x2f, 0x13, 0xe1, 0x1d, 0x70, 0xca, 0x77, 0xca, 0x24, 0x86, 0xc9, 0xb8, 0x88, 0x47, 0x24, 0x32, - 0x7e, 0xd8, 0x4f, 0x2d, 0x8c, 0x3a, 0x1d, 0x6c, 0xab, 0x28, 0x3a, 0x88, 0x35, 0xc6, 0x05, 0x5c, - 0x07, 0x51, 0x93, 0x35, 0x9a, 0xd4, 0x0e, 0xd0, 0xd3, 0x12, 0x7d, 0xee, 0xb0, 0x9f, 0x3a, 0x3b, - 0x30, 0x65, 0xb8, 0xab, 0xa2, 0xb9, 0x20, 0xf4, 0xb0, 0x72, 0x40, 0x43, 0xea, 0x1f, 0x0a, 0x98, - 0xf1, 0x84, 0xe8, 0xce, 0x2e, 0x83, 0xe7, 0xc1, 0xac, 0xd4, 0xb9, 0x87, 0xf9, 0x9e, 0x9c, 0xcc, - 0x28, 0x9a, 0xf1, 0x16, 0x36, 0x30, 0xdf, 0x83, 0x71, 0x30, 0x6d, 0xba, 0x04, 0x0b, 0xe6, 0xfa, - 0xe3, 0x8f, 0x06, 0x21, 0x5c, 0x02, 0x11, 0xce, 0x5a, 0xae, 0x49, 0x64, 0xf7, 0x66, 0x51, 0x10, - 0x79, 0x88, 0x5a, 0x8b, 0xda, 0x16, 0x71, 0xa5, 0xb1, 0xb3, 0x68, 0x10, 0xc2, 0x07, 0x00, 0x8e, - 0x4e, 0x90, 0x29, 0x1b, 0x2a, 0x5d, 0x1b, 0xb3, 0xf7, 0x93, 0x5e, 0xef, 0xd1, 0x99, 0x11, 0x12, - 0x7f, 0x43, 0xfd, 0x2d, 0x0c, 0xa2, 0x5a, 0xd0, 0x70, 0xa9, 0xe9, 0x32, 0x98, 0x96, 0x9a, 0xa8, - 0x25, 0x15, 0x4d, 0xe6, 0xc1, 0x41, 0x3f, 0x15, 0x91, 0x92, 0x0b, 0x28, 0xe2, 0x6d, 0xe9, 0xd6, - 0x5b, 0xb4, 0x2d, 0x80, 0x29, 0x6c, 0x35, 0xa8, 0x13, 0x48, 0xf3, 0x03, 0x6f, 0xd5, 0xc6, 0x35, - 0x62, 0x07, 0xba, 0xfc, 0x00, 0x6a, 0x01, 0x0b, 0xb1, 0x02, 0x29, 0x57, 0xdf, 0x24, 0xa5, 0xc6, - 0x99, 0xdd, 0x12, 0xa4, 0xda, 0xde, 0x62, 0x9c, 0x0a, 0xca, 0x1c, 0x34, 0x40, 0xc2, 0x1b, 0x60, - 0x8e, 0xd6, 0x4c, 0xa3, 0xc9, 0x5c, 0xe1, 0xbd, 0x73, 0x44, 0xde, 0x34, 0xa7, 0x0e, 0xfa, 0xa9, - 0x59, 0x3d, 0xaf, 0x6d, 0x31, 0x57, 0xe8, 0x05, 0x34, 0x4b, 0x6b, 0xa6, 0x7c, 0xb4, 0xe0, 0x1d, - 0x10, 0xf1, 0xe7, 0x5d, 0xf6, 0x7e, 0x7e, 0xed, 0xca, 0x1b, 0x4a, 0x6a, 0x47, 0x0e, 0x01, 0x0a, - 0x40, 0xeb, 0x93, 0xff, 0x78, 0xb7, 0xd4, 0x37, 0x61, 0x10, 0x1f, 0x24, 0x78, 0xce, 0x6c, 0x50, - 0x2e, 0x98, 0xdb, 0x29, 0x3a, 0xc2, 0xed, 0xc0, 0x6d, 0x30, 0xcb, 0x9a, 0xc4, 0xc5, 0x62, 0x78, - 0x9f, 0xde, 0x3e, 0xa1, 0xc8, 0x08, 0x47, 0x79, 0x00, 0xf5, 0x6e, 0x10, 0x34, 0x64, 0x1a, 0xed, - 0x4b, 0xf8, 0x8d, 0x7d, 0xd1, 0xc0, 0x74, 0xab, 0x69, 0x49, 0x47, 0x27, 0xfe, 0xb7, 0xa3, 0x01, - 0x12, 0x66, 0xc0, 0x44, 0x83, 0xd7, 0x65, 0xab, 0xa2, 0xf9, 0x0b, 0x2f, 0xfa, 0xa9, 0x38, 0x71, - 0x4c, 0x66, 0x51, 0xa7, 0x9e, 0xfd, 0x92, 0x33, 0x27, 0x83, 0xf0, 0xa3, 0x4d, 0xc2, 0x39, 0xae, - 0x13, 0xe4, 0x25, 0xaa, 0x08, 0xc0, 0x57, 0xe9, 0xe0, 0x25, 0x10, 0xad, 0xd9, 0xcc, 0x7c, 0x68, - 0xec, 0x11, 0x5a, 0xdf, 0x13, 0xfe, 0x30, 0xa1, 0x39, 0xb9, 0xb6, 0x21, 0x97, 0xe0, 0x32, 0x98, - 0x11, 0x6d, 0x83, 0x3a, 0x16, 0x69, 0xfb, 0x9a, 0xd0, 0xb4, 0x68, 0xeb, 0x5e, 0xa8, 0x62, 0x30, - 0xb5, 0xc9, 0x2c, 0x62, 0xc3, 0x3c, 0x98, 0x78, 0x48, 0x3a, 0xfe, 0xe1, 0xca, 0xdf, 0x7c, 0xd1, - 0x4f, 0xad, 0xd6, 0xa9, 0xd8, 0x6b, 0xd5, 0x32, 0x26, 0x6b, 0x64, 0x6d, 0xea, 0x90, 0x2c, 0xe3, - 0x9e, 0x87, 0xcc, 0xc9, 0xda, 0xb4, 0xc6, 0xb3, 0xb5, 0x8e, 0x20, 0x3c, 0xb3, 0x41, 0xda, 0x79, - 0xef, 0x01, 0x79, 0x60, 0x6f, 0xfa, 0xfc, 0x8f, 0x68, 0x58, 0x1e, 0x51, 0x3f, 0xb8, 0xf6, 0xaf, - 0x02, 0xc0, 0xf0, 0xb2, 0x86, 0x1f, 0x80, 0x73, 0x39, 0x4d, 0x2b, 0x56, 0x2a, 0x46, 0x75, 0x67, - 0xab, 0x68, 0x6c, 0x97, 0x2a, 0x5b, 0x45, 0x4d, 0xff, 0x44, 0x2f, 0x16, 0x62, 0xa1, 0xc4, 0x72, - 0xb7, 0x97, 0x5e, 0x1c, 0x26, 0x6f, 0x3b, 0xbc, 0x49, 0x4c, 0xba, 0x4b, 0x89, 0x05, 0x57, 0x01, - 0x1c, 0xc5, 0x95, 0xca, 0xf9, 0x72, 0x61, 0x27, 0xa6, 0x24, 0x16, 0xba, 0xbd, 0x74, 0x6c, 0x08, - 0x29, 0xb1, 0x1a, 0xb3, 0x3a, 0xf0, 0x36, 0x88, 0x8f, 0x66, 0x97, 0x4b, 0x9f, 0xed, 0x18, 0xb9, - 0x42, 0x01, 0x15, 0x2b, 0x95, 0x58, 0xf8, 0x78, 0x99, 0xb2, 0x63, 0x77, 0x72, 0xfe, 0xe7, 0x11, - 0xae, 0x81, 0xc5, 0x51, 0x60, 0xf1, 0x5e, 0x11, 0xed, 0xc8, 0x4a, 0x13, 0x89, 0x73, 0xdd, 0x5e, - 0xfa, 0xec, 0x10, 0x55, 0xdc, 0x27, 0x6e, 0xc7, 0x2b, 0x96, 0x98, 0xf9, 0xfa, 0xe7, 0x64, 0xe8, - 0xc9, 0x2f, 0xc9, 0xd0, 0xb5, 0xdf, 0x15, 0x30, 0x7f, 0x74, 0xa2, 0xe1, 0xc7, 0xe0, 0xbc, 0x56, - 0x2e, 0x55, 0x51, 0x4e, 0xab, 0x1a, 0x95, 0x6a, 0xae, 0xba, 0x5d, 0x39, 0xa6, 0xf9, 0x62, 0xb7, - 0x97, 0x5e, 0x3e, 0x0a, 0x1a, 0xd5, 0xfd, 0x3e, 0x58, 0x3a, 0x8e, 0xcf, 0x69, 0x55, 0xfd, 0x5e, - 0x31, 0xa6, 0x24, 0xe2, 0xdd, 0x5e, 0x7a, 0x41, 0x3b, 0xf6, 0x19, 0x11, 0x74, 0x9f, 0xc0, 0x0f, - 0x41, 0xfc, 0x38, 0x4a, 0x2f, 0x05, 0xb8, 0x70, 0x22, 0xd1, 0xed, 0xa5, 0x97, 0x8e, 0xe2, 0x74, - 0x07, 0x4b, 0xe4, 0x88, 0x98, 0x5f, 0x27, 0x40, 0xfa, 0xa4, 0x93, 0x03, 0x09, 0xb8, 0xf9, 0xb2, - 0x90, 0x56, 0x2e, 0x14, 0x8d, 0x0d, 0xbd, 0x52, 0x2d, 0xa3, 0x1d, 0xa3, 0xbc, 0x55, 0x44, 0xb9, - 0xaa, 0x5e, 0x2e, 0xbd, 0xae, 0xcf, 0xd9, 0x6e, 0x2f, 0x7d, 0xfd, 0x24, 0xee, 0x51, 0x17, 0xee, - 0x83, 0xab, 0x63, 0x95, 0xd1, 0x4b, 0x7a, 0x35, 0xa6, 0x24, 0x56, 0xba, 0xbd, 0xf4, 0x3b, 0x27, - 0xf1, 0xeb, 0x0e, 0x15, 0xf0, 0x0b, 0xb0, 0x3a, 0x16, 0xf1, 0xa6, 0x7e, 0x17, 0xe5, 0xaa, 0x9e, - 0x79, 0xd7, 0xbb, 0xbd, 0xf4, 0xbb, 0x27, 0x71, 0x6f, 0xd2, 0xba, 0x8b, 0x05, 0x19, 0x9b, 0xfe, - 0x6e, 0xb1, 0x54, 0xac, 0xe8, 0x95, 0xd8, 0xc4, 0x78, 0xf4, 0x77, 0x89, 0x43, 0x38, 0xe5, 0x89, - 0x49, 0xaf, 0x59, 0xf9, 0xf2, 0xd3, 0xbf, 0x93, 0xa1, 0x27, 0x07, 0x49, 0xe5, 0xe9, 0x41, 0x52, - 0x79, 0x76, 0x90, 0x54, 0xfe, 0x3a, 0x48, 0x2a, 0xdf, 0x3e, 0x4f, 0x86, 0x9e, 0x3d, 0x4f, 0x86, - 0xfe, 0x7c, 0x9e, 0x0c, 0x7d, 0x7e, 0xe3, 0xf8, 0x61, 0xb6, 0x77, 0x6b, 0x37, 0xb8, 0xf5, 0x30, - 0xdb, 0xce, 0x7a, 0xd7, 0x55, 0x96, 0x3a, 0x82, 0xb8, 0x0e, 0xb6, 0xb3, 0xf2, 0x3f, 0x75, 0x2d, - 0x22, 0xff, 0x27, 0xbf, 0xf7, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xe4, 0x99, 0xb3, 0x63, - 0x0b, 0x00, 0x00, + // 1405 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0x13, 0x47, + 0x14, 0xf6, 0xc6, 0x89, 0x13, 0x4f, 0x4c, 0x30, 0x43, 0x12, 0x1c, 0x03, 0xb6, 0x59, 0x40, 0x0d, + 0x10, 0x6c, 0x48, 0xab, 0xd2, 0x46, 0xa2, 0x92, 0xbd, 0x36, 0x64, 0xab, 0xc6, 0x8e, 0xc6, 0x0e, + 0x90, 0x4a, 0xd5, 0x6a, 0xbc, 0x3b, 0x71, 0xb6, 0xac, 0x77, 0xac, 0x9d, 0x71, 0xb0, 0x39, 0xb5, + 0xb7, 0xca, 0xbd, 0x54, 0x3d, 0xf5, 0x50, 0x57, 0x95, 0x5a, 0x55, 0xfc, 0x01, 0xfd, 0x23, 0x10, + 0x52, 0x25, 0x8e, 0x3d, 0x59, 0x6d, 0xb8, 0xb4, 0xd7, 0x1c, 0x39, 0x55, 0x3b, 0xbb, 0xc6, 0x9b, + 0xf0, 0x23, 0xee, 0x25, 0xf2, 0x7b, 0xf3, 0xbe, 0xef, 0xcd, 0xfb, 0xde, 0x9b, 0xb7, 0x01, 0xb3, + 0xbc, 0xdb, 0x22, 0x2c, 0xdb, 0x72, 0x28, 0xa7, 0x70, 0x41, 0xa7, 0xac, 0xf9, 0x08, 0xb3, 0x66, + 0x56, 0xfc, 0xd9, 0xbb, 0x59, 0x27, 0x1c, 0xdf, 0x4c, 0x2e, 0xb9, 0x6e, 0xca, 0x34, 0x11, 0x94, + 0xf3, 0x0c, 0x0f, 0x91, 0x9c, 0x6f, 0xd0, 0x06, 0xf5, 0xfc, 0xee, 0x2f, 0xdf, 0xbb, 0xd4, 0xa0, + 0xb4, 0x61, 0x91, 0x9c, 0xb0, 0xea, 0xed, 0x9d, 0x1c, 0xb6, 0xbb, 0xde, 0x91, 0x5c, 0x07, 0x27, + 0xf3, 0xba, 0x4e, 0x18, 0xab, 0x75, 0x5b, 0x64, 0x13, 0x3b, 0xb8, 0x09, 0x55, 0x30, 0xb5, 0x87, + 0xad, 0x36, 0x49, 0x48, 0x19, 0x69, 0x79, 0x6e, 0xf5, 0x42, 0xf6, 0x8d, 0xb7, 0xc8, 0x8e, 0x60, + 0x85, 0xf8, 0xc1, 0x20, 0x1d, 0xeb, 0xe2, 0xa6, 0xb5, 0x26, 0x0b, 0xa4, 0x8c, 0x3c, 0x86, 0xb5, + 0xc9, 0x1f, 0x7e, 0x4e, 0x4b, 0xf2, 0x8f, 0x12, 0x88, 0x79, 0xd1, 0x0a, 0xb5, 0x77, 0xcc, 0x06, + 0x7c, 0x00, 0x40, 0x8b, 0x38, 0x4d, 0x93, 0x31, 0x93, 0xda, 0xe3, 0xa7, 0x59, 0x38, 0x18, 0xa4, + 0x4f, 0x79, 0x69, 0x46, 0x70, 0x19, 0x05, 0xb8, 0xe0, 0x0a, 0x98, 0xc6, 0x86, 0xe1, 0x10, 0xc6, + 0x12, 0x13, 0x19, 0x69, 0x39, 0x5a, 0x80, 0x07, 0x83, 0xf4, 0x9c, 0x87, 0xf1, 0x0f, 0x64, 0x34, + 0x0c, 0xf1, 0xaf, 0xf7, 0xd3, 0x14, 0x88, 0x88, 0xca, 0x19, 0xe4, 0x00, 0xea, 0xd4, 0x20, 0x5a, + 0xbb, 0x65, 0x51, 0x6c, 0x68, 0x58, 0xe4, 0x16, 0x17, 0x9c, 0x5d, 0xbd, 0xf8, 0xce, 0x0b, 0x7a, + 0x95, 0x15, 0x2e, 0x3c, 0x1d, 0xa4, 0x43, 0x07, 0x83, 0xf4, 0x92, 0x97, 0xf2, 0x75, 0x32, 0x19, + 0xc5, 0x5d, 0xe7, 0x96, 0xf0, 0x79, 0x50, 0xf8, 0xbd, 0x04, 0x52, 0xa6, 0xcd, 0x38, 0xb6, 0xb9, + 0x89, 0x39, 0xd1, 0x0c, 0xb2, 0x83, 0xdb, 0x16, 0xd7, 0x02, 0x1a, 0x4d, 0x8c, 0xab, 0xd1, 0x95, + 0x83, 0x41, 0xfa, 0xb2, 0x97, 0xfc, 0xdd, 0x94, 0x32, 0x3a, 0x17, 0x08, 0x28, 0x7a, 0xe7, 0x9b, + 0x23, 0x25, 0xbf, 0x92, 0xc0, 0xa2, 0x4e, 0x6d, 0xee, 0x60, 0x9d, 0x6b, 0x8c, 0x63, 0xde, 0x66, + 0x43, 0x3d, 0xc2, 0xe3, 0xeb, 0x71, 0xd9, 0xd7, 0xe3, 0xfc, 0x50, 0x8f, 0x37, 0x11, 0xca, 0x68, + 0x7e, 0x78, 0x50, 0x15, 0x7e, 0x5f, 0x97, 0x4f, 0x01, 0x6c, 0xe2, 0x8e, 0xe6, 0xb2, 0x6b, 0x42, + 0x49, 0x66, 0x3e, 0x26, 0x89, 0xc9, 0x8c, 0xb4, 0x3c, 0x59, 0x38, 0x3f, 0x12, 0xf9, 0xf5, 0x18, + 0x19, 0x9d, 0x6c, 0xe2, 0xce, 0x7d, 0xcc, 0x9a, 0x0a, 0x35, 0x48, 0xd5, 0x7c, 0x4c, 0xe0, 0xc7, + 0x60, 0xae, 0x81, 0x99, 0xd6, 0x6c, 0x5b, 0xdc, 0x6c, 0x59, 0x26, 0x71, 0x12, 0x53, 0x82, 0x27, + 0x30, 0x1f, 0x2e, 0x4f, 0x03, 0x33, 0x19, 0x9d, 0x68, 0x60, 0xb6, 0xf1, 0x2a, 0x10, 0xde, 0x06, + 0x27, 0x3c, 0xa5, 0x74, 0xa2, 0xe9, 0x94, 0xf1, 0x44, 0x44, 0x20, 0x13, 0x07, 0x83, 0xf4, 0x7c, + 0x50, 0x69, 0xff, 0x58, 0x46, 0xb1, 0xa1, 0xad, 0x50, 0xc6, 0xe1, 0x1a, 0x88, 0xe9, 0xb4, 0xd9, + 0x32, 0x2d, 0x1f, 0x3d, 0x2d, 0xd0, 0x67, 0x0e, 0x06, 0xe9, 0xd3, 0x43, 0x51, 0x46, 0xa7, 0x32, + 0x9a, 0xf5, 0x4d, 0x17, 0x2b, 0x06, 0x34, 0x24, 0xff, 0x21, 0x81, 0x19, 0xb7, 0x10, 0xd5, 0xde, + 0xa1, 0xf0, 0x2c, 0x88, 0x8a, 0x3a, 0x77, 0x31, 0xdb, 0x15, 0x93, 0x19, 0x43, 0x33, 0xae, 0x63, + 0x1d, 0xb3, 0x5d, 0x98, 0x00, 0xd3, 0xba, 0x43, 0x30, 0xa7, 0x8e, 0x37, 0xfe, 0x68, 0x68, 0xc2, + 0x45, 0x10, 0x61, 0xb4, 0xed, 0xe8, 0x44, 0x74, 0x2f, 0x8a, 0x7c, 0xcb, 0x45, 0xd4, 0xdb, 0xa6, + 0x65, 0x10, 0x47, 0x08, 0x1b, 0x45, 0x43, 0x13, 0x3e, 0x00, 0x30, 0x38, 0x41, 0xba, 0x68, 0xa8, + 0x50, 0x6d, 0xcc, 0xde, 0x4f, 0xba, 0xbd, 0x47, 0xa7, 0x02, 0x24, 0xde, 0x81, 0xfc, 0x75, 0x18, + 0xc4, 0x14, 0xbf, 0xe1, 0xa2, 0xa6, 0x8b, 0x60, 0x5a, 0xd4, 0x64, 0x1a, 0xa2, 0xa2, 0xc9, 0x02, + 0xd8, 0x1f, 0xa4, 0x23, 0xa2, 0xe4, 0x22, 0x8a, 0xb8, 0x47, 0xaa, 0xf1, 0x8e, 0xda, 0xe6, 0xc1, + 0x14, 0x36, 0x9a, 0xa6, 0xed, 0x97, 0xe6, 0x19, 0xae, 0xd7, 0xc2, 0x75, 0x62, 0xf9, 0x75, 0x79, + 0x06, 0x54, 0x7c, 0x16, 0x62, 0xf8, 0xa5, 0x5c, 0x79, 0x5b, 0x29, 0x75, 0x46, 0xad, 0x36, 0x27, + 0xb5, 0xce, 0x26, 0x65, 0x26, 0x37, 0xa9, 0x8d, 0x86, 0x48, 0x78, 0x1d, 0xcc, 0x9a, 0x75, 0x5d, + 0x6b, 0x51, 0x87, 0xbb, 0x77, 0x8e, 0x88, 0x4d, 0x73, 0x62, 0x7f, 0x90, 0x8e, 0xaa, 0x05, 0x65, + 0x93, 0x3a, 0x5c, 0x2d, 0xa2, 0xa8, 0x59, 0xd7, 0xc5, 0x4f, 0x03, 0xde, 0x06, 0x11, 0x6f, 0xde, + 0x45, 0xef, 0xe7, 0x56, 0x2f, 0xbf, 0x25, 0xa5, 0x72, 0xe8, 0x11, 0x20, 0x1f, 0x04, 0x37, 0x40, + 0x94, 0x74, 0x38, 0xb1, 0xc5, 0x22, 0x98, 0x11, 0x97, 0x9e, 0xcf, 0x7a, 0x1b, 0x3d, 0x3b, 0xdc, + 0xe8, 0xd9, 0xbc, 0xdd, 0x2d, 0x2c, 0x3d, 0xfb, 0xfd, 0xfa, 0x42, 0x50, 0xd8, 0xd2, 0x10, 0x86, + 0x46, 0x0c, 0x6b, 0x93, 0xff, 0xb8, 0x4b, 0xef, 0xdb, 0x09, 0x90, 0x18, 0x86, 0xba, 0x42, 0xaf, + 0x9b, 0x8c, 0x53, 0xa7, 0x5b, 0xb2, 0xb9, 0xd3, 0x85, 0x5b, 0x20, 0x4a, 0x5b, 0xc4, 0xc1, 0x7c, + 0xb4, 0x9e, 0x6f, 0x1d, 0x73, 0xe7, 0x00, 0x47, 0x65, 0x08, 0x75, 0x17, 0x12, 0x1a, 0x31, 0x05, + 0xdb, 0x3c, 0xf1, 0xd6, 0x36, 0x2b, 0x60, 0xba, 0xdd, 0x32, 0x44, 0x83, 0xc2, 0xff, 0xbb, 0x41, + 0x3e, 0x12, 0x66, 0x41, 0xb8, 0xc9, 0x1a, 0xa2, 0xf3, 0xb1, 0xc2, 0xb9, 0x97, 0x83, 0x74, 0x82, + 0xd8, 0x3a, 0x35, 0x4c, 0xbb, 0x91, 0xfb, 0x92, 0x51, 0x3b, 0x8b, 0xf0, 0xa3, 0x0d, 0xc2, 0x18, + 0x6e, 0x10, 0xe4, 0x06, 0xca, 0x08, 0xc0, 0xd7, 0xe9, 0xe0, 0x05, 0x10, 0xab, 0x5b, 0x54, 0x7f, + 0xa8, 0xed, 0x12, 0xb3, 0xb1, 0xcb, 0xbd, 0xd9, 0x44, 0xb3, 0xc2, 0xb7, 0x2e, 0x5c, 0x70, 0x09, + 0xcc, 0xf0, 0x8e, 0x66, 0xda, 0x06, 0xe9, 0x78, 0x35, 0xa1, 0x69, 0xde, 0x51, 0x5d, 0x53, 0xc6, + 0x60, 0x6a, 0x83, 0x1a, 0xc4, 0x82, 0x05, 0x10, 0x7e, 0x48, 0xba, 0xde, 0x5b, 0x2d, 0xdc, 0x78, + 0x39, 0x48, 0xaf, 0x34, 0x4c, 0xbe, 0xdb, 0xae, 0x67, 0x75, 0xda, 0xcc, 0x59, 0xa6, 0x4d, 0x72, + 0x94, 0xb9, 0x1a, 0x52, 0x3b, 0x67, 0x99, 0x75, 0x96, 0xab, 0x77, 0x39, 0x61, 0xd9, 0x75, 0xd2, + 0x29, 0xb8, 0x3f, 0x90, 0x0b, 0x76, 0x87, 0xd9, 0xfb, 0x26, 0x4f, 0x88, 0x17, 0xef, 0x19, 0x57, + 0xff, 0x95, 0x00, 0x18, 0xed, 0x7e, 0xf8, 0x21, 0x38, 0x93, 0x57, 0x94, 0x52, 0xb5, 0xaa, 0xd5, + 0xb6, 0x37, 0x4b, 0xda, 0x56, 0xb9, 0xba, 0x59, 0x52, 0xd4, 0x3b, 0x6a, 0xa9, 0x18, 0x0f, 0x25, + 0x97, 0x7a, 0xfd, 0xcc, 0xc2, 0x28, 0x78, 0xcb, 0x66, 0x2d, 0xa2, 0x9b, 0x3b, 0x26, 0x31, 0xe0, + 0x0a, 0x80, 0x41, 0x5c, 0xb9, 0x52, 0xa8, 0x14, 0xb7, 0xe3, 0x52, 0x72, 0xbe, 0xd7, 0xcf, 0xc4, + 0x47, 0x90, 0x32, 0xad, 0x53, 0xa3, 0x0b, 0x6f, 0x81, 0x44, 0x30, 0xba, 0x52, 0xfe, 0x6c, 0x5b, + 0xcb, 0x17, 0x8b, 0xa8, 0x54, 0xad, 0xc6, 0x27, 0x8e, 0xa6, 0xa9, 0xd8, 0x56, 0x37, 0xef, 0x7d, + 0x6d, 0xe1, 0x2a, 0x58, 0x08, 0x02, 0x4b, 0xf7, 0x4a, 0x68, 0x5b, 0x64, 0x0a, 0x27, 0xcf, 0xf4, + 0xfa, 0x99, 0xd3, 0x23, 0x54, 0x69, 0x8f, 0x38, 0x5d, 0x37, 0x59, 0x72, 0xe6, 0x9b, 0x5f, 0x52, + 0xa1, 0x27, 0xbf, 0xa6, 0x42, 0x57, 0x9f, 0x49, 0x60, 0xee, 0xf0, 0x03, 0x81, 0x9f, 0x80, 0xb3, + 0x4a, 0xa5, 0x5c, 0x43, 0x79, 0xa5, 0xa6, 0x55, 0x6b, 0xf9, 0xda, 0x56, 0xf5, 0x48, 0xcd, 0xe7, + 0x7b, 0xfd, 0xcc, 0xd2, 0x61, 0x50, 0xb0, 0xee, 0x0f, 0xc0, 0xe2, 0x51, 0x7c, 0x5e, 0xa9, 0xa9, + 0xf7, 0x4a, 0x71, 0x29, 0x99, 0xe8, 0xf5, 0x33, 0xf3, 0xca, 0x91, 0xaf, 0x12, 0x37, 0xf7, 0x08, + 0xfc, 0x08, 0x24, 0x8e, 0xa2, 0xd4, 0xb2, 0x8f, 0x9b, 0x48, 0x26, 0x7b, 0xfd, 0xcc, 0xe2, 0x61, + 0x9c, 0x6a, 0x63, 0x81, 0x0c, 0x14, 0xf3, 0x5b, 0x18, 0x64, 0x8e, 0x7b, 0x39, 0x90, 0x80, 0x1b, + 0xaf, 0x12, 0x29, 0x95, 0x62, 0x49, 0x5b, 0x57, 0xab, 0xb5, 0x0a, 0xda, 0xd6, 0x2a, 0x9b, 0x25, + 0x94, 0xaf, 0xa9, 0x95, 0xf2, 0x9b, 0xfa, 0x9c, 0xeb, 0xf5, 0x33, 0xd7, 0x8e, 0xe3, 0x0e, 0xaa, + 0x70, 0x1f, 0x5c, 0x19, 0x2b, 0x8d, 0x5a, 0x56, 0x6b, 0x71, 0x29, 0xb9, 0xdc, 0xeb, 0x67, 0x2e, + 0x1d, 0xc7, 0xaf, 0xda, 0x26, 0x87, 0x5f, 0x80, 0x95, 0xb1, 0x88, 0x37, 0xd4, 0xbb, 0x28, 0x5f, + 0x73, 0xc5, 0xbb, 0xd6, 0xeb, 0x67, 0xde, 0x3b, 0x8e, 0x7b, 0xc3, 0x6c, 0x38, 0x98, 0x93, 0xb1, + 0xe9, 0xef, 0x96, 0xca, 0xa5, 0xaa, 0x5a, 0x8d, 0x87, 0xc7, 0xa3, 0xbf, 0x4b, 0x6c, 0xc2, 0x4c, + 0x96, 0x9c, 0x74, 0x9b, 0x55, 0xb8, 0xf3, 0xf4, 0xef, 0x54, 0xe8, 0xc9, 0x7e, 0x4a, 0x7a, 0xba, + 0x9f, 0x92, 0x9e, 0xef, 0xa7, 0xa4, 0xbf, 0xf6, 0x53, 0xd2, 0x77, 0x2f, 0x52, 0xa1, 0xe7, 0x2f, + 0x52, 0xa1, 0x3f, 0x5f, 0xa4, 0x42, 0x9f, 0x5f, 0x3a, 0xfa, 0x98, 0xad, 0x9d, 0xfa, 0x75, 0x66, + 0x3c, 0xcc, 0x75, 0x72, 0xee, 0xba, 0xca, 0x89, 0xff, 0xe7, 0xeb, 0x11, 0xb1, 0xa8, 0xdf, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0xff, 0x88, 0xec, 0xe8, 0x19, 0xdf, 0x0b, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -739,6 +751,9 @@ func (this *ContractInfo) Equal(that interface{}) bool { if this.Status != that1.Status { return false } + if !this.Extension.Equal(that1.Extension) { + return false + } return true } func (this *ContractCodeHistoryEntry) Equal(that interface{}) bool { @@ -1040,6 +1055,18 @@ func (m *ContractInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Extension != nil { + { + size, err := m.Extension.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if m.Status != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.Status)) i-- @@ -1341,6 +1368,10 @@ func (m *ContractInfo) Size() (n int) { if m.Status != 0 { n += 1 + sovTypes(uint64(m.Status)) } + if m.Extension != nil { + l = m.Extension.Size() + n += 1 + l + sovTypes(uint64(l)) + } return n } @@ -2230,6 +2261,42 @@ func (m *ContractInfo) Unmarshal(dAtA []byte) error { break } } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Extension == nil { + m.Extension = &types.Any{} + } + if err := m.Extension.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/x/wasm/internal/types/types.proto b/x/wasm/types/types.proto similarity index 93% rename from x/wasm/internal/types/types.proto rename to x/wasm/types/types.proto index bbc77ad6b5..8323d94942 100644 --- a/x/wasm/internal/types/types.proto +++ b/x/wasm/types/types.proto @@ -1,9 +1,11 @@ syntax = "proto3"; package cosmwasm.wasm.v1beta1; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; -option go_package = "github.com/line/lfb-sdk/x/wasm/internal/types"; +option go_package = "github.com/line/lfb-sdk/x/wasm/types"; option (gogoproto.goproto_getters_all) = false; option (gogoproto.equal_all) = true; @@ -67,7 +69,8 @@ message CodeInfo { bytes code_hash = 1; // Creator address who initially stored the code string creator = 2; - // Source is a valid absolute HTTPS URI to the contract's source code, optional + // Source is a valid absolute HTTPS URI to the contract's source code, + // optional string source = 3; // Builder is a valid docker image name with tag, optional string builder = 4; @@ -88,11 +91,15 @@ message ContractInfo { // Label is optional metadata to be stored with a contract instance. string label = 4; // Created Tx position when the contract was instantiated. - // This data should kept internal and not be exposed via query results. Just use for sorting + // This data should kept internal and not be exposed via query results. Just + // use for sorting AbsoluteTxPosition created = 5; string ibc_port_id = 6 [(gogoproto.customname) = "IBCPortID"]; // Status is a status of a contract ContractStatus status = 7; + // Extension is an extension point to store custom metadata within the + // persistence model. + google.protobuf.Any extension = 8 [(cosmos_proto.accepts_interface) = "ContractInfoExtension"]; } // ContractCodeHistoryOperationType actions that caused a code change @@ -122,11 +129,13 @@ message ContractCodeHistoryEntry { bytes msg = 4 [(gogoproto.casttype) = "encoding/json.RawMessage"]; } -// AbsoluteTxPosition is a unique transaction position that allows for global ordering of transactions. +// AbsoluteTxPosition is a unique transaction position that allows for global +// ordering of transactions. message AbsoluteTxPosition { // BlockHeight is the block the contract was created at uint64 block_height = 1; - // TxIndex is a monotonic counter within the block (actual transaction index, or gas consumed) + // TxIndex is a monotonic counter within the block (actual transaction index, + // or gas consumed) uint64 tx_index = 2; } @@ -136,4 +145,4 @@ message Model { bytes key = 1 [(gogoproto.casttype) = "github.com/line/ostracon/libs/bytes.HexBytes"]; // base64-encode raw value bytes value = 2; -} +} \ No newline at end of file diff --git a/x/wasm/types/types_test.go b/x/wasm/types/types_test.go new file mode 100644 index 0000000000..360763be67 --- /dev/null +++ b/x/wasm/types/types_test.go @@ -0,0 +1,342 @@ +package types + +import ( + "strings" + "testing" + "time" + + "github.com/line/lfb-sdk/codec" + "github.com/line/lfb-sdk/codec/types" + codectypes "github.com/line/lfb-sdk/codec/types" + sdk "github.com/line/lfb-sdk/types" + govtypes "github.com/line/lfb-sdk/x/gov/types" + "github.com/line/ostracon/libs/rand" + wasmvmtypes "github.com/line/wasmvm/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestContractInfoValidateBasic(t *testing.T) { + specs := map[string]struct { + srcMutator func(*ContractInfo) + expError bool + }{ + "all good": {srcMutator: func(_ *ContractInfo) {}}, + "code id empty": { + srcMutator: func(c *ContractInfo) { c.CodeID = 0 }, + expError: true, + }, + "creator empty": { + srcMutator: func(c *ContractInfo) { c.Creator = "" }, + expError: true, + }, + "creator not an address": { + srcMutator: func(c *ContractInfo) { c.Creator = "invalid address" }, + expError: true, + }, + "admin empty": { + srcMutator: func(c *ContractInfo) { c.Admin = "" }, + expError: false, + }, + "admin not an address": { + srcMutator: func(c *ContractInfo) { c.Admin = "invalid address" }, + expError: true, + }, + "label empty": { + srcMutator: func(c *ContractInfo) { c.Label = "" }, + expError: true, + }, + "label exceeds limit": { + srcMutator: func(c *ContractInfo) { c.Label = strings.Repeat("a", MaxLabelSize+1) }, + expError: true, + }, + "invalid extension": { + srcMutator: func(c *ContractInfo) { + // any protobuf type with ValidateBasic method + any, err := codectypes.NewAnyWithValue(&govtypes.TextProposal{}) + require.NoError(t, err) + c.Extension = any + }, + expError: true, + }, + "not validatable extension": { + srcMutator: func(c *ContractInfo) { + // any protobuf type with ValidateBasic method + any, err := codectypes.NewAnyWithValue(&govtypes.Proposal{}) + require.NoError(t, err) + c.Extension = any + }, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + state := ContractInfoFixture(spec.srcMutator) + got := state.ValidateBasic() + if spec.expError { + require.Error(t, got) + return + } + require.NoError(t, got) + }) + } +} + +func TestCodeInfoValidateBasic(t *testing.T) { + specs := map[string]struct { + srcMutator func(*CodeInfo) + expError bool + }{ + "all good": {srcMutator: func(_ *CodeInfo) {}}, + "code hash empty": { + srcMutator: func(c *CodeInfo) { c.CodeHash = []byte{} }, + expError: true, + }, + "code hash nil": { + srcMutator: func(c *CodeInfo) { c.CodeHash = nil }, + expError: true, + }, + "creator empty": { + srcMutator: func(c *CodeInfo) { c.Creator = "" }, + expError: true, + }, + "creator not an address": { + srcMutator: func(c *CodeInfo) { c.Creator = "invalid address" }, + expError: true, + }, + "source empty": { + srcMutator: func(c *CodeInfo) { c.Source = "" }, + }, + "source not an url": { + srcMutator: func(c *CodeInfo) { c.Source = "invalid" }, + expError: true, + }, + "source not an absolute url": { + srcMutator: func(c *CodeInfo) { c.Source = "../bar.txt" }, + expError: true, + }, + "source not https schema url": { + srcMutator: func(c *CodeInfo) { c.Source = "http://example.com" }, + expError: true, + }, + "builder tag exceeds limit": { + srcMutator: func(c *CodeInfo) { c.Builder = strings.Repeat("a", MaxBuildTagSize+1) }, + expError: true, + }, + "builder tag does not match pattern": { + srcMutator: func(c *CodeInfo) { c.Builder = "invalid" }, + expError: true, + }, + "Instantiate config invalid": { + srcMutator: func(c *CodeInfo) { c.InstantiateConfig = AccessConfig{} }, + expError: true, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + state := CodeInfoFixture(spec.srcMutator) + got := state.ValidateBasic() + if spec.expError { + require.Error(t, got) + return + } + require.NoError(t, got) + }) + } +} + +func TestContractInfoSetExtension(t *testing.T) { + anyTime := time.Now().UTC() + aNestedProtobufExt := func() ContractInfoExtension { + // using gov proposal here as a random protobuf types as it contains an Any type inside for nested unpacking + myExtension, err := govtypes.NewProposal(&govtypes.TextProposal{Title: "bar"}, 1, anyTime, anyTime) + require.NoError(t, err) + myExtension.TotalDeposit = nil + return &myExtension + } + + specs := map[string]struct { + src ContractInfoExtension + expErr bool + expNil bool + }{ + "all good with any proto extension": { + src: aNestedProtobufExt(), + }, + "nil allowed": { + src: nil, + expNil: true, + }, + "validated and accepted": { + src: &govtypes.TextProposal{Title: "bar", Description: "set"}, + }, + "validated and rejected": { + src: &govtypes.TextProposal{Title: "bar"}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var c ContractInfo + gotErr := c.SetExtension(spec.src) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + if spec.expNil { + return + } + require.NotNil(t, c.Extension) + assert.NotNil(t, c.Extension.GetCachedValue()) + }) + } +} + +func TestContractInfoMarshalUnmarshal(t *testing.T) { + var myAddr sdk.AccAddress = rand.Bytes(sdk.AddrLen) + var myOtherAddr sdk.AccAddress = rand.Bytes(sdk.AddrLen) + var anyPos = AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2} + + anyTime := time.Now().UTC() + // using gov proposal here as a random protobuf types as it contains an Any type inside for nested unpacking + myExtension, err := govtypes.NewProposal(&govtypes.TextProposal{Title: "bar"}, 1, anyTime, anyTime) + require.NoError(t, err) + myExtension.TotalDeposit = nil + + src := NewContractInfo(1, myAddr, myOtherAddr, "bar", &anyPos) + err = src.SetExtension(&myExtension) + require.NoError(t, err) + + interfaceRegistry := types.NewInterfaceRegistry() + marshaler := codec.NewProtoCodec(interfaceRegistry) + RegisterInterfaces(interfaceRegistry) + // register proposal as extension type + interfaceRegistry.RegisterImplementations( + (*ContractInfoExtension)(nil), + &govtypes.Proposal{}, + ) + // register gov types for nested Anys + govtypes.RegisterInterfaces(interfaceRegistry) + + // when encode + bz, err := marshaler.MarshalBinaryBare(&src) + require.NoError(t, err) + // and decode + var dest ContractInfo + err = marshaler.UnmarshalBinaryBare(bz, &dest) + // then + require.NoError(t, err) + assert.Equal(t, src, dest) + // and sanity check nested any + var destExt govtypes.Proposal + require.NoError(t, dest.ReadExtension(&destExt)) + assert.Equal(t, destExt.GetTitle(), "bar") +} + +func TestContractInfoReadExtension(t *testing.T) { + anyTime := time.Now().UTC() + myExtension, err := govtypes.NewProposal(&govtypes.TextProposal{Title: "foo"}, 1, anyTime, anyTime) + require.NoError(t, err) + type TestExtensionAsStruct struct { + ContractInfoExtension + } + + specs := map[string]struct { + setup func(*ContractInfo) + param func() ContractInfoExtension + expVal ContractInfoExtension + expErr bool + }{ + "all good": { + setup: func(i *ContractInfo) { + i.SetExtension(&myExtension) + }, + param: func() ContractInfoExtension { + return &govtypes.Proposal{} + }, + expVal: &myExtension, + }, + "no extension set": { + setup: func(i *ContractInfo) { + }, + param: func() ContractInfoExtension { + return &govtypes.Proposal{} + }, + expVal: &govtypes.Proposal{}, + }, + "nil argument value": { + setup: func(i *ContractInfo) { + i.SetExtension(&myExtension) + }, + param: func() ContractInfoExtension { + return nil + }, + expErr: true, + }, + "non matching types": { + setup: func(i *ContractInfo) { + i.SetExtension(&myExtension) + }, + param: func() ContractInfoExtension { + return &govtypes.TextProposal{} + }, + expErr: true, + }, + "not a pointer argument": { + setup: func(i *ContractInfo) { + }, + param: func() ContractInfoExtension { + return TestExtensionAsStruct{} + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var c ContractInfo + spec.setup(&c) + // when + + gotValue := spec.param() + gotErr := c.ReadExtension(gotValue) + + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expVal, gotValue) + }) + } +} + +func TestNewEnv(t *testing.T) { + myTime := time.Unix(0, 1619700924259075000) + t.Logf("++ unix: %d", myTime.UnixNano()) + var myContractAddr sdk.AccAddress = randBytes(sdk.AddrLen) + specs := map[string]struct { + srcCtx sdk.Context + exp wasmvmtypes.Env + }{ + "all good": { + srcCtx: sdk.Context{}.WithBlockHeight(1).WithBlockTime(myTime).WithChainID("testing"), + exp: wasmvmtypes.Env{ + Block: wasmvmtypes.BlockInfo{ + Height: 1, + Time: 1619700924259075000, + ChainID: "testing", + }, + Contract: wasmvmtypes.ContractInfo{ + Address: myContractAddr.String(), + }, + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + assert.Equal(t, spec.exp, NewEnv(spec.srcCtx, myContractAddr)) + }) + } + +} diff --git a/x/wasm/internal/types/validation.go b/x/wasm/types/validation.go similarity index 100% rename from x/wasm/internal/types/validation.go rename to x/wasm/types/validation.go diff --git a/x/wasm/internal/types/wasmer_engine.go b/x/wasm/types/wasmer_engine.go similarity index 98% rename from x/wasm/internal/types/wasmer_engine.go rename to x/wasm/types/wasmer_engine.go index 0998c3a60b..970b301a87 100644 --- a/x/wasm/internal/types/wasmer_engine.go +++ b/x/wasm/types/wasmer_engine.go @@ -18,7 +18,7 @@ type WasmerEngine interface { // be instantiated with custom inputs in the future. Create(code wasmvm.WasmCode) (wasmvm.Checksum, error) - // This will statically analyze the code. + // AnalyzeCode will statically analyze the code. // Currently just reports if it exposes all IBC entry points. AnalyzeCode(checksum wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) @@ -220,4 +220,7 @@ type WasmerEngine interface { // the implementor's choice. // Unpin is idempotent. Unpin(checksum wasmvm.Checksum) error + + // GetMetrics some internal metrics for monitoring purposes. + GetMetrics() (*wasmvmtypes.Metrics, error) }