From 956d8b4915d0344a8656e400fb4ffa7e466dfb2f Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Fri, 22 Oct 2021 15:13:37 +0200 Subject: [PATCH 01/38] feat: Add `fee.{payer,granter}` and `tip` fields to StdSignDoc (#10348) * Add IsTipper * Use addr in signer data * Always populate addr in signer data * fi error messages * make proto gen * fix build * Add fields to sign docs and sign mode handler * Remove getSequence * Update x/auth/migrations/legacytx/stdtx.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/migrations/legacytx/stdsign.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Use addressCodec * NewTxConfig with addrCdc * REmove simapp.NewBech32 * Move bech32 stuff to x/auth/address * Add changelog * Move address.Codec to x/auth * Fix test * Add tests for tipper and feepayer * Rename tests * Add more tests * Empty tip test * Revert unwanted files * Less line diff * fix test * fix another test * Fix test * Update x/auth/migrations/legacytx/stdtx_test.go Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> * Address reviews Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> --- CHANGELOG.md | 4 +- types/tx/tips.go | 11 +++ x/auth/migrations/legacytx/amino_signing.go | 2 +- .../migrations/legacytx/amino_signing_test.go | 2 +- x/auth/migrations/legacytx/stdsign.go | 15 ++- x/auth/migrations/legacytx/stdsignmsg.go | 2 +- x/auth/migrations/legacytx/stdtx.go | 12 ++- x/auth/migrations/legacytx/stdtx_test.go | 63 +++++++++++-- x/auth/signing/verify_test.go | 4 +- x/auth/tx/builder.go | 5 + x/auth/tx/direct_aux.go | 2 +- x/auth/tx/legacy_amino_json.go | 28 +++++- x/auth/tx/legacy_amino_json_test.go | 92 +++++++++++++++---- 13 files changed, 203 insertions(+), 39 deletions(-) create mode 100644 types/tx/tips.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 911984bb0cf5..ff7a44201e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. * [\#10024](https://github.com/cosmos/cosmos-sdk/pull/10024) `store/cachekv` performance improvement by reduced growth factor for iterator ranging by using binary searches to find dirty items when unsorted key count >= 1024 +* [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. ### API Breaking Changes @@ -98,8 +99,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Replace `baseapp.SetAnteHandler` with `baseapp.SetTxHandler`. * Move Msg routers from BaseApp to middlewares. * Move Baseapp panic recovery into a middleware. - * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}**. + * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}**`. * (x/gov) [\#10373](https://github.com/cosmos/cosmos-sdk/pull/10373) Removed gov `keeper.{MustMarshal, MustUnmarshal}`. +* [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) StdSignBytes takes a new argument of type `*tx.Tip` for signing over tips using LEGACY_AMINO_JSON. ### Client Breaking Changes diff --git a/types/tx/tips.go b/types/tx/tips.go new file mode 100644 index 000000000000..ca8afb36d5ae --- /dev/null +++ b/types/tx/tips.go @@ -0,0 +1,11 @@ +package tx + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TipTx defines the interface to be implemented by Txs that handle Tips. +type TipTx interface { + sdk.FeeTx + GetTip() *Tip +} diff --git a/x/auth/migrations/legacytx/amino_signing.go b/x/auth/migrations/legacytx/amino_signing.go index 2f5b1d4a4218..4115efa70493 100644 --- a/x/auth/migrations/legacytx/amino_signing.go +++ b/x/auth/migrations/legacytx/amino_signing.go @@ -43,7 +43,7 @@ func (stdTxSignModeHandler) GetSignBytes(mode signingtypes.SignMode, data signin } return StdSignBytes( - data.ChainID, data.AccountNumber, data.Sequence, stdTx.GetTimeoutHeight(), StdFee{Amount: stdTx.GetFee(), Gas: stdTx.GetGas()}, tx.GetMsgs(), stdTx.GetMemo(), + data.ChainID, data.AccountNumber, data.Sequence, stdTx.GetTimeoutHeight(), StdFee{Amount: stdTx.GetFee(), Gas: stdTx.GetGas()}, tx.GetMsgs(), stdTx.GetMemo(), nil, ), nil } diff --git a/x/auth/migrations/legacytx/amino_signing_test.go b/x/auth/migrations/legacytx/amino_signing_test.go index 89410d6c8948..3342c2dba01b 100644 --- a/x/auth/migrations/legacytx/amino_signing_test.go +++ b/x/auth/migrations/legacytx/amino_signing_test.go @@ -55,7 +55,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.NoError(t, err) - expectedSignBz := StdSignBytes(chainId, accNum, seqNum, timeoutHeight, fee, msgs, memo) + expectedSignBz := StdSignBytes(chainId, accNum, seqNum, timeoutHeight, fee, msgs, memo, nil) require.Equal(t, expectedSignBz, signBz) diff --git a/x/auth/migrations/legacytx/stdsign.go b/x/auth/migrations/legacytx/stdsign.go index d22e3786d9f0..9467ee8027c8 100644 --- a/x/auth/migrations/legacytx/stdsign.go +++ b/x/auth/migrations/legacytx/stdsign.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -47,10 +48,11 @@ type StdSignDoc struct { Memo string `json:"memo" yaml:"memo"` Fee json.RawMessage `json:"fee" yaml:"fee"` Msgs []json.RawMessage `json:"msgs" yaml:"msgs"` + Tip *StdTip `json:"tip,omitempty" yaml:"tip"` } // StdSignBytes returns the bytes to sign for a transaction. -func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string) []byte { +func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string, tip *tx.Tip) []byte { msgsBytes := make([]json.RawMessage, 0, len(msgs)) for _, msg := range msgs { legacyMsg, ok := msg.(LegacyMsg) @@ -61,6 +63,15 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgsBytes = append(msgsBytes, json.RawMessage(legacyMsg.GetSignBytes())) } + var stdTip *StdTip + if tip != nil { + if tip.Tipper == "" { + panic(fmt.Errorf("tipper cannot be empty")) + } + + stdTip = &StdTip{Amount: tip.Amount, Tipper: tip.Tipper} + } + bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{ AccountNumber: accnum, ChainID: chainID, @@ -69,6 +80,7 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, Msgs: msgsBytes, Sequence: sequence, TimeoutHeight: timeout, + Tip: stdTip, }) if err != nil { panic(err) @@ -106,7 +118,6 @@ func (ss StdSignature) MarshalYAML() (interface{}, error) { pk = ss.PubKey.String() } - bz, err := yaml.Marshal(struct { PubKey string `json:"pub_key"` Signature string `json:"signature"` diff --git a/x/auth/migrations/legacytx/stdsignmsg.go b/x/auth/migrations/legacytx/stdsignmsg.go index 07ee29a06324..56e68b0f5b6f 100644 --- a/x/auth/migrations/legacytx/stdsignmsg.go +++ b/x/auth/migrations/legacytx/stdsignmsg.go @@ -21,7 +21,7 @@ type StdSignMsg struct { // get message bytes func (msg StdSignMsg) Bytes() []byte { - return StdSignBytes(msg.ChainID, msg.AccountNumber, msg.Sequence, msg.TimeoutHeight, msg.Fee, msg.Msgs, msg.Memo) + return StdSignBytes(msg.ChainID, msg.AccountNumber, msg.Sequence, msg.TimeoutHeight, msg.Fee, msg.Msgs, msg.Memo, nil) } func (msg StdSignMsg) UnpackInterfaces(unpacker types.AnyUnpacker) error { diff --git a/x/auth/migrations/legacytx/stdtx.go b/x/auth/migrations/legacytx/stdtx.go index 55ec38e603cc..68f3b330eae8 100644 --- a/x/auth/migrations/legacytx/stdtx.go +++ b/x/auth/migrations/legacytx/stdtx.go @@ -25,8 +25,10 @@ var ( // which must be above some miminum to be accepted into the mempool. // [Deprecated] type StdFee struct { - Amount sdk.Coins `json:"amount" yaml:"amount"` - Gas uint64 `json:"gas" yaml:"gas"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Gas uint64 `json:"gas" yaml:"gas"` + Payer string `json:"payer,omitempty" yaml:"payer"` + Granter string `json:"granter,omitempty" yaml:"granter"` } // Deprecated: NewStdFee returns a new instance of StdFee @@ -70,6 +72,12 @@ func (fee StdFee) GasPrices() sdk.DecCoins { return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas))) } +// StdTip is the tips used in a tipped transaction. +type StdTip struct { + Amount sdk.Coins `json:"amount" yaml:"amount"` + Tipper string `json:"tipper" yaml:"tipper"` +} + // StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures. // It only works with Amino, please prefer the new protobuf Tx in types/tx. // NOTE: the first signature is the fee payer (Signatures must not be nil). diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index ec70281f6828..650f6f4b155c 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -41,7 +42,7 @@ func NewTestStdFee() StdFee { func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey, accNums []uint64, seqs []uint64, timeout uint64, fee StdFee) sdk.Tx { sigs := make([]StdSignature, len(privs)) for i, priv := range privs { - signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "") + signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "", nil) sig, err := priv.Sign(signBytes) if err != nil { @@ -80,24 +81,72 @@ func TestStdSignBytes(t *testing.T) { fee StdFee msgs []sdk.Msg memo string + tip *tx.Tip } defaultFee := NewTestStdFee() + defaultTip := &tx.Tip{Tipper: addr.String(), Amount: sdk.NewCoins(sdk.NewInt64Coin("tiptoken", 150))} tests := []struct { + name string args args want string }{ { - args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"}, - fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\",\"timeout_height\":\"10\"}", addr), + "with timeout height", + args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","timeout_height":"10"}`, addr), }, { - args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"}, - fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\"}", addr), + "no timeout height (omitempty)", + args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "empty fee", + args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "no fee payer and fee granter (both omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "with fee granter, no fee payer (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), + }, + { + "with fee payer, no fee granter (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), + }, + { + "with fee payer and fee granter", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String(), Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr, addr), + }, + { + "no fee, with tip", + args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr), + }, + { + "with fee and with tip", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr, addr), + }, + { + "with empty tip (but not nil), tipper cannot be empty", + args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", &tx.Tip{Tipper: addr.String()}}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[],"tipper":"%s"}}`, addr, addr), }, } for i, tc := range tests { - got := string(StdSignBytes(tc.args.chainID, tc.args.accnum, tc.args.sequence, tc.args.timeoutHeight, tc.args.fee, tc.args.msgs, tc.args.memo)) - require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i) + tc := tc + t.Run(tc.name, func(t *testing.T) { + got := string(StdSignBytes(tc.args.chainID, tc.args.accnum, tc.args.sequence, tc.args.timeoutHeight, tc.args.fee, tc.args.msgs, tc.args.memo, tc.args.tip)) + require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i) + }) } } diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index 99eeaf8a04e3..f67590491d61 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -55,7 +55,7 @@ func TestVerifySignature(t *testing.T) { Sequence: acc.GetSequence(), SignerIndex: 0, } - signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo) + signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil) signature, err := priv.Sign(signBytes) require.NoError(t, err) @@ -73,7 +73,7 @@ func TestVerifySignature(t *testing.T) { multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet) multisignature := multisig.NewMultisig(2) msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)} - multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo) + multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil) sig1, err := priv.Sign(multiSignBytes) require.NoError(t, err) diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index 52e35705f062..d3b83d5018bb 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -35,6 +35,7 @@ var ( _ client.TxBuilder = &wrapper{} _ middleware.HasExtensionOptionsTx = &wrapper{} _ ExtensionOptionsTxBuilder = &wrapper{} + _ tx.TipTx = &wrapper{} ) // ExtensionOptionsTxBuilder defines a TxBuilder that can also set extensions. @@ -156,6 +157,10 @@ func (w *wrapper) FeeGranter() sdk.AccAddress { return nil } +func (w *wrapper) GetTip() *tx.Tip { + return w.tx.AuthInfo.Tip +} + func (w *wrapper) GetMemo() string { return w.tx.Body.Memo } diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index c7324c18bb90..71a3fd5c0426 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -50,7 +50,7 @@ func (signModeDirectAuxHandler) GetSignBytes( AccountNumber: data.AccountNumber, Sequence: data.Sequence, Tip: protoTx.tx.AuthInfo.Tip, - PublicKey: protoTx.tx.AuthInfo.SignerInfos[data.SignerIndex].PublicKey, + PublicKey: signerInfo.PublicKey, } return signDocDirectAux.Marshal() diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index fea9d78a9bd3..01274f9f6ed9 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -46,9 +46,33 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s does not support protobuf extension options", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } + addr := data.Address + if addr == "" { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) + } + + tip := protoTx.GetTip() + isTipper := tip != nil && tip.Tipper == addr + + // We set a convention that if the tipper signs with LEGACY_AMINO_JSON, then + // they sign over empty fees and 0 gas. + if isTipper { + return legacytx.StdSignBytes( + data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), + // The tipper signs over 0 fee and 0 gas, no feepayer, no feegranter by convention. + legacytx.StdFee{}, + tx.GetMsgs(), protoTx.GetMemo(), tip, + ), nil + } + return legacytx.StdSignBytes( data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), - legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()}, - tx.GetMsgs(), protoTx.GetMemo(), + legacytx.StdFee{ + Amount: protoTx.GetFee(), + Gas: protoTx.GetGas(), + Payer: protoTx.tx.AuthInfo.Fee.Payer, + Granter: protoTx.tx.AuthInfo.Fee.Granter, + }, + tx.GetMsgs(), protoTx.GetMemo(), tip, ), nil } diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 893d06f5ff2d..9734e7704eea 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -8,6 +8,7 @@ import ( cdctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -33,17 +34,79 @@ func buildTx(t *testing.T, bldr *wrapper) { } func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { - bldr := newBuilder() - buildTx(t, bldr) - tx := bldr.GetTx() - var ( - chainId = "test-chain" - accNum uint64 = 7 - seqNum uint64 = 7 + chainId = "test-chain" + accNum uint64 = 7 + seqNum uint64 = 7 + tip *tx.Tip = &tx.Tip{Tipper: addr1.String(), Amount: coins} ) + testcases := []struct { + name string + signer string + malleate func(*wrapper) + expectedSignBz []byte + }{ + { + "signer which is also fee payer (no tips)", addr1.String(), + func(w *wrapper) {}, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, nil), + }, + { + "signer which is also fee payer (with tips)", addr2.String(), + func(w *wrapper) { w.SetTip(tip) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, tip), + }, + { + "explicit fee payer", addr1.String(), + func(w *wrapper) { w.SetFeePayer(addr2) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String()}, []sdk.Msg{msg}, memo, nil), + }, + { + "explicit fee granter", addr1.String(), + func(w *wrapper) { w.SetFeeGranter(addr2) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Granter: addr2.String()}, []sdk.Msg{msg}, memo, nil), + }, + { + "explicit fee payer and fee granter", addr1.String(), + func(w *wrapper) { + w.SetFeePayer(addr2) + w.SetFeeGranter(addr2) + }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String(), Granter: addr2.String()}, []sdk.Msg{msg}, memo, nil), + }, + { + "signer which is also tipper", addr1.String(), + func(w *wrapper) { w.SetTip(tip) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{}, []sdk.Msg{msg}, memo, tip), + }, + } + handler := signModeLegacyAminoJSONHandler{} + for _, tc := range testcases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + bldr := newBuilder() + buildTx(t, bldr) + tx := bldr.GetTx() + tc.malleate(bldr) + + signingData := signing.SignerData{ + Address: tc.signer, + ChainID: chainId, + AccountNumber: accNum, + Sequence: seqNum, + } + signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + require.NoError(t, err) + + require.Equal(t, tc.expectedSignBz, signBz) + }) + } + + bldr := newBuilder() + buildTx(t, bldr) + tx := bldr.GetTx() signingData := signing.SignerData{ Address: addr1.String(), ChainID: chainId, @@ -51,18 +114,9 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { Sequence: seqNum, SignerIndex: 0, } - signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) - require.NoError(t, err) - - expectedSignBz := legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{ - Amount: coins, - Gas: gas, - }, []sdk.Msg{msg}, memo) - - require.Equal(t, expectedSignBz, signBz) // expect error with wrong sign mode - _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx) + _, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx) require.Error(t, err) // expect error with extension options @@ -72,7 +126,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { require.NoError(t, err) bldr.tx.Body.ExtensionOptions = []*cdctypes.Any{any} tx = bldr.GetTx() - signBz, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.Error(t, err) // expect error with non-critical extension options @@ -80,7 +134,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { buildTx(t, bldr) bldr.tx.Body.NonCriticalExtensionOptions = []*cdctypes.Any{any} tx = bldr.GetTx() - signBz, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.Error(t, err) } From 8d70efa79988f1514347a6ced08d6f26530f2d8f Mon Sep 17 00:00:00 2001 From: MD Aleem <72057206+aleem1314@users.noreply.github.com> Date: Mon, 25 Oct 2021 02:22:26 +0530 Subject: [PATCH 02/38] fix: fix cosmovisor test (#10424) * fix: fix cosmovisor test * fix: fix failing test Co-authored-by: Marko --- cosmovisor/upgrade_test.go | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/cosmovisor/upgrade_test.go b/cosmovisor/upgrade_test.go index e33ccad788ca..faf7d7cff0de 100644 --- a/cosmovisor/upgrade_test.go +++ b/cosmovisor/upgrade_test.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package cosmovisor_test @@ -208,18 +209,18 @@ func (s *upgradeTestSuite) TestDownloadBinary() { canDownload: false, }, "get zipped directory": { - url: "./testdata/repo/zip_directory/autod.zip", + url: "./testdata/repo/chain3-zip_dir/autod.zip", canDownload: true, validBinary: true, }, "get zipped directory with valid checksum": { - // sha256sum ./testdata/repo/zip_directory/autod.zip - url: "./testdata/repo/zip_directory/autod.zip?checksum=sha256:3784e4574cad69b67e34d4ea4425eff140063a3870270a301d6bb24a098a27ae", + // sha256sum ./testdata/repo/chain3-zip_dir/autod.zip + url: "./testdata/repo/chain3-zip_dir/autod.zip?checksum=sha256:8951f52a0aea8617de0ae459a20daf704c29d259c425e60d520e363df0f166b4", canDownload: true, validBinary: true, }, "get zipped directory with invalid checksum": { - url: "./testdata/repo/zip_directory/autod.zip?checksum=sha256:73e2bd6cbb99261733caf137015d5cc58e3f96248d8b01da68be8564989dd906", + url: "./testdata/repo/chain3-zip_dir/autod.zip?checksum=sha256:73e2bd6cbb99261733caf137015d5cc58e3f96248d8b01da68be8564989dd906", canDownload: false, }, "invalid url": { @@ -255,15 +256,15 @@ func (s *upgradeTestSuite) TestDownloadBinary() { err = cosmovisor.DownloadBinary(cfg, info) if !tc.canDownload { s.Require().Error(err) - return - } - s.Require().NoError(err) - - err = cosmovisor.EnsureBinary(cfg.UpgradeBin(upgrade)) - if tc.validBinary { - s.Require().NoError(err) } else { - s.Require().Error(err) + s.Require().NoError(err) + + err = cosmovisor.EnsureBinary(cfg.UpgradeBin(upgrade)) + if tc.validBinary { + s.Require().NoError(err) + } else { + s.Require().Error(err) + } } } } From 1326fa2a7dfc3d83cf23dc1c1f33ff131152ad60 Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Sun, 24 Oct 2021 16:37:37 -0500 Subject: [PATCH 03/38] feat: ADR-038 Part 2: StreamingService interface, file writing implementation, and configuration (#8664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Hello 👋 this PR introduces the second stage of changes to support [ADR-038](https://github.com/cosmos/cosmos-sdk/pull/8012) state listening. This is rebased on top of the [first segment](https://github.com/cosmos/cosmos-sdk/pull/8551), which introduces the low level changes to the MultiStore and KVStore interfaces and implementations, the new WriteListener types, and the new listen.KVStore type. In this segment we introduce the StreamingService interface, an implementation that writes out to files, and it's integration and configuration at the BaseApp level. The idea was to have the first segment reviewed independently first but if people think it is easier/more time efficient to review both at the same time then we could start here. Thanks! This work is towards satisfying [ADR-038](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-038-state-listening.md) --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [x] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [x] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). - [x] Wrote unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] Updated relevant documentation (`docs/`) or specification (`x//spec/`) - [x] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [x] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` - [x] Re-reviewed `Files changed` in the Github PR explorer - [x] Review `Codecov Report` in the comment section below once CI passes --- CHANGELOG.md | 1 + baseapp/abci.go | 31 +- baseapp/baseapp.go | 4 + baseapp/options.go | 11 + baseapp/streaming.go | 33 ++ docs/architecture/adr-038-state-listening.md | 212 ++++++---- docs/core/store.md | 10 + simapp/app.go | 7 + store/cachemulti/store.go | 12 +- store/streaming/README.md | 67 ++++ store/streaming/constructor.go | 137 +++++++ store/streaming/constructor_test.go | 43 ++ store/streaming/file/README.md | 64 +++ store/streaming/file/example_config.toml | 10 + store/streaming/file/service.go | 279 +++++++++++++ store/streaming/file/service_test.go | 401 +++++++++++++++++++ 16 files changed, 1229 insertions(+), 93 deletions(-) create mode 100644 baseapp/streaming.go create mode 100644 store/streaming/README.md create mode 100644 store/streaming/constructor.go create mode 100644 store/streaming/constructor_test.go create mode 100644 store/streaming/file/README.md create mode 100644 store/streaming/file/example_config.toml create mode 100644 store/streaming/file/service.go create mode 100644 store/streaming/file/service_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ff7a44201e69..21ba59c3ad77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#9776](https://github.com/cosmos/cosmos-sdk/pull/9776) Add flag `staking-bond-denom` to specify the staking bond denomination value when initializing a new chain. * [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination. * (bank) [\#9618](https://github.com/cosmos/cosmos-sdk/pull/9618) Update bank.Metadata: add URI and URIHash attributes. +* (store) [\#8664](https://github.com/cosmos/cosmos-sdk/pull/8664) Implementation of ADR-038 file StreamingService * [\#9837](https://github.com/cosmos/cosmos-sdk/issues/9837) `--generate-only` flag will accept the keyname now. * [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. diff --git a/baseapp/abci.go b/baseapp/abci.go index fca332fe1857..a5b142b51571 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -195,6 +195,14 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg } // set the signed validators for addition to context in deliverTx app.voteInfos = req.LastCommitInfo.GetVotes() + + // call the hooks with the BeginBlock messages + for _, streamingListener := range app.abciListeners { + if err := streamingListener.ListenBeginBlock(app.deliverState.ctx, req, res); err != nil { + app.logger.Error("BeginBlock listening hook failed", "height", req.Header.Height, "err", err) + } + } + return res } @@ -215,6 +223,13 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc res.ConsensusParamUpdates = cp } + // call the streaming service hooks with the EndBlock messages + for _, streamingListener := range app.abciListeners { + if err := streamingListener.ListenEndBlock(app.deliverState.ctx, req, res); err != nil { + app.logger.Error("EndBlock listening hook failed", "height", req.Height, "err", err) + } + } + return res } @@ -262,15 +277,25 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx") + var res abci.ResponseDeliverTx + defer func() { + for _, streamingListener := range app.abciListeners { + if err := streamingListener.ListenDeliverTx(app.deliverState.ctx, req, res); err != nil { + app.logger.Error("DeliverTx listening hook failed", "err", err) + } + } + }() tx, err := app.txDecoder(req.Tx) if err != nil { - return sdkerrors.ResponseDeliverTx(err, 0, 0, app.trace) + res = sdkerrors.ResponseDeliverTx(err, 0, 0, app.trace) + return res } ctx := app.getContextForTx(runTxModeDeliver, req.Tx) - res, err := app.txHandler.DeliverTx(ctx, tx, req) + res, err = app.txHandler.DeliverTx(ctx, tx, req) if err != nil { - return sdkerrors.ResponseDeliverTx(err, uint64(res.GasUsed), uint64(res.GasWanted), app.trace) + res = sdkerrors.ResponseDeliverTx(err, uint64(res.GasUsed), uint64(res.GasWanted), app.trace) + return res } return res diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 54cb68e74138..ec9fb28ad449 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -125,6 +125,10 @@ type BaseApp struct { // nolint: maligned // indexEvents defines the set of events in the form {eventType}.{attributeKey}, // which informs Tendermint what to index. If empty, all events will be indexed. indexEvents map[string]struct{} + + // abciListeners for hooking into the ABCI message processing of the BaseApp + // and exposing the requests and responses to external consumers + abciListeners []ABCIListener } // NewBaseApp returns a reference to an initialized BaseApp. It accepts a diff --git a/baseapp/options.go b/baseapp/options.go index b0b3af2ca70c..1d74d1229c3f 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -229,3 +229,14 @@ func (app *BaseApp) SetInterfaceRegistry(registry types.InterfaceRegistry) { app.interfaceRegistry = registry app.grpcQueryRouter.SetInterfaceRegistry(registry) } + +// SetStreamingService is used to set a streaming service into the BaseApp hooks and load the listeners into the multistore +func (app *BaseApp) SetStreamingService(s StreamingService) { + // add the listeners for each StoreKey + for key, lis := range s.Listeners() { + app.cms.AddListeners(key, lis) + } + // register the StreamingService within the BaseApp + // BaseApp will pass BeginBlock, DeliverTx, and EndBlock requests and responses to the streaming services to update their ABCI context + app.abciListeners = append(app.abciListeners, s) +} diff --git a/baseapp/streaming.go b/baseapp/streaming.go new file mode 100644 index 000000000000..39e0f1ca6e9b --- /dev/null +++ b/baseapp/streaming.go @@ -0,0 +1,33 @@ +package baseapp + +import ( + "io" + "sync" + + abci "github.com/tendermint/tendermint/abci/types" + + store "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/types" +) + +// ABCIListener interface used to hook into the ABCI message processing of the BaseApp +type ABCIListener interface { + // ListenBeginBlock updates the streaming service with the latest BeginBlock messages + ListenBeginBlock(ctx types.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error + // ListenEndBlock updates the steaming service with the latest EndBlock messages + ListenEndBlock(ctx types.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error + // ListenDeliverTx updates the steaming service with the latest DeliverTx messages + ListenDeliverTx(ctx types.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error +} + +// StreamingService interface for registering WriteListeners with the BaseApp and updating the service with the ABCI messages using the hooks +type StreamingService interface { + // Stream is the streaming service loop, awaits kv pairs and writes them to some destination stream or file + Stream(wg *sync.WaitGroup) error + // Listeners returns the streaming service's listeners for the BaseApp to register + Listeners() map[store.StoreKey][]store.WriteListener + // ABCIListener interface for hooking into the ABCI messages from inside the BaseApp + ABCIListener + // Closer interface + io.Closer +} diff --git a/docs/architecture/adr-038-state-listening.md b/docs/architecture/adr-038-state-listening.md index 9bc644dddb26..e6d321e8cfbd 100644 --- a/docs/architecture/adr-038-state-listening.md +++ b/docs/architecture/adr-038-state-listening.md @@ -32,7 +32,7 @@ In a new file, `store/types/listening.go`, we will create a `WriteListener` inte type WriteListener interface { // if value is nil then it was deleted // storeKey indicates the source KVStore, to facilitate using the the same WriteListener across separate KVStores - // set bool indicates if it was a set; true: set, false: delete + // delete bool indicates if it was a delete; true: delete, false: set OnWrite(storeKey StoreKey, key []byte, value []byte, delete bool) error } ``` @@ -205,20 +205,30 @@ func (rs *Store) CacheMultiStore() types.CacheMultiStore { ### Exposing the data We will introduce a new `StreamingService` interface for exposing `WriteListener` data streams to external consumers. +In addition to streaming state changes as `StoreKVPair`s, the interface satisfies an `ABCIListener` interface that plugs into the BaseApp +and relays ABCI requests and responses so that the service can group the state changes with the ABCI requests that affected them and the ABCI responses they affected. ```go -// Hook interface used to hook into the ABCI message processing of the BaseApp -type Hook interface { - ListenBeginBlock(ctx sdk.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) // update the streaming service with the latest BeginBlock messages - ListenEndBlock(ctx sdk.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) // update the steaming service with the latest EndBlock messages - ListenDeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) // update the steaming service with the latest DeliverTx messages +// ABCIListener interface used to hook into the ABCI message processing of the BaseApp +type ABCIListener interface { + // ListenBeginBlock updates the streaming service with the latest BeginBlock messages + ListenBeginBlock(ctx types.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error + // ListenEndBlock updates the steaming service with the latest EndBlock messages + ListenEndBlock(ctx types.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error + // ListenDeliverTx updates the steaming service with the latest DeliverTx messages + ListenDeliverTx(ctx types.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error } // StreamingService interface for registering WriteListeners with the BaseApp and updating the service with the ABCI messages using the hooks type StreamingService interface { - Stream(wg *sync.WaitGroup, quitChan <-chan struct{}) // streaming service loop, awaits kv pairs and writes them to some destination stream or file - Listeners() map[sdk.StoreKey][]storeTypes.WriteListener // returns the streaming service's listeners for the BaseApp to register - Hook + // Stream is the streaming service loop, awaits kv pairs and writes them to some destination stream or file + Stream(wg *sync.WaitGroup) error + // Listeners returns the streaming service's listeners for the BaseApp to register + Listeners() map[types.StoreKey][]store.WriteListener + // ABCIListener interface for hooking into the ABCI messages from inside the BaseApp + ABCIListener + // Closer interface + io.Closer } ``` @@ -228,18 +238,45 @@ We will introduce an implementation of `StreamingService` which writes state cha This service uses the same `StoreKVPairWriteListener` for every KVStore, writing all the KV pairs from every KVStore out to the same files, relying on the `StoreKey` field in the `StoreKVPair` protobuf message to later distinguish the source for each pair. -The file naming schema is as such: +Writing to a file is the simplest approach for streaming the data out to consumers. +This approach also provides the advantages of being persistent and durable, and the files can be read directly, +or an auxiliary streaming services can read from the files and serve the data over a remote interface. + +##### Encoding + +For each pair of `BeginBlock` requests and responses, a file is created and named `block-{N}-begin`, where N is the block number. +At the head of this file the length-prefixed protobuf encoded `BeginBlock` request is written. +At the tail of this file the length-prefixed protobuf encoded `BeginBlock` response is written. +In between these two encoded messages, the state changes that occurred due to the `BeginBlock` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +For each pair of `DeliverTx` requests and responses, a file is created and named `block-{N}-tx-{M}` where N is the block number and M +is the tx number in the block (i.e. 0, 1, 2...). +At the head of this file the length-prefixed protobuf encoded `DeliverTx` request is written. +At the tail of this file the length-prefixed protobuf encoded `DeliverTx` response is written. +In between these two encoded messages, the state changes that occurred due to the `DeliverTx` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +For each pair of `EndBlock` requests and responses, a file is created and named `block-{N}-end`, where N is the block number. +At the head of this file the length-prefixed protobuf encoded `EndBlock` request is written. +At the tail of this file the length-prefixed protobuf encoded `EndBlock` response is written. +In between these two encoded messages, the state changes that occurred due to the `EndBlock` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +##### Decoding -* After every `BeginBlock` request a new file is created with the name `block-{N}-begin`, where N is the block number. All -subsequent state changes are written out to this file until the first `DeliverTx` request is received. At the head of these files, - the length-prefixed protobuf encoded `BeginBlock` request is written, and the response is written at the tail. -* After every `DeliverTx` request a new file is created with the name `block-{N}-tx-{M}` where N is the block number and M -is the tx number in the block (i.e. 0, 1, 2...). All subsequent state changes are written out to this file until the next -`DeliverTx` request is received or an `EndBlock` request is received. At the head of these files, the length-prefixed protobuf - encoded `DeliverTx` request is written, and the response is written at the tail. -* After every `EndBlock` request a new file is created with the name `block-{N}-end`, where N is the block number. All -subsequent state changes are written out to this file until the next `BeginBlock` request is received. At the head of these files, - the length-prefixed protobuf encoded `EndBlock` request is written, and the response is written at the tail. +To decode the files written in the above format we read all the bytes from a given file into memory and segment them into proto +messages based on the length-prefixing of each message. Once segmented, it is known that the first message is the ABCI request, +the last message is the ABCI response, and that every message in between is a `StoreKVPair`. This enables us to decode each segment into +the appropriate message type. + +The type of ABCI req/res, the block height, and the transaction index (where relevant) is known +from the file name, and the KVStore each `StoreKVPair` originates from is known since the `StoreKey` is included as a field in the proto message. + +##### Implementation example ```go // FileStreamingService is a concrete implementation of StreamingService that writes state changes out to a file @@ -357,10 +394,6 @@ func (fss *FileStreamingService) Stream(wg *sync.WaitGroup, quitChan <-chan stru } ``` -Writing to a file is the simplest approach for streaming the data out to consumers. -This approach also provides the advantages of being persistent and durable, and the files can be read directly, -or an auxiliary streaming services can read from the files and serve the data over a remote interface. - #### Auxiliary streaming service We will create a separate standalone process that reads and internally queues the state as it is written out to these files @@ -384,8 +417,8 @@ using the provided `AppOptions` and TOML configuration fields. We will add a new method to the `BaseApp` to enable the registration of `StreamingService`s: ```go -// RegisterStreamingService is used to register a streaming service with the BaseApp -func (app *BaseApp) RegisterHooks(s StreamingService) { +// SetStreamingService is used to register a streaming service with the BaseApp +func (app *BaseApp) SetStreamingService(s StreamingService) { // set the listeners for each StoreKey for key, lis := range s.Listeners() { app.cms.AddListeners(key, lis) @@ -474,68 +507,70 @@ Note: the actual namespace is TBD. [streamers] [streamers.file] keys = ["list", "of", "store", "keys", "we", "want", "to", "expose", "for", "this", "streaming", "service"] - writeDir = "path to the write directory" + write_dir = "path to the write directory" prefix = "optional prefix to prepend to the generated file names" ``` We will also provide a mapping of the TOML `store.streamers` "file" configuration option to a helper functions for constructing the specified streaming service. In the future, as other streaming services are added, their constructors will be added here as well. +Each configured streamer will receive the + ```go -// StreamingServiceConstructor is used to construct a streaming service -type StreamingServiceConstructor func(opts servertypes.AppOptions, keys []sdk.StoreKey) (StreamingService, error) +// ServiceConstructor is used to construct a streaming service +type ServiceConstructor func(opts serverTypes.AppOptions, keys []sdk.StoreKey, marshaller codec.BinaryMarshaler) (sdk.StreamingService, error) -// StreamingServiceType enum for specifying the type of StreamingService -type StreamingServiceType int +// ServiceType enum for specifying the type of StreamingService +type ServiceType int const ( - Unknown StreamingServiceType = iota - File - // add more in the future + Unknown ServiceType = iota + File + // add more in the future ) -// NewStreamingServiceType returns the StreamingServiceType corresponding to the provided name -func NewStreamingServiceType(name string) StreamingServiceType { - switch strings.ToLower(name) { - case "file", "f": - return File - default: - return Unknown - } -} - -// String returns the string name of a StreamingServiceType -func (sst StreamingServiceType) String() string { - switch sst { - case File: - return "file" - default: - return "" - } -} - -// StreamingServiceConstructorLookupTable is a mapping of StreamingServiceTypes to StreamingServiceConstructors -var StreamingServiceConstructorLookupTable = map[StreamingServiceType]StreamingServiceConstructor{ - File: FileStreamingConstructor, -} - -// NewStreamingServiceConstructor returns the StreamingServiceConstructor corresponding to the provided name -func NewStreamingServiceConstructor(name string) (StreamingServiceConstructor, error) { - ssType := NewStreamingServiceType(name) - if ssType == Unknown { - return nil, fmt.Errorf("unrecognized streaming service name %s", name) - } - if constructor, ok := StreamingServiceConstructorLookupTable[ssType]; ok { - return constructor, nil - } - return nil, fmt.Errorf("streaming service constructor of type %s not found", ssType.String()) -} - -// FileStreamingConstructor is the StreamingServiceConstructor function for creating a FileStreamingService -func FileStreamingConstructor(opts servertypes.AppOptions, keys []sdk.StoreKey) (StreamingService, error) { - filePrefix := cast.ToString(opts.Get("streamers.file.prefix")) - fileDir := cast.ToString(opts.Get("streamers.file.writeDir")) - return streaming.NewFileStreamingService(fileDir, filePrefix, keys), nil +// NewStreamingServiceType returns the streaming.ServiceType corresponding to the provided name +func NewStreamingServiceType(name string) ServiceType { + switch strings.ToLower(name) { + case "file", "f": + return File + default: + return Unknown + } +} + +// String returns the string name of a streaming.ServiceType +func (sst ServiceType) String() string { + switch sst { + case File: + return "file" + default: + return "" + } +} + +// ServiceConstructorLookupTable is a mapping of streaming.ServiceTypes to streaming.ServiceConstructors +var ServiceConstructorLookupTable = map[ServiceType]ServiceConstructor{ + File: NewFileStreamingService, +} + +// ServiceTypeFromString returns the streaming.ServiceConstructor corresponding to the provided name +func ServiceTypeFromString(name string) (ServiceConstructor, error) { + ssType := NewStreamingServiceType(name) + if ssType == Unknown { + return nil, fmt.Errorf("unrecognized streaming service name %s", name) + } + if constructor, ok := ServiceConstructorLookupTable[ssType]; ok { + return constructor, nil + } + return nil, fmt.Errorf("streaming service constructor of type %s not found", ssType.String()) +} + +// NewFileStreamingService is the streaming.ServiceConstructor function for creating a FileStreamingService +func NewFileStreamingService(opts serverTypes.AppOptions, keys []sdk.StoreKey, marshaller codec.BinaryMarshaler) (sdk.StreamingService, error) { + filePrefix := cast.ToString(opts.Get("streamers.file.prefix")) + fileDir := cast.ToString(opts.Get("streamers.file.write_dir")) + return file.NewStreamingService(fileDir, filePrefix, keys, marshaller) } ``` @@ -563,13 +598,24 @@ func NewSimApp( // configure state listening capabilities using AppOptions listeners := cast.ToStringSlice(appOpts.Get("store.streamers")) for _, listenerName := range listeners { - // get the store keys allowed to be exposed for this streaming service/state listeners - exposeKeyStrs := cast.ToStringSlice(appOpts.Get(fmt.Sprintf("streamers.%s.keys", listenerName)) - exposeStoreKeys = make([]storeTypes.StoreKey, 0, len(exposeKeyStrs)) - for _, keyStr := range exposeKeyStrs { - if storeKey, ok := keys[keyStr]; ok { + // get the store keys allowed to be exposed for this streaming service + exposeKeyStrs := cast.ToStringSlice(appOpts.Get(fmt.Sprintf("streamers.%s.keys", streamerName))) + var exposeStoreKeys []sdk.StoreKey + if exposeAll(exposeKeyStrs) { // if list contains `*`, expose all StoreKeys + exposeStoreKeys = make([]sdk.StoreKey, 0, len(keys)) + for _, storeKey := range keys { exposeStoreKeys = append(exposeStoreKeys, storeKey) } + } else { + exposeStoreKeys = make([]sdk.StoreKey, 0, len(exposeKeyStrs)) + for _, keyStr := range exposeKeyStrs { + if storeKey, ok := keys[keyStr]; ok { + exposeStoreKeys = append(exposeStoreKeys, storeKey) + } + } + } + if len(exposeStoreKeys) == 0 { // short circuit if we are not exposing anything + continue } // get the constructor for this listener name constructor, err := baseapp.NewStreamingServiceConstructor(listenerName) @@ -577,7 +623,7 @@ func NewSimApp( tmos.Exit(err.Error()) // or continue? } // generate the streaming service using the constructor, appOptions, and the StoreKeys we want to expose - streamingService, err := constructor(appOpts, exposeStoreKeys) + streamingService, err := constructor(appOpts, exposeStoreKeys, appCodec) if err != nil { tmos.Exit(err.Error()) } @@ -585,7 +631,7 @@ func NewSimApp( bApp.RegisterStreamingService(streamingService) // waitgroup and quit channel for optional shutdown coordination of the streaming service wg := new(sync.WaitGroup) - quitChan := new(chan struct{})) + quitChan := make(chan struct{})) // kick off the background streaming service loop streamingService.Stream(wg, quitChan) // maybe this should be done from inside BaseApp instead? } diff --git a/docs/core/store.md b/docs/core/store.md index 6f74afcf1fd7..afded48f76a2 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -222,6 +222,16 @@ When `Store.{Get, Set}()` is called, the store forwards the call to its parent, When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix. +### `ListenKv` Store + +`listenkv.Store` is a wrapper `KVStore` which provides state listening capabilities over the underlying `KVStore`. +It is applied automatically by the Cosmos SDK on any `KVStore` whose `StoreKey` is specified during state streaming configuration. +Additional information about state streaming configuration can be found in the [store/streaming/README.md](../../store/streaming/README.md). + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.44.1/store/listenkv/store.go#L11-L18 + +When `KVStore.Set` or `KVStore.Delete` methods are called, `listenkv.Store` automatically writes the operations to the set of `Store.listeners`. + ## New Store package (`store/v2`) The SDK is in the process of transitioning to use the types listed here as the default interface for state storage. At the time of writing, these cannot be used within an application and are not directly compatible with the `CommitMultiStore` and related types. diff --git a/simapp/app.go b/simapp/app.go index ebddd0b62046..4673514d4731 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -25,6 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/cosmos/cosmos-sdk/store/streaming" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -215,6 +216,12 @@ func NewSimApp( // not include this key. memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey") + // configure state listening capabilities using AppOptions + // we are doing nothing with the returned streamingServices and waitGroup in this case + if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil { + tmos.Exit(err.Error()) + } + app := &SimApp{ BaseApp: bApp, legacyAmino: legacyAmino, diff --git a/store/cachemulti/store.go b/store/cachemulti/store.go index 05637a45ff16..b60ed0465392 100644 --- a/store/cachemulti/store.go +++ b/store/cachemulti/store.go @@ -8,6 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/listenkv" + "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/types" ) @@ -49,17 +51,13 @@ func NewFromKVStore( } for key, store := range stores { - var cacheWrapped types.CacheWrap if cms.TracingEnabled() { - cacheWrapped = store.CacheWrapWithTrace(cms.traceWriter, cms.traceContext) - } else { - cacheWrapped = store.CacheWrap() + store = tracekv.NewStore(store.(types.KVStore), cms.traceWriter, cms.traceContext) } if cms.ListeningEnabled(key) { - cms.stores[key] = cacheWrapped.CacheWrapWithListeners(key, cms.listeners[key]) - } else { - cms.stores[key] = cacheWrapped + store = listenkv.NewStore(store.(types.KVStore), key, listeners[key]) } + cms.stores[key] = cachekv.NewStore(store.(types.KVStore)) } return cms diff --git a/store/streaming/README.md b/store/streaming/README.md new file mode 100644 index 000000000000..819514aef796 --- /dev/null +++ b/store/streaming/README.md @@ -0,0 +1,67 @@ +# State Streaming Service +This package contains the constructors for the `StreamingService`s used to write state changes out from individual KVStores to a +file or stream, as described in [ADR-038](../../docs/architecture/adr-038-state-listening.md) and defined in [types/streaming.go](../../baseapp/streaming.go). +The child directories contain the implementations for specific output destinations. + +Currently, a `StreamingService` implementation that writes state changes out to files is supported, in the future support for additional +output destinations can be added. + +The `StreamingService` is configured from within an App using the `AppOptions` loaded from the app.toml file: + +```toml +[store] + streamers = [ # if len(streamers) > 0 we are streaming + "file", # name of the streaming service, used by constructor + ] + +[streamers] + [streamers.file] + keys = ["list", "of", "store", "keys", "we", "want", "to", "expose", "for", "this", "streaming", "service"] + write_dir = "path to the write directory" + prefix = "optional prefix to prepend to the generated file names" +``` + +`store.streamers` contains a list of the names of the `StreamingService` implementations to employ which are used by `ServiceTypeFromString` +to return the `ServiceConstructor` for that particular implementation: + + +```go +listeners := cast.ToStringSlice(appOpts.Get("store.streamers")) +for _, listenerName := range listeners { + constructor, err := ServiceTypeFromString(listenerName) + if err != nil { + // handle error + } +} +``` + +`streamers` contains a mapping of the specific `StreamingService` implementation name to the configuration parameters for that specific service. +`streamers.x.keys` contains the list of `StoreKey` names for the KVStores to expose using this service and is required by every type of `StreamingService`. +In order to expose *all* KVStores, we can include `*` in this list. An empty list is equivalent to turning the service off. + +Additional configuration parameters are optional and specific to the implementation. +In the case of the file streaming service, `streamers.file.write_dir` contains the path to the +directory to write the files to, and `streamers.file.prefix` contains an optional prefix to prepend to the output files to prevent potential collisions +with other App `StreamingService` output files. + +The `ServiceConstructor` accepts `AppOptions`, the store keys collected using `streamers.x.keys`, a `BinaryMarshaller` and +returns a `StreamingService` implementation. The `AppOptions` are passed in to provide access to any implementation specific configuration options, +e.g. in the case of the file streaming service the `streamers.file.write_dir` and `streamers.file.prefix`. + +```go +streamingService, err := constructor(appOpts, exposeStoreKeys, appCodec) +if err != nil { + // handler error +} +``` + +The returned `StreamingService` is loaded into the BaseApp using the BaseApp's `SetStreamingService` method. +The `Stream` method is called on the service to begin the streaming process. Depending on the implementation this process +may be synchronous or asynchronous with the message processing of the state machine. + +```go +bApp.SetStreamingService(streamingService) +wg := new(sync.WaitGroup) +quitChan := make(chan struct{}) +streamingService.Stream(wg, quitChan) +``` diff --git a/store/streaming/constructor.go b/store/streaming/constructor.go new file mode 100644 index 000000000000..e576f84b83d1 --- /dev/null +++ b/store/streaming/constructor.go @@ -0,0 +1,137 @@ +package streaming + +import ( + "fmt" + "strings" + "sync" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + serverTypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/store/streaming/file" + "github.com/cosmos/cosmos-sdk/store/types" + + "github.com/spf13/cast" +) + +// ServiceConstructor is used to construct a streaming service +type ServiceConstructor func(opts serverTypes.AppOptions, keys []types.StoreKey, marshaller codec.BinaryCodec) (baseapp.StreamingService, error) + +// ServiceType enum for specifying the type of StreamingService +type ServiceType int + +const ( + Unknown ServiceType = iota + File + // add more in the future +) + +// ServiceTypeFromString returns the streaming.ServiceType corresponding to the provided name +func ServiceTypeFromString(name string) ServiceType { + switch strings.ToLower(name) { + case "file", "f": + return File + default: + return Unknown + } +} + +// String returns the string name of a streaming.ServiceType +func (sst ServiceType) String() string { + switch sst { + case File: + return "file" + default: + return "unknown" + } +} + +// ServiceConstructorLookupTable is a mapping of streaming.ServiceTypes to streaming.ServiceConstructors +var ServiceConstructorLookupTable = map[ServiceType]ServiceConstructor{ + File: NewFileStreamingService, +} + +// NewServiceConstructor returns the streaming.ServiceConstructor corresponding to the provided name +func NewServiceConstructor(name string) (ServiceConstructor, error) { + ssType := ServiceTypeFromString(name) + if ssType == Unknown { + return nil, fmt.Errorf("unrecognized streaming service name %s", name) + } + if constructor, ok := ServiceConstructorLookupTable[ssType]; ok && constructor != nil { + return constructor, nil + } + return nil, fmt.Errorf("streaming service constructor of type %s not found", ssType.String()) +} + +// NewFileStreamingService is the streaming.ServiceConstructor function for creating a FileStreamingService +func NewFileStreamingService(opts serverTypes.AppOptions, keys []types.StoreKey, marshaller codec.BinaryCodec) (baseapp.StreamingService, error) { + filePrefix := cast.ToString(opts.Get("streamers.file.prefix")) + fileDir := cast.ToString(opts.Get("streamers.file.write_dir")) + return file.NewStreamingService(fileDir, filePrefix, keys, marshaller) +} + +// LoadStreamingServices is a function for loading StreamingServices onto the BaseApp using the provided AppOptions, codec, and keys +// It returns the WaitGroup and quit channel used to synchronize with the streaming services and any error that occurs during the setup +func LoadStreamingServices(bApp *baseapp.BaseApp, appOpts serverTypes.AppOptions, appCodec codec.BinaryCodec, keys map[string]*types.KVStoreKey) ([]baseapp.StreamingService, *sync.WaitGroup, error) { + // waitgroup and quit channel for optional shutdown coordination of the streaming service(s) + wg := new(sync.WaitGroup) + // configure state listening capabilities using AppOptions + streamers := cast.ToStringSlice(appOpts.Get("store.streamers")) + activeStreamers := make([]baseapp.StreamingService, 0, len(streamers)) + for _, streamerName := range streamers { + // get the store keys allowed to be exposed for this streaming service + exposeKeyStrs := cast.ToStringSlice(appOpts.Get(fmt.Sprintf("streamers.%s.keys", streamerName))) + var exposeStoreKeys []types.StoreKey + if exposeAll(exposeKeyStrs) { // if list contains `*`, expose all StoreKeys + exposeStoreKeys = make([]types.StoreKey, 0, len(keys)) + for _, storeKey := range keys { + exposeStoreKeys = append(exposeStoreKeys, storeKey) + } + } else { + exposeStoreKeys = make([]types.StoreKey, 0, len(exposeKeyStrs)) + for _, keyStr := range exposeKeyStrs { + if storeKey, ok := keys[keyStr]; ok { + exposeStoreKeys = append(exposeStoreKeys, storeKey) + } + } + } + if len(exposeStoreKeys) == 0 { // short circuit if we are not exposing anything + continue + } + // get the constructor for this streamer name + constructor, err := NewServiceConstructor(streamerName) + if err != nil { + // close any services we may have already spun up before hitting the error on this one + for _, activeStreamer := range activeStreamers { + activeStreamer.Close() + } + return nil, nil, err + } + // generate the streaming service using the constructor, appOptions, and the StoreKeys we want to expose + streamingService, err := constructor(appOpts, exposeStoreKeys, appCodec) + if err != nil { + // close any services we may have already spun up before hitting the error on this one + for _, activeStreamer := range activeStreamers { + activeStreamer.Close() + } + return nil, nil, err + } + // register the streaming service with the BaseApp + bApp.SetStreamingService(streamingService) + // kick off the background streaming service loop + streamingService.Stream(wg) + // add to the list of active streamers + activeStreamers = append(activeStreamers, streamingService) + } + // if there are no active streamers, activeStreamers is empty (len == 0) and the waitGroup is not waiting on anything + return activeStreamers, wg, nil +} + +func exposeAll(list []string) bool { + for _, ele := range list { + if ele == "*" { + return true + } + } + return false +} diff --git a/store/streaming/constructor_test.go b/store/streaming/constructor_test.go new file mode 100644 index 000000000000..5f9d58016f68 --- /dev/null +++ b/store/streaming/constructor_test.go @@ -0,0 +1,43 @@ +package streaming + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codecTypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store/streaming/file" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/require" +) + +type fakeOptions struct{} + +func (f *fakeOptions) Get(string) interface{} { return nil } + +var ( + mockOptions = new(fakeOptions) + mockKeys = []types.StoreKey{sdk.NewKVStoreKey("mockKey1"), sdk.NewKVStoreKey("mockKey2")} + interfaceRegistry = codecTypes.NewInterfaceRegistry() + testMarshaller = codec.NewProtoCodec(interfaceRegistry) +) + +func TestStreamingServiceConstructor(t *testing.T) { + _, err := NewServiceConstructor("unexpectedName") + require.NotNil(t, err) + + constructor, err := NewServiceConstructor("file") + require.Nil(t, err) + var expectedType ServiceConstructor + require.IsType(t, expectedType, constructor) + + serv, err := constructor(mockOptions, mockKeys, testMarshaller) + require.Nil(t, err) + require.IsType(t, &file.StreamingService{}, serv) + listeners := serv.Listeners() + for _, key := range mockKeys { + _, ok := listeners[key] + require.True(t, ok) + } +} diff --git a/store/streaming/file/README.md b/store/streaming/file/README.md new file mode 100644 index 000000000000..7243f15dd0bf --- /dev/null +++ b/store/streaming/file/README.md @@ -0,0 +1,64 @@ +# File Streaming Service +This pkg contains an implementation of the [StreamingService](../../../baseapp/streaming.go) that writes +the data stream out to files on the local filesystem. This process is performed synchronously with the message processing +of the state machine. + +## Configuration + +The `file.StreamingService` is configured from within an App using the `AppOptions` loaded from the app.toml file: + +```toml +[store] + streamers = [ # if len(streamers) > 0 we are streaming + "file", # name of the streaming service, used by constructor + ] + +[streamers] + [streamers.file] + keys = ["list", "of", "store", "keys", "we", "want", "to", "expose", "for", "this", "streaming", "service"] + write_dir = "path to the write directory" + prefix = "optional prefix to prepend to the generated file names" +``` + +We turn the service on by adding its name, "file", to `store.streamers`- the list of streaming services for this App to employ. + +In `streamers.file` we include three configuration parameters for the file streaming service: +1. `streamers.x.keys` contains the list of `StoreKey` names for the KVStores to expose using this service. +In order to expose *all* KVStores, we can include `*` in this list. An empty list is equivalent to turning the service off. +2. `streamers.file.write_dir` contains the path to the directory to write the files to. +3. `streamers.file.prefix` contains an optional prefix to prepend to the output files to prevent potential collisions +with other App `StreamingService` output files. + +##### Encoding + +For each pair of `BeginBlock` requests and responses, a file is created and named `block-{N}-begin`, where N is the block number. +At the head of this file the length-prefixed protobuf encoded `BeginBlock` request is written. +At the tail of this file the length-prefixed protobuf encoded `BeginBlock` response is written. +In between these two encoded messages, the state changes that occurred due to the `BeginBlock` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +For each pair of `DeliverTx` requests and responses, a file is created and named `block-{N}-tx-{M}` where N is the block number and M +is the tx number in the block (i.e. 0, 1, 2...). +At the head of this file the length-prefixed protobuf encoded `DeliverTx` request is written. +At the tail of this file the length-prefixed protobuf encoded `DeliverTx` response is written. +In between these two encoded messages, the state changes that occurred due to the `DeliverTx` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +For each pair of `EndBlock` requests and responses, a file is created and named `block-{N}-end`, where N is the block number. +At the head of this file the length-prefixed protobuf encoded `EndBlock` request is written. +At the tail of this file the length-prefixed protobuf encoded `EndBlock` response is written. +In between these two encoded messages, the state changes that occurred due to the `EndBlock` request are written chronologically as +a series of length-prefixed protobuf encoded `StoreKVPair`s representing `Set` and `Delete` operations within the KVStores the service +is configured to listen to. + +##### Decoding + +To decode the files written in the above format we read all the bytes from a given file into memory and segment them into proto +messages based on the length-prefixing of each message. Once segmented, it is known that the first message is the ABCI request, +the last message is the ABCI response, and that every message in between is a `StoreKVPair`. This enables us to decode each segment into +the appropriate message type. + +The type of ABCI req/res, the block height, and the transaction index (where relevant) is known +from the file name, and the KVStore each `StoreKVPair` originates from is known since the `StoreKey` is included as a field in the proto message. diff --git a/store/streaming/file/example_config.toml b/store/streaming/file/example_config.toml new file mode 100644 index 000000000000..8202bd8ef559 --- /dev/null +++ b/store/streaming/file/example_config.toml @@ -0,0 +1,10 @@ +[store] + streamers = [ # if len(streamers) > 0 we are streaming + "file", # name of the streaming service, used by constructor + ] + +[streamers] + [streamers.file] + keys = ["list", "of", "store", "keys", "we", "want", "to", "expose", "for", "this", "streaming", "service"] + write_dir = "path to the write directory" + prefix = "optional prefix to prepend to the generated file names" diff --git a/store/streaming/file/service.go b/store/streaming/file/service.go new file mode 100644 index 000000000000..02feb403e99b --- /dev/null +++ b/store/streaming/file/service.go @@ -0,0 +1,279 @@ +package file + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "sync" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ baseapp.StreamingService = &StreamingService{} + +// StreamingService is a concrete implementation of StreamingService that writes state changes out to files +type StreamingService struct { + listeners map[types.StoreKey][]types.WriteListener // the listeners that will be initialized with BaseApp + srcChan <-chan []byte // the channel that all the WriteListeners write their data out to + filePrefix string // optional prefix for each of the generated files + writeDir string // directory to write files into + codec codec.BinaryCodec // marshaller used for re-marshalling the ABCI messages to write them out to the destination files + stateCache [][]byte // cache the protobuf binary encoded StoreKVPairs in the order they are received + stateCacheLock *sync.Mutex // mutex for the state cache + currentBlockNumber int64 // the current block number + currentTxIndex int64 // the index of the current tx + quitChan chan struct{} // channel to synchronize closure +} + +// IntermediateWriter is used so that we do not need to update the underlying io.Writer +// inside the StoreKVPairWriteListener everytime we begin writing to a new file +type IntermediateWriter struct { + outChan chan<- []byte +} + +// NewIntermediateWriter create an instance of an intermediateWriter that sends to the provided channel +func NewIntermediateWriter(outChan chan<- []byte) *IntermediateWriter { + return &IntermediateWriter{ + outChan: outChan, + } +} + +// Write satisfies io.Writer +func (iw *IntermediateWriter) Write(b []byte) (int, error) { + iw.outChan <- b + return len(b), nil +} + +// NewStreamingService creates a new StreamingService for the provided writeDir, (optional) filePrefix, and storeKeys +func NewStreamingService(writeDir, filePrefix string, storeKeys []types.StoreKey, c codec.BinaryCodec) (*StreamingService, error) { + listenChan := make(chan []byte) + iw := NewIntermediateWriter(listenChan) + listener := types.NewStoreKVPairWriteListener(iw, c) + listeners := make(map[types.StoreKey][]types.WriteListener, len(storeKeys)) + // in this case, we are using the same listener for each Store + for _, key := range storeKeys { + listeners[key] = append(listeners[key], listener) + } + // check that the writeDir exists and is writeable so that we can catch the error here at initialization if it is not + // we don't open a dstFile until we receive our first ABCI message + if err := isDirWriteable(writeDir); err != nil { + return nil, err + } + return &StreamingService{ + listeners: listeners, + srcChan: listenChan, + filePrefix: filePrefix, + writeDir: writeDir, + codec: c, + stateCache: make([][]byte, 0), + stateCacheLock: new(sync.Mutex), + }, nil +} + +// Listeners satisfies the baseapp.StreamingService interface +// It returns the StreamingService's underlying WriteListeners +// Use for registering the underlying WriteListeners with the BaseApp +func (fss *StreamingService) Listeners() map[types.StoreKey][]types.WriteListener { + return fss.listeners +} + +// ListenBeginBlock satisfies the baseapp.ABCIListener interface +// It writes the received BeginBlock request and response and the resulting state changes +// out to a file as described in the above the naming schema +func (fss *StreamingService) ListenBeginBlock(ctx sdk.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error { + // generate the new file + dstFile, err := fss.openBeginBlockFile(req) + if err != nil { + return err + } + // write req to file + lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedReqBytes); err != nil { + return err + } + // write all state changes cached for this stage to file + fss.stateCacheLock.Lock() + for _, stateChange := range fss.stateCache { + if _, err = dstFile.Write(stateChange); err != nil { + fss.stateCache = nil + fss.stateCacheLock.Unlock() + return err + } + } + // reset cache + fss.stateCache = nil + fss.stateCacheLock.Unlock() + // write res to file + lengthPrefixedResBytes, err := fss.codec.MarshalLengthPrefixed(&res) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil { + return err + } + // close file + return dstFile.Close() +} + +func (fss *StreamingService) openBeginBlockFile(req abci.RequestBeginBlock) (*os.File, error) { + fss.currentBlockNumber = req.GetHeader().Height + fss.currentTxIndex = 0 + fileName := fmt.Sprintf("block-%d-begin", fss.currentBlockNumber) + if fss.filePrefix != "" { + fileName = fmt.Sprintf("%s-%s", fss.filePrefix, fileName) + } + return os.OpenFile(filepath.Join(fss.writeDir, fileName), os.O_CREATE|os.O_WRONLY, 0600) +} + +// ListenDeliverTx satisfies the baseapp.ABCIListener interface +// It writes the received DeliverTx request and response and the resulting state changes +// out to a file as described in the above the naming schema +func (fss *StreamingService) ListenDeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error { + // generate the new file + dstFile, err := fss.openDeliverTxFile() + if err != nil { + return err + } + // write req to file + lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedReqBytes); err != nil { + return err + } + // write all state changes cached for this stage to file + fss.stateCacheLock.Lock() + for _, stateChange := range fss.stateCache { + if _, err = dstFile.Write(stateChange); err != nil { + fss.stateCache = nil + fss.stateCacheLock.Unlock() + return err + } + } + // reset cache + fss.stateCache = nil + fss.stateCacheLock.Unlock() + // write res to file + lengthPrefixedResBytes, err := fss.codec.MarshalLengthPrefixed(&res) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil { + return err + } + // close file + return dstFile.Close() +} + +func (fss *StreamingService) openDeliverTxFile() (*os.File, error) { + fileName := fmt.Sprintf("block-%d-tx-%d", fss.currentBlockNumber, fss.currentTxIndex) + if fss.filePrefix != "" { + fileName = fmt.Sprintf("%s-%s", fss.filePrefix, fileName) + } + fss.currentTxIndex++ + return os.OpenFile(filepath.Join(fss.writeDir, fileName), os.O_CREATE|os.O_WRONLY, 0600) +} + +// ListenEndBlock satisfies the baseapp.ABCIListener interface +// It writes the received EndBlock request and response and the resulting state changes +// out to a file as described in the above the naming schema +func (fss *StreamingService) ListenEndBlock(ctx sdk.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error { + // generate the new file + dstFile, err := fss.openEndBlockFile() + if err != nil { + return err + } + // write req to file + lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedReqBytes); err != nil { + return err + } + // write all state changes cached for this stage to file + fss.stateCacheLock.Lock() + for _, stateChange := range fss.stateCache { + if _, err = dstFile.Write(stateChange); err != nil { + fss.stateCache = nil + fss.stateCacheLock.Unlock() + return err + } + } + // reset cache + fss.stateCache = nil + fss.stateCacheLock.Unlock() + // write res to file + lengthPrefixedResBytes, err := fss.codec.MarshalLengthPrefixed(&res) + if err != nil { + return err + } + if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil { + return err + } + // close file + return dstFile.Close() +} + +func (fss *StreamingService) openEndBlockFile() (*os.File, error) { + fileName := fmt.Sprintf("block-%d-end", fss.currentBlockNumber) + if fss.filePrefix != "" { + fileName = fmt.Sprintf("%s-%s", fss.filePrefix, fileName) + } + return os.OpenFile(filepath.Join(fss.writeDir, fileName), os.O_CREATE|os.O_WRONLY, 0600) +} + +// Stream satisfies the baseapp.StreamingService interface +// It spins up a goroutine select loop which awaits length-prefixed binary encoded KV pairs +// and caches them in the order they were received +// returns an error if it is called twice +func (fss *StreamingService) Stream(wg *sync.WaitGroup) error { + if fss.quitChan != nil { + return errors.New("`Stream` has already been called. The stream needs to be closed before it can be started again") + } + fss.quitChan = make(chan struct{}) + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-fss.quitChan: + fss.quitChan = nil + return + case by := <-fss.srcChan: + fss.stateCacheLock.Lock() + fss.stateCache = append(fss.stateCache, by) + fss.stateCacheLock.Unlock() + } + } + }() + return nil +} + +// Close satisfies the io.Closer interface, which satisfies the baseapp.StreamingService interface +func (fss *StreamingService) Close() error { + close(fss.quitChan) + return nil +} + +// isDirWriteable checks if dir is writable by writing and removing a file +// to dir. It returns nil if dir is writable. +func isDirWriteable(dir string) error { + f := path.Join(dir, ".touch") + if err := ioutil.WriteFile(f, []byte(""), 0600); err != nil { + return err + } + return os.Remove(f) +} diff --git a/store/streaming/file/service_test.go b/store/streaming/file/service_test.go new file mode 100644 index 000000000000..493f2297b08c --- /dev/null +++ b/store/streaming/file/service_test.go @@ -0,0 +1,401 @@ +package file + +import ( + "encoding/binary" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codecTypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + types1 "github.com/tendermint/tendermint/proto/tendermint/types" +) + +var ( + interfaceRegistry = codecTypes.NewInterfaceRegistry() + testMarshaller = codec.NewProtoCodec(interfaceRegistry) + testStreamingService *StreamingService + testListener1, testListener2 types.WriteListener + emptyContext = sdk.Context{} + + // test abci message types + mockHash = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} + testBeginBlockReq = abci.RequestBeginBlock{ + Header: types1.Header{ + Height: 1, + }, + ByzantineValidators: []abci.Evidence{}, + Hash: mockHash, + LastCommitInfo: abci.LastCommitInfo{ + Round: 1, + Votes: []abci.VoteInfo{}, + }, + } + testBeginBlockRes = abci.ResponseBeginBlock{ + Events: []abci.Event{ + { + Type: "testEventType1", + }, + { + Type: "testEventType2", + }, + }, + } + testEndBlockReq = abci.RequestEndBlock{ + Height: 1, + } + testEndBlockRes = abci.ResponseEndBlock{ + Events: []abci.Event{}, + ConsensusParamUpdates: &abci.ConsensusParams{}, + ValidatorUpdates: []abci.ValidatorUpdate{}, + } + mockTxBytes1 = []byte{9, 8, 7, 6, 5, 4, 3, 2, 1} + testDeliverTxReq1 = abci.RequestDeliverTx{ + Tx: mockTxBytes1, + } + mockTxBytes2 = []byte{8, 7, 6, 5, 4, 3, 2} + testDeliverTxReq2 = abci.RequestDeliverTx{ + Tx: mockTxBytes2, + } + mockTxResponseData1 = []byte{1, 3, 5, 7, 9} + testDeliverTxRes1 = abci.ResponseDeliverTx{ + Events: []abci.Event{}, + Code: 1, + Codespace: "mockCodeSpace", + Data: mockTxResponseData1, + GasUsed: 2, + GasWanted: 3, + Info: "mockInfo", + Log: "mockLog", + } + mockTxResponseData2 = []byte{1, 3, 5, 7, 9} + testDeliverTxRes2 = abci.ResponseDeliverTx{ + Events: []abci.Event{}, + Code: 1, + Codespace: "mockCodeSpace", + Data: mockTxResponseData2, + GasUsed: 2, + GasWanted: 3, + Info: "mockInfo", + Log: "mockLog", + } + + // mock store keys + mockStoreKey1 = sdk.NewKVStoreKey("mockStore1") + mockStoreKey2 = sdk.NewKVStoreKey("mockStore2") + + // file stuff + testPrefix = "testPrefix" + testDir = "./.test" + + // mock state changes + mockKey1 = []byte{1, 2, 3} + mockValue1 = []byte{3, 2, 1} + mockKey2 = []byte{2, 3, 4} + mockValue2 = []byte{4, 3, 2} + mockKey3 = []byte{3, 4, 5} + mockValue3 = []byte{5, 4, 3} +) + +func TestIntermediateWriter(t *testing.T) { + outChan := make(chan []byte, 0) + iw := NewIntermediateWriter(outChan) + require.IsType(t, &IntermediateWriter{}, iw) + testBytes := []byte{1, 2, 3, 4, 5} + var length int + var err error + waitChan := make(chan struct{}, 0) + go func() { + length, err = iw.Write(testBytes) + waitChan <- struct{}{} + }() + receivedBytes := <-outChan + <-waitChan + require.Equal(t, len(testBytes), length) + require.Equal(t, testBytes, receivedBytes) + require.Nil(t, err) +} + +func TestFileStreamingService(t *testing.T) { + if os.Getenv("CI") != "" { + t.Skip("Skipping TestFileStreamingService in CI environment") + } + err := os.Mkdir(testDir, 0700) + require.Nil(t, err) + defer os.RemoveAll(testDir) + + testKeys := []types.StoreKey{mockStoreKey1, mockStoreKey2} + testStreamingService, err = NewStreamingService(testDir, testPrefix, testKeys, testMarshaller) + require.Nil(t, err) + require.IsType(t, &StreamingService{}, testStreamingService) + require.Equal(t, testPrefix, testStreamingService.filePrefix) + require.Equal(t, testDir, testStreamingService.writeDir) + require.Equal(t, testMarshaller, testStreamingService.codec) + testListener1 = testStreamingService.listeners[mockStoreKey1][0] + testListener2 = testStreamingService.listeners[mockStoreKey2][0] + wg := new(sync.WaitGroup) + testStreamingService.Stream(wg) + testListenBeginBlock(t) + testListenDeliverTx1(t) + testListenDeliverTx2(t) + testListenEndBlock(t) + testStreamingService.Close() + wg.Wait() +} + +func testListenBeginBlock(t *testing.T) { + expectedBeginBlockReqBytes, err := testMarshaller.Marshal(&testBeginBlockReq) + require.Nil(t, err) + expectedBeginBlockResBytes, err := testMarshaller.Marshal(&testBeginBlockRes) + require.Nil(t, err) + + // write state changes + testListener1.OnWrite(mockStoreKey1, mockKey1, mockValue1, false) + testListener2.OnWrite(mockStoreKey2, mockKey2, mockValue2, false) + testListener1.OnWrite(mockStoreKey1, mockKey3, mockValue3, false) + + // expected KV pairs + expectedKVPair1, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey1, + Value: mockValue1, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair2, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey2, + Value: mockValue2, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair3, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey3, + Value: mockValue3, + Delete: false, + }) + require.Nil(t, err) + + // send the ABCI messages + err = testStreamingService.ListenBeginBlock(emptyContext, testBeginBlockReq, testBeginBlockRes) + require.Nil(t, err) + + // load the file, checking that it was created with the expected name + fileName := fmt.Sprintf("%s-block-%d-begin", testPrefix, testBeginBlockReq.GetHeader().Height) + fileBytes, err := readInFile(fileName) + require.Nil(t, err) + + // segment the file into the separate gRPC messages and check the correctness of each + segments, err := segmentBytes(fileBytes) + require.Nil(t, err) + require.Equal(t, 5, len(segments)) + require.Equal(t, expectedBeginBlockReqBytes, segments[0]) + require.Equal(t, expectedKVPair1, segments[1]) + require.Equal(t, expectedKVPair2, segments[2]) + require.Equal(t, expectedKVPair3, segments[3]) + require.Equal(t, expectedBeginBlockResBytes, segments[4]) +} + +func testListenDeliverTx1(t *testing.T) { + expectedDeliverTxReq1Bytes, err := testMarshaller.Marshal(&testDeliverTxReq1) + require.Nil(t, err) + expectedDeliverTxRes1Bytes, err := testMarshaller.Marshal(&testDeliverTxRes1) + require.Nil(t, err) + + // write state changes + testListener1.OnWrite(mockStoreKey1, mockKey1, mockValue1, false) + testListener2.OnWrite(mockStoreKey2, mockKey2, mockValue2, false) + testListener1.OnWrite(mockStoreKey2, mockKey3, mockValue3, false) + + // expected KV pairs + expectedKVPair1, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey1, + Value: mockValue1, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair2, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey2, + Value: mockValue2, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair3, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey3, + Value: mockValue3, + Delete: false, + }) + require.Nil(t, err) + + // send the ABCI messages + err = testStreamingService.ListenDeliverTx(emptyContext, testDeliverTxReq1, testDeliverTxRes1) + require.Nil(t, err) + + // load the file, checking that it was created with the expected name + fileName := fmt.Sprintf("%s-block-%d-tx-%d", testPrefix, testBeginBlockReq.GetHeader().Height, 0) + fileBytes, err := readInFile(fileName) + require.Nil(t, err) + + // segment the file into the separate gRPC messages and check the correctness of each + segments, err := segmentBytes(fileBytes) + require.Nil(t, err) + require.Equal(t, 5, len(segments)) + require.Equal(t, expectedDeliverTxReq1Bytes, segments[0]) + require.Equal(t, expectedKVPair1, segments[1]) + require.Equal(t, expectedKVPair2, segments[2]) + require.Equal(t, expectedKVPair3, segments[3]) + require.Equal(t, expectedDeliverTxRes1Bytes, segments[4]) +} + +func testListenDeliverTx2(t *testing.T) { + expectedDeliverTxReq2Bytes, err := testMarshaller.Marshal(&testDeliverTxReq2) + require.Nil(t, err) + expectedDeliverTxRes2Bytes, err := testMarshaller.Marshal(&testDeliverTxRes2) + require.Nil(t, err) + + // write state changes + testListener1.OnWrite(mockStoreKey2, mockKey1, mockValue1, false) + testListener2.OnWrite(mockStoreKey1, mockKey2, mockValue2, false) + testListener1.OnWrite(mockStoreKey2, mockKey3, mockValue3, false) + + // expected KV pairs + expectedKVPair1, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey1, + Value: mockValue1, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair2, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey2, + Value: mockValue2, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair3, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey3, + Value: mockValue3, + Delete: false, + }) + require.Nil(t, err) + + // send the ABCI messages + err = testStreamingService.ListenDeliverTx(emptyContext, testDeliverTxReq2, testDeliverTxRes2) + require.Nil(t, err) + + // load the file, checking that it was created with the expected name + fileName := fmt.Sprintf("%s-block-%d-tx-%d", testPrefix, testBeginBlockReq.GetHeader().Height, 1) + fileBytes, err := readInFile(fileName) + require.Nil(t, err) + + // segment the file into the separate gRPC messages and check the correctness of each + segments, err := segmentBytes(fileBytes) + require.Nil(t, err) + require.Equal(t, 5, len(segments)) + require.Equal(t, expectedDeliverTxReq2Bytes, segments[0]) + require.Equal(t, expectedKVPair1, segments[1]) + require.Equal(t, expectedKVPair2, segments[2]) + require.Equal(t, expectedKVPair3, segments[3]) + require.Equal(t, expectedDeliverTxRes2Bytes, segments[4]) +} + +func testListenEndBlock(t *testing.T) { + expectedEndBlockReqBytes, err := testMarshaller.Marshal(&testEndBlockReq) + require.Nil(t, err) + expectedEndBlockResBytes, err := testMarshaller.Marshal(&testEndBlockRes) + require.Nil(t, err) + + // write state changes + testListener1.OnWrite(mockStoreKey1, mockKey1, mockValue1, false) + testListener2.OnWrite(mockStoreKey1, mockKey2, mockValue2, false) + testListener1.OnWrite(mockStoreKey2, mockKey3, mockValue3, false) + + // expected KV pairs + expectedKVPair1, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey1, + Value: mockValue1, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair2, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey1.Name(), + Key: mockKey2, + Value: mockValue2, + Delete: false, + }) + require.Nil(t, err) + expectedKVPair3, err := testMarshaller.Marshal(&types.StoreKVPair{ + StoreKey: mockStoreKey2.Name(), + Key: mockKey3, + Value: mockValue3, + Delete: false, + }) + require.Nil(t, err) + + // send the ABCI messages + err = testStreamingService.ListenEndBlock(emptyContext, testEndBlockReq, testEndBlockRes) + require.Nil(t, err) + + // load the file, checking that it was created with the expected name + fileName := fmt.Sprintf("%s-block-%d-end", testPrefix, testEndBlockReq.Height) + fileBytes, err := readInFile(fileName) + require.Nil(t, err) + + // segment the file into the separate gRPC messages and check the correctness of each + segments, err := segmentBytes(fileBytes) + require.Nil(t, err) + require.Equal(t, 5, len(segments)) + require.Equal(t, expectedEndBlockReqBytes, segments[0]) + require.Equal(t, expectedKVPair1, segments[1]) + require.Equal(t, expectedKVPair2, segments[2]) + require.Equal(t, expectedKVPair3, segments[3]) + require.Equal(t, expectedEndBlockResBytes, segments[4]) +} + +func readInFile(name string) ([]byte, error) { + path := filepath.Join(testDir, name) + return ioutil.ReadFile(path) +} + +// Returns all of the protobuf messages contained in the byte array as an array of byte arrays +// The messages have their length prefix removed +func segmentBytes(bz []byte) ([][]byte, error) { + var err error + segments := make([][]byte, 0) + for len(bz) > 0 { + var segment []byte + segment, bz, err = getHeadSegment(bz) + if err != nil { + return nil, err + } + segments = append(segments, segment) + } + return segments, nil +} + +// Returns the bytes for the leading protobuf object in the byte array (removing the length prefix) and returns the remainder of the byte array +func getHeadSegment(bz []byte) ([]byte, []byte, error) { + size, prefixSize := binary.Uvarint(bz) + if prefixSize < 0 { + return nil, nil, fmt.Errorf("invalid number of bytes read from length-prefixed encoding: %d", prefixSize) + } + if size > uint64(len(bz)-prefixSize) { + return nil, nil, fmt.Errorf("not enough bytes to read; want: %v, got: %v", size, len(bz)-prefixSize) + } + return bz[prefixSize:(uint64(prefixSize) + size)], bz[uint64(prefixSize)+size:], nil +} From d6699edfa9c6216ec867df490022711c7b3edbf0 Mon Sep 17 00:00:00 2001 From: atheeshp <59333759+atheeshp@users.noreply.github.com> Date: Tue, 26 Oct 2021 15:32:01 +0530 Subject: [PATCH 04/38] docs: add ibc migration docs in migration docs (#10438) ## Description Closes: #10398 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- docs/migrations/chain-upgrade-guide-044.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/migrations/chain-upgrade-guide-044.md b/docs/migrations/chain-upgrade-guide-044.md index 6d29c30a39e5..652324524a4b 100644 --- a/docs/migrations/chain-upgrade-guide-044.md +++ b/docs/migrations/chain-upgrade-guide-044.md @@ -18,6 +18,8 @@ You must upgrade to Stargate v0.42 before upgrading to v0.44. If you have not do Cosmos SDK v0.44 introduces a new way of handling chain upgrades that no longer requires exporting state to JSON, making the necesssary changes, and then creating a new chain with the modified JSON as the new genesis file. +The IBC module for the Cosmos SDK has moved to its [own repository](https://github.com/cosmos/ibc-go) for v0.42 and later versions. If you are using IBC, make sure to also go through the [IBC migration docs](https://github.com/cosmos/ibc-go/blob/main/docs/migrations/ibc-migration-043.md). + Instead of starting a new chain, the upgrade binary will read the existing database and perform in-place store migrations. This new way of handling chain upgrades can be used alongside [Cosmovisor](../run-node/cosmovisor.html) to make the upgrade process seamless. ## In-Place Store Migrations From 3cc5658c9e41bc0862c4d36fc28367b399fe044a Mon Sep 17 00:00:00 2001 From: likhita-809 <78951027+likhita-809@users.noreply.github.com> Date: Tue, 26 Oct 2021 16:36:44 +0530 Subject: [PATCH 05/38] fix: Migrate key names correctly (#10328) ## Description Closes: #10219 Migrate key names correctly when migrating from v0.42.9 to master keyring --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- client/keys/add_ledger_test.go | 5 +++-- client/keys/add_test.go | 3 +-- client/keys/delete.go | 4 ++-- client/keys/delete_test.go | 2 +- client/keys/rename.go | 3 ++- client/keys/rename_test.go | 2 +- crypto/keyring/keyring.go | 11 ++++++++--- crypto/keyring/keyring_test.go | 4 ++-- crypto/keyring/legacy_info.go | 2 ++ crypto/keyring/types.go | 1 + server/init.go | 3 +-- 11 files changed, 24 insertions(+), 16 deletions(-) diff --git a/client/keys/add_ledger_test.go b/client/keys/add_ledger_test.go index 90ffc16b78f5..e46b7e26fcc4 100644 --- a/client/keys/add_ledger_test.go +++ b/client/keys/add_ledger_test.go @@ -1,4 +1,5 @@ -//+build ledger test_ledger_mock +//go:build ledger || test_ledger_mock +// +build ledger test_ledger_mock package keys @@ -194,7 +195,7 @@ func Test_runAddCmdLedgerDryRun(t *testing.T) { } else { _, err = kb.Key("testkey") require.Error(t, err) - require.Equal(t, "testkey: key not found", err.Error()) + require.Equal(t, "testkey.info: key not found", err.Error()) } }) } diff --git a/client/keys/add_test.go b/client/keys/add_test.go index 6368fec6f1b9..edc749122259 100644 --- a/client/keys/add_test.go +++ b/client/keys/add_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/cli" "github.com/cosmos/cosmos-sdk/client" @@ -226,7 +225,7 @@ func Test_runAddCmdDryRun(t *testing.T) { } else { _, err = kb.Key("testkey") require.Error(t, err) - require.Equal(t, "testkey: key not found", err.Error()) + require.Equal(t, "testkey.info: key not found", err.Error()) } }) } diff --git a/client/keys/delete.go b/client/keys/delete.go index 939ede062303..46a269091dab 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -3,11 +3,11 @@ package keys import ( "bufio" + "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/crypto/keyring" - - "github.com/spf13/cobra" ) const ( diff --git a/client/keys/delete_test.go b/client/keys/delete_test.go index 2250eac5ce9c..b87a98da5a80 100644 --- a/client/keys/delete_test.go +++ b/client/keys/delete_test.go @@ -53,7 +53,7 @@ func Test_runDeleteCmd(t *testing.T) { err = cmd.ExecuteContext(ctx) require.Error(t, err) - require.EqualError(t, err, "blah: key not found") + require.EqualError(t, err, "blah.info: key not found") // User confirmation missing cmd.SetArgs([]string{ diff --git a/client/keys/rename.go b/client/keys/rename.go index 18326c8d356a..f703c60f20eb 100644 --- a/client/keys/rename.go +++ b/client/keys/rename.go @@ -4,10 +4,11 @@ import ( "bufio" "fmt" + "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/spf13/cobra" ) // RenameKeyCommand renames a key from the key store. diff --git a/client/keys/rename_test.go b/client/keys/rename_test.go index cf2e859648db..b32e08c096f9 100644 --- a/client/keys/rename_test.go +++ b/client/keys/rename_test.go @@ -49,7 +49,7 @@ func Test_runRenameCmd(t *testing.T) { cmd.SetArgs([]string{"blah", "blaah", fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome)}) err = cmd.ExecuteContext(ctx) require.Error(t, err) - require.EqualError(t, err, "blah: key not found") + require.EqualError(t, err, "blah.info: key not found") // User confirmation missing cmd.SetArgs([]string{ diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index 156147eaaf45..7686d18cdd6e 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -11,7 +11,6 @@ import ( "strings" "github.com/99designs/keyring" - "github.com/cosmos/go-bip39" "github.com/pkg/errors" "github.com/tendermint/crypto/bcrypt" tmcrypto "github.com/tendermint/tendermint/crypto" @@ -24,6 +23,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/go-bip39" ) // Backend options for Keyring @@ -440,6 +440,8 @@ func (ks keystore) Rename(oldName, newName string) error { return nil } +// Delete deletes a key in the keyring. `uid` represents the key name, without +// the `.info` suffix. func (ks keystore) Delete(uid string) error { k, err := ks.Key(uid) if err != nil { @@ -456,7 +458,7 @@ func (ks keystore) Delete(uid string) error { return err } - err = ks.db.Remove(uid) + err = ks.db.Remove(infoKey(uid)) if err != nil { return err } @@ -770,7 +772,7 @@ func (ks keystore) writeRecord(k *Record) error { return err } - key := k.Name + key := infoKey(k.Name) exists, err := ks.existsInDb(addr, key) if err != nil { @@ -877,6 +879,9 @@ func (ks keystore) MigrateAll() (bool, error) { // migrate converts keyring.Item from amino to proto serialization format. func (ks keystore) migrate(key string) (*Record, bool, error) { + if !(strings.HasSuffix(key, infoSuffix)) && !(strings.HasPrefix(key, sdk.Bech32PrefixAccAddr)) { + key = infoKey(key) + } item, err := ks.db.Get(key) if err != nil { return nil, false, wrapKeyNotFound(err, key) diff --git a/crypto/keyring/keyring_test.go b/crypto/keyring/keyring_test.go index 6fc968240b21..3afd35676fb7 100644 --- a/crypto/keyring/keyring_test.go +++ b/crypto/keyring/keyring_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/99designs/keyring" - bip39 "github.com/cosmos/go-bip39" + "github.com/cosmos/go-bip39" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/codec" @@ -432,7 +432,7 @@ func TestKeyringKeybaseExportImportPrivKey(t *testing.T) { // try export non existing key _, err = kb.ExportPrivKeyArmor("john3", "wrongpassword") - require.EqualError(t, err, "john3: key not found") + require.EqualError(t, err, "john3.info: key not found") } func TestInMemoryLanguage(t *testing.T) { diff --git a/crypto/keyring/legacy_info.go b/crypto/keyring/legacy_info.go index 0480fa5eb262..8b05b6a0312c 100644 --- a/crypto/keyring/legacy_info.go +++ b/crypto/keyring/legacy_info.go @@ -43,6 +43,8 @@ type legacyLocalInfo struct { Algo hd.PubKeyType `json:"algo"` } +func infoKey(name string) string { return fmt.Sprintf("%s.%s", name, infoSuffix) } + // GetType implements Info interface func (i legacyLocalInfo) GetType() KeyType { return TypeLocal diff --git a/crypto/keyring/types.go b/crypto/keyring/types.go index 307eb9b3f097..0b893ea4cccc 100644 --- a/crypto/keyring/types.go +++ b/crypto/keyring/types.go @@ -37,6 +37,7 @@ const ( // bits of entropy to draw when creating a mnemonic defaultEntropySize = 256 addressSuffix = "address" + infoSuffix = "info" ) // KeyType reflects a human-readable type for key listing. diff --git a/server/init.go b/server/init.go index e00ca1d35a70..1b6e0cdc51d7 100644 --- a/server/init.go +++ b/server/init.go @@ -3,9 +3,8 @@ package server import ( "fmt" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" ) From b565069bcfcdedbc628692b90992653dd57b18ad Mon Sep 17 00:00:00 2001 From: Marin Basic Date: Tue, 26 Oct 2021 15:14:13 +0200 Subject: [PATCH 06/38] build(deps): upgrade rosetta to 0.7.0 (#10432) ## Description Closes: #10155 Rosetta v0.7.0 introduces a new parameter while initializing Asserter. This includes more validation by passing validation config path. Since we are not using this feature, we are passing a empty string. [Here is the rosetta release changelog](https://github.com/coinbase/rosetta-sdk-go/releases/tag/v0.7.0) --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- go.mod | 2 +- go.sum | 2 ++ server/rosetta/lib/server/server.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index cba6c316d7f0..42403b96becd 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/armon/go-metrics v0.3.10 github.com/bgentry/speakeasy v0.1.0 github.com/btcsuite/btcd v0.22.0-beta - github.com/coinbase/rosetta-sdk-go v0.6.10 + github.com/coinbase/rosetta-sdk-go v0.7.0 github.com/confio/ics23/go v0.6.6 github.com/cosmos/btcutil v1.0.4 github.com/cosmos/cosmos-proto v0.0.0-20210914142853-23ed61ac79ce diff --git a/go.sum b/go.sum index c0c00448e529..f0a7eae77169 100644 --- a/go.sum +++ b/go.sum @@ -165,6 +165,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM= github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo= +github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= +github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= 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= diff --git a/server/rosetta/lib/server/server.go b/server/rosetta/lib/server/server.go index 81747511a815..1d82ce8a6ff5 100644 --- a/server/rosetta/lib/server/server.go +++ b/server/rosetta/lib/server/server.go @@ -49,6 +49,7 @@ func NewServer(settings Settings) (Server, error) { []*types.NetworkIdentifier{settings.Network}, nil, false, + "", ) if err != nil { return Server{}, fmt.Errorf("cannot build asserter: %w", err) From e01fa1ac35f2ddf59cec10dbeb37fd37b51ea41b Mon Sep 17 00:00:00 2001 From: NagaTulasi <40757909+NagaTulasi@users.noreply.github.com> Date: Tue, 26 Oct 2021 20:43:50 +0530 Subject: [PATCH 07/38] docs: Added evidence client docs (#10355) ## Description Closes: #10289 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- x/evidence/spec/07_client.md | 182 +++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 x/evidence/spec/07_client.md diff --git a/x/evidence/spec/07_client.md b/x/evidence/spec/07_client.md new file mode 100644 index 000000000000..83edd18d76b4 --- /dev/null +++ b/x/evidence/spec/07_client.md @@ -0,0 +1,182 @@ +# Client + +## CLI + +A user can query and interact with the `evidence` module using the CLI. + +### Query + +The `query` commands allows users to query `evidence` state. + +```bash +simd query evidence --help +``` +### evidence + +The `evidence` command allows users to list all evidence or evidence by hash. + +Usage: + +```bash +simd query evidence [flags] +``` +To query evidence by hash + +Example: + +```bash +simd query evidence "DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660" +``` + +Example Output: + +```bash +evidence: + consensus_address: cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h + height: 11 + power: 100 + time: "2021-10-20T16:08:38.194017624Z" +``` + +To get all evidence + +Example: + +```bash +simd query evidence +``` +Example Output: + +```bash +evidence: + consensus_address: cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h + height: 11 + power: 100 + time: "2021-10-20T16:08:38.194017624Z" +pagination: + next_key: null + total: "1" +``` + +## REST + +A user can query the `evidence` module using REST endpoints. + +### Evidence + +Get evidence by hash + +```bash +/cosmos/evidence/v1beta1/evidence/{evidence_hash} +``` + +Example: + +```bash +curl -X GET "http://localhost:1317/cosmos/evidence/v1beta1/evidence/DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660" +``` +Example Output: + +```bash +{ + "evidence": { + "consensus_address": "cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h", + "height": "11", + "power": "100", + "time": "2021-10-20T16:08:38.194017624Z" + } +} +``` + +### All evidence + +Get all evidence + +```bash +/cosmos/evidence/v1beta1/evidence +``` + +Example: + +```bash +curl -X GET "http://localhost:1317/cosmos/evidence/v1beta1/evidence" +``` +Example Output: + +```bash +{ + "evidence": [ + { + "consensus_address": "cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h", + "height": "11", + "power": "100", + "time": "2021-10-20T16:08:38.194017624Z" + } + ], + "pagination": { + "total": "1" + } +} +``` + +## gRPC + +A user can query the `evidence` module using gRPC endpoints. + +### Evidence + +Get evidence by hash + +```bash +cosmos.evidence.v1beta1.Query/Evidence +``` + +Example: + +```bash +grpcurl -plaintext -d '{"evidence_hash":"DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660"}' localhost:9090 cosmos.evidence.v1beta1.Query/Evidence +``` + +Example Output: + +```bash +{ + "evidence": { + "consensus_address": "cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h", + "height": "11", + "power": "100", + "time": "2021-10-20T16:08:38.194017624Z" + } +} +``` + +### All evidence + +Get all evidence + +```bash +cosmos.evidence.v1beta1.Query/AllEvidence +``` + +Example: + +```bash +grpcurl -plaintext localhost:9090 cosmos.evidence.v1beta1.Query/AllEvidence +``` +Example Output: + +```bash +{ + "evidence": [ + { + "consensus_address": "cosmosvalcons1ntk8eualewuprz0gamh8hnvcem2nrcdsgz563h", + "height": "11", + "power": "100", + "time": "2021-10-20T16:08:38.194017624Z" + } + ], + "pagination": { + "total": "1" + } +} +``` \ No newline at end of file From 33737f4d8a7c8d75939308281102091ffc18d0e3 Mon Sep 17 00:00:00 2001 From: NevermoreRandom <92708920+NevermoreRandom@users.noreply.github.com> Date: Wed, 27 Oct 2021 17:47:50 +0800 Subject: [PATCH 08/38] fix: use sdk.config hdpath (#10414) ## Description Other cosmos-sdk based chains cannot reset hdpath on running `app testnet` command. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + server/init.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ba59c3ad77..23d99e27e275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* [\#10414](https://github.com/cosmos/cosmos-sdk/pull/10414) Use `sdk.GetConfig().GetFullBIP44Path()` instead `sdk.FullFundraiserPath` to generate key * (rosetta) [\#10340](https://github.com/cosmos/cosmos-sdk/pull/10340) Use `GenesisChunked(ctx)` instead `Genesis(ctx)` to get genesis block height * (client) [#10226](https://github.com/cosmos/cosmos-sdk/pull/10226) Fix --home flag parsing. * [#10180](https://github.com/cosmos/cosmos-sdk/issues/10180) Documentation: make references to Cosmos SDK consistent diff --git a/server/init.go b/server/init.go index 1b6e0cdc51d7..7559dbc5ab56 100644 --- a/server/init.go +++ b/server/init.go @@ -12,7 +12,7 @@ import ( // phrase to recover the private key. func GenerateCoinKey(algo keyring.SignatureAlgo, cdc codec.Codec) (sdk.AccAddress, string, error) { // generate a private key, with recovery phrase - k, secret, err := keyring.NewInMemory(cdc).NewMnemonic("name", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, algo) + k, secret, err := keyring.NewInMemory(cdc).NewMnemonic("name", keyring.English, sdk.GetConfig().GetFullBIP44Path(), keyring.DefaultBIP39Passphrase, algo) if err != nil { return sdk.AccAddress([]byte{}), "", err } @@ -47,7 +47,7 @@ func GenerateSaveCoinKey(keybase keyring.Keyring, keyName string, overwrite bool } } - k, secret, err := keybase.NewMnemonic(keyName, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, algo) + k, secret, err := keybase.NewMnemonic(keyName, keyring.English, sdk.GetConfig().GetFullBIP44Path(), keyring.DefaultBIP39Passphrase, algo) if err != nil { return sdk.AccAddress([]byte{}), "", err } From d8196920aadc64faa85e11d2eda91cfe757d7af6 Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Wed, 27 Oct 2021 14:49:37 +0200 Subject: [PATCH 09/38] feat: Add Table-Store (aka ORM) package - `AutoUInt64Table` and `PrimaryKeyTable` (#10415) ## Description ref: #9237, #9156 This PR is a follow-up of #9751. It introduces 2 new public table types: `AutoUInt64Table` and `PrimaryKeyTable` based on the parent `table` struct introduced by #9751. Upcoming work will include: - multi-key secondary indexes - iterator and pagination - import/export genesis --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- go.sum | 2 - testutil/testdata/table.go | 4 + testutil/testdata/testdata.pb.go | 146 +++++++++--- testutil/testdata/testdata.proto | 2 + types/errors/errors.go | 2 +- x/group/go.mod | 12 +- x/group/go.sum | 28 ++- x/group/internal/orm/auto_uint64.go | 75 +++++++ x/group/internal/orm/example_test.go | 35 +++ x/group/internal/orm/generators_test.go | 18 ++ x/group/internal/orm/key_codec.go | 75 +++++++ x/group/internal/orm/key_codec_test.go | 46 ++++ x/group/internal/orm/orm_scenario_test.go | 207 ++++++++++++++++++ x/group/internal/orm/primary_key.go | 113 ++++++++++ .../internal/orm/primary_key_property_test.go | 188 ++++++++++++++++ x/group/internal/orm/primary_key_test.go | 67 ++++++ x/group/internal/orm/spec/01_table.md | 38 ++++ x/group/internal/orm/spec/README.md | 27 +-- x/group/internal/orm/testsupport.go | 70 ++++++ x/group/internal/orm/types.go | 2 +- 20 files changed, 1089 insertions(+), 68 deletions(-) create mode 100644 x/group/internal/orm/auto_uint64.go create mode 100644 x/group/internal/orm/example_test.go create mode 100644 x/group/internal/orm/generators_test.go create mode 100644 x/group/internal/orm/key_codec.go create mode 100644 x/group/internal/orm/key_codec_test.go create mode 100644 x/group/internal/orm/orm_scenario_test.go create mode 100644 x/group/internal/orm/primary_key.go create mode 100644 x/group/internal/orm/primary_key_property_test.go create mode 100644 x/group/internal/orm/primary_key_test.go create mode 100644 x/group/internal/orm/spec/01_table.md diff --git a/go.sum b/go.sum index f0a7eae77169..40118db668ec 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,6 @@ github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod 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/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM= -github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo= github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= diff --git a/testutil/testdata/table.go b/testutil/testdata/table.go index 576b911f3f0d..8faae88a451d 100644 --- a/testutil/testdata/table.go +++ b/testutil/testdata/table.go @@ -6,6 +6,10 @@ var ( ErrTest = errors.Register("table_testdata", 2, "test") ) +func (g TableModel) PrimaryKeyFields() []interface{} { + return []interface{}{g.Id} +} + func (g TableModel) ValidateBasic() error { if g.Name == "" { return errors.Wrap(ErrTest, "name") diff --git a/testutil/testdata/testdata.pb.go b/testutil/testdata/testdata.pb.go index 4894d5ec9fef..07942ea668c5 100644 --- a/testutil/testdata/testdata.pb.go +++ b/testutil/testdata/testdata.pb.go @@ -323,8 +323,10 @@ func (m *BadMultiSignature) GetMaliciousField() []byte { } type TableModel struct { - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Number uint64 `protobuf:"varint,3,opt,name=number,proto3" json:"number,omitempty"` + Metadata []byte `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` } func (m *TableModel) Reset() { *m = TableModel{} } @@ -374,6 +376,20 @@ func (m *TableModel) GetName() string { return "" } +func (m *TableModel) GetNumber() uint64 { + if m != nil { + return m.Number + } + return 0 +} + +func (m *TableModel) GetMetadata() []byte { + if m != nil { + return m.Metadata + } + return nil +} + func init() { proto.RegisterType((*Dog)(nil), "testdata.Dog") proto.RegisterType((*Cat)(nil), "testdata.Cat") @@ -387,32 +403,34 @@ func init() { func init() { proto.RegisterFile("testdata.proto", fileDescriptor_40c4782d007dfce9) } var fileDescriptor_40c4782d007dfce9 = []byte{ - // 393 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xb1, 0x8e, 0xda, 0x40, - 0x14, 0x45, 0x19, 0x0c, 0x24, 0xbc, 0x58, 0x46, 0x19, 0x51, 0x38, 0x14, 0x0e, 0x72, 0x13, 0x8a, - 0x60, 0x47, 0x41, 0x69, 0xe8, 0x80, 0x28, 0xa1, 0xa1, 0x71, 0x52, 0xa5, 0x41, 0x63, 0x3c, 0xd8, - 0x23, 0xc6, 0x9e, 0x88, 0x19, 0x47, 0x90, 0xaf, 0xd8, 0x5f, 0xd8, 0xbf, 0xd9, 0x92, 0x72, 0xcb, - 0x15, 0xfc, 0xc8, 0xca, 0x63, 0xbc, 0x50, 0x6c, 0x41, 0xe5, 0x7b, 0xef, 0xf3, 0x3d, 0x7a, 0x96, - 0x1f, 0x58, 0x8a, 0x4a, 0x15, 0x11, 0x45, 0xbc, 0xbf, 0x5b, 0xa1, 0x04, 0x7e, 0x5b, 0xf9, 0x5e, - 0x37, 0x16, 0xb1, 0xd0, 0xa1, 0x5f, 0xa8, 0x72, 0xde, 0xfb, 0x10, 0x0b, 0x11, 0x73, 0xea, 0x6b, - 0x17, 0xe6, 0x6b, 0x9f, 0x64, 0xfb, 0x72, 0xe4, 0x0e, 0xc1, 0xf8, 0x2e, 0x62, 0x8c, 0xa1, 0x21, - 0xd9, 0x7f, 0x6a, 0xa3, 0x3e, 0x1a, 0xb4, 0x03, 0xad, 0x8b, 0x2c, 0x23, 0x29, 0xb5, 0xeb, 0x65, - 0x56, 0x68, 0xf7, 0x1b, 0x18, 0x33, 0xa2, 0xb0, 0x0d, 0x6f, 0x52, 0x91, 0xb1, 0x0d, 0xdd, 0x9e, - 0x1b, 0x95, 0xc5, 0x5d, 0x68, 0x72, 0xf6, 0x8f, 0x4a, 0xdd, 0x6a, 0x06, 0xa5, 0x71, 0x7f, 0x42, - 0x7b, 0x4e, 0xe4, 0x24, 0x63, 0x29, 0xe1, 0xf8, 0x33, 0xb4, 0x88, 0x56, 0xba, 0xfb, 0xee, 0x6b, - 0xd7, 0x2b, 0xd7, 0xf3, 0xaa, 0xf5, 0xbc, 0x49, 0xb6, 0x0f, 0xce, 0xef, 0x60, 0x13, 0xd0, 0x4e, - 0xc3, 0x8c, 0x00, 0xed, 0xdc, 0x19, 0x98, 0x73, 0x22, 0x2f, 0xac, 0x11, 0x40, 0x42, 0xe4, 0xf2, - 0x06, 0x5e, 0x3b, 0xa9, 0x4a, 0xee, 0x02, 0x3a, 0x25, 0xe4, 0xc2, 0x19, 0x83, 0x55, 0x70, 0x6e, - 0x64, 0x99, 0xc9, 0x55, 0xd7, 0x0d, 0xe1, 0xfd, 0x94, 0x44, 0x8b, 0x9c, 0x2b, 0xf6, 0x8b, 0xc5, - 0x19, 0x51, 0xf9, 0x96, 0x62, 0x07, 0x40, 0x56, 0x46, 0xda, 0xa8, 0x6f, 0x0c, 0xcc, 0xe0, 0x2a, - 0xc1, 0x9f, 0xa0, 0x93, 0x12, 0xce, 0x56, 0x4c, 0xe4, 0x72, 0xb9, 0x66, 0x94, 0x47, 0x76, 0xb3, - 0x8f, 0x06, 0x66, 0x60, 0xbd, 0xc4, 0x3f, 0x8a, 0x74, 0xdc, 0x38, 0xdc, 0x7f, 0x44, 0xee, 0x17, - 0x80, 0xdf, 0x24, 0xe4, 0x74, 0x21, 0x22, 0xca, 0xb1, 0x05, 0x75, 0x16, 0xe9, 0x0d, 0x1b, 0x41, - 0x9d, 0x45, 0xaf, 0xfd, 0xa9, 0xe9, 0xfc, 0xe1, 0xe8, 0xa0, 0xc3, 0xd1, 0x41, 0x4f, 0x47, 0x07, - 0xdd, 0x9d, 0x9c, 0xda, 0xe1, 0xe4, 0xd4, 0x1e, 0x4f, 0x4e, 0xed, 0x8f, 0x17, 0x33, 0x95, 0xe4, - 0xa1, 0xb7, 0x12, 0xa9, 0xbf, 0x12, 0x32, 0x15, 0xf2, 0xfc, 0x18, 0xca, 0x68, 0xe3, 0x17, 0xa7, - 0x94, 0x2b, 0xc6, 0xfd, 0xea, 0xa6, 0xc2, 0x96, 0xfe, 0xf6, 0xd1, 0x73, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x7a, 0x9a, 0x17, 0x6f, 0x76, 0x02, 0x00, 0x00, + // 419 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xb1, 0x6e, 0xdb, 0x30, + 0x10, 0x35, 0x2d, 0xd9, 0x8d, 0xaf, 0x82, 0x82, 0x12, 0x46, 0xa1, 0x7a, 0x50, 0x0d, 0x2d, 0xf5, + 0xd0, 0x48, 0x40, 0x83, 0x2e, 0xd9, 0x92, 0x14, 0xad, 0x17, 0x2f, 0x6a, 0xa7, 0x2e, 0x01, 0x65, + 0x32, 0x12, 0x11, 0x52, 0x2c, 0x44, 0xaa, 0x48, 0xfa, 0x15, 0xfd, 0x85, 0xfe, 0x4d, 0x47, 0x8f, + 0x1d, 0x0b, 0xfb, 0x47, 0x0a, 0x51, 0x92, 0xed, 0xa1, 0x83, 0x27, 0xbe, 0xf7, 0xee, 0xde, 0xe3, + 0x81, 0x3c, 0xf0, 0x0d, 0xd3, 0x86, 0x12, 0x43, 0xe2, 0x6f, 0x95, 0x32, 0x0a, 0x9f, 0xf5, 0x7c, + 0x36, 0xcd, 0x55, 0xae, 0xac, 0x98, 0x34, 0xa8, 0xad, 0xcf, 0x5e, 0xe5, 0x4a, 0xe5, 0x82, 0x25, + 0x96, 0x65, 0xf5, 0x7d, 0x42, 0xca, 0xa7, 0xb6, 0x14, 0x5d, 0x80, 0xf3, 0x41, 0xe5, 0x18, 0x83, + 0xab, 0xf9, 0x0f, 0x16, 0xa0, 0x39, 0x5a, 0x4c, 0x52, 0x8b, 0x1b, 0xad, 0x24, 0x92, 0x05, 0xc3, + 0x56, 0x6b, 0x70, 0xf4, 0x1e, 0x9c, 0x5b, 0x62, 0x70, 0x00, 0xcf, 0xa4, 0x2a, 0xf9, 0x03, 0xab, + 0x3a, 0x47, 0x4f, 0xf1, 0x14, 0x46, 0x82, 0x7f, 0x67, 0xda, 0xba, 0x46, 0x69, 0x4b, 0xa2, 0x4f, + 0x30, 0x59, 0x12, 0x7d, 0x5d, 0x72, 0x49, 0x04, 0x7e, 0x0b, 0x63, 0x62, 0x91, 0xf5, 0x3e, 0x7f, + 0x37, 0x8d, 0xdb, 0xf1, 0xe2, 0x7e, 0xbc, 0xf8, 0xba, 0x7c, 0x4a, 0xbb, 0x1e, 0xec, 0x01, 0x7a, + 0xb4, 0x61, 0x4e, 0x8a, 0x1e, 0xa3, 0x5b, 0xf0, 0x96, 0x44, 0x1f, 0xb2, 0x2e, 0x01, 0x0a, 0xa2, + 0xef, 0x4e, 0xc8, 0x9b, 0x14, 0xbd, 0x29, 0x5a, 0xc1, 0x79, 0x1b, 0x72, 0xc8, 0xb9, 0x02, 0xbf, + 0xc9, 0x39, 0x31, 0xcb, 0x2b, 0x8e, 0xbc, 0x51, 0x06, 0x2f, 0x6e, 0x08, 0x5d, 0xd5, 0xc2, 0xf0, + 0xcf, 0x3c, 0x2f, 0x89, 0xa9, 0x2b, 0x86, 0x43, 0x00, 0xdd, 0x13, 0x1d, 0xa0, 0xb9, 0xb3, 0xf0, + 0xd2, 0x23, 0x05, 0xbf, 0x81, 0x73, 0x49, 0x04, 0x5f, 0x73, 0x55, 0xeb, 0xbb, 0x7b, 0xce, 0x04, + 0x0d, 0x46, 0x73, 0xb4, 0xf0, 0x52, 0x7f, 0x2f, 0x7f, 0x6c, 0xd4, 0x2b, 0x77, 0xf3, 0xeb, 0x35, + 0x8a, 0x28, 0xc0, 0x17, 0x92, 0x09, 0xb6, 0x52, 0x94, 0x09, 0xec, 0xc3, 0x90, 0x53, 0x3b, 0xa1, + 0x9b, 0x0e, 0x39, 0xfd, 0xdf, 0x4f, 0xe1, 0x97, 0x30, 0x2e, 0x6b, 0x99, 0xb1, 0x2a, 0x70, 0x6c, + 0x5f, 0xc7, 0xf0, 0x0c, 0xce, 0x24, 0x33, 0xa4, 0xd9, 0x96, 0xc0, 0xb5, 0x37, 0xee, 0xf9, 0xcd, + 0xf2, 0xf7, 0x36, 0x44, 0x9b, 0x6d, 0x88, 0xfe, 0x6e, 0x43, 0xf4, 0x73, 0x17, 0x0e, 0x36, 0xbb, + 0x70, 0xf0, 0x67, 0x17, 0x0e, 0xbe, 0xc6, 0x39, 0x37, 0x45, 0x9d, 0xc5, 0x6b, 0x25, 0x93, 0xb5, + 0xd2, 0x52, 0xe9, 0xee, 0xb8, 0xd0, 0xf4, 0x21, 0x69, 0xd6, 0xaf, 0x36, 0x5c, 0x24, 0xfd, 0x1e, + 0x66, 0x63, 0xfb, 0x5e, 0x97, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x8f, 0xef, 0x9c, 0xaa, + 0x02, 0x00, 0x00, } func (m *Dog) Marshal() (dAtA []byte, err error) { @@ -660,6 +678,18 @@ func (m *TableModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Metadata) > 0 { + i -= len(m.Metadata) + copy(dAtA[i:], m.Metadata) + i = encodeVarintTestdata(dAtA, i, uint64(len(m.Metadata))) + i-- + dAtA[i] = 0x22 + } + if m.Number != 0 { + i = encodeVarintTestdata(dAtA, i, uint64(m.Number)) + i-- + dAtA[i] = 0x18 + } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) @@ -796,6 +826,13 @@ func (m *TableModel) Size() (n int) { if l > 0 { n += 1 + l + sovTestdata(uint64(l)) } + if m.Number != 0 { + n += 1 + sovTestdata(uint64(m.Number)) + } + l = len(m.Metadata) + if l > 0 { + n += 1 + l + sovTestdata(uint64(l)) + } return n } @@ -1494,6 +1531,59 @@ func (m *TableModel) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Number", wireType) + } + m.Number = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTestdata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Number |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTestdata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTestdata + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTestdata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Metadata = append(m.Metadata[:0], dAtA[iNdEx:postIndex]...) + if m.Metadata == nil { + m.Metadata = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTestdata(dAtA[iNdEx:]) diff --git a/testutil/testdata/testdata.proto b/testutil/testdata/testdata.proto index 1da9aef16e8e..b46cbf031df7 100644 --- a/testutil/testdata/testdata.proto +++ b/testutil/testdata/testdata.proto @@ -39,4 +39,6 @@ message BadMultiSignature { message TableModel { uint64 id = 1; string name = 2; + uint64 number = 3; + bytes metadata = 4; } diff --git a/types/errors/errors.go b/types/errors/errors.go index 29ba3195f146..ece008e10da1 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -170,7 +170,7 @@ var ( ErrORMEmptyModel = Register(ormCodespace, 45, "invalid argument") // ErrORMKeyMaxLength defines an error when a key exceeds max length - ErrORMKeyMaxLength = Register(ormCodespace, 46, "index key exceeds max length") + ErrORMKeyMaxLength = Register(ormCodespace, 46, "key exceeds max length") // ErrORMEmptyKey defines an error for an empty key ErrORMEmptyKey = Register(ormCodespace, 47, "cannot use empty key") diff --git a/x/group/go.mod b/x/group/go.mod index be3763bc17b8..5941713b48c5 100644 --- a/x/group/go.mod +++ b/x/group/go.mod @@ -17,7 +17,7 @@ require github.com/tendermint/tm-db v0.6.4 require ( github.com/DataDog/zstd v1.4.5 // indirect - github.com/armon/go-metrics v0.3.9 // indirect + github.com/armon/go-metrics v0.3.10 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd v0.22.0-beta // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -27,12 +27,13 @@ require ( github.com/cosmos/iavl v0.17.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgraph-io/badger/v2 v2.2007.2 // indirect - github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-kit/kit v0.10.0 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/btree v1.0.0 // indirect @@ -44,6 +45,7 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 // indirect github.com/libp2p/go-buffer-pool v0.0.2 // indirect github.com/magiconair/properties v1.8.5 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -56,7 +58,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.11.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.31.1 // indirect + github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect github.com/spf13/afero v1.6.0 // indirect @@ -69,7 +71,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tendermint/tendermint v0.34.13 // indirect + github.com/tendermint/tendermint v0.34.14 // indirect go.etcd.io/bbolt v1.3.5 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f // indirect @@ -87,3 +89,5 @@ replace google.golang.org/grpc => google.golang.org/grpc v1.33.2 replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 replace github.com/cosmos/cosmos-sdk => ../../ + +replace github.com/cosmos/cosmos-sdk/db => ../../db diff --git a/x/group/go.sum b/x/group/go.sum index 1de48c261123..fdb0cd5ac51a 100644 --- a/x/group/go.sum +++ b/x/group/go.sum @@ -101,8 +101,8 @@ github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1: 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.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -162,8 +162,8 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80 github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= 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/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM= -github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo= +github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= +github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= 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= @@ -217,9 +217,11 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM 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/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E= 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/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= +github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= 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/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= @@ -300,6 +302,7 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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 h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 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= @@ -342,6 +345,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW 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/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -480,7 +484,7 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= 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/jhump/protoreflect v1.10.0/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= +github.com/jhump/protoreflect v1.10.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= @@ -506,8 +510,9 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= 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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -520,6 +525,8 @@ 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 h1:nDOkLO7klmnEw1s4AyKt1Arvpgyh33uj1JmkYlJaDsk= +github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554/go.mod h1:9+Pb2/tg1PvEgW7aFx4bFhDE4bvbI03zuJ8kb7nJ9Jc= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -689,8 +696,8 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.31.1 h1:d18hG4PkHnNAKNMOmFuXFaiY8Us0nird/2m60uS1AMs= -github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 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= @@ -809,8 +816,9 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM 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.13 h1:fu+tsHudbOr5PvepjH0q47Jae59hQAvn3IqAHv2EbC8= github.com/tendermint/tendermint v0.34.13/go.mod h1:6RVVRBqwtKhA+H59APKumO+B7Nye4QXSFc6+TYxAxCI= +github.com/tendermint/tendermint v0.34.14 h1:GCXmlS8Bqd2Ix3TQCpwYLUNHe+Y+QyJsm5YE+S/FkPo= +github.com/tendermint/tendermint v0.34.14/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= 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= diff --git a/x/group/internal/orm/auto_uint64.go b/x/group/internal/orm/auto_uint64.go new file mode 100644 index 000000000000..62eb84cbbabc --- /dev/null +++ b/x/group/internal/orm/auto_uint64.go @@ -0,0 +1,75 @@ +package orm + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ Indexable = &AutoUInt64Table{} + +// AutoUInt64Table is the table type with an auto incrementing ID. +type AutoUInt64Table struct { + *table + seq Sequence +} + +// NewAutoUInt64Table creates a new AutoUInt64Table. +func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model codec.ProtoMarshaler, cdc codec.Codec) (*AutoUInt64Table, error) { + table, err := newTable(prefixData, model, cdc) + if err != nil { + return nil, err + } + return &AutoUInt64Table{ + table: table, + seq: NewSequence(prefixSeq), + }, nil +} + +// Create a new persistent object with an auto generated uint64 primary key. The +// key is returned. +// +// Create iterates through the registered callbacks that may add secondary index +// keys. +func (a AutoUInt64Table) Create(store sdk.KVStore, obj codec.ProtoMarshaler) (uint64, error) { + autoIncID := a.seq.NextVal(store) + err := a.table.Create(store, EncodeSequence(autoIncID), obj) + if err != nil { + return 0, err + } + return autoIncID, nil +} + +// Update updates the given object under the rowID key. It expects the key to +// exists already and fails with an `ErrNotFound` otherwise. Any caller must +// therefore make sure that this contract is fulfilled. Parameters must not be +// nil. +// +// Update iterates through the registered callbacks that may add or remove +// secondary index keys. +func (a AutoUInt64Table) Update(store sdk.KVStore, rowID uint64, newValue codec.ProtoMarshaler) error { + return a.table.Update(store, EncodeSequence(rowID), newValue) +} + +// Delete removes the object under the rowID key. It expects the key to exists already +// and fails with a `ErrNotFound` otherwise. Any caller must therefore make sure that this contract +// is fulfilled. +// +// Delete iterates though the registered callbacks and removes secondary index keys by them. +func (a AutoUInt64Table) Delete(store sdk.KVStore, rowID uint64) error { + return a.table.Delete(store, EncodeSequence(rowID)) +} + +// Has checks if a rowID exists. +func (a AutoUInt64Table) Has(store sdk.KVStore, rowID uint64) bool { + return a.table.Has(store, EncodeSequence(rowID)) +} + +// GetOne load the object persisted for the given RowID into the dest parameter. +// If none exists `ErrNotFound` is returned instead. Parameters must not be nil. +func (a AutoUInt64Table) GetOne(store sdk.KVStore, rowID uint64, dest codec.ProtoMarshaler) (RowID, error) { + rawRowID := EncodeSequence(rowID) + if err := a.table.GetOne(store, rawRowID, dest); err != nil { + return nil, err + } + return rawRowID, nil +} diff --git a/x/group/internal/orm/example_test.go b/x/group/internal/orm/example_test.go new file mode 100644 index 000000000000..a6bddf0b855b --- /dev/null +++ b/x/group/internal/orm/example_test.go @@ -0,0 +1,35 @@ +package orm + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/testutil/testdata" +) + +type TestKeeper struct { + autoUInt64Table *AutoUInt64Table + primaryKeyTable *PrimaryKeyTable +} + +var ( + AutoUInt64TableTablePrefix [2]byte = [2]byte{0x0} + PrimaryKeyTablePrefix [2]byte = [2]byte{0x1} + AutoUInt64TableSeqPrefix byte = 0x2 +) + +func NewTestKeeper(cdc codec.Codec) TestKeeper { + k := TestKeeper{} + + autoUInt64Table, err := NewAutoUInt64Table(AutoUInt64TableTablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + if err != nil { + panic(err.Error()) + } + k.autoUInt64Table = autoUInt64Table + + primaryKeyTable, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) + if err != nil { + panic(err.Error()) + } + k.primaryKeyTable = primaryKeyTable + + return k +} diff --git a/x/group/internal/orm/generators_test.go b/x/group/internal/orm/generators_test.go new file mode 100644 index 000000000000..0cc95eedaae0 --- /dev/null +++ b/x/group/internal/orm/generators_test.go @@ -0,0 +1,18 @@ +package orm + +import ( + "pgregory.net/rapid" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" +) + +// genTableModel generates a new table model. At the moment it doesn't +// generate empty strings for Name. +var genTableModel = rapid.Custom(func(t *rapid.T) *testdata.TableModel { + return &testdata.TableModel{ + Id: rapid.Uint64().Draw(t, "id").(uint64), + Name: rapid.StringN(1, 100, 150).Draw(t, "name").(string), + Number: rapid.Uint64().Draw(t, "number ").(uint64), + Metadata: []byte(rapid.StringN(1, 100, 150).Draw(t, "metadata").(string)), + } +}) diff --git a/x/group/internal/orm/key_codec.go b/x/group/internal/orm/key_codec.go new file mode 100644 index 000000000000..099ed1571cf1 --- /dev/null +++ b/x/group/internal/orm/key_codec.go @@ -0,0 +1,75 @@ +package orm + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/types/errors" +) + +// MaxBytesLen is the maximum allowed length for a key part of type []byte +const MaxBytesLen = 255 + +// buildKeyFromParts encodes and concatenates primary key and index parts. +// They can be []byte, string, and integer types. The function will return +// an error if there is a part of any other type. +// Key parts, except the last part, follow these rules: +// - []byte is encoded with a single byte length prefix +// - strings are null-terminated +// - integers are encoded using 8 byte big endian. +func buildKeyFromParts(parts []interface{}) ([]byte, error) { + bytesSlice := make([][]byte, len(parts)) + totalLen := 0 + var err error + for i, part := range parts { + bytesSlice[i], err = keyPartBytes(part, len(parts) > 1 && i == len(parts)-1) + if err != nil { + return nil, err + } + totalLen += len(bytesSlice[i]) + } + key := make([]byte, 0, totalLen) + for _, bs := range bytesSlice { + key = append(key, bs...) + } + return key, nil +} + +func keyPartBytes(part interface{}, last bool) ([]byte, error) { + switch v := part.(type) { + case []byte: + if last || len(v) == 0 { + return v, nil + } + return AddLengthPrefix(v), nil + case string: + if last || len(v) == 0 { + return []byte(v), nil + } + return NullTerminatedBytes(v), nil + case uint64: + return EncodeSequence(v), nil + default: + return nil, fmt.Errorf("type %T not allowed as key part", v) + } +} + +// AddLengthPrefix prefixes the byte array with its length as 8 bytes. The function will panic +// if the bytes length is bigger than 255. +func AddLengthPrefix(bytes []byte) []byte { + byteLen := len(bytes) + if byteLen > MaxBytesLen { + panic(errors.Wrap(errors.ErrORMKeyMaxLength, "Cannot create key part with an []byte of length greater than 255 bytes. Try again with a smaller []byte.")) + } + + prefixedBytes := make([]byte, 1+len(bytes)) + copy(prefixedBytes, []byte{uint8(byteLen)}) + copy(prefixedBytes[1:], bytes) + return prefixedBytes +} + +// NullTerminatedBytes converts string to byte array and null terminate it +func NullTerminatedBytes(s string) []byte { + bytes := make([]byte, len(s)+1) + copy(bytes, s) + return bytes +} diff --git a/x/group/internal/orm/key_codec_test.go b/x/group/internal/orm/key_codec_test.go new file mode 100644 index 000000000000..4c5e8dcfbe8b --- /dev/null +++ b/x/group/internal/orm/key_codec_test.go @@ -0,0 +1,46 @@ +package orm + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAddLengthPrefix(t *testing.T) { + tcs := []struct { + name string + in []byte + expected []byte + }{ + {"empty", []byte{}, []byte{0}}, + {"nil", nil, []byte{0}}, + {"some data", []byte{0, 1, 100, 200}, []byte{4, 0, 1, 100, 200}}, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + out := AddLengthPrefix(tc.in) + require.Equal(t, tc.expected, out) + }) + } + + require.Panics(t, func() { + AddLengthPrefix(make([]byte, 256)) + }) +} + +func TestNullTerminatedBytes(t *testing.T) { + tcs := []struct { + name string + in string + expected []byte + }{ + {"empty", "", []byte{0}}, + {"some data", "abc", []byte{0x61, 0x62, 0x63, 0}}, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + out := NullTerminatedBytes(tc.in) + require.Equal(t, tc.expected, out) + }) + } +} diff --git a/x/group/internal/orm/orm_scenario_test.go b/x/group/internal/orm/orm_scenario_test.go new file mode 100644 index 000000000000..ad934349ff82 --- /dev/null +++ b/x/group/internal/orm/orm_scenario_test.go @@ -0,0 +1,207 @@ +package orm + +import ( + "encoding/binary" + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" +) + +func TestKeeperEndToEndWithAutoUInt64Table(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + k := NewTestKeeper(cdc) + + tm := testdata.TableModel{ + Id: 1, + Name: "name", + Number: 123, + Metadata: []byte("metadata"), + } + // when stored + rowID, err := k.autoUInt64Table.Create(store, &tm) + require.NoError(t, err) + // then we should find it + exists := k.autoUInt64Table.Has(store, rowID) + require.True(t, exists) + + // and load it + var loaded testdata.TableModel + + binKey, err := k.autoUInt64Table.GetOne(store, rowID, &loaded) + require.NoError(t, err) + + require.Equal(t, rowID, binary.BigEndian.Uint64(binKey)) + require.Equal(t, tm, loaded) + + // when updated + tm.Name = "new name" + err = k.autoUInt64Table.Update(store, rowID, &tm) + require.NoError(t, err) + + binKey, err = k.autoUInt64Table.GetOne(store, rowID, &loaded) + require.NoError(t, err) + + require.Equal(t, rowID, binary.BigEndian.Uint64(binKey)) + require.Equal(t, tm, loaded) + + // when deleted + err = k.autoUInt64Table.Delete(store, rowID) + require.NoError(t, err) + + exists = k.autoUInt64Table.Has(store, rowID) + require.False(t, exists) +} + +func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + k := NewTestKeeper(cdc) + + tm := testdata.TableModel{ + Id: 1, + Name: "name", + Number: 123, + Metadata: []byte("metadata"), + } + // when stored + err := k.primaryKeyTable.Create(store, &tm) + require.NoError(t, err) + // then we should find it by primary key + primaryKey := PrimaryKey(&tm) + exists := k.primaryKeyTable.Has(store, primaryKey) + require.True(t, exists) + + // and load it by primary key + var loaded testdata.TableModel + err = k.primaryKeyTable.GetOne(store, primaryKey, &loaded) + require.NoError(t, err) + + // then values should match expectations + require.Equal(t, tm, loaded) + + // and when we create another entry with the same primary key + err = k.primaryKeyTable.Create(store, &tm) + // then it should fail as the primary key must be unique + require.True(t, errors.ErrORMUniqueConstraint.Is(err), err) + + // and when entity updated with new primary key + updatedMember := &testdata.TableModel{ + Id: 2, + Name: tm.Name, + Number: tm.Number, + Metadata: tm.Metadata, + } + // then it should fail as the primary key is immutable + err = k.primaryKeyTable.Update(store, updatedMember) + require.Error(t, err) + + // and when entity updated with non primary key attribute modified + updatedMember = &testdata.TableModel{ + Id: 1, + Name: "new name", + Number: tm.Number, + Metadata: tm.Metadata, + } + // then it should not fail + err = k.primaryKeyTable.Update(store, updatedMember) + require.NoError(t, err) + + // and when entity deleted + err = k.primaryKeyTable.Delete(store, &tm) + require.NoError(t, err) + + exists = k.primaryKeyTable.Has(store, primaryKey) + require.False(t, exists) +} + +func TestGasCostsPrimaryKeyTable(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + k := NewTestKeeper(cdc) + + tm := testdata.TableModel{ + Id: 1, + Name: "name", + Number: 123, + Metadata: []byte("metadata"), + } + rowID, err := k.autoUInt64Table.Create(store, &tm) + require.NoError(t, err) + require.Equal(t, uint64(1), rowID) + + gCtx := NewGasCountingMockContext() + err = k.primaryKeyTable.Create(gCtx.KVStore(store), &tm) + require.NoError(t, err) + t.Logf("gas consumed on create: %d", gCtx.GasConsumed()) + + // get by primary key + gCtx.ResetGasMeter() + var loaded testdata.TableModel + err = k.primaryKeyTable.GetOne(gCtx.KVStore(store), PrimaryKey(&tm), &loaded) + require.NoError(t, err) + t.Logf("gas consumed on get by primary key: %d", gCtx.GasConsumed()) + + // delete + gCtx.ResetGasMeter() + err = k.primaryKeyTable.Delete(gCtx.KVStore(store), &tm) + require.NoError(t, err) + t.Logf("gas consumed on delete by primary key: %d", gCtx.GasConsumed()) + + // with 3 elements + var tms []testdata.TableModel + for i := 1; i < 4; i++ { + gCtx.ResetGasMeter() + tm := testdata.TableModel{ + Id: uint64(i), + Name: fmt.Sprintf("name%d", i), + Number: 123, + Metadata: []byte("metadata"), + } + err = k.primaryKeyTable.Create(gCtx.KVStore(store), &tm) + require.NoError(t, err) + t.Logf("%d: gas consumed on create: %d", i, gCtx.GasConsumed()) + tms = append(tms, tm) + } + + for i := 1; i < 4; i++ { + gCtx.ResetGasMeter() + tm := testdata.TableModel{ + Id: uint64(i), + Name: fmt.Sprintf("name%d", i), + Number: 123, + Metadata: []byte("metadata"), + } + err = k.primaryKeyTable.GetOne(gCtx.KVStore(store), PrimaryKey(&tm), &loaded) + require.NoError(t, err) + t.Logf("%d: gas consumed on get by primary key: %d", i, gCtx.GasConsumed()) + } + + // delete + for i, m := range tms { + gCtx.ResetGasMeter() + + err = k.primaryKeyTable.Delete(gCtx.KVStore(store), &m) + require.NoError(t, err) + t.Logf("%d: gas consumed on delete: %d", i, gCtx.GasConsumed()) + } +} diff --git a/x/group/internal/orm/primary_key.go b/x/group/internal/orm/primary_key.go new file mode 100644 index 000000000000..8bfeae402dea --- /dev/null +++ b/x/group/internal/orm/primary_key.go @@ -0,0 +1,113 @@ +package orm + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ Indexable = &PrimaryKeyTable{} + +// PrimaryKeyTable provides simpler object style orm methods without passing database RowIDs. +// Entries are persisted and loaded with a reference to their unique primary key. +type PrimaryKeyTable struct { + *table +} + +// NewPrimaryKeyTable creates a new PrimaryKeyTable. +func NewPrimaryKeyTable(prefixData [2]byte, model PrimaryKeyed, cdc codec.Codec) (*PrimaryKeyTable, error) { + table, err := newTable(prefixData, model, cdc) + if err != nil { + return nil, err + } + return &PrimaryKeyTable{ + table: table, + }, nil +} + +// PrimaryKeyed defines an object type that is aware of its immutable primary key. +type PrimaryKeyed interface { + // PrimaryKeyFields returns the fields of the object that will make up + // the primary key. The PrimaryKey function will encode and concatenate + // the fields to build the primary key. + // + // PrimaryKey parts can be []byte, string, and integer types. []byte is + // encoded with a length prefix, strings are null-terminated, and + // integers are encoded using 8 byte big endian. + // + // IMPORTANT: []byte parts are encoded with a single byte length prefix, + // so cannot be longer than 255 bytes. + PrimaryKeyFields() []interface{} + codec.ProtoMarshaler +} + +// PrimaryKey returns the immutable and serialized primary key of this object. +// The primary key has to be unique within it's domain so that not two with same +// value can exist in the same table. This means PrimaryKeyFields() has to +// return a unique value for each object. +func PrimaryKey(obj PrimaryKeyed) []byte { + fields := obj.PrimaryKeyFields() + key, err := buildKeyFromParts(fields) + if err != nil { + panic(err) + } + return key +} + +// Create persists the given object under their primary key. It checks if the +// key already exists and may return an `ErrUniqueConstraint`. +// +// Create iterates through the registered callbacks that may add secondary +// index keys. +func (a PrimaryKeyTable) Create(store sdk.KVStore, obj PrimaryKeyed) error { + rowID := PrimaryKey(obj) + return a.table.Create(store, rowID, obj) +} + +// Update updates the given object under the primary key. It expects the key to +// exists already and fails with an `ErrNotFound` otherwise. Any caller must +// therefore make sure that this contract is fulfilled. Parameters must not be +// nil. +// +// Update iterates through the registered callbacks that may add or remove +// secondary index keys. +func (a PrimaryKeyTable) Update(store sdk.KVStore, newValue PrimaryKeyed) error { + return a.table.Update(store, PrimaryKey(newValue), newValue) +} + +// Set persists the given object under the rowID key. It does not check if the +// key already exists and overwrites the value if it does. +// +// Set iterates through the registered callbacks that may add secondary index +// keys. +func (a PrimaryKeyTable) Set(store sdk.KVStore, newValue PrimaryKeyed) error { + return a.table.Set(store, PrimaryKey(newValue), newValue) +} + +// Delete removes the object. It expects the primary key to exists already and +// fails with a `ErrNotFound` otherwise. Any caller must therefore make sure +// that this contract is fulfilled. +// +// Delete iterates through the registered callbacks that remove secondary index +// keys. +func (a PrimaryKeyTable) Delete(store sdk.KVStore, obj PrimaryKeyed) error { + return a.table.Delete(store, PrimaryKey(obj)) +} + +// Has checks if a key exists. Always returns false on nil or empty key. +func (a PrimaryKeyTable) Has(store sdk.KVStore, primaryKey RowID) bool { + return a.table.Has(store, primaryKey) +} + +// Contains returns true when an object with same type and primary key is persisted in this table. +func (a PrimaryKeyTable) Contains(store sdk.KVStore, obj PrimaryKeyed) bool { + if err := assertCorrectType(a.table.model, obj); err != nil { + return false + } + return a.table.Has(store, PrimaryKey(obj)) +} + +// GetOne loads the object persisted for the given primary Key into the dest parameter. +// If none exists `ErrNotFound` is returned instead. Parameters must not be nil. +func (a PrimaryKeyTable) GetOne(store sdk.KVStore, primKey RowID, dest codec.ProtoMarshaler) error { + return a.table.GetOne(store, primKey, dest) +} diff --git a/x/group/internal/orm/primary_key_property_test.go b/x/group/internal/orm/primary_key_property_test.go new file mode 100644 index 000000000000..083fd2c2944b --- /dev/null +++ b/x/group/internal/orm/primary_key_property_test.go @@ -0,0 +1,188 @@ +package orm + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "pgregory.net/rapid" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" +) + +func TestPrimaryKeyTable(t *testing.T) { + rapid.Check(t, rapid.Run(&primaryKeyMachine{})) +} + +// primaryKeyMachine is a state machine model of the PrimaryKeyTable. The state +// is modelled as a map of strings to TableModels. +type primaryKeyMachine struct { + store sdk.KVStore + table *PrimaryKeyTable + state map[string]*testdata.TableModel +} + +// stateKeys gets all the keys in the model map +func (m *primaryKeyMachine) stateKeys() []string { + keys := make([]string, len(m.state)) + + i := 0 + for k := range m.state { + keys[i] = k + i++ + } + + return keys +} + +// Generate a TableModel that has a 50% chance of being a part of the existing +// state +func (m *primaryKeyMachine) genTableModel() *rapid.Generator { + genStateTableModel := rapid.Custom(func(t *rapid.T) *testdata.TableModel { + pk := rapid.SampledFrom(m.stateKeys()).Draw(t, "key").(string) + return m.state[pk] + }) + + if len(m.stateKeys()) == 0 { + return genTableModel + } else { + return rapid.OneOf(genTableModel, genStateTableModel) + } +} + +// Init creates a new instance of the state machine model by building the real +// table and making the empty model map +func (m *primaryKeyMachine) Init(t *rapid.T) { + // Create context + ctx := NewMockContext() + m.store = ctx.KVStore(sdk.NewKVStoreKey("test")) + + // Create primary key table + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + table, err := NewPrimaryKeyTable( + [2]byte{0x1}, + &testdata.TableModel{}, + cdc, + ) + require.NoError(t, err) + + m.table = table + + // Create model state + m.state = make(map[string]*testdata.TableModel) +} + +// Check that the real values match the state values. +func (m *primaryKeyMachine) Check(t *rapid.T) { + for i := range m.state { + has := m.table.Has(m.store, []byte(i)) + require.Equal(t, true, has) + } +} + +// Create is one of the model commands. It adds an object to the table, creating +// an error if it already exists. +func (m *primaryKeyMachine) Create(t *rapid.T) { + g := genTableModel.Draw(t, "g").(*testdata.TableModel) + pk := string(PrimaryKey(g)) + + t.Logf("pk: %v", pk) + t.Logf("m.state: %v", m.state) + + err := m.table.Create(m.store, g) + + if m.state[pk] != nil { + require.Error(t, err) + } else { + require.NoError(t, err) + m.state[pk] = g + } +} + +// Update is one of the model commands. It updates the value at a given primary +// key and fails if that primary key doesn't already exist in the table. +func (m *primaryKeyMachine) Update(t *rapid.T) { + tm := m.genTableModel().Draw(t, "tm").(*testdata.TableModel) + + newName := rapid.StringN(1, 100, 150).Draw(t, "newName").(string) + tm.Name = newName + + // Perform the real Update + err := m.table.Update(m.store, tm) + + if m.state[string(PrimaryKey(tm))] == nil { + // If there's no value in the model, we expect an error + require.Error(t, err) + } else { + // If we have a value in the model, expect no error + require.NoError(t, err) + + // Update the model with the new value + m.state[string(PrimaryKey(tm))] = tm + } +} + +// Set is one of the model commands. It sets the value at a key in the table +// whether it exists or not. +func (m *primaryKeyMachine) Set(t *rapid.T) { + g := genTableModel.Draw(t, "g").(*testdata.TableModel) + pk := string(PrimaryKey(g)) + + err := m.table.Set(m.store, g) + + require.NoError(t, err) + m.state[pk] = g +} + +// Delete is one of the model commands. It removes the object with the given +// primary key from the table and returns an error if that primary key doesn't +// already exist in the table. +func (m *primaryKeyMachine) Delete(t *rapid.T) { + tm := m.genTableModel().Draw(t, "tm").(*testdata.TableModel) + + // Perform the real Delete + err := m.table.Delete(m.store, tm) + + if m.state[string(PrimaryKey(tm))] == nil { + // If there's no value in the model, we expect an error + require.Error(t, err) + } else { + // If we have a value in the model, expect no error + require.NoError(t, err) + + // Delete the value from the model + delete(m.state, string(PrimaryKey(tm))) + } +} + +// Has is one of the model commands. It checks whether a key already exists in +// the table. +func (m *primaryKeyMachine) Has(t *rapid.T) { + pk := PrimaryKey(m.genTableModel().Draw(t, "g").(*testdata.TableModel)) + + realHas := m.table.Has(m.store, pk) + modelHas := m.state[string(pk)] != nil + + require.Equal(t, realHas, modelHas) +} + +// GetOne is one of the model commands. It fetches an object from the table by +// its primary key and returns an error if that primary key isn't in the table. +func (m *primaryKeyMachine) GetOne(t *rapid.T) { + pk := PrimaryKey(m.genTableModel().Draw(t, "tm").(*testdata.TableModel)) + + var tm testdata.TableModel + + err := m.table.GetOne(m.store, pk, &tm) + t.Logf("tm: %v", tm) + + if m.state[string(pk)] == nil { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, *m.state[string(pk)], tm) + } +} diff --git a/x/group/internal/orm/primary_key_test.go b/x/group/internal/orm/primary_key_test.go new file mode 100644 index 000000000000..6338fd5ce5b8 --- /dev/null +++ b/x/group/internal/orm/primary_key_test.go @@ -0,0 +1,67 @@ +package orm + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" +) + +func TestContains(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + tb, err := NewPrimaryKeyTable([2]byte{0x1}, &testdata.TableModel{}, cdc) + require.NoError(t, err) + + obj := testdata.TableModel{ + Id: 1, + Name: "Some name", + } + err = tb.Create(store, &obj) + require.NoError(t, err) + + specs := map[string]struct { + src PrimaryKeyed + exp bool + }{ + + "same object": {src: &obj, exp: true}, + "clone": { + src: &testdata.TableModel{ + Id: 1, + Name: "Some name", + }, + exp: true, + }, + "different primary key": { + src: &testdata.TableModel{ + Id: 2, + Name: "Some name", + }, + exp: false, + }, + "different type, same key": { + src: mockPrimaryKeyed{&obj}, + exp: false, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + got := tb.Contains(store, spec.src) + assert.Equal(t, spec.exp, got) + }) + } +} + +type mockPrimaryKeyed struct { + *testdata.TableModel +} diff --git a/x/group/internal/orm/spec/01_table.md b/x/group/internal/orm/spec/01_table.md new file mode 100644 index 000000000000..6240b06467fc --- /dev/null +++ b/x/group/internal/orm/spec/01_table.md @@ -0,0 +1,38 @@ +# Table + +A table can be built given a `codec.ProtoMarshaler` model type, a prefix to access the underlying prefix store used to store table data as well as a `Codec` for marshalling/unmarshalling. + ++++ https://github.com/cosmos/cosmos-sdk/blob/9f78f16ae75cc42fc5fe636bde18a453ba74831f/x/group/internal/orm/table.go#L24-L30 + +In the prefix store, entities should be stored by an unique identifier called `RowID` which can be based either on an `uint64` auto-increment counter, string or dynamic size bytes. +Regular CRUD operations can be performed on a table, these methods take a `sdk.KVStore` as parameter to get the table prefix store. + +The `table` struct does not: + - enforce uniqueness of the `RowID` + - enforce prefix uniqueness of keys, i.e. not allowing one key to be a prefix + of another + - optimize Gas usage conditions +The `table` struct is private, so that we only have custom tables built on top of it, that do satisfy these requirements. + +## AutoUInt64Table + +`AutoUInt64Table` is a table type with an auto incrementing `uint64` ID. + ++++ https://github.com/cosmos/cosmos-sdk/blob/9f78f16ae75cc42fc5fe636bde18a453ba74831f/x/group/internal/orm/auto_uint64.go#L11-L14 + +It's based on the `Sequence` struct which is a persistent unique key generator based on a counter encoded using 8 byte big endian. + +## PrimaryKeyTable + +`PrimaryKeyTable` provides simpler object style orm methods where are persisted and loaded with a reference to their unique primary key. + +The model provided for creating a `PrimaryKeyTable` should implement the `PrimaryKeyed` interface: + ++++ https://github.com/cosmos/cosmos-sdk/blob/9f78f16ae75cc42fc5fe636bde18a453ba74831f/x/group/internal/orm/primary_key.go#L28-L41 + +`PrimaryKeyFields()` method returns the list of key parts for a given object. +The primary key parts can be []byte, string, and `uint64` types. + Key parts, except the last part, follow these rules: + - []byte is encoded with a single byte length prefix + - strings are null-terminated + - `uint64` are encoded using 8 byte big endian. diff --git a/x/group/internal/orm/spec/README.md b/x/group/internal/orm/spec/README.md index edf57ce74f27..c8eccb01f596 100644 --- a/x/group/internal/orm/spec/README.md +++ b/x/group/internal/orm/spec/README.md @@ -1,26 +1,9 @@ -## Abstract +# Abstract The orm package provides a framework for creating relational database tables with primary and secondary keys. -### Tables +## Contents -```go -type table struct { - model reflect.Type - prefix [2]byte - afterSet []AfterSetInterceptor - afterDelete []AfterDeleteInterceptor - cdc codec.Codec -} -``` - -A table can be built given a `codec.ProtoMarshaler` model type, a prefix to access the underlying prefix store used to store table data as well as a `Codec` for marshalling/unmarshalling. -In the prefix store, entities should be stored by an unique identifier called `RowID` which can be based either on an `uint64` auto-increment counter, string or dynamic size bytes. -Regular CRUD operations can be performed on a table, these methods take a `sdk.KVStore` as parameter to get the table prefix store. - -The `table` struct does not: - - enforce uniqueness of the `RowID` - - enforce prefix uniqueness of keys, i.e. not allowing one key to be a prefix - of another - - optimize Gas usage conditions -The `table` struct is private, so that we only have custom tables built on top of it, that do satisfy these requirements. \ No newline at end of file +1. **[Table](01_table.md)** + - [AutoUInt64Table](01_table.md#autouint64table) + - [PrimaryKeyTable](01_table.md#primarykeytable) diff --git a/x/group/internal/orm/testsupport.go b/x/group/internal/orm/testsupport.go index 07316145404c..df95b0f27414 100644 --- a/x/group/internal/orm/testsupport.go +++ b/x/group/internal/orm/testsupport.go @@ -1,7 +1,10 @@ package orm import ( + "fmt" + "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/gaskv" "github.com/cosmos/cosmos-sdk/store/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -31,3 +34,70 @@ func (m MockContext) KVStore(key storetypes.StoreKey) sdk.KVStore { } return m.store.GetCommitKVStore(key) } + +type debuggingGasMeter struct { + g types.GasMeter +} + +func (d debuggingGasMeter) GasConsumed() types.Gas { + return d.g.GasConsumed() +} + +func (d debuggingGasMeter) GasRemaining() types.Gas { + return d.g.GasRemaining() +} + +func (d debuggingGasMeter) GasConsumedToLimit() types.Gas { + return d.g.GasConsumedToLimit() +} + +func (d debuggingGasMeter) RefundGas(amount uint64, descriptor string) { + d.g.RefundGas(amount, descriptor) +} + +func (d debuggingGasMeter) Limit() types.Gas { + return d.g.Limit() +} + +func (d debuggingGasMeter) ConsumeGas(amount types.Gas, descriptor string) { + fmt.Printf("++ Consuming gas: %q :%d\n", descriptor, amount) + d.g.ConsumeGas(amount, descriptor) +} + +func (d debuggingGasMeter) IsPastLimit() bool { + return d.g.IsPastLimit() +} + +func (d debuggingGasMeter) IsOutOfGas() bool { + return d.g.IsOutOfGas() +} + +func (d debuggingGasMeter) String() string { + return d.g.String() +} + +type GasCountingMockContext struct { + GasMeter sdk.GasMeter +} + +func NewGasCountingMockContext() *GasCountingMockContext { + return &GasCountingMockContext{ + GasMeter: &debuggingGasMeter{sdk.NewInfiniteGasMeter()}, + } +} + +func (g GasCountingMockContext) KVStore(store sdk.KVStore) sdk.KVStore { + return gaskv.NewStore(store, g.GasMeter, types.KVGasConfig()) +} + +func (g GasCountingMockContext) GasConsumed() types.Gas { + return g.GasMeter.GasConsumed() +} + +func (g GasCountingMockContext) GasRemaining() types.Gas { + return g.GasMeter.GasRemaining() +} + +func (g *GasCountingMockContext) ResetGasMeter() { + g.GasMeter = sdk.NewInfiniteGasMeter() +} diff --git a/x/group/internal/orm/types.go b/x/group/internal/orm/types.go index 48e2f631839d..c06bbebd6de0 100644 --- a/x/group/internal/orm/types.go +++ b/x/group/internal/orm/types.go @@ -32,7 +32,7 @@ type Iterator interface { // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items the ErrORMIteratorDone error is returned // The key is the rowID. - LoadNext(dest codec.ProtoMarshaler) (RowID, error) + LoadNext(store sdk.KVStore, dest codec.ProtoMarshaler) (RowID, error) // Close releases the iterator and should be called at the end of iteration io.Closer } From 0a3660d2ac96e75edfa6ddfce8e97fccb012d19c Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 27 Oct 2021 16:13:35 +0200 Subject: [PATCH 10/38] chore: Add "Since:" on proto doc comments (#10434) ## Description ref: https://github.com/cosmos/cosmos-sdk/discussions/10406#discussioncomment-1533289 For clients to know whether a protobuf feature is available for a certain SDK version, we decided to use the [`@since` doc comment](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html#@since) inside protobuf files. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- client/grpc/tmservice/query.pb.go | 17 +-- docs/core/proto-docs.md | 102 +++++++++++++----- proto/cosmos/auth/v1beta1/query.proto | 6 ++ proto/cosmos/authz/v1beta1/authz.proto | 1 + proto/cosmos/authz/v1beta1/event.proto | 1 + proto/cosmos/authz/v1beta1/genesis.proto | 1 + proto/cosmos/authz/v1beta1/query.proto | 1 + proto/cosmos/authz/v1beta1/tx.proto | 1 + proto/cosmos/bank/v1beta1/authz.proto | 2 + proto/cosmos/bank/v1beta1/bank.proto | 8 ++ proto/cosmos/bank/v1beta1/query.proto | 4 + .../base/query/v1beta1/pagination.proto | 2 + .../base/reflection/v2alpha1/reflection.proto | 1 + .../cosmos/base/store/v1beta1/listening.proto | 2 + .../base/tendermint/v1beta1/query.proto | 1 + proto/cosmos/crypto/secp256r1/keys.proto | 1 + proto/cosmos/feegrant/v1beta1/feegrant.proto | 1 + proto/cosmos/feegrant/v1beta1/genesis.proto | 1 + proto/cosmos/feegrant/v1beta1/query.proto | 1 + proto/cosmos/feegrant/v1beta1/tx.proto | 1 + proto/cosmos/gov/v1beta1/gov.proto | 3 + proto/cosmos/gov/v1beta1/tx.proto | 6 ++ proto/cosmos/staking/v1beta1/authz.proto | 4 + proto/cosmos/tx/v1beta1/service.proto | 2 + proto/cosmos/tx/v1beta1/tx.proto | 2 + proto/cosmos/upgrade/v1beta1/query.proto | 7 ++ proto/cosmos/upgrade/v1beta1/upgrade.proto | 2 + proto/cosmos/vesting/v1beta1/vesting.proto | 2 + store/types/listening.pb.go | 2 + types/query/pagination.pb.go | 2 + types/tx/service.pb.go | 2 + types/tx/tx.pb.go | 2 + x/auth/types/query.pb.go | 8 ++ x/auth/vesting/types/vesting.pb.go | 2 + x/bank/types/authz.pb.go | 2 + x/bank/types/bank.pb.go | 8 ++ x/bank/types/query.pb.go | 4 + x/gov/types/gov.pb.go | 5 +- x/gov/types/tx.pb.go | 8 ++ x/staking/types/authz.pb.go | 4 + x/upgrade/types/query.pb.go | 9 ++ x/upgrade/types/upgrade.pb.go | 2 + 42 files changed, 208 insertions(+), 35 deletions(-) diff --git a/client/grpc/tmservice/query.pb.go b/client/grpc/tmservice/query.pb.go index 3594da2c5f2f..ea4588c7fc3d 100644 --- a/client/grpc/tmservice/query.pb.go +++ b/client/grpc/tmservice/query.pb.go @@ -689,14 +689,15 @@ func (m *GetNodeInfoResponse) GetApplicationVersion() *VersionInfo { // VersionInfo is the type for the GetNodeInfoResponse message. type VersionInfo struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` - BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"` - GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` - BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"` - CosmosSdkVersion string `protobuf:"bytes,8,opt,name=cosmos_sdk_version,json=cosmosSdkVersion,proto3" json:"cosmos_sdk_version,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` + BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"` + GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` + BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"` + // Since: cosmos-sdk 0.43 + CosmosSdkVersion string `protobuf:"bytes,8,opt,name=cosmos_sdk_version,json=cosmosSdkVersion,proto3" json:"cosmos_sdk_version,omitempty"` } func (m *VersionInfo) Reset() { *m = VersionInfo{} } diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index dbc0ff6b21ce..855e9e838a0a 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -855,7 +855,9 @@ pagination. Ex: | `offset` | [uint64](#uint64) | | offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set. | | `limit` | [uint64](#uint64) | | limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app. | | `count_total` | [bool](#bool) | | count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set. | -| `reverse` | [bool](#bool) | | reverse is set to true if results are to be returned in the descending order. | +| `reverse` | [bool](#bool) | | reverse is set to true if results are to be returned in the descending order. + +Since: cosmos-sdk 0.43 | @@ -1020,6 +1022,8 @@ QueryAccountResponse is the response type for the Query/Account RPC method. ### QueryAccountsRequest QueryAccountsRequest is the request type for the Query/Accounts RPC method. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -1035,6 +1039,8 @@ QueryAccountsRequest is the request type for the Query/Accounts RPC method. ### QueryAccountsResponse QueryAccountsResponse is the response type for the Query/Accounts RPC method. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -1109,7 +1115,9 @@ Query defines the gRPC querier service. | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Accounts` | [QueryAccountsRequest](#cosmos.auth.v1beta1.QueryAccountsRequest) | [QueryAccountsResponse](#cosmos.auth.v1beta1.QueryAccountsResponse) | Accounts returns all the existing accounts | GET|/cosmos/auth/v1beta1/accounts| +| `Accounts` | [QueryAccountsRequest](#cosmos.auth.v1beta1.QueryAccountsRequest) | [QueryAccountsResponse](#cosmos.auth.v1beta1.QueryAccountsResponse) | Accounts returns all the existing accounts + +Since: cosmos-sdk 0.43 | GET|/cosmos/auth/v1beta1/accounts| | `Account` | [QueryAccountRequest](#cosmos.auth.v1beta1.QueryAccountRequest) | [QueryAccountResponse](#cosmos.auth.v1beta1.QueryAccountResponse) | Account returns account details based on address. | GET|/cosmos/auth/v1beta1/accounts/{address}| | `Params` | [QueryParamsRequest](#cosmos.auth.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#cosmos.auth.v1beta1.QueryParamsResponse) | Params queries all parameters. | GET|/cosmos/auth/v1beta1/params| | `ModuleAccounts` | [QueryModuleAccountsRequest](#cosmos.auth.v1beta1.QueryModuleAccountsRequest) | [QueryModuleAccountsResponse](#cosmos.auth.v1beta1.QueryModuleAccountsResponse) | ModuleAccounts returns all the existing module accounts. | GET|/cosmos/auth/v1beta1/module_accounts| @@ -1125,7 +1133,7 @@ Query defines the gRPC querier service.

Top

## cosmos/authz/v1beta1/authz.proto - +Since: cosmos-sdk 0.43 @@ -1174,7 +1182,7 @@ the provide method with expiration time.

Top

## cosmos/authz/v1beta1/event.proto - +Since: cosmos-sdk 0.43 @@ -1224,7 +1232,7 @@ EventRevoke is emitted on Msg/Revoke

Top

## cosmos/authz/v1beta1/genesis.proto - +Since: cosmos-sdk 0.43 @@ -1273,7 +1281,7 @@ GrantAuthorization defines the GenesisState/GrantAuthorization type.

Top

## cosmos/authz/v1beta1/query.proto - +Since: cosmos-sdk 0.43 @@ -1563,7 +1571,7 @@ tags are stringified and the log is JSON decoded.

Top

## cosmos/authz/v1beta1/tx.proto - +Since: cosmos-sdk 0.43 @@ -1773,6 +1781,8 @@ IntProto defines a Protobuf wrapper around an Int object. SendAuthorization allows the grantee to spend up to spend_limit coins from the granter's account. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -1846,10 +1856,18 @@ a basic token. | `denom_units` | [DenomUnit](#cosmos.bank.v1beta1.DenomUnit) | repeated | denom_units represents the list of DenomUnit's for a given coin | | `base` | [string](#string) | | base represents the base denom (should be the DenomUnit with exponent = 0). | | `display` | [string](#string) | | display indicates the suggested denom that should be displayed in clients. | -| `name` | [string](#string) | | name defines the name of the token (eg: Cosmos Atom) | -| `symbol` | [string](#string) | | symbol is the token symbol usually shown on exchanges (eg: ATOM). This can be the same as the display. | -| `uri` | [string](#string) | | URI to a document (on or off-chain) that contains additional information. Optional. | -| `uri_hash` | [string](#string) | | URIHash is a sha256 hash of a document pointed by URI. It's used to verify that the document didn't change. Optional. | +| `name` | [string](#string) | | name defines the name of the token (eg: Cosmos Atom) + +Since: cosmos-sdk 0.43 | +| `symbol` | [string](#string) | | symbol is the token symbol usually shown on exchanges (eg: ATOM). This can be the same as the display. + +Since: cosmos-sdk 0.43 | +| `uri` | [string](#string) | | URI to a document (on or off-chain) that contains additional information. Optional. + +Since: cosmos-sdk 0.45 | +| `uri_hash` | [string](#string) | | URIHash is a sha256 hash of a document pointed by URI. It's used to verify that the document didn't change. Optional. + +Since: cosmos-sdk 0.45 | @@ -2232,7 +2250,9 @@ method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. + +Since: cosmos-sdk 0.43 | @@ -2249,7 +2269,9 @@ method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `supply` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | supply is the supply of the coins | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. + +Since: cosmos-sdk 0.43 | @@ -2497,7 +2519,7 @@ ReflectionService defines a service for interface reflection.

Top

## cosmos/base/reflection/v2alpha1/reflection.proto - +Since: cosmos-sdk 0.43 @@ -3037,6 +3059,8 @@ StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and De It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and Deletes +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -3354,7 +3378,7 @@ VersionInfo is the type for the GetNodeInfoResponse message. | `build_tags` | [string](#string) | | | | `go_version` | [string](#string) | | | | `build_deps` | [Module](#cosmos.base.tendermint.v1beta1.Module) | repeated | | -| `cosmos_sdk_version` | [string](#string) | | | +| `cosmos_sdk_version` | [string](#string) | | Since: cosmos-sdk 0.43 | @@ -3896,7 +3920,7 @@ This prefix is followed with the x-coordinate.

Top

## cosmos/crypto/secp256r1/keys.proto - +Since: cosmos-sdk 0.43 @@ -5007,7 +5031,7 @@ Msg defines the evidence Msg service.

Top

## cosmos/feegrant/v1beta1/feegrant.proto - +Since: cosmos-sdk 0.43 @@ -5093,7 +5117,7 @@ as well as a limit per time period.

Top

## cosmos/feegrant/v1beta1/genesis.proto - +Since: cosmos-sdk 0.43 @@ -5124,7 +5148,7 @@ GenesisState contains a set of fee allowances, persisted from the store

Top

## cosmos/feegrant/v1beta1/query.proto - +Since: cosmos-sdk 0.43 @@ -5214,7 +5238,7 @@ Query defines the gRPC querier service.

Top

## cosmos/feegrant/v1beta1/tx.proto - +Since: cosmos-sdk 0.43 @@ -5450,7 +5474,7 @@ A Vote consists of a proposal ID, the voter, and the vote option. | `proposal_id` | [uint64](#uint64) | | | | `voter` | [string](#string) | | | | `option` | [VoteOption](#cosmos.gov.v1beta1.VoteOption) | | **Deprecated.** Deprecated: Prefer to use `options` instead. This field is set in queries if and only if `len(options) == 1` and that option has weight 1. In all other cases, this field will default to VOTE_OPTION_UNSPECIFIED. | -| `options` | [WeightedVoteOption](#cosmos.gov.v1beta1.WeightedVoteOption) | repeated | | +| `options` | [WeightedVoteOption](#cosmos.gov.v1beta1.WeightedVoteOption) | repeated | Since: cosmos-sdk 0.43 | @@ -5477,6 +5501,8 @@ VotingParams defines the params for voting on governance proposals. ### WeightedVoteOption WeightedVoteOption defines a unit of vote for vote split. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -5950,6 +5976,8 @@ MsgVoteResponse defines the Msg/Vote response type. ### MsgVoteWeighted MsgVoteWeighted defines a message to cast a vote. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -5967,6 +5995,8 @@ MsgVoteWeighted defines a message to cast a vote. ### MsgVoteWeightedResponse MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +Since: cosmos-sdk 0.43 + @@ -5987,7 +6017,9 @@ Msg defines the bank Msg service. | ----------- | ------------ | ------------- | ------------| ------- | -------- | | `SubmitProposal` | [MsgSubmitProposal](#cosmos.gov.v1beta1.MsgSubmitProposal) | [MsgSubmitProposalResponse](#cosmos.gov.v1beta1.MsgSubmitProposalResponse) | SubmitProposal defines a method to create new proposal given a content. | | | `Vote` | [MsgVote](#cosmos.gov.v1beta1.MsgVote) | [MsgVoteResponse](#cosmos.gov.v1beta1.MsgVoteResponse) | Vote defines a method to add a vote on a specific proposal. | | -| `VoteWeighted` | [MsgVoteWeighted](#cosmos.gov.v1beta1.MsgVoteWeighted) | [MsgVoteWeightedResponse](#cosmos.gov.v1beta1.MsgVoteWeightedResponse) | VoteWeighted defines a method to add a weighted vote on a specific proposal. | | +| `VoteWeighted` | [MsgVoteWeighted](#cosmos.gov.v1beta1.MsgVoteWeighted) | [MsgVoteWeightedResponse](#cosmos.gov.v1beta1.MsgVoteWeightedResponse) | VoteWeighted defines a method to add a weighted vote on a specific proposal. + +Since: cosmos-sdk 0.43 | | | `Deposit` | [MsgDeposit](#cosmos.gov.v1beta1.MsgDeposit) | [MsgDepositResponse](#cosmos.gov.v1beta1.MsgDepositResponse) | Deposit defines a method to add deposit on a specific proposal. | | @@ -8120,6 +8152,8 @@ Msg defines the slashing Msg service. ### StakeAuthorization StakeAuthorization defines authorization for delegate/undelegate/redelegate. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -8155,6 +8189,8 @@ Validators defines list of validator addresses. ### AuthorizationType AuthorizationType defines the type of staking module authorization type +Since: cosmos-sdk 0.43 + | Name | Number | Description | | ---- | ------ | ----------- | | AUTHORIZATION_TYPE_UNSPECIFIED | 0 | AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type | @@ -9429,7 +9465,9 @@ transaction. | ----- | ---- | ----- | ----------- | | `signer_infos` | [SignerInfo](#cosmos.tx.v1beta1.SignerInfo) | repeated | signer_infos defines the signing modes for the required signers. The number and order of elements must match the required signers from TxBody's messages. The first element is the primary signer and the one which pays the fee. | | `fee` | [Fee](#cosmos.tx.v1beta1.Fee) | | Fee is the fee and gas limit for the transaction. The first signer is the primary signer and the one which pays the fee. The fee can be calculated based on the cost of evaluating the body and doing signature verification of the signers. This can be estimated via simulation. | -| `tip` | [Tip](#cosmos.tx.v1beta1.Tip) | | Tip is the optional tip used for meta-transactions. | +| `tip` | [Tip](#cosmos.tx.v1beta1.Tip) | | Tip is the optional tip used for meta-transactions. + +Since: cosmos-sdk 0.45 | @@ -9762,7 +9800,9 @@ RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `tx` | [Tx](#cosmos.tx.v1beta1.Tx) | | **Deprecated.** tx is the transaction to simulate. Deprecated. Send raw tx bytes instead. | -| `tx_bytes` | [bytes](#bytes) | | tx_bytes is the raw transaction. | +| `tx_bytes` | [bytes](#bytes) | | tx_bytes is the raw transaction. + +Since: cosmos-sdk 0.43 | @@ -9864,6 +9904,8 @@ upgrade. ### ModuleVersion ModuleVersion specifies a module and its consensus version. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -9993,6 +10035,8 @@ method. QueryModuleVersionsRequest is the request type for the Query/ModuleVersions RPC method. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -10009,6 +10053,8 @@ RPC method. QueryModuleVersionsResponse is the response type for the Query/ModuleVersions RPC method. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | @@ -10044,7 +10090,7 @@ RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `upgraded_consensus_state` | [bytes](#bytes) | | | +| `upgraded_consensus_state` | [bytes](#bytes) | | Since: cosmos-sdk 0.43 | @@ -10067,7 +10113,9 @@ Query defines the gRPC upgrade querier service. | `CurrentPlan` | [QueryCurrentPlanRequest](#cosmos.upgrade.v1beta1.QueryCurrentPlanRequest) | [QueryCurrentPlanResponse](#cosmos.upgrade.v1beta1.QueryCurrentPlanResponse) | CurrentPlan queries the current upgrade plan. | GET|/cosmos/upgrade/v1beta1/current_plan| | `AppliedPlan` | [QueryAppliedPlanRequest](#cosmos.upgrade.v1beta1.QueryAppliedPlanRequest) | [QueryAppliedPlanResponse](#cosmos.upgrade.v1beta1.QueryAppliedPlanResponse) | AppliedPlan queries a previously applied upgrade plan by its name. | GET|/cosmos/upgrade/v1beta1/applied_plan/{name}| | `UpgradedConsensusState` | [QueryUpgradedConsensusStateRequest](#cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateRequest) | [QueryUpgradedConsensusStateResponse](#cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateResponse) | UpgradedConsensusState queries the consensus state that will serve as a trusted kernel for the next version of this chain. It will only be stored at the last height of this chain. UpgradedConsensusState RPC not supported with legacy querier This rpc is deprecated now that IBC has its own replacement (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) | GET|/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}| -| `ModuleVersions` | [QueryModuleVersionsRequest](#cosmos.upgrade.v1beta1.QueryModuleVersionsRequest) | [QueryModuleVersionsResponse](#cosmos.upgrade.v1beta1.QueryModuleVersionsResponse) | ModuleVersions queries the list of module versions from state. | GET|/cosmos/upgrade/v1beta1/module_versions| +| `ModuleVersions` | [QueryModuleVersionsRequest](#cosmos.upgrade.v1beta1.QueryModuleVersionsRequest) | [QueryModuleVersionsResponse](#cosmos.upgrade.v1beta1.QueryModuleVersionsResponse) | ModuleVersions queries the list of module versions from state. + +Since: cosmos-sdk 0.43 | GET|/cosmos/upgrade/v1beta1/module_versions| @@ -10175,6 +10223,8 @@ PermanentLockedAccount implements the VestingAccount interface. It does not ever release coins, locking them indefinitely. Coins in this account can still be used for delegating and for governance votes even while locked. +Since: cosmos-sdk 0.43 + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | diff --git a/proto/cosmos/auth/v1beta1/query.proto b/proto/cosmos/auth/v1beta1/query.proto index 845695fd87af..d99d594016a6 100644 --- a/proto/cosmos/auth/v1beta1/query.proto +++ b/proto/cosmos/auth/v1beta1/query.proto @@ -13,6 +13,8 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; // Query defines the gRPC querier service. service Query { // Accounts returns all the existing accounts + // + // Since: cosmos-sdk 0.43 rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) { option (google.api.http).get = "/cosmos/auth/v1beta1/accounts"; } @@ -49,12 +51,16 @@ service Query { } // QueryAccountsRequest is the request type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 message QueryAccountsRequest { // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 1; } // QueryAccountsResponse is the response type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 message QueryAccountsResponse { // accounts are the existing accounts repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; diff --git a/proto/cosmos/authz/v1beta1/authz.proto b/proto/cosmos/authz/v1beta1/authz.proto index c69a93c11f4a..2c376905eb8b 100644 --- a/proto/cosmos/authz/v1beta1/authz.proto +++ b/proto/cosmos/authz/v1beta1/authz.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.authz.v1beta1; diff --git a/proto/cosmos/authz/v1beta1/event.proto b/proto/cosmos/authz/v1beta1/event.proto index f763854b38d6..0476649afc1b 100644 --- a/proto/cosmos/authz/v1beta1/event.proto +++ b/proto/cosmos/authz/v1beta1/event.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.authz.v1beta1; diff --git a/proto/cosmos/authz/v1beta1/genesis.proto b/proto/cosmos/authz/v1beta1/genesis.proto index 504739bc0cce..8bf5f82e1562 100644 --- a/proto/cosmos/authz/v1beta1/genesis.proto +++ b/proto/cosmos/authz/v1beta1/genesis.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.authz.v1beta1; diff --git a/proto/cosmos/authz/v1beta1/query.proto b/proto/cosmos/authz/v1beta1/query.proto index 5b01be7e1fc4..eefd894170c3 100644 --- a/proto/cosmos/authz/v1beta1/query.proto +++ b/proto/cosmos/authz/v1beta1/query.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.authz.v1beta1; diff --git a/proto/cosmos/authz/v1beta1/tx.proto b/proto/cosmos/authz/v1beta1/tx.proto index 65c0e45caeed..b99feee45889 100644 --- a/proto/cosmos/authz/v1beta1/tx.proto +++ b/proto/cosmos/authz/v1beta1/tx.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.authz.v1beta1; diff --git a/proto/cosmos/bank/v1beta1/authz.proto b/proto/cosmos/bank/v1beta1/authz.proto index f3505ad41cab..4f58b15e4970 100644 --- a/proto/cosmos/bank/v1beta1/authz.proto +++ b/proto/cosmos/bank/v1beta1/authz.proto @@ -9,6 +9,8 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; // SendAuthorization allows the grantee to spend up to spend_limit coins from // the granter's account. +// +// Since: cosmos-sdk 0.43 message SendAuthorization { option (cosmos_proto.implements_interface) = "Authorization"; diff --git a/proto/cosmos/bank/v1beta1/bank.proto b/proto/cosmos/bank/v1beta1/bank.proto index 3ae2074ff0fe..0e1733e6065d 100644 --- a/proto/cosmos/bank/v1beta1/bank.proto +++ b/proto/cosmos/bank/v1beta1/bank.proto @@ -85,13 +85,21 @@ message Metadata { // displayed in clients. string display = 4; // name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 string name = 5; // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can // be the same as the display. + // + // Since: cosmos-sdk 0.43 string symbol = 6; // URI to a document (on or off-chain) that contains additional information. Optional. + // + // Since: cosmos-sdk 0.45 string uri = 7 [(gogoproto.customname) = "URI"]; // URIHash is a sha256 hash of a document pointed by URI. It's used to verify that // the document didn't change. Optional. + // + // Since: cosmos-sdk 0.45 string uri_hash = 8 [(gogoproto.customname) = "URIHash"]; } diff --git a/proto/cosmos/bank/v1beta1/query.proto b/proto/cosmos/bank/v1beta1/query.proto index f42c93a758ef..bfe4ebaa819c 100644 --- a/proto/cosmos/bank/v1beta1/query.proto +++ b/proto/cosmos/bank/v1beta1/query.proto @@ -103,6 +103,8 @@ message QueryTotalSupplyRequest { option (gogoproto.goproto_getters) = false; // pagination defines an optional pagination for the request. + // + // Since: cosmos-sdk 0.43 cosmos.base.query.v1beta1.PageRequest pagination = 1; } @@ -114,6 +116,8 @@ message QueryTotalSupplyResponse { [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; // pagination defines the pagination in the response. + // + // Since: cosmos-sdk 0.43 cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/proto/cosmos/base/query/v1beta1/pagination.proto b/proto/cosmos/base/query/v1beta1/pagination.proto index 784c479562a9..cd5eb066d399 100644 --- a/proto/cosmos/base/query/v1beta1/pagination.proto +++ b/proto/cosmos/base/query/v1beta1/pagination.proto @@ -32,6 +32,8 @@ message PageRequest { bool count_total = 4; // reverse is set to true if results are to be returned in the descending order. + // + // Since: cosmos-sdk 0.43 bool reverse = 5; } diff --git a/proto/cosmos/base/reflection/v2alpha1/reflection.proto b/proto/cosmos/base/reflection/v2alpha1/reflection.proto index 3e8e94048221..d5b048558fa0 100644 --- a/proto/cosmos/base/reflection/v2alpha1/reflection.proto +++ b/proto/cosmos/base/reflection/v2alpha1/reflection.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.base.reflection.v2alpha1; diff --git a/proto/cosmos/base/store/v1beta1/listening.proto b/proto/cosmos/base/store/v1beta1/listening.proto index 186ecee4b080..359997109c10 100644 --- a/proto/cosmos/base/store/v1beta1/listening.proto +++ b/proto/cosmos/base/store/v1beta1/listening.proto @@ -6,6 +6,8 @@ option go_package = "github.com/cosmos/cosmos-sdk/store/types"; // StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) // It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and // Deletes +// +// Since: cosmos-sdk 0.43 message StoreKVPair { string store_key = 1; // the store key for the KVStore this pair originates from bool delete = 2; // true indicates a delete operation, false indicates a set operation diff --git a/proto/cosmos/base/tendermint/v1beta1/query.proto b/proto/cosmos/base/tendermint/v1beta1/query.proto index e88ed74a6718..c5a64c3c651c 100644 --- a/proto/cosmos/base/tendermint/v1beta1/query.proto +++ b/proto/cosmos/base/tendermint/v1beta1/query.proto @@ -124,6 +124,7 @@ message VersionInfo { string build_tags = 5; string go_version = 6; repeated Module build_deps = 7; + // Since: cosmos-sdk 0.43 string cosmos_sdk_version = 8; } diff --git a/proto/cosmos/crypto/secp256r1/keys.proto b/proto/cosmos/crypto/secp256r1/keys.proto index b0aad99d1f94..2e96c6e3c65e 100644 --- a/proto/cosmos/crypto/secp256r1/keys.proto +++ b/proto/cosmos/crypto/secp256r1/keys.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.crypto.secp256r1; diff --git a/proto/cosmos/feegrant/v1beta1/feegrant.proto b/proto/cosmos/feegrant/v1beta1/feegrant.proto index 1a82b01e895d..769490c59992 100644 --- a/proto/cosmos/feegrant/v1beta1/feegrant.proto +++ b/proto/cosmos/feegrant/v1beta1/feegrant.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.feegrant.v1beta1; diff --git a/proto/cosmos/feegrant/v1beta1/genesis.proto b/proto/cosmos/feegrant/v1beta1/genesis.proto index 4c1e51fdd2c2..5b1ac4ca5593 100644 --- a/proto/cosmos/feegrant/v1beta1/genesis.proto +++ b/proto/cosmos/feegrant/v1beta1/genesis.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.feegrant.v1beta1; diff --git a/proto/cosmos/feegrant/v1beta1/query.proto b/proto/cosmos/feegrant/v1beta1/query.proto index 657114b80453..69fef2e7eb19 100644 --- a/proto/cosmos/feegrant/v1beta1/query.proto +++ b/proto/cosmos/feegrant/v1beta1/query.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.feegrant.v1beta1; diff --git a/proto/cosmos/feegrant/v1beta1/tx.proto b/proto/cosmos/feegrant/v1beta1/tx.proto index 69a1a25fc2d9..cf7e800f49a3 100644 --- a/proto/cosmos/feegrant/v1beta1/tx.proto +++ b/proto/cosmos/feegrant/v1beta1/tx.proto @@ -1,3 +1,4 @@ +// Since: cosmos-sdk 0.43 syntax = "proto3"; package cosmos.feegrant.v1beta1; diff --git a/proto/cosmos/gov/v1beta1/gov.proto b/proto/cosmos/gov/v1beta1/gov.proto index c867ecef59e4..2b5dd881a2cb 100644 --- a/proto/cosmos/gov/v1beta1/gov.proto +++ b/proto/cosmos/gov/v1beta1/gov.proto @@ -30,6 +30,8 @@ enum VoteOption { } // WeightedVoteOption defines a unit of vote for vote split. +// +// Since: cosmos-sdk 0.43 message WeightedVoteOption { VoteOption option = 1; string weight = 2 [ @@ -134,6 +136,7 @@ message Vote { // if and only if `len(options) == 1` and that option has weight 1. In all // other cases, this field will default to VOTE_OPTION_UNSPECIFIED. VoteOption option = 3 [deprecated = true]; + // Since: cosmos-sdk 0.43 repeated WeightedVoteOption options = 4 [(gogoproto.nullable) = false]; } diff --git a/proto/cosmos/gov/v1beta1/tx.proto b/proto/cosmos/gov/v1beta1/tx.proto index 50b23684e9b8..35e49eb2d765 100644 --- a/proto/cosmos/gov/v1beta1/tx.proto +++ b/proto/cosmos/gov/v1beta1/tx.proto @@ -18,6 +18,8 @@ service Msg { rpc Vote(MsgVote) returns (MsgVoteResponse); // VoteWeighted defines a method to add a weighted vote on a specific proposal. + // + // Since: cosmos-sdk 0.43 rpc VoteWeighted(MsgVoteWeighted) returns (MsgVoteWeightedResponse); // Deposit defines a method to add deposit on a specific proposal. @@ -61,6 +63,8 @@ message MsgVote { message MsgVoteResponse {} // MsgVoteWeighted defines a message to cast a vote. +// +// Since: cosmos-sdk 0.43 message MsgVoteWeighted { option (gogoproto.equal) = false; option (gogoproto.goproto_stringer) = false; @@ -73,6 +77,8 @@ message MsgVoteWeighted { } // MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +// +// Since: cosmos-sdk 0.43 message MsgVoteWeightedResponse {} // MsgDeposit defines a message to submit a deposit to an existing proposal. diff --git a/proto/cosmos/staking/v1beta1/authz.proto b/proto/cosmos/staking/v1beta1/authz.proto index 9d3c09dce35c..677edaad1a26 100644 --- a/proto/cosmos/staking/v1beta1/authz.proto +++ b/proto/cosmos/staking/v1beta1/authz.proto @@ -8,6 +8,8 @@ import "cosmos/base/v1beta1/coin.proto"; option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; // StakeAuthorization defines authorization for delegate/undelegate/redelegate. +// +// Since: cosmos-sdk 0.43 message StakeAuthorization { option (cosmos_proto.implements_interface) = "Authorization"; @@ -31,6 +33,8 @@ message StakeAuthorization { } // AuthorizationType defines the type of staking module authorization type +// +// Since: cosmos-sdk 0.43 enum AuthorizationType { // AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type AUTHORIZATION_TYPE_UNSPECIFIED = 0; diff --git a/proto/cosmos/tx/v1beta1/service.proto b/proto/cosmos/tx/v1beta1/service.proto index 646175c00d09..acfbf15b3689 100644 --- a/proto/cosmos/tx/v1beta1/service.proto +++ b/proto/cosmos/tx/v1beta1/service.proto @@ -104,6 +104,8 @@ message SimulateRequest { // Deprecated. Send raw tx bytes instead. cosmos.tx.v1beta1.Tx tx = 1 [deprecated = true]; // tx_bytes is the raw transaction. + // + // Since: cosmos-sdk 0.43 bytes tx_bytes = 2; } diff --git a/proto/cosmos/tx/v1beta1/tx.proto b/proto/cosmos/tx/v1beta1/tx.proto index f26c02051ff6..a26cad5d54df 100644 --- a/proto/cosmos/tx/v1beta1/tx.proto +++ b/proto/cosmos/tx/v1beta1/tx.proto @@ -137,6 +137,8 @@ message AuthInfo { Fee fee = 2; // Tip is the optional tip used for meta-transactions. + // + // Since: cosmos-sdk 0.45 Tip tip = 3; } diff --git a/proto/cosmos/upgrade/v1beta1/query.proto b/proto/cosmos/upgrade/v1beta1/query.proto index 0703ef347b83..dd14ba6401c4 100644 --- a/proto/cosmos/upgrade/v1beta1/query.proto +++ b/proto/cosmos/upgrade/v1beta1/query.proto @@ -31,6 +31,8 @@ service Query { } // ModuleVersions queries the list of module versions from state. + // + // Since: cosmos-sdk 0.43 rpc ModuleVersions(QueryModuleVersionsRequest) returns (QueryModuleVersionsResponse) { option (google.api.http).get = "/cosmos/upgrade/v1beta1/module_versions"; } @@ -77,11 +79,14 @@ message QueryUpgradedConsensusStateResponse { option deprecated = true; reserved 1; + // Since: cosmos-sdk 0.43 bytes upgraded_consensus_state = 2; } // QueryModuleVersionsRequest is the request type for the Query/ModuleVersions // RPC method. +// +// Since: cosmos-sdk 0.43 message QueryModuleVersionsRequest { // module_name is a field to query a specific module // consensus version from state. Leaving this empty will @@ -91,6 +96,8 @@ message QueryModuleVersionsRequest { // QueryModuleVersionsResponse is the response type for the Query/ModuleVersions // RPC method. +// +// Since: cosmos-sdk 0.43 message QueryModuleVersionsResponse { // module_versions is a list of module names with their consensus versions. repeated ModuleVersion module_versions = 1; diff --git a/proto/cosmos/upgrade/v1beta1/upgrade.proto b/proto/cosmos/upgrade/v1beta1/upgrade.proto index 067124a2340e..70a90b1f0ad5 100644 --- a/proto/cosmos/upgrade/v1beta1/upgrade.proto +++ b/proto/cosmos/upgrade/v1beta1/upgrade.proto @@ -64,6 +64,8 @@ message CancelSoftwareUpgradeProposal { } // ModuleVersion specifies a module and its consensus version. +// +// Since: cosmos-sdk 0.43 message ModuleVersion { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; diff --git a/proto/cosmos/vesting/v1beta1/vesting.proto b/proto/cosmos/vesting/v1beta1/vesting.proto index f24069e54719..59580245aea4 100644 --- a/proto/cosmos/vesting/v1beta1/vesting.proto +++ b/proto/cosmos/vesting/v1beta1/vesting.proto @@ -72,6 +72,8 @@ message PeriodicVestingAccount { // PermanentLockedAccount implements the VestingAccount interface. It does // not ever release coins, locking them indefinitely. Coins in this account can // still be used for delegating and for governance votes even while locked. +// +// Since: cosmos-sdk 0.43 message PermanentLockedAccount { option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; diff --git a/store/types/listening.pb.go b/store/types/listening.pb.go index bc0b84514c00..47d5a23a8367 100644 --- a/store/types/listening.pb.go +++ b/store/types/listening.pb.go @@ -25,6 +25,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) // It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and // Deletes +// +// Since: cosmos-sdk 0.43 type StoreKVPair struct { StoreKey string `protobuf:"bytes,1,opt,name=store_key,json=storeKey,proto3" json:"store_key,omitempty"` Delete bool `protobuf:"varint,2,opt,name=delete,proto3" json:"delete,omitempty"` diff --git a/types/query/pagination.pb.go b/types/query/pagination.pb.go index 3b1455d6f299..c631ecfb1eaf 100644 --- a/types/query/pagination.pb.go +++ b/types/query/pagination.pb.go @@ -47,6 +47,8 @@ type PageRequest struct { // is set. CountTotal bool `protobuf:"varint,4,opt,name=count_total,json=countTotal,proto3" json:"count_total,omitempty"` // reverse is set to true if results are to be returned in the descending order. + // + // Since: cosmos-sdk 0.43 Reverse bool `protobuf:"varint,5,opt,name=reverse,proto3" json:"reverse,omitempty"` } diff --git a/types/tx/service.pb.go b/types/tx/service.pb.go index c61222acaed8..13c068cae088 100644 --- a/types/tx/service.pb.go +++ b/types/tx/service.pb.go @@ -342,6 +342,8 @@ type SimulateRequest struct { // Deprecated. Send raw tx bytes instead. Tx *Tx `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` // Deprecated: Do not use. // tx_bytes is the raw transaction. + // + // Since: cosmos-sdk 0.43 TxBytes []byte `protobuf:"bytes,2,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"` } diff --git a/types/tx/tx.pb.go b/types/tx/tx.pb.go index cb9f6bb6de5e..6a7df6c004c3 100644 --- a/types/tx/tx.pb.go +++ b/types/tx/tx.pb.go @@ -450,6 +450,8 @@ type AuthInfo struct { // of the signers. This can be estimated via simulation. Fee *Fee `protobuf:"bytes,2,opt,name=fee,proto3" json:"fee,omitempty"` // Tip is the optional tip used for meta-transactions. + // + // Since: cosmos-sdk 0.45 Tip *Tip `protobuf:"bytes,3,opt,name=tip,proto3" json:"tip,omitempty"` } diff --git a/x/auth/types/query.pb.go b/x/auth/types/query.pb.go index a0c621434008..2a3f8493aa21 100644 --- a/x/auth/types/query.pb.go +++ b/x/auth/types/query.pb.go @@ -33,6 +33,8 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // QueryAccountsRequest is the request type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 type QueryAccountsRequest struct { // pagination defines an optional pagination for the request. Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` @@ -79,6 +81,8 @@ func (m *QueryAccountsRequest) GetPagination() *query.PageRequest { } // QueryAccountsResponse is the response type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 type QueryAccountsResponse struct { // accounts are the existing accounts Accounts []*types.Any `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts,omitempty"` @@ -732,6 +736,8 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { // Accounts returns all the existing accounts + // + // Since: cosmos-sdk 0.43 Accounts(ctx context.Context, in *QueryAccountsRequest, opts ...grpc.CallOption) (*QueryAccountsResponse, error) // Account returns account details based on address. Account(ctx context.Context, in *QueryAccountRequest, opts ...grpc.CallOption) (*QueryAccountResponse, error) @@ -821,6 +827,8 @@ func (c *queryClient) AddressStringToBytes(ctx context.Context, in *AddressStrin // QueryServer is the server API for Query service. type QueryServer interface { // Accounts returns all the existing accounts + // + // Since: cosmos-sdk 0.43 Accounts(context.Context, *QueryAccountsRequest) (*QueryAccountsResponse, error) // Account returns account details based on address. Account(context.Context, *QueryAccountRequest) (*QueryAccountResponse, error) diff --git a/x/auth/vesting/types/vesting.pb.go b/x/auth/vesting/types/vesting.pb.go index dc2425b1a79a..1404b5891cc6 100644 --- a/x/auth/vesting/types/vesting.pb.go +++ b/x/auth/vesting/types/vesting.pb.go @@ -241,6 +241,8 @@ var xxx_messageInfo_PeriodicVestingAccount proto.InternalMessageInfo // PermanentLockedAccount implements the VestingAccount interface. It does // not ever release coins, locking them indefinitely. Coins in this account can // still be used for delegating and for governance votes even while locked. +// +// Since: cosmos-sdk 0.43 type PermanentLockedAccount struct { *BaseVestingAccount `protobuf:"bytes,1,opt,name=base_vesting_account,json=baseVestingAccount,proto3,embedded=base_vesting_account" json:"base_vesting_account,omitempty"` } diff --git a/x/bank/types/authz.pb.go b/x/bank/types/authz.pb.go index e5352246fbef..904a7f9ce793 100644 --- a/x/bank/types/authz.pb.go +++ b/x/bank/types/authz.pb.go @@ -28,6 +28,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // SendAuthorization allows the grantee to spend up to spend_limit coins from // the granter's account. +// +// Since: cosmos-sdk 0.43 type SendAuthorization struct { SpendLimit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=spend_limit,json=spendLimit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"spend_limit"` } diff --git a/x/bank/types/bank.pb.go b/x/bank/types/bank.pb.go index c720f94a3d98..947acfdc16ef 100644 --- a/x/bank/types/bank.pb.go +++ b/x/bank/types/bank.pb.go @@ -332,14 +332,22 @@ type Metadata struct { // displayed in clients. Display string `protobuf:"bytes,4,opt,name=display,proto3" json:"display,omitempty"` // name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can // be the same as the display. + // + // Since: cosmos-sdk 0.43 Symbol string `protobuf:"bytes,6,opt,name=symbol,proto3" json:"symbol,omitempty"` // URI to a document (on or off-chain) that contains additional information. Optional. + // + // Since: cosmos-sdk 0.45 URI string `protobuf:"bytes,7,opt,name=uri,proto3" json:"uri,omitempty"` // URIHash is a sha256 hash of a document pointed by URI. It's used to verify that // the document didn't change. Optional. + // + // Since: cosmos-sdk 0.45 URIHash string `protobuf:"bytes,8,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } diff --git a/x/bank/types/query.pb.go b/x/bank/types/query.pb.go index 36018d4df0fd..637218150c0e 100644 --- a/x/bank/types/query.pb.go +++ b/x/bank/types/query.pb.go @@ -221,6 +221,8 @@ func (m *QueryAllBalancesResponse) GetPagination() *query.PageResponse { // method. type QueryTotalSupplyRequest struct { // pagination defines an optional pagination for the request. + // + // Since: cosmos-sdk 0.43 Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -263,6 +265,8 @@ type QueryTotalSupplyResponse struct { // supply is the supply of the coins Supply github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=supply,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"supply"` // pagination defines the pagination in the response. + // + // Since: cosmos-sdk 0.43 Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } diff --git a/x/gov/types/gov.pb.go b/x/gov/types/gov.pb.go index 97330037ae3e..4b32cf249afe 100644 --- a/x/gov/types/gov.pb.go +++ b/x/gov/types/gov.pb.go @@ -122,6 +122,8 @@ func (ProposalStatus) EnumDescriptor() ([]byte, []int) { } // WeightedVoteOption defines a unit of vote for vote split. +// +// Since: cosmos-sdk 0.43 type WeightedVoteOption struct { Option VoteOption `protobuf:"varint,1,opt,name=option,proto3,enum=cosmos.gov.v1beta1.VoteOption" json:"option,omitempty"` Weight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weight"` @@ -331,7 +333,8 @@ type Vote struct { // Deprecated: Prefer to use `options` instead. This field is set in queries // if and only if `len(options) == 1` and that option has weight 1. In all // other cases, this field will default to VOTE_OPTION_UNSPECIFIED. - Option VoteOption `protobuf:"varint,3,opt,name=option,proto3,enum=cosmos.gov.v1beta1.VoteOption" json:"option,omitempty"` // Deprecated: Do not use. + Option VoteOption `protobuf:"varint,3,opt,name=option,proto3,enum=cosmos.gov.v1beta1.VoteOption" json:"option,omitempty"` // Deprecated: Do not use. + // Since: cosmos-sdk 0.43 Options []WeightedVoteOption `protobuf:"bytes,4,rep,name=options,proto3" json:"options"` } diff --git a/x/gov/types/tx.pb.go b/x/gov/types/tx.pb.go index 77dc90080839..1326c6575c9d 100644 --- a/x/gov/types/tx.pb.go +++ b/x/gov/types/tx.pb.go @@ -194,6 +194,8 @@ func (m *MsgVoteResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgVoteResponse proto.InternalMessageInfo // MsgVoteWeighted defines a message to cast a vote. +// +// Since: cosmos-sdk 0.43 type MsgVoteWeighted struct { ProposalId uint64 `protobuf:"varint,1,opt,name=proposal_id,json=proposalId,proto3" json:"proposal_id,omitempty"` Voter string `protobuf:"bytes,2,opt,name=voter,proto3" json:"voter,omitempty"` @@ -233,6 +235,8 @@ func (m *MsgVoteWeighted) XXX_DiscardUnknown() { var xxx_messageInfo_MsgVoteWeighted proto.InternalMessageInfo // MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +// +// Since: cosmos-sdk 0.43 type MsgVoteWeightedResponse struct { } @@ -420,6 +424,8 @@ type MsgClient interface { // Vote defines a method to add a vote on a specific proposal. Vote(ctx context.Context, in *MsgVote, opts ...grpc.CallOption) (*MsgVoteResponse, error) // VoteWeighted defines a method to add a weighted vote on a specific proposal. + // + // Since: cosmos-sdk 0.43 VoteWeighted(ctx context.Context, in *MsgVoteWeighted, opts ...grpc.CallOption) (*MsgVoteWeightedResponse, error) // Deposit defines a method to add deposit on a specific proposal. Deposit(ctx context.Context, in *MsgDeposit, opts ...grpc.CallOption) (*MsgDepositResponse, error) @@ -476,6 +482,8 @@ type MsgServer interface { // Vote defines a method to add a vote on a specific proposal. Vote(context.Context, *MsgVote) (*MsgVoteResponse, error) // VoteWeighted defines a method to add a weighted vote on a specific proposal. + // + // Since: cosmos-sdk 0.43 VoteWeighted(context.Context, *MsgVoteWeighted) (*MsgVoteWeightedResponse, error) // Deposit defines a method to add deposit on a specific proposal. Deposit(context.Context, *MsgDeposit) (*MsgDepositResponse, error) diff --git a/x/staking/types/authz.pb.go b/x/staking/types/authz.pb.go index c3e5f0d186c2..ac9c88271f25 100644 --- a/x/staking/types/authz.pb.go +++ b/x/staking/types/authz.pb.go @@ -26,6 +26,8 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // AuthorizationType defines the type of staking module authorization type +// +// Since: cosmos-sdk 0.43 type AuthorizationType int32 const ( @@ -62,6 +64,8 @@ func (AuthorizationType) EnumDescriptor() ([]byte, []int) { } // StakeAuthorization defines authorization for delegate/undelegate/redelegate. +// +// Since: cosmos-sdk 0.43 type StakeAuthorization struct { // max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is // empty, there is no spend limit and any amount of coins can be delegated. diff --git a/x/upgrade/types/query.pb.go b/x/upgrade/types/query.pb.go index 1f3acb808439..9b2daef286eb 100644 --- a/x/upgrade/types/query.pb.go +++ b/x/upgrade/types/query.pb.go @@ -263,6 +263,7 @@ func (m *QueryUpgradedConsensusStateRequest) GetLastHeight() int64 { // // Deprecated: Do not use. type QueryUpgradedConsensusStateResponse struct { + // Since: cosmos-sdk 0.43 UpgradedConsensusState []byte `protobuf:"bytes,2,opt,name=upgraded_consensus_state,json=upgradedConsensusState,proto3" json:"upgraded_consensus_state,omitempty"` } @@ -308,6 +309,8 @@ func (m *QueryUpgradedConsensusStateResponse) GetUpgradedConsensusState() []byte // QueryModuleVersionsRequest is the request type for the Query/ModuleVersions // RPC method. +// +// Since: cosmos-sdk 0.43 type QueryModuleVersionsRequest struct { // module_name is a field to query a specific module // consensus version from state. Leaving this empty will @@ -357,6 +360,8 @@ func (m *QueryModuleVersionsRequest) GetModuleName() string { // QueryModuleVersionsResponse is the response type for the Query/ModuleVersions // RPC method. +// +// Since: cosmos-sdk 0.43 type QueryModuleVersionsResponse struct { // module_versions is a list of module names with their consensus versions. ModuleVersions []*ModuleVersion `protobuf:"bytes,1,rep,name=module_versions,json=moduleVersions,proto3" json:"module_versions,omitempty"` @@ -482,6 +487,8 @@ type QueryClient interface { // (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) UpgradedConsensusState(ctx context.Context, in *QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*QueryUpgradedConsensusStateResponse, error) // ModuleVersions queries the list of module versions from state. + // + // Since: cosmos-sdk 0.43 ModuleVersions(ctx context.Context, in *QueryModuleVersionsRequest, opts ...grpc.CallOption) (*QueryModuleVersionsResponse, error) } @@ -544,6 +551,8 @@ type QueryServer interface { // (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) UpgradedConsensusState(context.Context, *QueryUpgradedConsensusStateRequest) (*QueryUpgradedConsensusStateResponse, error) // ModuleVersions queries the list of module versions from state. + // + // Since: cosmos-sdk 0.43 ModuleVersions(context.Context, *QueryModuleVersionsRequest) (*QueryModuleVersionsResponse, error) } diff --git a/x/upgrade/types/upgrade.pb.go b/x/upgrade/types/upgrade.pb.go index 7d496f5bd67b..20fb4b235077 100644 --- a/x/upgrade/types/upgrade.pb.go +++ b/x/upgrade/types/upgrade.pb.go @@ -166,6 +166,8 @@ func (m *CancelSoftwareUpgradeProposal) XXX_DiscardUnknown() { var xxx_messageInfo_CancelSoftwareUpgradeProposal proto.InternalMessageInfo // ModuleVersion specifies a module and its consensus version. +// +// Since: cosmos-sdk 0.43 type ModuleVersion struct { // name of the app module Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` From 1d1fcc9d204fadab00888829edfaa38397f3636a Mon Sep 17 00:00:00 2001 From: Zhiqiang Zhang <745124335@qq.com> Date: Wed, 27 Oct 2021 22:43:47 +0800 Subject: [PATCH 11/38] feat: implement nft module msg server (#10074) ## Description MsgServer implementation and corresponding keeper methods, refer #9826 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- docs/architecture/adr-043-nft-module.md | 12 +- docs/core/proto-docs.md | 12 +- proto/cosmos/nft/v1beta1/nft.proto | 12 +- simapp/app.go | 12 +- x/nft/codec.go | 14 + x/nft/errors.go | 15 ++ x/nft/expected_keepers.go | 18 ++ x/nft/genesis.go | 30 +++ x/nft/keeper/class.go | 67 +++++ x/nft/keeper/genesis.go | 65 +++++ x/nft/keeper/keeper.go | 30 +++ x/nft/keeper/keeper_test.go | 342 ++++++++++++++++++++++++ x/nft/keeper/keys.go | 76 ++++++ x/nft/keeper/msg_server.go | 42 +++ x/nft/keeper/nft.go | 192 +++++++++++++ x/nft/keys.go | 12 + x/nft/module/module.go | 157 +++++++++++ x/nft/msgs.go | 43 +++ x/nft/nft.pb.go | 12 +- x/nft/validation.go | 33 +++ 20 files changed, 1175 insertions(+), 21 deletions(-) create mode 100644 x/nft/codec.go create mode 100644 x/nft/errors.go create mode 100644 x/nft/expected_keepers.go create mode 100644 x/nft/genesis.go create mode 100644 x/nft/keeper/class.go create mode 100644 x/nft/keeper/genesis.go create mode 100644 x/nft/keeper/keeper.go create mode 100644 x/nft/keeper/keeper_test.go create mode 100644 x/nft/keeper/keys.go create mode 100644 x/nft/keeper/msg_server.go create mode 100644 x/nft/keeper/nft.go create mode 100644 x/nft/keys.go create mode 100644 x/nft/module/module.go create mode 100644 x/nft/msgs.go create mode 100644 x/nft/validation.go diff --git a/docs/architecture/adr-043-nft-module.md b/docs/architecture/adr-043-nft-module.md index 8c2f967b1694..d4db3d3f9c92 100644 --- a/docs/architecture/adr-043-nft-module.md +++ b/docs/architecture/adr-043-nft-module.md @@ -12,7 +12,13 @@ DRAFT ## Abstract -This ADR defines the `x/nft` module which is a generic implementation of NFTs, roughly "compatible" with ERC721. +This ADR defines the `x/nft` module which is a generic implementation of NFTs, roughly "compatible" with ERC721. **Applications using the `x/nft` module must implement the following functions**: + +- `MsgNewClass` - Receive the user's request to create a class, and call the `NewClass` of the `x/nft` module. +- `MsgUpdateClass` - Receive the user's request to update a class, and call the `UpdateClass` of the `x/nft` module. +- `MsgMintNFT` - Receive the user's request to mint a nft, and call the `MintNFT` of the `x/nft` module. +- `BurnNFT` - Receive the user's request to burn a nft, and call the `BurnNFT` of the `x/nft` module. +- `UpdateNFT` - Receive the user's request to update a nft, and call the `UpdateNFT` of the `x/nft` module. ## Context @@ -55,6 +61,7 @@ message Class { string symbol = 3; string description = 4; string uri = 5; + string uri_hash = 6; } ``` @@ -63,6 +70,7 @@ message Class { - `symbol` is the symbol usually shown on exchanges for the NFT class; _optional_ - `description` is a detailed description of the NFT class; _optional_ - `uri` is a URL pointing to an off-chain JSON file that contains metadata about this NFT class ([OpenSea example](https://docs.opensea.io/docs/contract-level-metadata)); _optional_ +- `uri_hash` is a hash of the `uri`; _optional_ #### NFT @@ -73,6 +81,7 @@ message NFT { string class_id = 1; string id = 2; string uri = 3; + string uri_hash = 4; google.protobuf.Any data = 10; } ``` @@ -83,6 +92,7 @@ message NFT { {class_id}/{id} --> NFT (bytes) ``` - `uri` is a URL pointing to an off-chain JSON file that contains metadata about this NFT (Ref: [ERC721 standard and OpenSea extension](https://docs.opensea.io/docs/metadata-standards)); _required_ +- `uri_hash` is a hash of the `uri`; - `data` is a field that CAN be used by composing modules to specify additional properties for the NFT; _optional_ This ADR doesn't specify values that `data` can take; however, best practices recommend upper-level NFT modules clearly specify their contents. Although the value of this field doesn't provide the additional context required to manage NFT records, which means that the field can technically be removed from the specification, the field's existence allows basic informational/UI functionality. diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 855e9e838a0a..04cffc6b13e9 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -7290,11 +7290,11 @@ Class defines the class of the nft type. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `id` | [string](#string) | | id defines the unique identifier of the NFT classification, similar to the contract address of ERC721 | -| `name` | [string](#string) | | name defines the human-readable name of the NFT classification | -| `symbol` | [string](#string) | | symbol is an abbreviated name for nft classification | -| `description` | [string](#string) | | description is a brief description of nft classification | -| `uri` | [string](#string) | | uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema. | -| `uri_hash` | [string](#string) | | uri_hash is a hash of the document pointed to uri | +| `name` | [string](#string) | | name defines the human-readable name of the NFT classification,optional | +| `symbol` | [string](#string) | | symbol is an abbreviated name for nft classification,optional | +| `description` | [string](#string) | | description is a brief description of nft classification,optional | +| `uri` | [string](#string) | | uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema.optional | +| `uri_hash` | [string](#string) | | uri_hash is a hash of the document pointed to uri,optional | @@ -7313,7 +7313,7 @@ NFT defines the NFT. | `id` | [string](#string) | | id defines the unique identification of NFT | | `uri` | [string](#string) | | uri defines NFT's metadata storage address outside the chain | | `uri_hash` | [string](#string) | | uri_hash is a hash of the document pointed to uri | -| `data` | [google.protobuf.Any](#google.protobuf.Any) | | data is the metadata of the NFT | +| `data` | [google.protobuf.Any](#google.protobuf.Any) | | data is the metadata of the NFT,optional | diff --git a/proto/cosmos/nft/v1beta1/nft.proto b/proto/cosmos/nft/v1beta1/nft.proto index aed091427daf..b11dd7c699a4 100644 --- a/proto/cosmos/nft/v1beta1/nft.proto +++ b/proto/cosmos/nft/v1beta1/nft.proto @@ -10,19 +10,19 @@ message Class { // id defines the unique identifier of the NFT classification, similar to the contract address of ERC721 string id = 1; - // name defines the human-readable name of the NFT classification + // name defines the human-readable name of the NFT classification,optional string name = 2; - // symbol is an abbreviated name for nft classification + // symbol is an abbreviated name for nft classification,optional string symbol = 3; - // description is a brief description of nft classification + // description is a brief description of nft classification,optional string description = 4; - // uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema. + // uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema.optional string uri = 5; - // uri_hash is a hash of the document pointed to uri + // uri_hash is a hash of the document pointed to uri,optional string uri_hash = 6; } @@ -40,6 +40,6 @@ message NFT { // uri_hash is a hash of the document pointed to uri string uri_hash = 4; - // data is the metadata of the NFT + // data is the metadata of the NFT,optional google.protobuf.Any data = 10; } \ No newline at end of file diff --git a/simapp/app.go b/simapp/app.go index 4673514d4731..33fcab3e5cbe 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -69,6 +69,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/cosmos/cosmos-sdk/x/nft" + nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper" + nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" @@ -117,6 +120,7 @@ var ( evidence.AppModuleBasic{}, authzmodule.AppModuleBasic{}, vesting.AppModuleBasic{}, + nftmodule.AppModuleBasic{}, ) // module account permissions @@ -127,6 +131,7 @@ var ( stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, + nft.ModuleName: nil, } ) @@ -168,6 +173,7 @@ type SimApp struct { AuthzKeeper authzkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper + NFTKeeper nftkeeper.Keeper // the module manager mm *module.Manager @@ -209,7 +215,7 @@ func NewSimApp( minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, capabilitytypes.StoreKey, - authzkeeper.StoreKey, + authzkeeper.StoreKey, nftkeeper.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) // NOTE: The testingkey is just mounted for testing purposes. Actual applications should @@ -297,6 +303,7 @@ func NewSimApp( // register the governance hooks ), ) + app.NFTKeeper = nftkeeper.NewKeeper(keys[nftkeeper.StoreKey], appCodec, app.AccountKeeper, app.BankKeeper) // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( @@ -333,6 +340,7 @@ func NewSimApp( evidence.NewAppModule(app.EvidenceKeeper), params.NewAppModule(app.ParamsKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -355,7 +363,7 @@ func NewSimApp( capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, - feegrant.ModuleName, + feegrant.ModuleName, nft.ModuleName, ) app.mm.RegisterInvariants(&app.CrisisKeeper) diff --git a/x/nft/codec.go b/x/nft/codec.go new file mode 100644 index 000000000000..d98e836c37ea --- /dev/null +++ b/x/nft/codec.go @@ -0,0 +1,14 @@ +package nft + +import ( + types "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgSend{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} diff --git a/x/nft/errors.go b/x/nft/errors.go new file mode 100644 index 000000000000..1982862d1f8b --- /dev/null +++ b/x/nft/errors.go @@ -0,0 +1,15 @@ +package nft + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/nft module sentinel errors +var ( + ErrInvalidNFT = sdkerrors.Register(ModuleName, 2, "invalid nft") + ErrClassExists = sdkerrors.Register(ModuleName, 3, "nft class already exist") + ErrClassNotExists = sdkerrors.Register(ModuleName, 4, "nft class does not exist") + ErrNFTExists = sdkerrors.Register(ModuleName, 5, "nft already exist") + ErrNFTNotExists = sdkerrors.Register(ModuleName, 6, "nft does not exist") + ErrInvalidID = sdkerrors.Register(ModuleName, 7, "invalid id") +) diff --git a/x/nft/expected_keepers.go b/x/nft/expected_keepers.go new file mode 100644 index 000000000000..0e0f1efd6e45 --- /dev/null +++ b/x/nft/expected_keepers.go @@ -0,0 +1,18 @@ +package nft + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// BankKeeper defines the contract needed to be fulfilled for banking and supply +// dependencies. +type BankKeeper interface { + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} + +// AccountKeeper defines the contract required for account APIs. +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI +} diff --git a/x/nft/genesis.go b/x/nft/genesis.go new file mode 100644 index 000000000000..43be6ffbddd1 --- /dev/null +++ b/x/nft/genesis.go @@ -0,0 +1,30 @@ +package nft + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ValidateGenesis check the given genesis state has no integrity issues +func ValidateGenesis(data GenesisState) error { + for _, class := range data.Classes { + if err := ValidateClassID(class.Id); err != nil { + return err + } + } + for _, entry := range data.Entries { + for _, nft := range entry.Nfts { + if err := ValidateNFTID(nft.Id); err != nil { + return err + } + if _, err := sdk.AccAddressFromBech32(entry.Owner); err != nil { + return err + } + } + } + return nil +} + +// DefaultGenesisState - Return a default genesis state +func DefaultGenesisState() *GenesisState { + return &GenesisState{} +} diff --git a/x/nft/keeper/class.go b/x/nft/keeper/class.go new file mode 100644 index 000000000000..d887ec6627b2 --- /dev/null +++ b/x/nft/keeper/class.go @@ -0,0 +1,67 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// SaveClass defines a method for creating a new nft class +func (k Keeper) SaveClass(ctx sdk.Context, class nft.Class) error { + if k.HasClass(ctx, class.Id) { + return sdkerrors.Wrap(nft.ErrClassExists, class.Id) + } + bz, err := k.cdc.Marshal(&class) + if err != nil { + return sdkerrors.Wrap(err, "Marshal nft.Class failed") + } + store := ctx.KVStore(k.storeKey) + store.Set(classStoreKey(class.Id), bz) + return nil +} + +// UpdateClass defines a method for updating a exist nft class +func (k Keeper) UpdateClass(ctx sdk.Context, class nft.Class) error { + if !k.HasClass(ctx, class.Id) { + return sdkerrors.Wrap(nft.ErrClassNotExists, class.Id) + } + bz, err := k.cdc.Marshal(&class) + if err != nil { + return sdkerrors.Wrap(err, "Marshal nft.Class failed") + } + store := ctx.KVStore(k.storeKey) + store.Set(classStoreKey(class.Id), bz) + return nil +} + +// GetClass defines a method for returning the class information of the specified id +func (k Keeper) GetClass(ctx sdk.Context, classID string) (nft.Class, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(classStoreKey(classID)) + + var class nft.Class + if len(bz) == 0 { + return class, false + } + k.cdc.MustUnmarshal(bz, &class) + return class, true +} + +// GetClasses defines a method for returning all classes information +func (k Keeper) GetClasses(ctx sdk.Context) (classes []*nft.Class) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, ClassKey) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var class nft.Class + k.cdc.MustUnmarshal(iterator.Value(), &class) + classes = append(classes, &class) + } + return +} + +// HasClass determines whether the specified classID exist +func (k Keeper) HasClass(ctx sdk.Context, classID string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(classStoreKey(classID)) +} diff --git a/x/nft/keeper/genesis.go b/x/nft/keeper/genesis.go new file mode 100644 index 000000000000..f8cf05184c0c --- /dev/null +++ b/x/nft/keeper/genesis.go @@ -0,0 +1,65 @@ +package keeper + +import ( + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// InitGenesis new nft genesis +func (k Keeper) InitGenesis(ctx sdk.Context, data *nft.GenesisState) { + for _, class := range data.Classes { + if err := k.SaveClass(ctx, *class); err != nil { + panic(err) + } + + } + for _, entry := range data.Entries { + for _, nft := range entry.Nfts { + owner, err := sdk.AccAddressFromBech32(entry.Owner) + if err != nil { + panic(err) + } + + if err := k.Mint(ctx, *nft, owner); err != nil { + panic(err) + } + } + } +} + +// ExportGenesis returns a GenesisState for a given context. +func (k Keeper) ExportGenesis(ctx sdk.Context) *nft.GenesisState { + classes := k.GetClasses(ctx) + nftMap := make(map[string][]*nft.NFT) + for _, class := range classes { + nfts := k.GetNFTsOfClass(ctx, class.Id) + for i, n := range nfts { + owner := k.GetOwner(ctx, n.ClassId, n.Id) + nftArr, ok := nftMap[owner.String()] + if !ok { + nftArr = make([]*nft.NFT, 0) + } + nftMap[owner.String()] = append(nftArr, &nfts[i]) + } + } + + owners := make([]string, 0, len(nftMap)) + for owner := range nftMap { + owners = append(owners, owner) + } + sort.Strings(owners) + + entries := make([]*nft.Entry, 0, len(nftMap)) + for _, owner := range owners { + entries = append(entries, &nft.Entry{ + Owner: owner, + Nfts: nftMap[owner], + }) + } + return &nft.GenesisState{ + Classes: classes, + Entries: entries, + } +} diff --git a/x/nft/keeper/keeper.go b/x/nft/keeper/keeper.go new file mode 100644 index 000000000000..8ae13ca98e27 --- /dev/null +++ b/x/nft/keeper/keeper.go @@ -0,0 +1,30 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// Keeper of the nft store +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + bk nft.BankKeeper +} + +// NewKeeper creates a new nft Keeper instance +func NewKeeper(key storetypes.StoreKey, + cdc codec.BinaryCodec, ak nft.AccountKeeper, bk nft.BankKeeper, +) Keeper { + // ensure nft module account is set + if addr := ak.GetModuleAddress(nft.ModuleName); addr == nil { + panic("the nft module account has not been set") + } + + return Keeper{ + cdc: cdc, + storeKey: key, + bk: bk, + } +} diff --git a/x/nft/keeper/keeper_test.go b/x/nft/keeper/keeper_test.go new file mode 100644 index 000000000000..dafe49a88e9a --- /dev/null +++ b/x/nft/keeper/keeper_test.go @@ -0,0 +1,342 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +const ( + testClassID = "kitty" + testClassName = "Crypto Kitty" + testClassSymbol = "kitty" + testClassDescription = "Crypto Kitty" + testClassURI = "class uri" + testClassURIHash = "ae702cefd6b6a65fe2f991ad6d9969ed" + testID = "kitty1" + testURI = "kitty uri" + testURIHash = "229bfd3c1b431c14a526497873897108" +) + +type TestSuite struct { + suite.Suite + + app *simapp.SimApp + ctx sdk.Context + addrs []sdk.AccAddress + queryClient nft.QueryClient +} + +func (s *TestSuite) SetupTest() { + app := simapp.Setup(s.T(), false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + ctx = ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()}) + + s.app = app + s.ctx = ctx + s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000)) +} + +func TestTestSuite(t *testing.T) { + suite.Run(t, new(TestSuite)) +} + +func (s *TestSuite) TestSaveClass() { + except := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, except) + s.Require().NoError(err) + + actual, has := s.app.NFTKeeper.GetClass(s.ctx, testClassID) + s.Require().True(has) + s.Require().EqualValues(except, actual) + + classes := s.app.NFTKeeper.GetClasses(s.ctx) + s.Require().EqualValues([]*nft.Class{&except}, classes) +} + +func (s *TestSuite) TestUpdateClass() { + class := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, class) + s.Require().NoError(err) + + noExistClass := nft.Class{ + Id: "kitty1", + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + + err = s.app.NFTKeeper.UpdateClass(s.ctx, noExistClass) + s.Require().Error(err) + s.Require().Contains(err.Error(), "nft class does not exist") + + except := nft.Class{ + Id: testClassID, + Name: "My crypto Kitty", + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + + err = s.app.NFTKeeper.UpdateClass(s.ctx, except) + s.Require().NoError(err) + + actual, has := s.app.NFTKeeper.GetClass(s.ctx, testClassID) + s.Require().True(has) + s.Require().EqualValues(except, actual) +} + +func (s *TestSuite) TestMint() { + class := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, class) + s.Require().NoError(err) + + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err = s.app.NFTKeeper.Mint(s.ctx, expNFT, s.addrs[0]) + s.Require().NoError(err) + + // test GetNFT + actNFT, has := s.app.NFTKeeper.GetNFT(s.ctx, testClassID, testID) + s.Require().True(has) + s.Require().EqualValues(expNFT, actNFT) + + // test GetOwner + owner := s.app.NFTKeeper.GetOwner(s.ctx, testClassID, testID) + s.Require().True(s.addrs[0].Equals(owner)) + + // test GetNFTsOfClass + actNFTs := s.app.NFTKeeper.GetNFTsOfClass(s.ctx, testClassID) + s.Require().EqualValues([]nft.NFT{expNFT}, actNFTs) + + // test GetNFTsOfClassByOwner + actNFTs = s.app.NFTKeeper.GetNFTsOfClassByOwner(s.ctx, testClassID, s.addrs[0]) + s.Require().EqualValues([]nft.NFT{expNFT}, actNFTs) + + // test GetBalance + balance := s.app.NFTKeeper.GetBalance(s.ctx, testClassID, s.addrs[0]) + s.Require().EqualValues(uint64(1), balance) + + // test GetTotalSupply + supply := s.app.NFTKeeper.GetTotalSupply(s.ctx, testClassID) + s.Require().EqualValues(uint64(1), supply) +} + +func (s *TestSuite) TestBurn() { + except := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, except) + s.Require().NoError(err) + + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err = s.app.NFTKeeper.Mint(s.ctx, expNFT, s.addrs[0]) + s.Require().NoError(err) + + err = s.app.NFTKeeper.Burn(s.ctx, testClassID, testID) + s.Require().NoError(err) + + // test GetNFT + _, has := s.app.NFTKeeper.GetNFT(s.ctx, testClassID, testID) + s.Require().False(has) + + // test GetOwner + owner := s.app.NFTKeeper.GetOwner(s.ctx, testClassID, testID) + s.Require().Nil(owner) + + // test GetNFTsOfClass + actNFTs := s.app.NFTKeeper.GetNFTsOfClass(s.ctx, testClassID) + s.Require().Empty(actNFTs) + + // test GetNFTsOfClassByOwner + actNFTs = s.app.NFTKeeper.GetNFTsOfClassByOwner(s.ctx, testClassID, s.addrs[0]) + s.Require().Empty(actNFTs) + + // test GetBalance + balance := s.app.NFTKeeper.GetBalance(s.ctx, testClassID, s.addrs[0]) + s.Require().EqualValues(uint64(0), balance) + + // test GetTotalSupply + supply := s.app.NFTKeeper.GetTotalSupply(s.ctx, testClassID) + s.Require().EqualValues(uint64(0), supply) +} + +func (s *TestSuite) TestUpdate() { + class := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, class) + s.Require().NoError(err) + + myNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err = s.app.NFTKeeper.Mint(s.ctx, myNFT, s.addrs[0]) + s.Require().NoError(err) + + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: "updated", + } + + err = s.app.NFTKeeper.Update(s.ctx, expNFT) + s.Require().NoError(err) + + // test GetNFT + actNFT, has := s.app.NFTKeeper.GetNFT(s.ctx, testClassID, testID) + s.Require().True(has) + s.Require().EqualValues(expNFT, actNFT) +} + +func (s *TestSuite) TestTransfer() { + class := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, class) + s.Require().NoError(err) + + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err = s.app.NFTKeeper.Mint(s.ctx, expNFT, s.addrs[0]) + s.Require().NoError(err) + + //valid owner + err = s.app.NFTKeeper.Transfer(s.ctx, testClassID, testID, s.addrs[1]) + s.Require().NoError(err) + + // test GetOwner + owner := s.app.NFTKeeper.GetOwner(s.ctx, testClassID, testID) + s.Require().Equal(s.addrs[1], owner) + + balanceAddr0 := s.app.NFTKeeper.GetBalance(s.ctx, testClassID, s.addrs[0]) + s.Require().EqualValues(uint64(0), balanceAddr0) + + balanceAddr1 := s.app.NFTKeeper.GetBalance(s.ctx, testClassID, s.addrs[1]) + s.Require().EqualValues(uint64(1), balanceAddr1) + + // test GetNFTsOfClassByOwner + actNFTs := s.app.NFTKeeper.GetNFTsOfClassByOwner(s.ctx, testClassID, s.addrs[1]) + s.Require().EqualValues([]nft.NFT{expNFT}, actNFTs) +} + +func (s *TestSuite) TestExportGenesis() { + class := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + err := s.app.NFTKeeper.SaveClass(s.ctx, class) + s.Require().NoError(err) + + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err = s.app.NFTKeeper.Mint(s.ctx, expNFT, s.addrs[0]) + s.Require().NoError(err) + + expGenesis := &nft.GenesisState{ + Classes: []*nft.Class{&class}, + Entries: []*nft.Entry{{ + Owner: s.addrs[0].String(), + Nfts: []*nft.NFT{&expNFT}, + }}, + } + genesis := s.app.NFTKeeper.ExportGenesis(s.ctx) + s.Require().Equal(expGenesis, genesis) +} + +func (s *TestSuite) TestInitGenesis() { + expClass := nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + expNFT := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + expGenesis := &nft.GenesisState{ + Classes: []*nft.Class{&expClass}, + Entries: []*nft.Entry{{ + Owner: s.addrs[0].String(), + Nfts: []*nft.NFT{&expNFT}, + }}, + } + s.app.NFTKeeper.InitGenesis(s.ctx, expGenesis) + + actual, has := s.app.NFTKeeper.GetClass(s.ctx, testClassID) + s.Require().True(has) + s.Require().EqualValues(expClass, actual) + + // test GetNFT + actNFT, has := s.app.NFTKeeper.GetNFT(s.ctx, testClassID, testID) + s.Require().True(has) + s.Require().EqualValues(expNFT, actNFT) +} diff --git a/x/nft/keeper/keys.go b/x/nft/keeper/keys.go new file mode 100644 index 000000000000..bf8d1ceab829 --- /dev/null +++ b/x/nft/keeper/keys.go @@ -0,0 +1,76 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/internal/conv" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +var ( + ClassKey = []byte{0x01} + NFTKey = []byte{0x02} + NFTOfClassByOwnerKey = []byte{0x03} + OwnerKey = []byte{0x04} + ClassTotalSupply = []byte{0x05} + + Delimiter = []byte{0x00} + Placeholder = []byte{0x01} +) + +// StoreKey is the store key string for nft +const StoreKey = nft.ModuleName + +// classStoreKey returns the byte representation of the nft class key +func classStoreKey(classID string) []byte { + key := make([]byte, len(ClassKey)+len(classID)) + copy(key, ClassKey) + copy(key[len(ClassKey):], classID) + return key +} + +// nftStoreKey returns the byte representation of the nft +func nftStoreKey(classID string) []byte { + key := make([]byte, len(NFTKey)+len(classID)+len(Delimiter)) + copy(key, NFTKey) + copy(key[len(NFTKey):], classID) + copy(key[len(NFTKey)+len(classID):], Delimiter) + return key +} + +// classTotalSupply returns the byte representation of the ClassTotalSupply +func classTotalSupply(classID string) []byte { + key := make([]byte, len(ClassTotalSupply)+len(classID)) + copy(key, ClassTotalSupply) + copy(key[len(ClassTotalSupply):], classID) + return key +} + +// nftOfClassByOwnerStoreKey returns the byte representation of the nft owner +// Items are stored with the following key: values +// 0x03 +func nftOfClassByOwnerStoreKey(owner sdk.AccAddress, classID string) []byte { + owner = address.MustLengthPrefix(owner) + classIDBz := conv.UnsafeStrToBytes(classID) + + var key = make([]byte, len(NFTOfClassByOwnerKey)+len(owner)+len(Delimiter)) + copy(key, NFTOfClassByOwnerKey) + copy(key[len(NFTOfClassByOwnerKey):], owner) + copy(key[len(NFTOfClassByOwnerKey)+len(owner):], classIDBz) + return append(key, Delimiter...) +} + +// ownerStoreKey returns the byte representation of the nft owner +// Items are stored with the following key: values +// 0x04 +func ownerStoreKey(classID, nftID string) []byte { + // key is of format: + classIDBz := conv.UnsafeStrToBytes(classID) + nftIDBz := conv.UnsafeStrToBytes(nftID) + + var key = make([]byte, len(OwnerKey)+len(classIDBz)+len(Delimiter)+len(nftIDBz)) + copy(key, OwnerKey) + copy(key[len(OwnerKey):], classIDBz) + copy(key[len(OwnerKey)+len(classIDBz):], Delimiter) + return append(key, nftIDBz...) +} diff --git a/x/nft/keeper/msg_server.go b/x/nft/keeper/msg_server.go new file mode 100644 index 000000000000..fc14a60559f5 --- /dev/null +++ b/x/nft/keeper/msg_server.go @@ -0,0 +1,42 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +var _ nft.MsgServer = Keeper{} + +// Send implement Send method of the types.MsgServer. +func (k Keeper) Send(goCtx context.Context, msg *nft.MsgSend) (*nft.MsgSendResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + sender, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, err + } + + owner := k.GetOwner(ctx, msg.ClassId, msg.Id) + if !owner.Equals(sender) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not the owner of nft %s", sender, msg.Id) + } + + receiver, err := sdk.AccAddressFromBech32(msg.Receiver) + if err != nil { + return nil, err + } + + if err := k.Transfer(ctx, msg.ClassId, msg.Id, receiver); err != nil { + return nil, err + } + + ctx.EventManager().EmitTypedEvent(&nft.EventSend{ + ClassId: msg.ClassId, + Id: msg.Id, + Sender: msg.Sender, + Receiver: msg.Receiver, + }) + return &nft.MsgSendResponse{}, nil +} diff --git a/x/nft/keeper/nft.go b/x/nft/keeper/nft.go new file mode 100644 index 000000000000..1cb4e817116c --- /dev/null +++ b/x/nft/keeper/nft.go @@ -0,0 +1,192 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// Mint defines a method for minting a new nft +func (k Keeper) Mint(ctx sdk.Context, token nft.NFT, receiver sdk.AccAddress) error { + if !k.HasClass(ctx, token.ClassId) { + return sdkerrors.Wrap(nft.ErrClassNotExists, token.ClassId) + } + + if k.HasNFT(ctx, token.ClassId, token.Id) { + return sdkerrors.Wrap(nft.ErrNFTExists, token.Id) + } + + k.setNFT(ctx, token) + k.setOwner(ctx, token.ClassId, token.Id, receiver) + k.incrTotalSupply(ctx, token.ClassId) + return nil +} + +// Burn defines a method for burning a nft from a specific account. +// Note: When the upper module uses this method, it needs to authenticate nft +func (k Keeper) Burn(ctx sdk.Context, classID string, nftID string) error { + if !k.HasClass(ctx, classID) { + return sdkerrors.Wrap(nft.ErrClassNotExists, classID) + } + + if !k.HasNFT(ctx, classID, nftID) { + return sdkerrors.Wrap(nft.ErrNFTNotExists, nftID) + } + + owner := k.GetOwner(ctx, classID, nftID) + nftStore := k.getNFTStore(ctx, classID) + nftStore.Delete([]byte(nftID)) + + k.deleteOwner(ctx, classID, nftID, owner) + k.decrTotalSupply(ctx, classID) + return nil +} + +// Update defines a method for updating an exist nft +// Note: When the upper module uses this method, it needs to authenticate nft +func (k Keeper) Update(ctx sdk.Context, token nft.NFT) error { + if !k.HasClass(ctx, token.ClassId) { + return sdkerrors.Wrap(nft.ErrClassNotExists, token.ClassId) + } + + if !k.HasNFT(ctx, token.ClassId, token.Id) { + return sdkerrors.Wrap(nft.ErrNFTNotExists, token.Id) + } + k.setNFT(ctx, token) + return nil +} + +// Transfer defines a method for sending a nft from one account to another account. +// Note: When the upper module uses this method, it needs to authenticate nft +func (k Keeper) Transfer(ctx sdk.Context, + classID string, + nftID string, + receiver sdk.AccAddress) error { + if !k.HasClass(ctx, classID) { + return sdkerrors.Wrap(nft.ErrClassNotExists, classID) + } + + if !k.HasNFT(ctx, classID, nftID) { + return sdkerrors.Wrap(nft.ErrNFTNotExists, nftID) + } + + owner := k.GetOwner(ctx, classID, nftID) + k.deleteOwner(ctx, classID, nftID, owner) + k.setOwner(ctx, classID, nftID, receiver) + return nil +} + +// GetNFT returns the nft information of the specified classID and nftID +func (k Keeper) GetNFT(ctx sdk.Context, classID, nftID string) (nft.NFT, bool) { + store := k.getNFTStore(ctx, classID) + bz := store.Get([]byte(nftID)) + if len(bz) == 0 { + return nft.NFT{}, false + } + var nft nft.NFT + k.cdc.MustUnmarshal(bz, &nft) + return nft, true +} + +// GetNFTsOfClassByOwner returns all nft information of the specified classID under the specified owner +func (k Keeper) GetNFTsOfClassByOwner(ctx sdk.Context, classID string, owner sdk.AccAddress) (nfts []nft.NFT) { + ownerStore := k.getClassStoreByOwner(ctx, owner, classID) + iterator := ownerStore.Iterator(nil, nil) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + nft, has := k.GetNFT(ctx, classID, string(iterator.Key())) + if has { + nfts = append(nfts, nft) + } + } + return nfts +} + +// GetNFTsOfClass returns all nft information under the specified classID +func (k Keeper) GetNFTsOfClass(ctx sdk.Context, classID string) (nfts []nft.NFT) { + nftStore := k.getNFTStore(ctx, classID) + iterator := nftStore.Iterator(nil, nil) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var nft nft.NFT + k.cdc.MustUnmarshal(iterator.Value(), &nft) + nfts = append(nfts, nft) + } + return nfts +} + +// GetOwner returns the owner information of the specified nft +func (k Keeper) GetOwner(ctx sdk.Context, classID string, nftID string) sdk.AccAddress { + store := ctx.KVStore(k.storeKey) + bz := store.Get(ownerStoreKey(classID, nftID)) + return sdk.AccAddress(bz) +} + +// GetBalance returns the specified account, the number of all nfts under the specified classID +func (k Keeper) GetBalance(ctx sdk.Context, classID string, owner sdk.AccAddress) uint64 { + nfts := k.GetNFTsOfClassByOwner(ctx, classID, owner) + return uint64(len(nfts)) +} + +// GetTotalSupply returns the number of all nfts under the specified classID +func (k Keeper) GetTotalSupply(ctx sdk.Context, classID string) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(classTotalSupply(classID)) + return sdk.BigEndianToUint64(bz) +} + +// HasNFT determines whether the specified classID and nftID exist +func (k Keeper) HasNFT(ctx sdk.Context, classID, id string) bool { + store := k.getNFTStore(ctx, classID) + return store.Has([]byte(id)) +} + +func (k Keeper) setNFT(ctx sdk.Context, token nft.NFT) { + nftStore := k.getNFTStore(ctx, token.ClassId) + bz := k.cdc.MustMarshal(&token) + nftStore.Set([]byte(token.Id), bz) +} + +func (k Keeper) setOwner(ctx sdk.Context, classID, nftID string, owner sdk.AccAddress) { + store := ctx.KVStore(k.storeKey) + store.Set(ownerStoreKey(classID, nftID), owner.Bytes()) + + ownerStore := k.getClassStoreByOwner(ctx, owner, classID) + ownerStore.Set([]byte(nftID), Placeholder) +} + +func (k Keeper) deleteOwner(ctx sdk.Context, classID, nftID string, owner sdk.AccAddress) { + store := ctx.KVStore(k.storeKey) + store.Delete(ownerStoreKey(classID, nftID)) + + ownerStore := k.getClassStoreByOwner(ctx, owner, classID) + ownerStore.Delete([]byte(nftID)) +} + +func (k Keeper) getNFTStore(ctx sdk.Context, classID string) prefix.Store { + store := ctx.KVStore(k.storeKey) + return prefix.NewStore(store, nftStoreKey(classID)) +} + +func (k Keeper) getClassStoreByOwner(ctx sdk.Context, owner sdk.AccAddress, classID string) prefix.Store { + store := ctx.KVStore(k.storeKey) + key := nftOfClassByOwnerStoreKey(owner, classID) + return prefix.NewStore(store, key) +} + +func (k Keeper) incrTotalSupply(ctx sdk.Context, classID string) { + supply := k.GetTotalSupply(ctx, classID) + 1 + k.updateTotalSupply(ctx, classID, supply) +} + +func (k Keeper) decrTotalSupply(ctx sdk.Context, classID string) { + supply := k.GetTotalSupply(ctx, classID) - 1 + k.updateTotalSupply(ctx, classID, supply) +} + +func (k Keeper) updateTotalSupply(ctx sdk.Context, classID string, supply uint64) { + store := ctx.KVStore(k.storeKey) + supplyKey := classTotalSupply(classID) + store.Set(supplyKey, sdk.Uint64ToBigEndian(supply)) +} diff --git a/x/nft/keys.go b/x/nft/keys.go new file mode 100644 index 000000000000..da03362d7cd4 --- /dev/null +++ b/x/nft/keys.go @@ -0,0 +1,12 @@ +package nft + +const ( + // module name + ModuleName = "nft" + + // StoreKey is the default store key for nft + StoreKey = ModuleName + + // RouterKey is the message route for nft + RouterKey = ModuleName +) diff --git a/x/nft/module/module.go b/x/nft/module/module.go new file mode 100644 index 000000000000..c68c5d28b87c --- /dev/null +++ b/x/nft/module/module.go @@ -0,0 +1,157 @@ +package nft + +import ( + "context" + "encoding/json" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + sdkclient "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/cosmos/cosmos-sdk/x/nft" + "github.com/cosmos/cosmos-sdk/x/nft/keeper" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the nft module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// Name returns the nft module's name. +func (AppModuleBasic) Name() string { + return nft.ModuleName +} + +// RegisterServices registers a gRPC query service to respond to the +// module-specific gRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + nft.RegisterMsgServer(cfg.MsgServer(), am.keeper) +} + +// RegisterLegacyAminoCodec registers the nft module's types for the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// RegisterInterfaces registers the nft module's interface types +func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + nft.RegisterInterfaces(registry) +} + +// DefaultGenesis returns default genesis state as raw bytes for the nft +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(nft.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the nft module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error { + var data nft.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return sdkerrors.Wrapf(err, "failed to unmarshal %s genesis state", nft.ModuleName) + } + + return nft.ValidateGenesis(data) +} + +// RegisterRESTRoutes registers the REST routes for the nft module. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, r *mux.Router) { +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the nft module. +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { + nft.RegisterQueryHandlerClient(context.Background(), mux, nft.NewQueryClient(clientCtx)) +} + +// GetQueryCmd returns the cli query commands for the nft module +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +// GetTxCmd returns the transaction commands for the nft module +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// AppModule implements the sdk.AppModule interface +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper + // TODO accountKeeper,bankKeeper will be replaced by query service + accountKeeper nft.AccountKeeper + bankKeeper nft.BankKeeper + registry cdctypes.InterfaceRegistry +} + +// NewAppModule creates a new AppModule object +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak nft.AccountKeeper, bk nft.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + accountKeeper: ak, + bankKeeper: bk, + registry: registry, + } +} + +// Name returns the nft module's name. +func (AppModule) Name() string { + return nft.ModuleName +} + +// RegisterInvariants does nothing, there are no invariants to enforce +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the message routing key for the staking module. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(nft.RouterKey, nil) +} + +func (am AppModule) NewHandler() sdk.Handler { + return nil +} + +// QuerierRoute returns the route we respond to for abci queries +func (AppModule) QuerierRoute() string { return "" } + +// LegacyQuerierHandler returns the nft module sdk.Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return nil +} + +// InitGenesis performs genesis initialization for the nft module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState nft.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + am.keeper.InitGenesis(ctx, &genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the nft +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} + +// EndBlock does nothing +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/nft/msgs.go b/x/nft/msgs.go new file mode 100644 index 000000000000..85fbc1ba4956 --- /dev/null +++ b/x/nft/msgs.go @@ -0,0 +1,43 @@ +package nft + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + // TypeMsgSend nft message types + TypeMsgSend = "send" +) + +var ( + _ sdk.Msg = &MsgSend{} +) + +// GetSigners implements the Msg.ValidateBasic method. +func (m MsgSend) ValidateBasic() error { + if err := ValidateClassID(m.ClassId); err != nil { + return sdkerrors.Wrapf(ErrInvalidID, "Invalid class id (%s)", m.ClassId) + } + + if err := ValidateNFTID(m.Id); err != nil { + return sdkerrors.Wrapf(ErrInvalidID, "Invalid nft id (%s)", m.Id) + } + + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", m.Sender) + } + + _, err = sdk.AccAddressFromBech32(m.Receiver) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid receiver address (%s)", m.Receiver) + } + return nil +} + +// GetSigners implements Msg +func (m MsgSend) GetSigners() []sdk.AccAddress { + signer, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{signer} +} diff --git a/x/nft/nft.pb.go b/x/nft/nft.pb.go index 468cb1e58c3a..6c349f4bdfb5 100644 --- a/x/nft/nft.pb.go +++ b/x/nft/nft.pb.go @@ -27,15 +27,15 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Class struct { // id defines the unique identifier of the NFT classification, similar to the contract address of ERC721 Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // name defines the human-readable name of the NFT classification + // name defines the human-readable name of the NFT classification,optional Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // symbol is an abbreviated name for nft classification + // symbol is an abbreviated name for nft classification,optional Symbol string `protobuf:"bytes,3,opt,name=symbol,proto3" json:"symbol,omitempty"` - // description is a brief description of nft classification + // description is a brief description of nft classification,optional Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` - // uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema. + // uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema.optional Uri string `protobuf:"bytes,5,opt,name=uri,proto3" json:"uri,omitempty"` - // uri_hash is a hash of the document pointed to uri + // uri_hash is a hash of the document pointed to uri,optional UriHash string `protobuf:"bytes,6,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } @@ -124,7 +124,7 @@ type NFT struct { Uri string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"` // uri_hash is a hash of the document pointed to uri UriHash string `protobuf:"bytes,4,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` - // data is the metadata of the NFT + // data is the metadata of the NFT,optional Data *types.Any `protobuf:"bytes,10,opt,name=data,proto3" json:"data,omitempty"` } diff --git a/x/nft/validation.go b/x/nft/validation.go new file mode 100644 index 000000000000..76621190f764 --- /dev/null +++ b/x/nft/validation.go @@ -0,0 +1,33 @@ +package nft + +import ( + fmt "fmt" + "regexp" +) + +var ( + // reClassIDString can be 3 ~ 100 characters long and support letters, followed by either + // a letter, a number or a slash ('/') or a colon (':'). + reClassIDString = `[a-zA-Z][a-zA-Z0-9/-:]{2,100}` + reClassID = regexp.MustCompile(fmt.Sprintf(`^%s$`, reClassIDString)) + + // reNFTIDString can be 3 ~ 100 characters long and support letters, followed by either + // a letter, a number or a slash ('/') or a colon (':'). + reNFTID = reClassID +) + +// ValidateClassID returns whether the class id is valid +func ValidateClassID(id string) error { + if !reClassID.MatchString(id) { + return fmt.Errorf("invalid class id: %s", id) + } + return nil +} + +// ValidateNFTID returns whether the nft id is valid +func ValidateNFTID(id string) error { + if !reNFTID.MatchString(id) { + return fmt.Errorf("invalid nft id: %s", id) + } + return nil +} From 2135de9d179429c82936cdbb8e4f02cd2b19cc08 Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Wed, 27 Oct 2021 12:44:18 -0400 Subject: [PATCH 12/38] docs: Update Cosmovisor README.md (#10284) ## Description Changes discussed on the call with @robert-zaremba Closes: #XXXX --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- cosmovisor/README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/cosmovisor/README.md b/cosmovisor/README.md index b6e3b3e8eff1..a87a7693d684 100644 --- a/cosmovisor/README.md +++ b/cosmovisor/README.md @@ -30,6 +30,29 @@ To install the latest version of `cosmovisor`, run the following command: go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@latest ``` +To install a previous version, you can specify the version. IMPORTANT: Chains that use Cosmos-SDK v0.42.x and want to use auto-download feature MUST use Cosmovisor v0.1.0 + +``` +go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@v0.1.0 +``` + +It is possible to confirm the version of cosmovisor when using Cosmovisor v1.0.0, but it is not possible to do so with `v0.1.0`. + +You can also install from source by pulling the cosmos-sdk repository and switching to the correct version and building as follows: + +``` +git clone git@github.com:cosmos/cosmos-sdk +cd cosmos-sdk +git checkout cosmovisor/vx.x.x +cd cosmovisor +make +``` +This will build cosmovisor in your current directory. Afterwards you may want to put it into your machine's PATH like as follows: + +``` +cp cosmovisor ~/go/bin/cosmovisor +``` + *Note: If you are using go `v1.15` or earlier, you will need to use `go get`, and you may want to run the command outside a project directory.* ### Command Line Arguments And Environment Variables @@ -128,6 +151,35 @@ If `DAEMON_ALLOW_DOWNLOAD_BINARIES` is set to `true`, and no local binary can be } ``` +You can include multiple binaries at once to ensure more than one environment will receive the correct binaries: + +```json +{ + "binaries": { + "linux/amd64":"https://example.com/gaia.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f", + "linux/arm64":"https://example.com/gaia.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f", + "darwin/amd64":"https://example.com/gaia.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f" + } +} +``` + +When submitting this as a proposal ensure there are no spaces. An example command using `gaiad` could look like: + +``` +> gaiad tx gov submit-proposal software-upgrade Vega \ +--title Vega \ +--deposit 100uatom \ +--upgrade-height 7368420 \ +--upgrade-info '{"binaries":{"linux/amd64":"https://github.com/cosmos/gaia/releases/download/v6.0.0-rc1/gaiad-v6.0.0-rc1-linux-amd64","linux/arm64":"https://github.com/cosmos/gaia/releases/download/v6.0.0-rc1/gaiad-v6.0.0-rc1-linux-arm64","darwin/amd64":"https://github.com/cosmos/gaia/releases/download/v6.0.0-rc1/gaiad-v6.0.0-rc1-darwin-amd64"}}' \ +--description "upgrade to Vega" \ +--gas 400000 \ +--from user \ +--chain-id test \ +--home test/val2 \ +--node tcp://localhost:36657 \ +--yes +``` + 2. Store a link to a file that contains all information in the above format (e.g. if you want to specify lots of binaries, changelog info, etc. without filling up the blockchain). For example: ``` From 2024a62c9e9f302cb98efa37b780392762805287 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Thu, 28 Oct 2021 11:49:37 +0200 Subject: [PATCH 13/38] chore: Update master changelog with 0.44 and 0.42 (#10431) ## Description This hasn't been done for a while. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 97 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23d99e27e275..b1c127bc3197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,15 +42,12 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10393](https://github.com/cosmos/cosmos-sdk/pull/10393) Add `HasSupply` method to bank keeper to ensure that input denom actually exists on chain. * [\#9933](https://github.com/cosmos/cosmos-sdk/pull/9933) Introduces the notion of a Cosmos "Scalar" type, which would just be simple aliases that give human-understandable meaning to the underlying type, both in Go code and in Proto definitions. * [\#9884](https://github.com/cosmos/cosmos-sdk/pull/9884) Provide a new gRPC query handler, `/cosmos/params/v1beta1/subspaces`, that allows the ability to query for all registered subspaces and their respective keys. -* [\#9860](https://github.com/cosmos/cosmos-sdk/pull/9860) Emit transaction fee in ante handler fee decorator. The event type is `tx` and the attribute is `fee`. * [\#9776](https://github.com/cosmos/cosmos-sdk/pull/9776) Add flag `staking-bond-denom` to specify the staking bond denomination value when initializing a new chain. * [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination. * (bank) [\#9618](https://github.com/cosmos/cosmos-sdk/pull/9618) Update bank.Metadata: add URI and URIHash attributes. * (store) [\#8664](https://github.com/cosmos/cosmos-sdk/pull/8664) Implementation of ADR-038 file StreamingService * [\#9837](https://github.com/cosmos/cosmos-sdk/issues/9837) `--generate-only` flag will accept the keyname now. -* [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. -* [\#10024](https://github.com/cosmos/cosmos-sdk/pull/10024) `store/cachekv` performance improvement by reduced growth factor for iterator ranging by using binary searches to find dirty items when unsorted key count >= 1024 * [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. ### API Breaking Changes @@ -73,7 +70,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ * `MkConsKeyOutput` * `MkValKeyOutput` * `MkAccKeyOutput` -* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077),[\#10334](https://github.com/cosmos/cosmos-sdk/pull/10334) Remove telemetry on `GasKV` and `CacheKV` store operations, significantly improving their performance. * [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `AuthKeeper` interface in `x/auth` now includes a function `HasAccount`. * [\#9759](https://github.com/cosmos/cosmos-sdk/pull/9759) `NewAccountKeeeper` in `x/auth` now takes an additional `bech32Prefix` argument that represents `sdk.Bech32MainPrefix`. * [\#9628](https://github.com/cosmos/cosmos-sdk/pull/9628) Rename `x/{mod}/legacy` to `x/{mod}/migrations`. @@ -107,7 +103,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Client Breaking Changes -* [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height. * [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) Remove legacy REST API. Please see the [REST Endpoints Migration guide](https://docs.cosmos.network/master/migrations/rest.html) to migrate to the new REST endpoints. * [\#9995](https://github.com/cosmos/cosmos-sdk/pull/9995) Increased gas cost for creating proposals. @@ -119,30 +114,22 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements -* [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` * [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Remove gogoproto `moretags` YAML annotations and add `sigs.k8s.io/yaml` for YAML marshalling. * (x/bank) [\#10134](https://github.com/cosmos/cosmos-sdk/pull/10134) Add `HasDenomMetadata` function to bank `Keeper` to check if a client coin denom metadata exists in state. -* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. * (types) [\#10076](https://github.com/cosmos/cosmos-sdk/pull/10076) Significantly speedup and lower allocations for `Coins.String()`. * (x/bank) [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `BankKeeper.SendCoins` now takes less execution time. * (deps) [\#9987](https://github.com/cosmos/cosmos-sdk/pull/9987) Bump Go version minimum requirement to `1.17` -* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12). * (cli) [\#9856](https://github.com/cosmos/cosmos-sdk/pull/9856) Overwrite `--sequence` and `--account-number` flags with default flag values when used with `offline=false` in `sign-batch` command. -* (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. * (rosetta) [\#10001](https://github.com/cosmos/cosmos-sdk/issues/10001) Add documentation for rosetta-cli dockerfile and rename folder for the rosetta-ci dockerfile * [\#9699](https://github.com/cosmos/cosmos-sdk/pull/9699) Add `:`, `.`, `-`, and `_` as allowed characters in the default denom regular expression. * (genesis) [\#9697](https://github.com/cosmos/cosmos-sdk/pull/9697) Ensure `InitGenesis` returns with non-empty validator set. -* [\#10262](https://github.com/cosmos/cosmos-sdk/pull/10262) Remove unnecessary logging in `x/feegrant` simulation. -* [\#10339](https://github.com/cosmos/cosmos-sdk/pull/10339) Improve performance of `removeZeroCoins` by only allocating memory when necessary * [\#10341](https://github.com/cosmos/cosmos-sdk/pull/10341) Move from `io/ioutil` to `io` and `os` packages. ### Bug Fixes * [\#10414](https://github.com/cosmos/cosmos-sdk/pull/10414) Use `sdk.GetConfig().GetFullBIP44Path()` instead `sdk.FullFundraiserPath` to generate key * (rosetta) [\#10340](https://github.com/cosmos/cosmos-sdk/pull/10340) Use `GenesisChunked(ctx)` instead `Genesis(ctx)` to get genesis block height -* (client) [#10226](https://github.com/cosmos/cosmos-sdk/pull/10226) Fix --home flag parsing. * [#10180](https://github.com/cosmos/cosmos-sdk/issues/10180) Documentation: make references to Cosmos SDK consistent -* (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly. * [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter. * [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`) * (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt` @@ -152,11 +139,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#9762](https://github.com/cosmos/cosmos-sdk/pull/9762) The init command uses the chain-id from the client config if --chain-id is not provided * [\#9854](https://github.com/cosmos/cosmos-sdk/pull/9854) Fixed the `make proto-gen` to get dynamic container name based on project name for the cosmos based sdks. * [\#9829](https://github.com/cosmos/cosmos-sdk/pull/9829) Fixed Coin denom sorting not being checked during `Balance.Validate` check. Refactored the Validation logic to use `Coins.Validate` for `Balance.Coins`. -+ [\#9965](https://github.com/cosmos/cosmos-sdk/pull/9965) Fixed `simd version` command output to report the right release tag. + [\#9980](https://github.com/cosmos/cosmos-sdk/pull/9980) Returning the error when the invalid argument is passed to bank query total supply cli. + [\#10061](https://github.com/cosmos/cosmos-sdk/pull/10061) Ensure that `LegacyAminoPubKey` struct correctly unmarshals from JSON * (server) [#10016](https://github.com/cosmos/cosmos-sdk/issues/10016) Fix marshaling of index-events into server config file. -* (x/feegrant) [\#10049](https://github.com/cosmos/cosmos-sdk/issues/10049) Fixed the error message when `period` or `period-limit` flag is not set on a feegrant grant transaction. * [\#10184](https://github.com/cosmos/cosmos-sdk/pull/10184) Fixed CLI tx commands to no longer explicitly require the chain-id flag as this value can come from a user config. * [\#10239](https://github.com/cosmos/cosmos-sdk/pull/10239) Fixed x/bank/044 migrateDenomMetadata. * (x/upgrade) [\#10189](https://github.com/cosmos/cosmos-sdk/issues/10189) Removed potential sources of non-determinism in upgrades @@ -178,6 +163,68 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) +## [v0.44.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.3) - 2021-10-21 + +### Improvements + +* [\#10262](https://github.com/cosmos/cosmos-sdk/pull/10262) Remove unnecessary logging in `x/feegrant` simulation. +* [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` +* [\#10339](https://github.com/cosmos/cosmos-sdk/pull/10339) Improve performance of `removeZeroCoins` by only allocating memory when necessary +* [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. +* (deps) [\#10375](https://github.com/cosmos/cosmos-sdk/pull/10375) Bump Tendermint to [v0.34.14](https://github.com/tendermint/tendermint/releases/tag/v0.34.14). +* [\#10024](https://github.com/cosmos/cosmos-sdk/pull/10024) `store/cachekv` performance improvement by reduced growth factor for iterator ranging by using binary searches to find dirty items when unsorted key count >= 1024. + +### Bug Fixes + +* (client) [#10226](https://github.com/cosmos/cosmos-sdk/pull/10226) Fix --home flag parsing. +* (rosetta) [\#10340](https://github.com/cosmos/cosmos-sdk/pull/10340) Use `GenesisChunked(ctx)` instead `Genesis(ctx)` to get genesis block height + +## [v0.44.2](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.2) - 2021-10-12 + +Security Release. No breaking changes related to 0.44.x. + +## [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1) - 2021-09-29 + +### Improvements + +* (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. +* (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. +* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. +* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. + +### Bug Fixes + +* [\#9969](https://github.com/cosmos/cosmos-sdk/pull/9969) fix: use keyring in config for add-genesis-account cmd. +* (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly. +* (x/feegrant) [\#10049](https://github.com/cosmos/cosmos-sdk/issues/10049) Fixed the error message when `period` or `period-limit` flag is not set on a feegrant grant transaction. + +### Client Breaking Changes + +* [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height. + +## [v0.44.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.0) - 2021-09-01 + +### Features + +* [\#9860](https://github.com/cosmos/cosmos-sdk/pull/9860) Emit transaction fee in ante handler fee decorator. The event type is `tx` and the attribute is `fee`. + +### Improvements + +* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12). + +### Deprecated + +* (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) + +### Bug Fixes + +* [\#9965](https://github.com/cosmos/cosmos-sdk/pull/9965) Fixed `simd version` command output to report the right release tag. +* (x/upgrade) [\#10189](https://github.com/cosmos/cosmos-sdk/issues/10189) Removed potential sources of non-determinism in upgrades. + +### Client Breaking Changes + +* [\#10041](https://github.com/cosmos/cosmos-sdk/pull/10041) Remove broadcast & encode legacy REST endpoints. Please see the [REST Endpoints Migration guide](https://docs.cosmos.network/master/migrations/rest.html) to migrate to the new REST endpoints. + ## [v0.43.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0) - 2021-08-10 ### Features @@ -352,6 +399,26 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (grpc) [\#8926](https://github.com/cosmos/cosmos-sdk/pull/8926) The `tx` field in `SimulateRequest` has been deprecated, prefer to pass `tx_bytes` instead. * (sdk types) [\#9498](https://github.com/cosmos/cosmos-sdk/pull/9498) `clientContext.JSONCodec` will be removed in the next version. use `clientContext.Codec` instead. +## [v0.42.10](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.10) - 2021-09-28 + +### Improvements + +* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. +* (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. +* [\#10211](https://github.com/cosmos/cosmos-sdk/pull/10211) Backport of the mechanism to reject redundant IBC transactions from [ibc-go \#235](https://github.com/cosmos/ibc-go/pull/235). + +### Bug Fixes + +* [\#9969](https://github.com/cosmos/cosmos-sdk/pull/9969) fix: use keyring in config for add-genesis-account cmd. + +### Client Breaking Changes + +* [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height. + +### API Breaking Changes + +* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. + ## [v0.42.9](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.9) - 2021-08-04 ### Bug Fixes From b5ca8e0b48279a74e126721929764d1ef09d3449 Mon Sep 17 00:00:00 2001 From: likhita-809 <78951027+likhita-809@users.noreply.github.com> Date: Thu, 28 Oct 2021 16:31:25 +0530 Subject: [PATCH 14/38] fix: Check error for RegisterQueryHandlerClient in all modules RegisterGRPCGatewayRoutes (#10439) ## Description Closes: #10437 Checks the error for `RegisterQueryHandlerClient` in all modules `RegisterGRPCGatewayRoutes` --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + x/authz/module/module.go | 4 +++- x/bank/module.go | 4 +++- x/distribution/module.go | 5 +++-- x/evidence/module.go | 6 +++--- x/feegrant/module/module.go | 5 +++-- x/gov/module.go | 4 +++- x/mint/module.go | 5 +++-- x/params/module.go | 5 +++-- x/slashing/module.go | 6 +++--- x/staking/module.go | 5 +++-- x/upgrade/module.go | 4 +++- 12 files changed, 34 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c127bc3197..787ddee263c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,6 +114,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* [\#10439](https://github.com/cosmos/cosmos-sdk/pull/10439) Check error for `RegisterQueryHandlerClient` in all modules `RegisterGRPCGatewayRoutes`. * [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Remove gogoproto `moretags` YAML annotations and add `sigs.k8s.io/yaml` for YAML marshalling. * (x/bank) [\#10134](https://github.com/cosmos/cosmos-sdk/pull/10134) Add `HasDenomMetadata` function to bank `Keeper` to check if a client coin denom metadata exists in state. * (types) [\#10076](https://github.com/cosmos/cosmos-sdk/pull/10076) Significantly speedup and lower allocations for `Coins.String()`. diff --git a/x/authz/module/module.go b/x/authz/module/module.go index b1afdc06e12f..5e779244aa48 100644 --- a/x/authz/module/module.go +++ b/x/authz/module/module.go @@ -76,7 +76,9 @@ func (AppModuleBasic) RegisterRESTRoutes(_ sdkclient.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the authz module. func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { - authz.RegisterQueryHandlerClient(context.Background(), mux, authz.NewQueryClient(clientCtx)) + if err := authz.RegisterQueryHandlerClient(context.Background(), mux, authz.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetQueryCmd returns the cli query commands for the authz module diff --git a/x/bank/module.go b/x/bank/module.go index 62038da8b7b8..169f5b26ac4b 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -68,7 +68,9 @@ func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the bank module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the bank module. diff --git a/x/distribution/module.go b/x/distribution/module.go index 09232331e333..13cf674e3be0 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -8,7 +8,6 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" @@ -69,7 +68,9 @@ func (AppModuleBasic) RegisterRESTRoutes(_ sdkclient.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the distribution module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the distribution module. diff --git a/x/evidence/module.go b/x/evidence/module.go index cb6a358c164a..2d65ef8ead8a 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -8,9 +8,7 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -80,7 +78,9 @@ func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the evidence module. func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the evidence module's root tx command. diff --git a/x/feegrant/module/module.go b/x/feegrant/module/module.go index df6089b40fba..44107bc733da 100644 --- a/x/feegrant/module/module.go +++ b/x/feegrant/module/module.go @@ -8,7 +8,6 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" sdkclient "github.com/cosmos/cosmos-sdk/client" @@ -87,7 +86,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, rtr *mux.R // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the feegrant module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { - feegrant.RegisterQueryHandlerClient(context.Background(), mux, feegrant.NewQueryClient(clientCtx)) + if err := feegrant.RegisterQueryHandlerClient(context.Background(), mux, feegrant.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the feegrant module. diff --git a/x/gov/module.go b/x/gov/module.go index 659e5559275c..311ef7ffa0df 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -78,7 +78,9 @@ func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Ro // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the gov module. func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the gov module. diff --git a/x/mint/module.go b/x/mint/module.go index e923790dc0fb..27fb7beba05c 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -70,8 +70,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the mint module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) - + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns no root tx command for the mint module. diff --git a/x/params/module.go b/x/params/module.go index e27eaf44a2ef..f17ab2199d44 100644 --- a/x/params/module.go +++ b/x/params/module.go @@ -7,7 +7,6 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" @@ -58,7 +57,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the params module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - proposal.RegisterQueryHandlerClient(context.Background(), mux, proposal.NewQueryClient(clientCtx)) + if err := proposal.RegisterQueryHandlerClient(context.Background(), mux, proposal.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns no root tx command for the params module. diff --git a/x/slashing/module.go b/x/slashing/module.go index 68c3c2919cdd..cf51b57066ad 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -8,9 +8,7 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -77,7 +75,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the slashig module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the slashing module. diff --git a/x/staking/module.go b/x/staking/module.go index 6dfd0c67f8a9..ffe1e69fdd70 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -8,7 +8,6 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" @@ -79,7 +78,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the staking module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the staking module. diff --git a/x/upgrade/module.go b/x/upgrade/module.go index 00e966912d13..ed4b6e0ed9f3 100644 --- a/x/upgrade/module.go +++ b/x/upgrade/module.go @@ -48,7 +48,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the upgrade module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetQueryCmd returns the cli query commands for this module From 3c3704fa88821c3345cbdfc8e5afafadea7cff98 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 29 Oct 2021 00:27:31 +0100 Subject: [PATCH 15/38] fix: github test workflow (#10325) ## Description Closes: #10319 @odeke-em reported that `db/memdb` doesn't build: https://github.com/cosmos/cosmos-sdk/issues/10319 The problem is not detected by the Github CI. Here we try to fix this. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- .github/workflows/test.yml | 30 ++++++++++++++++--------- scripts/module-tests.sh | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 scripts/module-tests.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 325305e4f5e4..099817208d38 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,39 +38,43 @@ jobs: with: PATTERNS: | **/**.go - go.mod - go.sum + **/go.mod + **/go.sum - name: Build run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build - test-cosmovisor: + - name: Build cosmovisor + run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make cosmovisor + + test-submodules: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2.1.4 with: go-version: 1.17 - - name: Display go version - run: go version - uses: technote-space/get-diff-action@v5 id: git_diff with: - PREFIX_FILTER: | - cosmovisor PATTERNS: | **/**.go go.mod go.sum - - name: Run cosmovisor tests - run: cd cosmovisor; make + - name: Run submodule tests and create test coverage profile. + # GIT_DIFF is passed to the scripts + run: bash scripts/module-tests.sh if: env.GIT_DIFF + - uses: actions/upload-artifact@v2 + with: + name: "${{ github.sha }}-go-submodules-coverage" + path: ./coverage-go-submod-profile.out split-test-files: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Create a file with all the pkgs - run: go list ./... > pkgs.txt + - name: Create a file with all core Cosmos SDK pkgs + run: go list ./... > pkgs.txt - name: Split pkgs into 4 files run: split -d -n l/4 pkgs.txt pkgs.txt.part. # cache multiple @@ -149,6 +153,10 @@ jobs: with: name: "${{ github.sha }}-03-coverage" if: env.GIT_DIFF + - uses: actions/download-artifact@v2 + with: + name: "${{ github.sha }}-go-submodules-coverage" + if: env.GIT_DIFF - run: | cat ./*profile.out | grep -v "mode: atomic" >> coverage.txt if: env.GIT_DIFF diff --git a/scripts/module-tests.sh b/scripts/module-tests.sh new file mode 100644 index 000000000000..c34ec9106886 --- /dev/null +++ b/scripts/module-tests.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# this script is used by Github CI to tranverse all modules an run module tests. +# the script expects a diff to be generated in order to skip some modules. + +# Executes go module tests and merges the coverage profile. +# If GIT_DIFF variable is set then it's used to test if a module has any file changes - if +# it doesn't have any file changes then we will ignore the module tests. +execute_mod_tests() { + go_mod=$1; + mod_dir=$(dirname "$go_mod"); + mod_dir=${mod_dir:2}; # remove "./" prefix + root_dir=$(pwd); + + # TODO: in the future we will need to disable it once we go into multi module setup, because + # we will have cross module dependencies. + if [ -n "$GIT_DIFF" ] && ! grep $mod_dir <<< $GIT_DIFF; then + echo "ignoring module $mod_dir - no changes in the module"; + return; + fi; + + echo "executing $go_mod tests" + cd $mod_dir; + go test -mod=readonly -timeout 30m -coverprofile=${root_dir}/${coverage_file}.tmp -covermode=atomic -tags='norace ledger test_ledger_mock' ./... + local ret=$? + echo "test return: " $ret; + cd -; + # strip mode statement + tail -n +1 ${coverage_file}.tmp >> ${coverage_file} + rm ${coverage_file}.tmp; + return $ret; +} + +GIT_DIFF=`git status --porcelain` + +coverage_file=coverage-go-submod-profile.out +return_val=0; + +for f in $(find -name go.mod -not -path "./go.mod") "./container/go.mod"; do + execute_mod_tests $f; + if [[ $? -ne 0 ]] ; then + return_val=2; + fi; +done + +exit $return_val; From bc3cda69f822722e7c2533ea8112833130116720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 13:34:25 +0200 Subject: [PATCH 16/38] build(deps): Bump amannn/action-semantic-pull-request (#10456) Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 3.4.2 to 3.4.5. - [Release notes](https://github.com/amannn/action-semantic-pull-request/releases) - [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/master/CHANGELOG.md) - [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v3.4.2...v3.4.5) --- updated-dependencies: - dependency-name: amannn/action-semantic-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index 774146009681..c1a343cfae1e 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -11,6 +11,6 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v3.4.2 + - uses: amannn/action-semantic-pull-request@v3.4.5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 479485f95dbb4f3721d688823b32370cb0020af3 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Sat, 30 Oct 2021 14:43:04 +0100 Subject: [PATCH 17/38] style: lint go and markdown (#10060) ## Description + fixing `x/bank/migrations/v44.migrateDenomMetadata` - we could potentially put a wrong data in a new key if the old keys have variable length. + linting the code Putting in the same PR because i found the issue when running a linter. Depends on: #10112 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CODING_GUIDELINES.md | 20 +++++++------ CONTRIBUTING.md | 22 ++++++++------ RELEASE_PROCESS.md | 29 ++++++++++--------- contrib/rosetta/README.md | 1 + cosmovisor/README.md | 5 ++++ crypto/keyring/keyring.go | 2 +- crypto/keys/multisig/amino.go | 2 +- crypto/keys/secp256k1/secp256k1_nocgo.go | 1 + crypto/ledger/ledger_notavail.go | 2 ++ db/README.md | 27 ++++++++++------- docs/404.md | 4 +-- docs/DOCS_README.md | 16 +++++----- .../adr-010-modular-antehandler.md | 4 --- .../adr-022-custom-panic-handling.md | 4 --- docs/architecture/adr-038-state-listening.md | 28 +++++++++--------- ...r-040-storage-and-smt-state-commitments.md | 2 +- docs/architecture/adr-043-nft-module.md | 4 +-- .../adr-044-protobuf-updates-guidelines.md | 10 +++---- docs/architecture/adr-046-module-params.md | 12 ++++---- docs/migrations/pre-upgrade.md | 4 +-- docs/migrations/rest.md | 2 +- docs/ru/README.md | 2 +- docs/run-node/rosetta.md | 2 +- docs/run-node/run-node.md | 2 ++ docs/run-node/run-testnet.md | 2 +- go.mod | 2 +- go.sum | 3 +- scripts/module-tests.sh | 10 ++++--- server/rosetta/client_online.go | 2 +- server/rosetta/lib/internal/service/online.go | 2 +- simapp/simd/cmd/genaccounts.go | 1 - snapshots/README.md | 2 +- store/streaming/README.md | 2 +- store/streaming/file/README.md | 4 ++- store/v2/flat/store.go | 18 ++++++------ store/v2/smt/store.go | 4 +-- types/denom.go | 2 +- x/auth/middleware/basic.go | 2 +- x/auth/middleware/sigverify.go | 6 ++-- x/auth/spec/01_concepts.md | 1 + x/auth/spec/05_vesting.md | 2 +- x/auth/spec/07_client.md | 3 +- x/authz/spec/05_client.md | 2 +- x/bank/spec/README.md | 2 +- x/crisis/spec/05_client.md | 9 +++++- x/distribution/migrations/v043/helpers.go | 2 +- x/distribution/spec/README.md | 2 +- x/epoching/keeper/keeper.go | 6 ++-- x/epoching/spec/03_to_improve.md | 2 +- x/evidence/spec/07_client.md | 8 ++++- x/feegrant/spec/README.md | 2 +- x/gov/spec/01_concepts.md | 2 +- x/gov/spec/07_client.md | 12 ++++---- x/group/internal/orm/spec/01_table.md | 16 +++++----- x/mint/spec/06_client.md | 12 +++----- x/slashing/spec/09_client.md | 2 -- x/slashing/spec/README.md | 2 +- x/staking/spec/09_client.md | 8 ++--- x/upgrade/spec/04_client.md | 11 +++---- 59 files changed, 197 insertions(+), 178 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index a2926bb3cd1d..3ea8d20556d4 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -5,9 +5,9 @@ This document is an extension to [CONTRIBUTING](./CONTRIBUTING.md) and provides ## API & Design + Code must be well structured: - + packages must have a limited responsibility (different concerns can go to different packages), - + types must be easy to compose, - + think about maintainbility and testability. + + packages must have a limited responsibility (different concerns can go to different packages), + + types must be easy to compose, + + think about maintainbility and testability. + "Depend upon abstractions, [not] concretions". + Try to limit the number of methods you are exposing. It's easier to expose something later than to hide it. + Take advantage of `internal` package concept. @@ -19,20 +19,22 @@ This document is an extension to [CONTRIBUTING](./CONTRIBUTING.md) and provides + Limit third-party dependencies. Performance: + + Avoid unnecessary operations or memory allocations. Security: + + Pay proper attention to exploits involving: - + gas usage - + transaction verification and signatures - + malleability - + code must be always deterministic + + gas usage + + transaction verification and signatures + + malleability + + code must be always deterministic + Thread safety. If some functionality is not thread-safe, or uses something that is not thread-safe, then clearly indicate the risk on each level. - ## Testing Make sure your code is well tested: + + Provide unit tests for every unit of your code if possible. Unit tests are expected to comprise 70%-80% of your tests. + Describe the test scenarios you are implementing for integration tests. + Create integration tests for queries and msgs. @@ -64,6 +66,7 @@ for tcIndex, tc := range cases { ## Quality Assurance We are forming a QA team that will support the core Cosmos SDK team and collaborators by: + - Improving the Cosmos SDK QA Processes - Improving automation in QA and testing - Defining high-quality metrics @@ -83,5 +86,4 @@ Desired outcomes: - Releases are more predictable. - QA reports. Goal is to guide with new tasks and be one of the QA measures. - As a developer, you must help the QA team by providing instructions for User Experience (UX) and functional testing. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0a51c6d6c05..168f1419c37b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,11 +23,13 @@ discussion or proposing code changes. To ensure a smooth workflow for all contributors, the general procedure for contributing has been established: 1. Start by browsing [new issues](https://github.com/cosmos/cosmos-sdk/issues) and [discussions](https://github.com/cosmos/cosmos-sdk/discussions). If you are looking for something interesting or if you have something in your mind, there is a chance it was has been discussed. - - Looking for a good place to start contributing? How about checking out some [good first issues](https://github.com/cosmos/cosmos-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)? + +- Looking for a good place to start contributing? How about checking out some [good first issues](https://github.com/cosmos/cosmos-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)? + 2. Determine whether a GitHub issue or discussion is more appropriate for your needs: - 1. If want to propose something new that requires specification or an additional design, or you would like to change a process, start with a [new discussion](https://github.com/cosmos/cosmos-sdk/discussions/new). With discussions, we can better handle the design process using discussion threads. A discussion usually leads to one or more issues. - 2. If the issue you want addressed is a specific proposal or a bug, then open a [new issue](https://github.com/cosmos/cosmos-sdk/issues/new/choose). - 3. Review existing [issues](https://github.com/cosmos/cosmos-sdk/issues) to find an issue you'd like to help with. +1. If want to propose something new that requires specification or an additional design, or you would like to change a process, start with a [new discussion](https://github.com/cosmos/cosmos-sdk/discussions/new). With discussions, we can better handle the design process using discussion threads. A discussion usually leads to one or more issues. +2. If the issue you want addressed is a specific proposal or a bug, then open a [new issue](https://github.com/cosmos/cosmos-sdk/issues/new/choose). +3. Review existing [issues](https://github.com/cosmos/cosmos-sdk/issues) to find an issue you'd like to help with. 3. Participate in thoughtful discussion on that issue. 4. If you would like to contribute: 1. Ensure that the proposal has been accepted. @@ -38,7 +40,7 @@ contributors, the general procedure for contributing has been established: to begin work. 5. To submit your work as a contribution to the repository follow standard GitHub best practices. See [pull request guideline](#pull-requests) below. -**Note: ** For very small or blatantly obvious problems such as typos, you are +**Note:** For very small or blatantly obvious problems such as typos, you are not required to an open issue to submit a PR, but be aware that for more complex problems/features, if a PR is opened before an adequate design discussion has taken place in a GitHub issue, that PR runs a high likelihood of being rejected. @@ -52,6 +54,7 @@ The developers are organized in working groups which are listed on a ["Working G The important development announcements are shared on [Discord](https://discord.com/invite/cosmosnetwork) in the \#dev-announcements channel. To synchronize we have few major meetings: + + Architecture calls: bi-weekly on Fridays at 14:00 UTC (alternating with the grooming meeting below). + Grooming / Planning: bi-weekly on Fridays at 14:00 UTC (alternating with the architecture meeting above). + Cosmos Community SDK Development Call on the last Wednesday of every month at 17:00 UTC. @@ -59,7 +62,6 @@ To synchronize we have few major meetings: If you would like to join one of those calls, then please contact us on [Discord](https://discord.com/invite/cosmosnetwork) or reach out directly to Cory Levinson from Regen Network (cory@regen.network). - ## Architecture Decision Records (ADR) When proposing an architecture decision for the Cosmos SDK, please start by opening an [issue](https://github.com/cosmos/cosmos-sdk/issues/new/choose) or a [discussion](https://github.com/cosmos/cosmos-sdk/discussions/new) with a summary of the proposal. Once the proposal has been discussed and there is rough alignment on a high-level approach to the design, the [ADR creation process](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/PROCESS.md) can begin. We are following this process to ensure all involved parties are in agreement before any party begins coding the proposed implementation. If you would like to see examples of how these are written, please refer to the current [ADRs](https://github.com/cosmos/cosmos-sdk/tree/master/docs/architecture). @@ -70,11 +72,11 @@ When proposing an architecture decision for the Cosmos SDK, please start by open - `master` must never fail `make lint test test-race`. - No `--force` onto `master` (except when reverting a broken commit, which should seldom happen). - Create a branch to start a wok: - - Fork the repo (core developers must create a branch directly in the Cosmos SDK repo), + - Fork the repo (core developers must create a branch directly in the Cosmos SDK repo), branch from the HEAD of `master`, make some commits, and submit a PR to `master`. - - For core developers working within the `cosmos-sdk` repo, follow branch name conventions to ensure a clear + - For core developers working within the `cosmos-sdk` repo, follow branch name conventions to ensure a clear ownership of branches: `{moniker}/{issue#}-branch-name`. - - See [Branching Model](#branching-model-and-release) for more details. + - See [Branching Model](#branching-model-and-release) for more details. - Be sure to run `make format` before every commit. The easiest way to do this is have your editor run it for you upon saving a file (most of the editors will do it anyway using a pre-configured setup of the programming language mode). @@ -92,10 +94,12 @@ Tests can be executed by running `make test` at the top level of the Cosmos SDK ### Pull Requests Before submitting a pull request: + - merge the latest master `git merge origin/master`, - run `make lint test` to ensure that all checks and tests pass. Then: + 1. If you have something to show, **start with a `Draft` PR**. It's good to have early validation of your work and we highly recommend this practice. A Draft PR also indicates to the community that the work is in progress. Draft PRs also helps the core team provide early feedback and ensure the work is in the right direction. 2. When the code is complete, change your PR from `Draft` to `Ready for Review`. diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 245a7bc866ca..c6fb76c28795 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -7,16 +7,17 @@ This document outlines the process for releasing a new version of Cosmos SDK, wh A _major release_ is an increment of the first number (eg: `v1.2` → `v2.0.0`) or the _point number_ (eg: `v1.1 → v1.2.0`, also called _point release_). Each major release opens a _stable release series_ and receives updates outlined in the [Major Release Maintenance](#major-release-maintenance)_section. Before making a new _major_ release we do beta and release candidate releases. For example, for release 1.0.0: + ``` v1.0.0-beta1 → v1.0.0-beta2 → ... → v1.0.0-rc1 → v1.0.0-rc2 → ... → v1.0.0 ``` - Release a first beta version on the `master` branch and freeze `master` from receiving any new features. After beta is released, we focus on releasing the release candidate: - - finish audits and reviews - - kick off a large round of simulation testing (e.g. 400 seeds for 2k blocks) - - perform functional tests - - add more tests - - release new beta version as the bugs are discovered and fixed. + - finish audits and reviews + - kick off a large round of simulation testing (e.g. 400 seeds for 2k blocks) + - perform functional tests + - add more tests + - release new beta version as the bugs are discovered and fixed. - After the team feels that the `master` works fine we create a `release/vY` branch (going forward known a release branch), where `Y` is the version number, with the patch part substituted to `x` (eg: 0.42.x, 1.0.x). Ensure the release branch is protected so that pushes against the release branch are permitted only by the release manager or release coordinator. - **PRs targeting this branch can be merged _only_ when exceptional circumstances arise** - update the GitHub mergify integration by adding instructions for automatically backporting commits from `master` to the `release/vY` using the `backport/Y` label. @@ -24,16 +25,17 @@ v1.0.0-beta1 → v1.0.0-beta2 → ... → v1.0.0-rc1 → v1.0.0-rc2 → ... → - All links must be link-ified: `$ python ./scripts/linkify_changelog.py CHANGELOG.md` - Copy the entries into a `RELEASE_CHANGELOG.md`, this is needed so the bot knows which entries to add to the release page on GitHub. - Create a new annotated git tag for a release candidate (eg: `git tag -a v1.1.0-rc1`) in the release branch. - - from this point we unfreeze master. - - the SDK teams collaborate and do their best to run testnets in order to validate the release. - - when bugs are found, create a PR for `master`, and backport fixes to the release branch. - - create new release candidate tags after bugs are fixed. + - from this point we unfreeze master. + - the SDK teams collaborate and do their best to run testnets in order to validate the release. + - when bugs are found, create a PR for `master`, and backport fixes to the release branch. + - create new release candidate tags after bugs are fixed. - After the team feels the release branch is stable and everything works, create a full release: - - update `CHANGELOG.md`. - - create a new annotated git tag (eg `git -a v1.1.0`) in the release branch. - - Create a GitHub release. + - update `CHANGELOG.md`. + - create a new annotated git tag (eg `git -a v1.1.0`) in the release branch. + - Create a GitHub release. Following _semver_ philosophy, point releases after `v1.0`: + - must not break API - can break consensus @@ -54,11 +56,11 @@ Lastly, it is core team's responsibility to ensure that the PR meets all the SRU Point Release must follow the [Stable Release Policy](#stable-release-policy). After the release branch has all commits required for the next patch release: + - update `CHANGELOG.md`. - create a new annotated git tag (eg `git -a v1.1.0`) in the release branch. - Create a GitHub release. - ## Major Release Maintenance Major Release series continue to receive bug fixes (released as a Patch Release) until they reach **End Of Life**. @@ -70,7 +72,6 @@ Only the following major release series have a stable release status: * **0.42 «Stargate»** will be supported until 6 months after **0.43.0** is published. A fairly strict **bugfix-only** rule applies to pull requests that are requested to be included into a stable point-release. * **0.44** is the latest major release. - ## Stable Release Policy ### Patch Releases diff --git a/contrib/rosetta/README.md b/contrib/rosetta/README.md index 068bf9ed2438..c34c31fa3ac6 100644 --- a/contrib/rosetta/README.md +++ b/contrib/rosetta/README.md @@ -20,6 +20,7 @@ Contains the required files to set up rosetta cli and make it work against its w Contains the files for a deterministic network, with fixed keys and some actions on there, to test parsing of msgs and historical balances. This image is used to run a simapp node and to run the rosetta server. ## Rosetta-cli + The docker image for ./rosetta-cli/Dockerfile is on [docker hub](https://hub.docker.com/r/tendermintdev/rosetta-cli). Whenever rosetta-cli releases a new version, rosetta-cli/Dockerfile should be updated to reflect the new version and pushed to docker hub. ## Notes diff --git a/cosmovisor/README.md b/cosmovisor/README.md index a87a7693d684..0f3419cf0f55 100644 --- a/cosmovisor/README.md +++ b/cosmovisor/README.md @@ -5,6 +5,7 @@ #### Design Cosmovisor is designed to be used as a wrapper for a `Cosmos SDK` app: + * it will pass arguments to the associated app (configured by `DAEMON_NAME` env variable). Running `cosmovisor run arg1 arg2 ....` will run `app arg1 arg2 ...`; * it will manage an app by restarting and upgrading if needed; @@ -47,6 +48,7 @@ git checkout cosmovisor/vx.x.x cd cosmovisor make ``` + This will build cosmovisor in your current directory. Afterwards you may want to put it into your machine's PATH like as follows: ``` @@ -58,6 +60,7 @@ cp cosmovisor ~/go/bin/cosmovisor ### Command Line Arguments And Environment Variables The first argument passed to `cosmovisor` is the action for `cosmovisor` to take. Options are: + * `help`, `--help`, or `-h` - Output `cosmovisor` help information and check your `cosmovisor` configuration. * `run` - Run the configured binary using the rest of the provided arguments. * `version`, or `--version` - Output the `cosmovisor` version and also run the binary with the `version` argument. @@ -124,12 +127,14 @@ The `DAEMON` specific code and operations (e.g. tendermint config, the applicati `cosmovisor` is polling the `$DAEMON_HOME/data/upgrade-info.json` file for new upgrade instructions. The file is created by the x/upgrade module in `BeginBlocker` when an upgrade is detected and the blockchain reaches the upgrade height. The following heuristic is applied to detect the upgrade: + + When starting, `cosmovisor` doesn't know much about currently running upgrade, except the binary which is `current/bin/`. It tries to read the `current/update-info.json` file to get information about the current upgrade name. + If neither `cosmovisor/current/upgrade-info.json` nor `data/upgrade-info.json` exist, then `cosmovisor` will wait for `data/upgrade-info.json` file to trigger an upgrade. + If `cosmovisor/current/upgrade-info.json` doesn't exist but `data/upgrade-info.json` exists, then `cosmovisor` assumes that whatever is in `data/upgrade-info.json` is a valid upgrade request. In this case `cosmovisor` tries immediately to make an upgrade according to the `name` attribute in `data/upgrade-info.json`. + Otherwise, `cosmovisor` waits for changes in `upgrade-info.json`. As soon as a new upgrade name is recorded in the file, `cosmovisor` will trigger an upgrade mechanism. When the upgrade mechanism is triggered, `cosmovisor` will: + 1. if `DAEMON_ALLOW_DOWNLOAD_BINARIES` is enabled, start by auto-downloading a new binary into `cosmovisor//bin` (where `` is the `upgrade-info.json:name` attribute); 2. update the `current` symbolic link to point to the new directory and save `data/upgrade-info.json` to `cosmovisor/current/upgrade-info.json`. diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index 7686d18cdd6e..f16eca046f37 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -496,7 +496,7 @@ func (ks keystore) List() ([]*Record, error) { return nil, err } - var res []*Record + var res []*Record //nolint:prealloc sort.Strings(keys) for _, key := range keys { if strings.Contains(key, addressSuffix) { diff --git a/crypto/keys/multisig/amino.go b/crypto/keys/multisig/amino.go index a1394fb0e9cf..da95ee4a7ddc 100644 --- a/crypto/keys/multisig/amino.go +++ b/crypto/keys/multisig/amino.go @@ -64,7 +64,7 @@ func tmToProto(tmPk tmMultisig) (*LegacyAminoPubKey, error) { } // MarshalAminoJSON overrides amino JSON unmarshaling. -func (m LegacyAminoPubKey) MarshalAminoJSON() (tmMultisig, error) { //nolint:golint +func (m LegacyAminoPubKey) MarshalAminoJSON() (tmMultisig, error) { //nolint:revive return protoToTm(&m) } diff --git a/crypto/keys/secp256k1/secp256k1_nocgo.go b/crypto/keys/secp256k1/secp256k1_nocgo.go index 2d605447f421..26735b44229b 100644 --- a/crypto/keys/secp256k1/secp256k1_nocgo.go +++ b/crypto/keys/secp256k1/secp256k1_nocgo.go @@ -1,3 +1,4 @@ +//go:build !libsecp256k1 // +build !libsecp256k1 package secp256k1 diff --git a/crypto/ledger/ledger_notavail.go b/crypto/ledger/ledger_notavail.go index 66d16adcc023..578c33d4369c 100644 --- a/crypto/ledger/ledger_notavail.go +++ b/crypto/ledger/ledger_notavail.go @@ -1,4 +1,6 @@ +//go:build !cgo || !ledger // +build !cgo !ledger + // test_ledger_mock package ledger diff --git a/db/README.md b/db/README.md index 1a9f5a978209..01471f144c61 100644 --- a/db/README.md +++ b/db/README.md @@ -9,23 +9,25 @@ The database interface types consist of objects to encapsulate the singular conn ### `DBConnection` This interface represents a connection to a versioned key-value database. All versioning operations are performed using methods on this type. - * The `Versions` method returns a `VersionSet` which represents an immutable view of the version history at the current state. - * Version history is modified via the `{Save,Delete}Version` methods. - * Operations on version history do not modify any database contents. + +* The `Versions` method returns a `VersionSet` which represents an immutable view of the version history at the current state. +* Version history is modified via the `{Save,Delete}Version` methods. +* Operations on version history do not modify any database contents. ### `DBReader`, `DBWriter`, and `DBReadWriter` These types represent transactions on the database contents. Their methods provide CRUD operations as well as iteration. - * Writeable transactions call `Commit` flushes operations to the source DB. - * All open transactions must be closed with `Discard` or `Commit` before a new version can be saved on the source DB. - * The maximum number of safely concurrent transactions is dependent on the backend implementation. - * A single transaction object is not safe for concurrent use. - * Write conflicts on concurrent transactions will cause an error at commit time (optimistic concurrency control). + +* Writeable transactions call `Commit` flushes operations to the source DB. +* All open transactions must be closed with `Discard` or `Commit` before a new version can be saved on the source DB. +* The maximum number of safely concurrent transactions is dependent on the backend implementation. +* A single transaction object is not safe for concurrent use. +* Write conflicts on concurrent transactions will cause an error at commit time (optimistic concurrency control). #### `Iterator` - * An iterator is invalidated by any writes within its `Domain` to the source transaction while it is open. - * An iterator must call `Close` before its source transaction is closed. +* An iterator is invalidated by any writes within its `Domain` to the source transaction while it is open. +* An iterator must call `Close` before its source transaction is closed. ### `VersionSet` @@ -36,7 +38,8 @@ This represents a self-contained and immutable view of a database's version hist ### In-memory DB The in-memory DB in the `db/memdb` package cannot be persisted to disk. It is implemented using the Google [btree](https://pkg.go.dev/github.com/google/btree) library. - * This currently does not perform write conflict detection, so it only supports a single open write-transaction at a time. Multiple and concurrent read-transactions are supported. + +* This currently does not perform write conflict detection, so it only supports a single open write-transaction at a time. Multiple and concurrent read-transactions are supported. ### BadgerDB @@ -54,6 +57,7 @@ err := tx2.Commit() // err is non-nil ``` But this will not: + ```go tx1, tx2 := db.Writer(), db.ReadWriter() key := []byte("key") @@ -62,6 +66,7 @@ tx2.Set(key, []byte("b")) tx1.Commit() // ok tx2.Commit() // ok ``` + ### RocksDB A [RocksDB](https://github.com/facebook/rocksdb)-based backend. Internally this uses [`OptimisticTransactionDB`](https://github.com/facebook/rocksdb/wiki/Transactions#optimistictransactiondb) to allow concurrent transactions with write conflict detection. Historical versioning is internally implemented with [Checkpoints](https://github.com/facebook/rocksdb/wiki/Checkpoints). diff --git a/docs/404.md b/docs/404.md index 572564ee62d6..d7b8b16782fa 100644 --- a/docs/404.md +++ b/docs/404.md @@ -44,6 +44,4 @@ footer: aside: false --> -# 404 - Lost in space, this is just an empty void... - - +# 404 - Lost in space, this is just an empty void diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 4ff03140ebd2..1388356a3b48 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -6,14 +6,14 @@ If you want to open a PR in Cosmos SDK to update the documentation, please follo - Translations for documentation live in a `docs//` folder, where `` is the language code for a specific language. For example, `zh` for Chinese, `ko` for Korean, `ru` for Russian, etc. - Each `docs//` folder must follow the same folder structure within `docs/`, but only content in the following folders needs to be translated and included in the respective `docs//` folder: - - `docs/basics/` - - `docs/building-modules/` - - `docs/core/` - - `docs/ibc/` - - `docs/intro/` - - `docs/migrations/` - - `docs/run-node/` -- Each `docs//` folder must also have a `README.md` that includes a translated version of both the layout and content within the root-level [`README.md`](https://github.com/cosmos/cosmos-sdk/tree/master/docs/README.md). The layout defined in the `README.md` is used to build the homepage. + - `docs/basics/` + - `docs/building-modules/` + - `docs/core/` + - `docs/ibc/` + - `docs/intro/` + - `docs/migrations/` + - `docs/run-node/` +- Each `docs//` folder must also have a `README.md` that includes a translated version of both the layout and content within the root-level [`README.md`](https://github.com/cosmos/cosmos-sdk/tree/master/docs/README.md). The layout defined in the `README.md` is used to build the homepage. - Always translate content living on `master` unless you are revising documentation for a specific release. Translated documentation like the root-level documentation is semantically versioned. - For additional configuration options, please see [VuePress Internationalization](https://vuepress.vuejs.org/guide/i18n.html). diff --git a/docs/architecture/adr-010-modular-antehandler.md b/docs/architecture/adr-010-modular-antehandler.md index d4ad05241867..c0be2c4d8e64 100644 --- a/docs/architecture/adr-010-modular-antehandler.md +++ b/docs/architecture/adr-010-modular-antehandler.md @@ -278,10 +278,6 @@ Cons: 1. Decorator pattern may have a deeply nested structure that is hard to understand, this is mitigated by having the decorator order explicitly listed in the `ChainAnteDecorators` function. 2. Does not make use of the ModuleManager design. Since this is already being used for BeginBlocker/EndBlocker, this proposal seems unaligned with that design pattern. -## Status - -> Accepted Simple Decorators approach - ## Consequences Since pros and cons are written for each approach, it is omitted from this section diff --git a/docs/architecture/adr-022-custom-panic-handling.md b/docs/architecture/adr-022-custom-panic-handling.md index eea066bcd1e5..aec42f861ccc 100644 --- a/docs/architecture/adr-022-custom-panic-handling.md +++ b/docs/architecture/adr-022-custom-panic-handling.md @@ -192,10 +192,6 @@ func (app *BaseApp) AddRunTxRecoveryHandler(handlers ...RecoveryHandler) { This method would prepend handlers to an existing chain. -## Status - -Proposed - ## Consequences ### Positive diff --git a/docs/architecture/adr-038-state-listening.md b/docs/architecture/adr-038-state-listening.md index e6d321e8cfbd..f774ffecf883 100644 --- a/docs/architecture/adr-038-state-listening.md +++ b/docs/architecture/adr-038-state-listening.md @@ -211,23 +211,23 @@ and relays ABCI requests and responses so that the service can group the state c ```go // ABCIListener interface used to hook into the ABCI message processing of the BaseApp type ABCIListener interface { - // ListenBeginBlock updates the streaming service with the latest BeginBlock messages - ListenBeginBlock(ctx types.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error - // ListenEndBlock updates the steaming service with the latest EndBlock messages - ListenEndBlock(ctx types.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error - // ListenDeliverTx updates the steaming service with the latest DeliverTx messages + // ListenBeginBlock updates the streaming service with the latest BeginBlock messages + ListenBeginBlock(ctx types.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error + // ListenEndBlock updates the steaming service with the latest EndBlock messages + ListenEndBlock(ctx types.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error + // ListenDeliverTx updates the steaming service with the latest DeliverTx messages ListenDeliverTx(ctx types.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error } // StreamingService interface for registering WriteListeners with the BaseApp and updating the service with the ABCI messages using the hooks type StreamingService interface { - // Stream is the streaming service loop, awaits kv pairs and writes them to some destination stream or file + // Stream is the streaming service loop, awaits kv pairs and writes them to some destination stream or file Stream(wg *sync.WaitGroup) error - // Listeners returns the streaming service's listeners for the BaseApp to register - Listeners() map[types.StoreKey][]store.WriteListener - // ABCIListener interface for hooking into the ABCI messages from inside the BaseApp - ABCIListener - // Closer interface + // Listeners returns the streaming service's listeners for the BaseApp to register + Listeners() map[types.StoreKey][]store.WriteListener + // ABCIListener interface for hooking into the ABCI messages from inside the BaseApp + ABCIListener + // Closer interface io.Closer } ``` @@ -598,10 +598,10 @@ func NewSimApp( // configure state listening capabilities using AppOptions listeners := cast.ToStringSlice(appOpts.Get("store.streamers")) for _, listenerName := range listeners { - // get the store keys allowed to be exposed for this streaming service + // get the store keys allowed to be exposed for this streaming service exposeKeyStrs := cast.ToStringSlice(appOpts.Get(fmt.Sprintf("streamers.%s.keys", streamerName))) var exposeStoreKeys []sdk.StoreKey - if exposeAll(exposeKeyStrs) { // if list contains `*`, expose all StoreKeys + if exposeAll(exposeKeyStrs) { // if list contains `*`, expose all StoreKeys exposeStoreKeys = make([]sdk.StoreKey, 0, len(keys)) for _, storeKey := range keys { exposeStoreKeys = append(exposeStoreKeys, storeKey) @@ -614,7 +614,7 @@ func NewSimApp( } } } - if len(exposeStoreKeys) == 0 { // short circuit if we are not exposing anything + if len(exposeStoreKeys) == 0 { // short circuit if we are not exposing anything continue } // get the constructor for this listener name diff --git a/docs/architecture/adr-040-storage-and-smt-state-commitments.md b/docs/architecture/adr-040-storage-and-smt-state-commitments.md index c97cc15ed998..9361d0d1cd3b 100644 --- a/docs/architecture/adr-040-storage-and-smt-state-commitments.md +++ b/docs/architecture/adr-040-storage-and-smt-state-commitments.md @@ -119,7 +119,6 @@ We need to be able to process transactions and roll-back state updates if a tran We identified use-cases, where modules will need to save an object commitment without storing an object itself. Sometimes clients are receiving complex objects, and they have no way to prove a correctness of that object without knowing the storage layout. For those use cases it would be easier to commit to the object without storing it directly. - ### Refactor MultiStore The Stargate `/store` implementation (store/v1) adds an additional layer in the SDK store construction - the `MultiStore` structure. The multistore exists to support the modularity of the Cosmos SDK - each module is using its own instance of IAVL, but in the current implementation, all instances share the same database. The latter indicates, however, that the implementation doesn't provide true modularity. Instead it causes problems related to race condition and atomic DB commits (see: [\#6370](https://github.com/cosmos/cosmos-sdk/issues/6370) and [discussion](https://github.com/cosmos/cosmos-sdk/discussions/8297#discussioncomment-757043)). @@ -192,6 +191,7 @@ The presented workaround can be used until the IBC module is fully upgraded to s ### Optimization: compress module key prefixes We consider a compression of prefix keys by creating a mapping from module key to an integer, and serializing the integer using varint coding. Varint coding assures that different values don't have common byte prefix. For Merkle Proofs we can't use prefix compression - so it should only apply for the `SS` keys. Moreover, the prefix compression should be only applied for the module namespace. More precisely: + + each module has it's own namespace; + when accessing a module namespace we create a KVStore with embedded prefix; + that prefix will be compressed only when accessing and managing `SS`. diff --git a/docs/architecture/adr-043-nft-module.md b/docs/architecture/adr-043-nft-module.md index d4db3d3f9c92..99152f990e61 100644 --- a/docs/architecture/adr-043-nft-module.md +++ b/docs/architecture/adr-043-nft-module.md @@ -88,9 +88,11 @@ message NFT { - `class_id` is the identifier of the NFT class where the NFT belongs; _required_ - `id` is an alphanumeric identifier of the NFT, unique within the scope of its class. It is specified by the creator of the NFT and may be expanded to use DID in the future. `class_id` combined with `id` uniquely identifies an NFT and is used as the primary index for storing the NFT; _required_ + ``` {class_id}/{id} --> NFT (bytes) ``` + - `uri` is a URL pointing to an off-chain JSON file that contains metadata about this NFT (Ref: [ERC721 standard and OpenSea extension](https://docs.opensea.io/docs/metadata-standards)); _required_ - `uri_hash` is a hash of the `uri`; - `data` is a field that CAN be used by composing modules to specify additional properties for the NFT; _optional_ @@ -291,7 +293,6 @@ message QueryClassesResponse { } ``` - ### Interoperability Interoperability is all about reusing assets between modules and chains. The former one is achieved by ADR-33: Protobuf client - server communication. At the time of writing ADR-33 is not finalized. The latter is achieved by IBC. Here we will focus on the IBC side. @@ -299,7 +300,6 @@ IBC is implemented per module. Here, we aligned that NFTs will be recorded and m For IBC interoperability, NFT custom modules MUST use the NFT object type understood by the IBC client. So, for x/nft interoperability, custom NFT implementations (example: x/cryptokitty) should use the canonical x/nft module and proxy all NFT balance keeping functionality to x/nft or else re-implement all functionality using the NFT object type understood by the IBC client. In other words: x/nft becomes the standard NFT registry for all Cosmos NFTs (example: x/cryptokitty will register a kitty NFT in x/nft and use x/nft for book keeping). This was [discussed](https://github.com/cosmos/cosmos-sdk/discussions/9065#discussioncomment-873206) in the context of using x/bank as a general asset balance book. Not using x/nft will require implementing another module for IBC. - ## Consequences ### Backward Compatibility diff --git a/docs/architecture/adr-044-protobuf-updates-guidelines.md b/docs/architecture/adr-044-protobuf-updates-guidelines.md index 68265f83076d..a76a7579ba07 100644 --- a/docs/architecture/adr-044-protobuf-updates-guidelines.md +++ b/docs/architecture/adr-044-protobuf-updates-guidelines.md @@ -37,7 +37,7 @@ On top of Buf's recommendations we add the following guidelines that are specifi ### Updating Protobuf Definition Without Bumping Version -#### 1. `Msg`s MUST NOT have new fields. +#### 1. `Msg`s MUST NOT have new fields When processing `Msg`s, the Cosmos SDK's antehandlers are strict and don't allow unknown fields in `Msg`s. This is checked by the unknown field rejection in the [`codec/unknownproto` package](https://github.com/cosmos/cosmos-sdk/blob/master/codec/unknownproto). @@ -47,11 +47,11 @@ For this reason, module developers MUST NOT add new fields to existing `Msg`s. It is worth mentioning that this does not limit adding fields to a `Msg`, but also to all nested structs and `Any`s inside a `Msg`. -#### 2. Non-`Msg`-related Protobuf definitions MAY have new fields. +#### 2. Non-`Msg`-related Protobuf definitions MAY have new fields On the other hand, module developers MAY add new fields to Protobuf definitions related to the `Query` service or to objects which are saved in the store. This recommendation follows the Protobuf specification, but is added in this document for clarity. -#### 3. Fields MAY be marked as `deprecated`, and nodes MAY implement a protocol-breaking change for handling these fields. +#### 3. Fields MAY be marked as `deprecated`, and nodes MAY implement a protocol-breaking change for handling these fields Protobuf supports the [`deprecated` field option](https://developers.google.com/protocol-buffers/docs/proto#options), and this option MAY be used on any field, including `Msg` fields. If a node handles a Protobuf message with a non-empty deprecated field, the node MAY change its behavior upon processing it, even in a protocol-breaking way. When possible, the node MUST handle backwards compatibility without breaking the consensus (unless we increment the proto version). @@ -60,7 +60,7 @@ As an example, the Cosmos SDK v0.42 to v0.43 update contained two Protobuf-break - The Cosmos SDK recently removed support for [time-based software upgrades](https://github.com/cosmos/cosmos-sdk/pull/8849). As such, the `time` field has been marked as deprecated in `cosmos.upgrade.v1beta1.Plan`. Moreover, the node will reject any proposal containing an upgrade Plan whose `time` field is non-empty. - The Cosmos SDK now supports [governance split votes](./adr-037-gov-split-vote.md). When querying for votes, the returned `cosmos.gov.v1beta1.Vote` message has its `option` field (used for 1 vote option) deprecated in favor of its `options` field (allowing multiple vote options). Whenever possible, the SDK still populates the deprecated `option` field, that is, if and only if the `len(options) == 1` and `options[0].Weight == 1.0`. -#### 4. Fields MUST NOT be renamed. +#### 4. Fields MUST NOT be renamed Whereas the official Protobuf recommendations do not prohibit renaming fields, as it does not break the Protobuf binary representation, the SDK explicitly forbids renaming fields in Protobuf structs. The main reason for this choice is to avoid introducing breaking changes for clients, which often rely on hard-coded fields from generated types. Moreover, renaming fields will lead to client-breaking JSON representations of Protobuf definitions, used in REST endpoints and in the CLI. @@ -70,7 +70,7 @@ TODO, needs architecture review. Some topics: - Bumping versions frequency - When bumping versions, should the Cosmos SDK support both versions? - - i.e. v1beta1 -> v1, should we have two folders in the Cosmos SDK, and handlers for both versions? + - i.e. v1beta1 -> v1, should we have two folders in the Cosmos SDK, and handlers for both versions? - mention ADR-023 Protobuf naming ## Consequences diff --git a/docs/architecture/adr-046-module-params.md b/docs/architecture/adr-046-module-params.md index 6539bd5513d1..520c79884e82 100644 --- a/docs/architecture/adr-046-module-params.md +++ b/docs/architecture/adr-046-module-params.md @@ -43,9 +43,9 @@ We will build off of the alignment of `x/gov` and `x/authz` work per [#9810](https://github.com/cosmos/cosmos-sdk/pull/9810). Namely, module developers will create one or more unique parameter data structures that must be serialized to state. The Param data structures must implement `sdk.Msg` interface with respective -Protobuf Msg service method which will validate and update the parameters with all -necessary changes. The `x/gov` module via the work done in -[#9810](https://github.com/cosmos/cosmos-sdk/pull/9810), will dispatch Param +Protobuf Msg service method which will validate and update the parameters with all +necessary changes. The `x/gov` module via the work done in +[#9810](https://github.com/cosmos/cosmos-sdk/pull/9810), will dispatch Param messages, which will be handled by Protobuf Msg services. Note, it is up to developers to decide how to structure their parameters and @@ -134,11 +134,11 @@ message QueryParamsResponse { As a result of implementing the module parameter methodology, we gain the ability for module parameter changes to be stateful and extensible to fit nearly every -application's use case. We will be able to emit events (and trigger hooks registered +application's use case. We will be able to emit events (and trigger hooks registered to that events using the work proposed in [even hooks](https://github.com/cosmos/cosmos-sdk/discussions/9656)), call other Msg service methods or perform migration. -In addition, there will be significant gains in performance when it comes to reading -and writing parameters from and to state, especially if a specific set of parameters +In addition, there will be significant gains in performance when it comes to reading +and writing parameters from and to state, especially if a specific set of parameters are read on a consistent basis. However, this methodology will require developers to implement more types and diff --git a/docs/migrations/pre-upgrade.md b/docs/migrations/pre-upgrade.md index 524867bfe858..00b4c54e2142 100644 --- a/docs/migrations/pre-upgrade.md +++ b/docs/migrations/pre-upgrade.md @@ -10,7 +10,6 @@ Before the application binary is upgraded, Cosmovisor calls a `pre-upgrade` comm The `pre-upgrade` command does not take in any command-line arguments and is expected to terminate with the following exit codes: - | Exit status code | How it is handled in Cosmosvisor | |------------------|---------------------------------------------------------------------------------------------------------------------| | `0` | Assumes `pre-upgrade` command executed successfully and continues the upgrade. | @@ -18,7 +17,6 @@ The `pre-upgrade` command does not take in any command-line arguments and is exp | `30` | `pre-upgrade` command was executed but failed. This fails the entire upgrade. | | `31` | `pre-upgrade` command was executed but failed. But the command is retried until exit code `1` or `30` are returned. | - ## Sample Here is a sample structure of the `pre-upgrade` command: @@ -46,8 +44,8 @@ func preUpgradeCommand() *cobra.Command { } ``` - Ensure that the pre-upgrade command has been registered in the application: + ```go rootCmd.AddCommand( // .. diff --git a/docs/migrations/rest.md b/docs/migrations/rest.md index 9881cc236746..9a65a3d95c70 100644 --- a/docs/migrations/rest.md +++ b/docs/migrations/rest.md @@ -82,4 +82,4 @@ Following the Protocol Buffers migration in v0.40, Cosmos SDK has been set to ta ## Migrating to gRPC -Instead of hitting REST endpoints as described above, the Cosmos SDK also exposes a gRPC server. Any client can use gRPC instead of REST to interact with the node. An overview of different ways to communicate with a node can be found [here](../core/grpc_rest.md), and a concrete tutorial for setting up a gRPC client can be found [here](../run-node/txs.md#programmatically-with-go). \ No newline at end of file +Instead of hitting REST endpoints as described above, the Cosmos SDK also exposes a gRPC server. Any client can use gRPC instead of REST to interact with the node. An overview of different ways to communicate with a node can be found [here](../core/grpc_rest.md), and a concrete tutorial for setting up a gRPC client can be found [here](../run-node/txs.md#programmatically-with-go). diff --git a/docs/ru/README.md b/docs/ru/README.md index b547e3601c7a..e6906b2b89b3 100755 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -1,3 +1,3 @@ # Cosmos SDK Documentation (Russian) -A Russian translation of the Cosmos SDK documentation is not available for this version. If you would like to help with translating, please see [Internationalization](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md#internationalization). A `v0.39` version of the documentation can be found [here](https://github.com/cosmos/cosmos-sdk/tree/v0.39.3/docs/ru). \ No newline at end of file +A Russian translation of the Cosmos SDK documentation is not available for this version. If you would like to help with translating, please see [Internationalization](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md#internationalization). A `v0.39` version of the documentation can be found [here](https://github.com/cosmos/cosmos-sdk/tree/v0.39.3/docs/ru). diff --git a/docs/run-node/rosetta.md b/docs/run-node/rosetta.md index 2356563e023c..a9fe6a9dc9d8 100644 --- a/docs/run-node/rosetta.md +++ b/docs/run-node/rosetta.md @@ -8,7 +8,7 @@ The `rosetta` package implements Coinbase's [Rosetta API](https://www.rosetta-ap ## Add Rosetta Command -The Rosetta API server is a stand-alone server that connects to a node of a chain developed with Cosmos SDK. +The Rosetta API server is a stand-alone server that connects to a node of a chain developed with Cosmos SDK. To enable Rosetta API support, it's required to add the `RosettaCommand` to your application's root command file (e.g. `appd/cmd/root.go`). diff --git a/docs/run-node/run-node.md b/docs/run-node/run-node.md index 85dd6d767267..ee3141403000 100644 --- a/docs/run-node/run-node.md +++ b/docs/run-node/run-node.md @@ -42,6 +42,7 @@ The `~/.simapp` folder has the following structure: ## Updating Some Default Settings If you want to change any field values in configuration files (for ex: genesis.json) you can use `jq` ([installation](https://stedolan.github.io/jq/download/) & [docs](https://stedolan.github.io/jq/manual/#Assignment)) & `sed` commands to do that. Few examples are listed here. + ```bash # to change the chain-id jq '.chain_id = "testing"' genesis.json > temp.json && mv temp.json genesis.json @@ -57,6 +58,7 @@ jq '.app_state.mint.minter.inflation = "0.300000000000000000"' genesis.json > te ``` ## Adding Genesis Accounts + Before starting the chain, you need to populate the state with at least one account. To do so, first [create a new account in the keyring](./keyring.md#adding-keys-to-the-keyring) named `my_validator` under the `test` keyring backend (feel free to choose another name and another backend). Now that you have created a local account, go ahead and grant it some `stake` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence: diff --git a/docs/run-node/run-testnet.md b/docs/run-node/run-testnet.md index 3f8478b4689d..0cbfe8cf9789 100644 --- a/docs/run-node/run-testnet.md +++ b/docs/run-node/run-testnet.md @@ -6,7 +6,7 @@ order: 7 The `simd testnet` subcommand makes it easy to initialize and start a simulated test network for testing purposes. {synopsis} -In addition to the commands for [running a node](./run-node.html), the `simd` binary also includes a `testnet` command that allows you to start a simulated test network in-process or to initialize files for a simulated test network that runs in a separate process. +In addition to the commands for [running a node](./run-node.html), the `simd` binary also includes a `testnet` command that allows you to start a simulated test network in-process or to initialize files for a simulated test network that runs in a separate process. ## Initialize Files diff --git a/go.mod b/go.mod index 42403b96becd..37e80d754cf8 100644 --- a/go.mod +++ b/go.mod @@ -92,7 +92,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect github.com/klauspost/compress v1.12.3 // indirect - github.com/lib/pq v1.2.0 // indirect + github.com/lib/pq v1.10.2 // indirect github.com/libp2p/go-buffer-pool v0.0.2 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect diff --git a/go.sum b/go.sum index 40118db668ec..09157cacd231 100644 --- a/go.sum +++ b/go.sum @@ -545,8 +545,9 @@ github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 h1:nDOkLO7klmnEw1 github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554/go.mod h1:9+Pb2/tg1PvEgW7aFx4bFhDE4bvbI03zuJ8kb7nJ9Jc= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/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= diff --git a/scripts/module-tests.sh b/scripts/module-tests.sh index c34ec9106886..86998b5aa99f 100644 --- a/scripts/module-tests.sh +++ b/scripts/module-tests.sh @@ -15,11 +15,11 @@ execute_mod_tests() { # TODO: in the future we will need to disable it once we go into multi module setup, because # we will have cross module dependencies. if [ -n "$GIT_DIFF" ] && ! grep $mod_dir <<< $GIT_DIFF; then - echo "ignoring module $mod_dir - no changes in the module"; + echo ">>> ignoring module $mod_dir - no changes in the module"; return; fi; - echo "executing $go_mod tests" + echo ">>> running $go_mod tests" cd $mod_dir; go test -mod=readonly -timeout 30m -coverprofile=${root_dir}/${coverage_file}.tmp -covermode=atomic -tags='norace ledger test_ledger_mock' ./... local ret=$? @@ -31,12 +31,14 @@ execute_mod_tests() { return $ret; } -GIT_DIFF=`git status --porcelain` +# GIT_DIFF=`git status --porcelain` + +echo "GIT_DIFF: " $GIT_DIFF coverage_file=coverage-go-submod-profile.out return_val=0; -for f in $(find -name go.mod -not -path "./go.mod") "./container/go.mod"; do +for f in $(find -name go.mod -not -path "./go.mod"); do execute_mod_tests $f; if [[ $? -ne 0 ]] ; then return_val=2; diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index 177c01131810..f8396aab3a43 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -507,7 +507,7 @@ func extractInitialHeightFromGenesisChunk(genesisChunk string) (int64, error) { return 0, err } - re, err := regexp.Compile("\"initial_height\":\"(\\d+)\"") + re, err := regexp.Compile("\"initial_height\":\"(\\d+)\"") //nolint:gocritic if err != nil { return 0, err } diff --git a/server/rosetta/lib/internal/service/online.go b/server/rosetta/lib/internal/service/online.go index c4315417267b..5cf3331273b1 100644 --- a/server/rosetta/lib/internal/service/online.go +++ b/server/rosetta/lib/internal/service/online.go @@ -51,7 +51,7 @@ func (o OnlineNetwork) AccountCoins(_ context.Context, _ *types.AccountCoinsRequ // networkOptionsFromClient builds network options given the client func networkOptionsFromClient(client crgtypes.Client, genesisBlock *types.BlockIdentifier) *types.NetworkOptionsResponse { - var tsi *int64 = nil + var tsi *int64 if genesisBlock != nil { tsi = &(genesisBlock.Index) } diff --git a/simapp/simd/cmd/genaccounts.go b/simapp/simd/cmd/genaccounts.go index 1ed59f80518e..97275a41fc43 100644 --- a/simapp/simd/cmd/genaccounts.go +++ b/simapp/simd/cmd/genaccounts.go @@ -39,7 +39,6 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - serverCtx := server.GetServerContextFromCmd(cmd) config := serverCtx.Config diff --git a/snapshots/README.md b/snapshots/README.md index 6abb497b8879..dfe2d66e7245 100644 --- a/snapshots/README.md +++ b/snapshots/README.md @@ -215,7 +215,7 @@ metadata in turn to the local application via the `OfferSnapshot` ABCI call. `BaseApp.OfferSnapshot()` attempts to start a restore operation by calling `snapshots.Manager.Restore()`. This may fail, e.g. if the snapshot format is unknown (it may have been generated by a different version of the Cosmos SDK), -in which case Tendermint will offer other discovered snapshots. +in which case Tendermint will offer other discovered snapshots. If the snapshot is accepted, `Manager.Restore()` will record that a restore operation is in progress, and spawn a separate goroutine that runs a synchronous diff --git a/store/streaming/README.md b/store/streaming/README.md index 819514aef796..46e343416a52 100644 --- a/store/streaming/README.md +++ b/store/streaming/README.md @@ -1,4 +1,5 @@ # State Streaming Service + This package contains the constructors for the `StreamingService`s used to write state changes out from individual KVStores to a file or stream, as described in [ADR-038](../../docs/architecture/adr-038-state-listening.md) and defined in [types/streaming.go](../../baseapp/streaming.go). The child directories contain the implementations for specific output destinations. @@ -24,7 +25,6 @@ The `StreamingService` is configured from within an App using the `AppOptions` l `store.streamers` contains a list of the names of the `StreamingService` implementations to employ which are used by `ServiceTypeFromString` to return the `ServiceConstructor` for that particular implementation: - ```go listeners := cast.ToStringSlice(appOpts.Get("store.streamers")) for _, listenerName := range listeners { diff --git a/store/streaming/file/README.md b/store/streaming/file/README.md index 7243f15dd0bf..3e4a248e1a95 100644 --- a/store/streaming/file/README.md +++ b/store/streaming/file/README.md @@ -1,4 +1,5 @@ # File Streaming Service + This pkg contains an implementation of the [StreamingService](../../../baseapp/streaming.go) that writes the data stream out to files on the local filesystem. This process is performed synchronously with the message processing of the state machine. @@ -23,7 +24,8 @@ The `file.StreamingService` is configured from within an App using the `AppOptio We turn the service on by adding its name, "file", to `store.streamers`- the list of streaming services for this App to employ. In `streamers.file` we include three configuration parameters for the file streaming service: -1. `streamers.x.keys` contains the list of `StoreKey` names for the KVStores to expose using this service. + +1. `streamers.x.keys` contains the list of `StoreKey` names for the KVStores to expose using this service. In order to expose *all* KVStores, we can include `*` in this list. An empty list is equivalent to turning the service off. 2. `streamers.file.write_dir` contains the path to the directory to write the files to. 3. `streamers.file.prefix` contains an optional prefix to prepend to the output files to prevent potential collisions diff --git a/store/v2/flat/store.go b/store/v2/flat/store.go index 2ea17f16cf7a..9076ec15f4c7 100644 --- a/store/v2/flat/store.go +++ b/store/v2/flat/store.go @@ -102,7 +102,7 @@ func NewStore(db dbm.DBConnection, opts StoreConfig) (ret *Store, err error) { } // Version sets of each DB must match if !versions.Equal(mversions) { - err = fmt.Errorf("Storage and Merkle DB have different version history") + err = fmt.Errorf("Storage and Merkle DB have different version history") //nolint:stylecheck return } err = opts.MerkleDB.Revert() @@ -424,12 +424,12 @@ func (s *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return sdkerrors.QueryResult(err, false) } if root == nil { - return sdkerrors.QueryResult(errors.New("Merkle root hash not found"), false) + return sdkerrors.QueryResult(errors.New("Merkle root hash not found"), false) //nolint:stylecheck } merkleStore := loadSMT(dbm.ReaderAsReadWriter(merkleView), root) res.ProofOps, err = merkleStore.GetProof(res.Key) if err != nil { - return sdkerrors.QueryResult(fmt.Errorf("Merkle proof creation failed for key: %v", res.Key), false) + return sdkerrors.QueryResult(fmt.Errorf("Merkle proof creation failed for key: %v", res.Key), false) //nolint:stylecheck } case "/subspace": @@ -466,14 +466,14 @@ func loadSMT(merkleTxn dbm.DBReadWriter, root []byte) *smt.Store { return smt.LoadStore(merkleNodes, merkleValues, root) } -func (st *Store) CacheWrap() types.CacheWrap { - return cachekv.NewStore(st) +func (s *Store) CacheWrap() types.CacheWrap { + return cachekv.NewStore(s) } -func (st *Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.CacheWrap { - return cachekv.NewStore(tracekv.NewStore(st, w, tc)) +func (s *Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.CacheWrap { + return cachekv.NewStore(tracekv.NewStore(s, w, tc)) } -func (st *Store) CacheWrapWithListeners(storeKey types.StoreKey, listeners []types.WriteListener) types.CacheWrap { - return cachekv.NewStore(listenkv.NewStore(st, storeKey, listeners)) +func (s *Store) CacheWrapWithListeners(storeKey types.StoreKey, listeners []types.WriteListener) types.CacheWrap { + return cachekv.NewStore(listenkv.NewStore(s, storeKey, listeners)) } diff --git a/store/v2/smt/store.go b/store/v2/smt/store.go index 1873f06b078d..ce4130174337 100644 --- a/store/v2/smt/store.go +++ b/store/v2/smt/store.go @@ -15,8 +15,8 @@ var ( ) var ( - errKeyEmpty error = errors.New("key is empty or nil") - errValueNil error = errors.New("value is nil") + errKeyEmpty = errors.New("key is empty or nil") + errValueNil = errors.New("value is nil") ) // Store Implements types.KVStore and CommitKVStore. diff --git a/types/denom.go b/types/denom.go index 160e2806e1df..0e8d716a2670 100644 --- a/types/denom.go +++ b/types/denom.go @@ -9,7 +9,7 @@ import ( var denomUnits = map[string]Dec{} // baseDenom is the denom of smallest unit registered -var baseDenom string = "" +var baseDenom string // RegisterDenom registers a denomination with a corresponding unit. If the // denomination is already registered, an error will be returned. diff --git a/x/auth/middleware/basic.go b/x/auth/middleware/basic.go index 04ea10bf416e..1bfd98d868d6 100644 --- a/x/auth/middleware/basic.go +++ b/x/auth/middleware/basic.go @@ -295,7 +295,7 @@ func (cgts consumeTxSizeGasTxHandler) simulateSigGasCost(ctx context.Context, tx return nil } -func (cgts consumeTxSizeGasTxHandler) consumeTxSizeGas(ctx context.Context, tx sdk.Tx, txBytes []byte, simulate bool) error { +func (cgts consumeTxSizeGasTxHandler) consumeTxSizeGas(ctx context.Context, _ sdk.Tx, txBytes []byte, simulate bool) error { sdkCtx := sdk.UnwrapSDKContext(ctx) params := cgts.ak.GetParams(sdkCtx) sdkCtx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*sdk.Gas(len(txBytes)), "txSize") diff --git a/x/auth/middleware/sigverify.go b/x/auth/middleware/sigverify.go index 0613b835c98f..504b7a27de46 100644 --- a/x/auth/middleware/sigverify.go +++ b/x/auth/middleware/sigverify.go @@ -429,7 +429,7 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { } } -func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, isReCheckTx, simulate bool) error { +func (svd sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, isReCheckTx, simulate bool) error { sdkCtx := sdk.UnwrapSDKContext(ctx) // no need to verify signatures on recheck tx if isReCheckTx { @@ -455,7 +455,7 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, is } for i, sig := range sigs { - acc, err := GetSignerAcc(sdkCtx, svm.ak, signerAddrs[i]) + acc, err := GetSignerAcc(sdkCtx, svd.ak, signerAddrs[i]) if err != nil { return err } @@ -491,7 +491,7 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, is } if !simulate { - err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svm.signModeHandler, tx) + err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svd.signModeHandler, tx) if err != nil { var errMsg string if OnlyLegacyAminoSigners(sig.Data) { diff --git a/x/auth/spec/01_concepts.md b/x/auth/spec/01_concepts.md index 57393d6ed561..e028ebe8e9a3 100644 --- a/x/auth/spec/01_concepts.md +++ b/x/auth/spec/01_concepts.md @@ -7,6 +7,7 @@ order: 1 **Note:** The auth module is different from the [authz module](../modules/authz/). The differences are: + * `auth` - authentication of accounts and transactions for Cosmos SDK applications and is responsible for specifying the base transaction and account types. * `authz` - authorization for accounts to perform actions on behalf of other accounts and enables a granter to grant authorizations to a grantee that allows the grantee to execute messages on behalf of the granter. diff --git a/x/auth/spec/05_vesting.md b/x/auth/spec/05_vesting.md index b085cc4c5d03..29f830ac7b72 100644 --- a/x/auth/spec/05_vesting.md +++ b/x/auth/spec/05_vesting.md @@ -621,4 +621,4 @@ all coins at a given time. - PeriodicVestingAccount: A vesting account implementation that vests coins according to a custom vesting schedule. - PermanentLockedAccount: It does not ever release coins, locking them indefinitely. -Coins in this account can still be used for delegating and for governance votes even while locked. \ No newline at end of file +Coins in this account can still be used for delegating and for governance votes even while locked. diff --git a/x/auth/spec/07_client.md b/x/auth/spec/07_client.md index 65aa7ec9aa92..bcfdc6f6faee 100644 --- a/x/auth/spec/07_client.md +++ b/x/auth/spec/07_client.md @@ -320,7 +320,6 @@ Example Output: } ``` - ### Params The `params` endpoint allow users to query the current auth parameters. @@ -419,4 +418,4 @@ Example: ```bash simd tx vesting create-vesting-account cosmos1.. 100stake 2592000 -``` \ No newline at end of file +``` diff --git a/x/authz/spec/05_client.md b/x/authz/spec/05_client.md index a67007e59467..f2ca6cc94690 100644 --- a/x/authz/spec/05_client.md +++ b/x/authz/spec/05_client.md @@ -169,4 +169,4 @@ Example Output: ], "pagination": null } -``` \ No newline at end of file +``` diff --git a/x/bank/spec/README.md b/x/bank/spec/README.md index 53b68c7d7b57..c9b19ccae690 100644 --- a/x/bank/spec/README.md +++ b/x/bank/spec/README.md @@ -102,4 +102,4 @@ The available permissions are: 5. **[Parameters](05_params.md)** 6. **[Client](06_client.md)** - [CLI](06_client.md#cli) - - [gRPC](06_client.md#grpc) \ No newline at end of file + - [gRPC](06_client.md#grpc) diff --git a/x/crisis/spec/05_client.md b/x/crisis/spec/05_client.md index bf7d6a4593b4..5f95955a65eb 100644 --- a/x/crisis/spec/05_client.md +++ b/x/crisis/spec/05_client.md @@ -1,24 +1,31 @@ + # Client ## CLI + A user can query and interact with the `crisis` module using the CLI. ### Transactions + The `tx` commands allow users to interact with the `crisis` module. + ```bash simd tx crisis --help ``` #### invariant-broken + The `invariant-broken` command submits proof when an invariant was broken to halt the chain + ```bash simd tx crisis invariant-broken [module-name] [invariant-route] [flags] ``` Example: + ```bash simd tx crisis invariant-broken bank total-supply --from=[keyname or address] -``` \ No newline at end of file +``` diff --git a/x/distribution/migrations/v043/helpers.go b/x/distribution/migrations/v043/helpers.go index 9c3df57596cc..185682217809 100644 --- a/x/distribution/migrations/v043/helpers.go +++ b/x/distribution/migrations/v043/helpers.go @@ -19,7 +19,7 @@ func MigratePrefixAddress(store sdk.KVStore, prefixBz []byte) { for ; oldStoreIter.Valid(); oldStoreIter.Next() { addr := oldStoreIter.Key() - var newStoreKey []byte = prefixBz + var newStoreKey = prefixBz newStoreKey = append(newStoreKey, address.MustLengthPrefix(addr)...) // Set new key on store. Values don't change. diff --git a/x/distribution/spec/README.md b/x/distribution/spec/README.md index 992c87821628..f8fdb8285540 100644 --- a/x/distribution/spec/README.md +++ b/x/distribution/spec/README.md @@ -103,4 +103,4 @@ to set up a script to periodically withdraw and rebond rewards. 7. **[Parameters](07_params.md)** 8. **[Parameters](07_params.md)** - [CLI](08_client.md#cli) - - [gRPC](08_client.md#grpc) \ No newline at end of file + - [gRPC](08_client.md#grpc) diff --git a/x/epoching/keeper/keeper.go b/x/epoching/keeper/keeper.go index f39d324bdf0a..f6869f50e8f6 100644 --- a/x/epoching/keeper/keeper.go +++ b/x/epoching/keeper/keeper.go @@ -107,7 +107,7 @@ func (k Keeper) GetEpochMsg(ctx sdk.Context, epochNumber int64, actionID uint64) // GetEpochActions get all actions func (k Keeper) GetEpochActions(ctx sdk.Context) []sdk.Msg { actions := []sdk.Msg{} - iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), []byte(EpochActionQueuePrefix)) + iterator := k.GetEpochActionsIterator(ctx) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -122,13 +122,13 @@ func (k Keeper) GetEpochActions(ctx sdk.Context) []sdk.Msg { // GetEpochActionsIterator returns iterator for EpochActions func (k Keeper) GetEpochActionsIterator(ctx sdk.Context) db.Iterator { - return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), []byte(EpochActionQueuePrefix)) + return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), EpochActionQueuePrefix) } // DequeueEpochActions dequeue all the actions store on epoch func (k Keeper) DequeueEpochActions(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte(EpochActionQueuePrefix)) + iterator := sdk.KVStorePrefixIterator(store, EpochActionQueuePrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { diff --git a/x/epoching/spec/03_to_improve.md b/x/epoching/spec/03_to_improve.md index d1b506f017ec..5ee5bd2ad0d5 100644 --- a/x/epoching/spec/03_to_improve.md +++ b/x/epoching/spec/03_to_improve.md @@ -29,7 +29,7 @@ In this case, unbonding should start instantly. // — BufferedMsgCreateValidatorQueue, BufferedMsgEditValidatorQueue // — BufferedMsgUnjailQueue, BufferedMsgDelegateQueue, BufferedMsgRedelegationQueue, BufferedMsgUndelegateQueue // Write epoch related tests with new scenarios -// — Simulation test is important for finding bugs [Ask Dev for questions) +// — Simulation test is important for finding bugs [Ask Dev for questions) // — Can easily add a simulator check to make sure all delegation amounts in queue add up to the same amount that’s in the EpochUnbondedPool // — I’d like it added as an invariant test for the simulator // — the simulator should check that the sum of all the queued delegations always equals the amount kept track in the data diff --git a/x/evidence/spec/07_client.md b/x/evidence/spec/07_client.md index 83edd18d76b4..52a4b34f70fe 100644 --- a/x/evidence/spec/07_client.md +++ b/x/evidence/spec/07_client.md @@ -11,6 +11,7 @@ The `query` commands allows users to query `evidence` state. ```bash simd query evidence --help ``` + ### evidence The `evidence` command allows users to list all evidence or evidence by hash. @@ -20,6 +21,7 @@ Usage: ```bash simd query evidence [flags] ``` + To query evidence by hash Example: @@ -45,6 +47,7 @@ Example: ```bash simd query evidence ``` + Example Output: ```bash @@ -75,6 +78,7 @@ Example: ```bash curl -X GET "http://localhost:1317/cosmos/evidence/v1beta1/evidence/DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660" ``` + Example Output: ```bash @@ -101,6 +105,7 @@ Example: ```bash curl -X GET "http://localhost:1317/cosmos/evidence/v1beta1/evidence" ``` + Example Output: ```bash @@ -163,6 +168,7 @@ Example: ```bash grpcurl -plaintext localhost:9090 cosmos.evidence.v1beta1.Query/AllEvidence ``` + Example Output: ```bash @@ -179,4 +185,4 @@ Example Output: "total": "1" } } -``` \ No newline at end of file +``` diff --git a/x/feegrant/spec/README.md b/x/feegrant/spec/README.md index d59854b665e6..eec99bcd1e16 100644 --- a/x/feegrant/spec/README.md +++ b/x/feegrant/spec/README.md @@ -32,4 +32,4 @@ This module allows accounts to grant fee allowances and to use fees from their a - [Exec fee allowance](04_events.md#exec-fee-allowance) 5. **[Client](05_client.md)** - [CLI](05_client.md#cli) - - [gRPC](05_client.md#grpc) \ No newline at end of file + - [gRPC](05_client.md#grpc) diff --git a/x/gov/spec/01_concepts.md b/x/gov/spec/01_concepts.md index dde2bd0b1071..91baf65ce4c4 100644 --- a/x/gov/spec/01_concepts.md +++ b/x/gov/spec/01_concepts.md @@ -69,7 +69,7 @@ The deposit is kept in escrow and held by the governance `ModuleAccount` until t When a proposal is finalized, the coins from the deposit are either refunded or burned, according to the final tally of the proposal: -- If the proposal is approved or rejected but _not_ vetoed, each deposit will be automatically refunded to its respective depositor (transferred from the governance `ModuleAccount`). +- If the proposal is approved or rejected but _not_ vetoed, each deposit will be automatically refunded to its respective depositor (transferred from the governance `ModuleAccount`). - When the proposal is vetoed with a supermajority, deposits will be burned from the governance `ModuleAccount` and the proposal information along with its deposit information will be removed from state. - All refunded or burned deposits are removed from the state. Events are issued when burning or refunding a deposit. - NOTE: The proposals which completed the voting period, cannot return the deposits when queried. diff --git a/x/gov/spec/07_client.md b/x/gov/spec/07_client.md index d3219abc207c..66cab628f2df 100644 --- a/x/gov/spec/07_client.md +++ b/x/gov/spec/07_client.md @@ -666,7 +666,7 @@ Example Output: } ``` -### Deposits +### deposits The `Deposits` endpoint allows users to query all deposits for a given proposal. @@ -739,7 +739,7 @@ Example Output: A user can query the `gov` module using REST endpoints. -### proposals +### proposal The `proposals` endpoint allows users to query a given proposal. @@ -787,7 +787,7 @@ Example Output: ### proposals -The `proposals` endpoint allows users to query all proposals with optional filters. +The `proposals` endpoint also allows users to query all proposals with optional filters. ```bash /cosmos/gov/v1beta1/proposals @@ -858,7 +858,7 @@ Example Output: } ``` -### votes +### voter vote The `votes` endpoint allows users to query a vote for a given proposal. @@ -995,7 +995,7 @@ Example Output: } ``` -### deposits +### proposal deposits The `deposits` endpoint allows users to query all deposits for a given proposal. @@ -1057,4 +1057,4 @@ Example Output: "no_with_veto": "0" } } -``` \ No newline at end of file +``` diff --git a/x/group/internal/orm/spec/01_table.md b/x/group/internal/orm/spec/01_table.md index 6240b06467fc..7b159b482dc1 100644 --- a/x/group/internal/orm/spec/01_table.md +++ b/x/group/internal/orm/spec/01_table.md @@ -8,10 +8,11 @@ In the prefix store, entities should be stored by an unique identifier called `R Regular CRUD operations can be performed on a table, these methods take a `sdk.KVStore` as parameter to get the table prefix store. The `table` struct does not: - - enforce uniqueness of the `RowID` - - enforce prefix uniqueness of keys, i.e. not allowing one key to be a prefix + +- enforce uniqueness of the `RowID` +- enforce prefix uniqueness of keys, i.e. not allowing one key to be a prefix of another - - optimize Gas usage conditions +- optimize Gas usage conditions The `table` struct is private, so that we only have custom tables built on top of it, that do satisfy these requirements. ## AutoUInt64Table @@ -31,8 +32,9 @@ The model provided for creating a `PrimaryKeyTable` should implement the `Primar +++ https://github.com/cosmos/cosmos-sdk/blob/9f78f16ae75cc42fc5fe636bde18a453ba74831f/x/group/internal/orm/primary_key.go#L28-L41 `PrimaryKeyFields()` method returns the list of key parts for a given object. -The primary key parts can be []byte, string, and `uint64` types. +The primary key parts can be []byte, string, and `uint64` types. Key parts, except the last part, follow these rules: - - []byte is encoded with a single byte length prefix - - strings are null-terminated - - `uint64` are encoded using 8 byte big endian. + +- []byte is encoded with a single byte length prefix +- strings are null-terminated +- `uint64` are encoded using 8 byte big endian. diff --git a/x/mint/spec/06_client.md b/x/mint/spec/06_client.md index 078f5cfb3a3f..e2c366d932be 100644 --- a/x/mint/spec/06_client.md +++ b/x/mint/spec/06_client.md @@ -4,7 +4,6 @@ order: 6 # Client - ## CLI A user can query and interact with the `mint` module using the CLI. @@ -28,7 +27,7 @@ simd query mint annual-provisions [flags] Example: ``` -simd query mint annual-provisions +simd query mint annual-provisions ``` Example Output: @@ -37,7 +36,6 @@ Example Output: 22268504368893.612100895088410693 ``` - #### inflation The `inflation` command allow users to query the current minting inflation value @@ -49,7 +47,7 @@ simd query mint inflation [flags] Example: ``` -simd query mint inflation +simd query mint inflation ``` Example Output: @@ -62,7 +60,6 @@ Example Output: The `params` command allow users to query the current minting parameters - ``` simd query mint params [flags] ``` @@ -90,7 +87,7 @@ The `AnnualProvisions` endpoint allow users to query the current minting annual /cosmos.mint.v1beta1.Query/AnnualProvisions ``` -Example: +Example: ``` grpcurl -plaintext localhost:9090 cosmos.mint.v1beta1.Query/AnnualProvisions @@ -130,7 +127,6 @@ Example Output: The `Params` endpoint allow users to query the current minting parameters - ``` /cosmos.mint.v1beta1.Query/Params ``` @@ -166,7 +162,7 @@ A user can query the `mint` module using REST endpoints. /cosmos/mint/v1beta1/annual_provisions ``` -Example: +Example: ``` curl "localhost:1317/cosmos/mint/v1beta1/annual_provisions" diff --git a/x/slashing/spec/09_client.md b/x/slashing/spec/09_client.md index e5c9492b91cf..fd5b2030fe43 100644 --- a/x/slashing/spec/09_client.md +++ b/x/slashing/spec/09_client.md @@ -38,7 +38,6 @@ slash_fraction_double_sign: "0.050000000000000000" slash_fraction_downtime: "0.010000000000000000" ``` - #### signing-info The `signing-info` command allows users to query signing-info of the validator using consensus public key. @@ -209,7 +208,6 @@ Example Output: A user can query the `slashing` module using REST endpoints. - ### Params ```bash diff --git a/x/slashing/spec/README.md b/x/slashing/spec/README.md index 2d35c8cba4ef..4f1fec931f0d 100644 --- a/x/slashing/spec/README.md +++ b/x/slashing/spec/README.md @@ -46,4 +46,4 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste 9. **[Client](09_client.md)** - [CLI](09_client.md#cli) - [gRPC](09_client.md#grpc) - - [REST](09_client.md#rest) \ No newline at end of file + - [REST](09_client.md#rest) diff --git a/x/staking/spec/09_client.md b/x/staking/spec/09_client.md index 5ad71eb61428..608705352cfc 100644 --- a/x/staking/spec/09_client.md +++ b/x/staking/spec/09_client.md @@ -915,7 +915,7 @@ Example Output: ```bash { - "delegation_response": + "delegation_response": { "delegation": { @@ -1348,7 +1348,6 @@ The `DelegtaorDelegations` REST endpoint queries all delegations of a given dele /cosmos/staking/v1beta1/delegations/{delegatorAddr} ``` - Example: ```bash @@ -1886,7 +1885,7 @@ Example Output: ### ValidatorDelegations -The `ValidatorDelegations` REST endpoint queries delegate information for given validator. +The `ValidatorDelegations` REST endpoint queries delegate information for given validator. ```bash /cosmos/staking/v1beta1/validators/{validatorAddr}/delegations @@ -2037,7 +2036,7 @@ Example Output: ### ValidatorUnbondingDelegations -The `ValidatorUnbondingDelegations` REST endpoint queries unbonding delegations of a validator. +The `ValidatorUnbondingDelegations` REST endpoint queries unbonding delegations of a validator. ```bash /cosmos/staking/v1beta1/validators/{validatorAddr}/unbonding_delegations @@ -2087,4 +2086,3 @@ Example Output: } } ``` - diff --git a/x/upgrade/spec/04_client.md b/x/upgrade/spec/04_client.md index 34a55691ff48..da55709ee712 100644 --- a/x/upgrade/spec/04_client.md +++ b/x/upgrade/spec/04_client.md @@ -16,7 +16,7 @@ The `query` commands allow users to query `upgrade` state. simd query upgrade --help ``` -#### applied +#### applied The `applied` command allows users to query the block header for height at which a completed upgrade was applied. @@ -72,7 +72,7 @@ Example Output: } ``` -#### module versions +#### module versions The `module_versions` command gets a list of module names and their respective consensus versions. @@ -82,6 +82,7 @@ that module's information. ```bash simd query upgrade module_versions [optional module_name] [flags] ``` + Example: ```bash @@ -89,6 +90,7 @@ simd query upgrade module_versions ``` Example Output: + ```bash module_versions: - name: auth @@ -167,7 +169,6 @@ time: "0001-01-01T00:00:00Z" upgraded_client_state: null ``` - ## REST A user can query the `upgrade` module using REST endpoints. @@ -216,7 +217,6 @@ Example Output: } ``` - ### Module versions `ModuleVersions` queries the list of module versions from state. @@ -363,7 +363,6 @@ Example Output: } ``` - ### Module versions `ModuleVersions` queries the list of module versions from state. @@ -458,5 +457,3 @@ Example Output: ] } ``` - - From 4f31170ff532cb467343a2b7a3b64c352ddd0743 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Sun, 31 Oct 2021 18:28:39 +0000 Subject: [PATCH 18/38] fix: middleware consumeTxSizeGas linting (#10476) LGTM, liveness test failure is certainly unrelated. (mismatched docker OS and binary version) --- x/auth/middleware/basic.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x/auth/middleware/basic.go b/x/auth/middleware/basic.go index 1bfd98d868d6..58d05bdd7610 100644 --- a/x/auth/middleware/basic.go +++ b/x/auth/middleware/basic.go @@ -295,7 +295,7 @@ func (cgts consumeTxSizeGasTxHandler) simulateSigGasCost(ctx context.Context, tx return nil } -func (cgts consumeTxSizeGasTxHandler) consumeTxSizeGas(ctx context.Context, _ sdk.Tx, txBytes []byte, simulate bool) error { +func (cgts consumeTxSizeGasTxHandler) consumeTxSizeGas(ctx context.Context, _ sdk.Tx, txBytes []byte) error { sdkCtx := sdk.UnwrapSDKContext(ctx) params := cgts.ak.GetParams(sdkCtx) sdkCtx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*sdk.Gas(len(txBytes)), "txSize") @@ -305,7 +305,7 @@ func (cgts consumeTxSizeGasTxHandler) consumeTxSizeGas(ctx context.Context, _ sd // CheckTx implements tx.Handler.CheckTx. func (cgts consumeTxSizeGasTxHandler) CheckTx(ctx context.Context, tx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { - if err := cgts.consumeTxSizeGas(ctx, tx, req.GetTx(), false); err != nil { + if err := cgts.consumeTxSizeGas(ctx, tx, req.GetTx()); err != nil { return abci.ResponseCheckTx{}, err } @@ -314,7 +314,7 @@ func (cgts consumeTxSizeGasTxHandler) CheckTx(ctx context.Context, tx sdk.Tx, re // DeliverTx implements tx.Handler.DeliverTx. func (cgts consumeTxSizeGasTxHandler) DeliverTx(ctx context.Context, tx sdk.Tx, req abci.RequestDeliverTx) (abci.ResponseDeliverTx, error) { - if err := cgts.consumeTxSizeGas(ctx, tx, req.GetTx(), false); err != nil { + if err := cgts.consumeTxSizeGas(ctx, tx, req.GetTx()); err != nil { return abci.ResponseDeliverTx{}, err } @@ -323,7 +323,7 @@ func (cgts consumeTxSizeGasTxHandler) DeliverTx(ctx context.Context, tx sdk.Tx, // SimulateTx implements tx.Handler.SimulateTx. func (cgts consumeTxSizeGasTxHandler) SimulateTx(ctx context.Context, sdkTx sdk.Tx, req tx.RequestSimulateTx) (tx.ResponseSimulateTx, error) { - if err := cgts.consumeTxSizeGas(ctx, sdkTx, req.TxBytes, true); err != nil { + if err := cgts.consumeTxSizeGas(ctx, sdkTx, req.TxBytes); err != nil { return tx.ResponseSimulateTx{}, err } From c42da590b1c84d6d9534d5eae9e0e72ca9b0df59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Nov 2021 01:29:50 +0100 Subject: [PATCH 19/38] build(deps): Bump amannn/action-semantic-pull-request (#10478) Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 3.4.5 to 3.4.6. - [Release notes](https://github.com/amannn/action-semantic-pull-request/releases) - [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/master/CHANGELOG.md) - [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v3.4.5...v3.4.6) --- updated-dependencies: - dependency-name: amannn/action-semantic-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index c1a343cfae1e..63418f12ae22 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -11,6 +11,6 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v3.4.5 + - uses: amannn/action-semantic-pull-request@v3.4.6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d83a3bf92c9a84bddf3f5eb6692a1101c18b42f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Nov 2021 18:50:20 +0100 Subject: [PATCH 20/38] build(deps): Bump github.com/rs/zerolog from 1.25.0 to 1.26.0 (#10483) Bumps [github.com/rs/zerolog](https://github.com/rs/zerolog) from 1.25.0 to 1.26.0. - [Release notes](https://github.com/rs/zerolog/releases) - [Commits](https://github.com/rs/zerolog/compare/v1.25.0...v1.26.0) --- updated-dependencies: - dependency-name: github.com/rs/zerolog dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 37e80d754cf8..1a80aca713d6 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/prometheus/common v0.32.1 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 - github.com/rs/zerolog v1.25.0 + github.com/rs/zerolog v1.26.0 github.com/spf13/cast v1.4.1 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 09157cacd231..682d6581ed61 100644 --- a/go.sum +++ b/go.sum @@ -752,8 +752,8 @@ 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/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= -github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= +github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE= +github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo= 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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -879,6 +879,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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/yuin/goldmark v1.4.0/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= @@ -1024,6 +1025,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1136,6 +1138,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1217,6 +1220,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 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= From 4e718a8541eeac45fdd4392d03a075b7dec16cb0 Mon Sep 17 00:00:00 2001 From: Zhiqiang Zhang <745124335@qq.com> Date: Sun, 7 Nov 2021 07:05:45 +0800 Subject: [PATCH 21/38] feat: implement nft module query server (#10462) ## Description QueryServer implementation and corresponding keeper methods,refer #9826 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- x/nft/errors.go | 1 + x/nft/keeper/grpc_query.go | 192 +++++++++++ x/nft/keeper/grpc_query_test.go | 588 ++++++++++++++++++++++++++++++++ x/nft/keeper/keeper_test.go | 5 + x/nft/validation.go | 6 +- 5 files changed, 790 insertions(+), 2 deletions(-) create mode 100644 x/nft/keeper/grpc_query.go create mode 100644 x/nft/keeper/grpc_query_test.go diff --git a/x/nft/errors.go b/x/nft/errors.go index 1982862d1f8b..c7d6836596f7 100644 --- a/x/nft/errors.go +++ b/x/nft/errors.go @@ -12,4 +12,5 @@ var ( ErrNFTExists = sdkerrors.Register(ModuleName, 5, "nft already exist") ErrNFTNotExists = sdkerrors.Register(ModuleName, 6, "nft does not exist") ErrInvalidID = sdkerrors.Register(ModuleName, 7, "invalid id") + ErrInvalidClassID = sdkerrors.Register(ModuleName, 8, "invalid class id") ) diff --git a/x/nft/keeper/grpc_query.go b/x/nft/keeper/grpc_query.go new file mode 100644 index 000000000000..602ea7a180b6 --- /dev/null +++ b/x/nft/keeper/grpc_query.go @@ -0,0 +1,192 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +var _ nft.QueryServer = Keeper{} + +// Balance return the number of NFTs of a given class owned by the owner, same as balanceOf in ERC721 +func (k Keeper) Balance(goCtx context.Context, r *nft.QueryBalanceRequest) (*nft.QueryBalanceResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + + owner, err := sdk.AccAddressFromBech32(r.Owner) + if err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + balance := k.GetBalance(ctx, r.ClassId, owner) + return &nft.QueryBalanceResponse{Amount: balance}, nil +} + +// Owner return the owner of the NFT based on its class and id, same as ownerOf in ERC721 +func (k Keeper) Owner(goCtx context.Context, r *nft.QueryOwnerRequest) (*nft.QueryOwnerResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + + if err := nft.ValidateNFTID(r.Id); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + owner := k.GetOwner(ctx, r.ClassId, r.Id) + return &nft.QueryOwnerResponse{Owner: owner.String()}, nil +} + +// Supply return the number of NFTs from the given class, same as totalSupply of ERC721. +func (k Keeper) Supply(goCtx context.Context, r *nft.QuerySupplyRequest) (*nft.QuerySupplyResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) + supply := k.GetTotalSupply(ctx, r.ClassId) + return &nft.QuerySupplyResponse{Amount: supply}, nil +} + +// NFTsOfClass return all NFTs of a given class or optional owner, similar to tokenByIndex in ERC721Enumerable +func (k Keeper) NFTsOfClass(goCtx context.Context, r *nft.QueryNFTsOfClassRequest) (*nft.QueryNFTsOfClassResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + + var nfts []*nft.NFT + ctx := sdk.UnwrapSDKContext(goCtx) + + // if owner is not empty, filter nft by owner + if len(r.Owner) > 0 { + owner, err := sdk.AccAddressFromBech32(r.Owner) + if err != nil { + return nil, err + } + + ownerStore := k.getClassStoreByOwner(ctx, owner, r.ClassId) + pageRes, err := query.Paginate(ownerStore, r.Pagination, func(key []byte, _ []byte) error { + nft, has := k.GetNFT(ctx, r.ClassId, string(key)) + if has { + nfts = append(nfts, &nft) + } + return nil + }) + + if err != nil { + return nil, err + } + return &nft.QueryNFTsOfClassResponse{ + Nfts: nfts, + Pagination: pageRes, + }, nil + } + + nftStore := k.getNFTStore(ctx, r.ClassId) + pageRes, err := query.Paginate(nftStore, r.Pagination, func(_ []byte, value []byte) error { + var nft nft.NFT + if err := k.cdc.Unmarshal(value, &nft); err != nil { + return err + } + nfts = append(nfts, &nft) + return nil + }) + + if err != nil { + return nil, err + } + return &nft.QueryNFTsOfClassResponse{ + Nfts: nfts, + Pagination: pageRes, + }, nil +} + +// NFT return an NFT based on its class and id. +func (k Keeper) NFT(goCtx context.Context, r *nft.QueryNFTRequest) (*nft.QueryNFTResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + if err := nft.ValidateNFTID(r.Id); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + n, has := k.GetNFT(ctx, r.ClassId, r.Id) + if !has { + return nil, sdkerrors.Wrapf(nft.ErrNFTNotExists, "not found nft: class: %s, id: %s", r.ClassId, r.Id) + } + return &nft.QueryNFTResponse{Nft: &n}, nil + +} + +// Class return an NFT class based on its id +func (k Keeper) Class(goCtx context.Context, r *nft.QueryClassRequest) (*nft.QueryClassResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + if err := nft.ValidateClassID(r.ClassId); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + class, has := k.GetClass(ctx, r.ClassId) + if !has { + return nil, sdkerrors.Wrapf(nft.ErrClassNotExists, "not found class: %s", r.ClassId) + } + return &nft.QueryClassResponse{Class: &class}, nil +} + +// Classes return all NFT classes +func (k Keeper) Classes(goCtx context.Context, r *nft.QueryClassesRequest) (*nft.QueryClassesResponse, error) { + if r == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + store := ctx.KVStore(k.storeKey) + classStore := prefix.NewStore(store, ClassKey) + + var classes []*nft.Class + pageRes, err := query.Paginate(classStore, r.Pagination, func(_ []byte, value []byte) error { + var class nft.Class + if err := k.cdc.Unmarshal(value, &class); err != nil { + return err + } + classes = append(classes, &class) + return nil + }) + + if err != nil { + return nil, err + } + return &nft.QueryClassesResponse{ + Classes: classes, + Pagination: pageRes, + }, nil +} diff --git a/x/nft/keeper/grpc_query_test.go b/x/nft/keeper/grpc_query_test.go new file mode 100644 index 000000000000..f70b0a0135d7 --- /dev/null +++ b/x/nft/keeper/grpc_query_test.go @@ -0,0 +1,588 @@ +package keeper_test + +import ( + gocontext "context" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/x/nft" +) + +func TestGRPCQuery(t *testing.T) { + suite.Run(t, new(TestSuite)) +} + +func (suite *TestSuite) TestBalance() { + var ( + req *nft.QueryBalanceRequest + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + balance uint64 + postTest func(index int, require *require.Assertions, res *nft.QueryBalanceResponse, expBalance uint64) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QueryBalanceRequest{} + }, + "invalid class id", + 0, + func(index int, require *require.Assertions, res *nft.QueryBalanceResponse, expBalance uint64) {}, + }, + { + "fail invalid Owner addr", + func(index int, require *require.Assertions) { + req = &nft.QueryBalanceRequest{ + ClassId: testClassID, + Owner: "owner", + } + }, + "decoding bech32 failed", + 0, + func(index int, require *require.Assertions, res *nft.QueryBalanceResponse, expBalance uint64) {}, + }, + { + "Success", + func(index int, require *require.Assertions) { + suite.TestMint() + req = &nft.QueryBalanceRequest{ + ClassId: testClassID, + Owner: suite.addrs[0].String(), + } + }, + "", + 1, + func(index int, require *require.Assertions, res *nft.QueryBalanceResponse, expBalance uint64) { + require.Equal(res.Amount, expBalance, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.Balance(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result, tc.balance) + }) + } +} + +func (suite *TestSuite) TestOwner() { + var ( + req *nft.QueryOwnerRequest + owner string + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + postTest func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QueryOwnerRequest{ + Id: testID, + } + }, + "invalid class id", + func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) {}, + }, + { + "fail empty nft id", + func(index int, require *require.Assertions) { + req = &nft.QueryOwnerRequest{ + ClassId: testClassID, + } + }, + "invalid nft id", + func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) {}, + }, + { + "success but nft id not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryOwnerRequest{ + ClassId: testClassID, + Id: "kitty2", + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) { + require.Equal(res.Owner, owner, "the error occurred on:%d", index) + }, + }, + { + "success but class id not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryOwnerRequest{ + ClassId: "kitty1", + Id: testID, + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) { + require.Equal(res.Owner, owner, "the error occurred on:%d", index) + }, + }, + { + "Success", + func(index int, require *require.Assertions) { + suite.TestMint() + req = &nft.QueryOwnerRequest{ + ClassId: testClassID, + Id: testID, + } + owner = suite.addrs[0].String() + }, + "", + func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) { + require.Equal(res.Owner, owner, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.Owner(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result) + }) + } +} + +func (suite *TestSuite) TestSupply() { + var ( + req *nft.QuerySupplyRequest + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + supply uint64 + postTest func(index int, require *require.Assertions, res *nft.QuerySupplyResponse, supply uint64) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QuerySupplyRequest{} + }, + "invalid class id", + 0, + func(index int, require *require.Assertions, res *nft.QuerySupplyResponse, supply uint64) {}, + }, + { + "success but class id not exist", + func(index int, require *require.Assertions) { + req = &nft.QuerySupplyRequest{ + ClassId: "kitty1", + } + }, + "", + 0, + func(index int, require *require.Assertions, res *nft.QuerySupplyResponse, supply uint64) { + require.Equal(res.Amount, supply, "the error occurred on:%d", index) + }, + }, + { + "success but supply equal zero", + func(index int, require *require.Assertions) { + req = &nft.QuerySupplyRequest{ + ClassId: testClassID, + } + suite.TestSaveClass() + }, + "", + 0, + func(index int, require *require.Assertions, res *nft.QuerySupplyResponse, supply uint64) { + require.Equal(res.Amount, supply, "the error occurred on:%d", index) + }, + }, + { + "Success", + func(index int, require *require.Assertions) { + n := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err := suite.app.NFTKeeper.Mint(suite.ctx, n, suite.addrs[0]) + require.NoError(err, "the error occurred on:%d", index) + + req = &nft.QuerySupplyRequest{ + ClassId: testClassID, + } + }, + "", + 1, + func(index int, require *require.Assertions, res *nft.QuerySupplyResponse, supply uint64) { + require.Equal(res.Amount, supply, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.Supply(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result, tc.supply) + }) + } +} + +func (suite *TestSuite) TestNFTsOfClass() { + var ( + req *nft.QueryNFTsOfClassRequest + nfts []*nft.NFT + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + postTest func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{} + }, + "invalid class id", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) {}, + }, + { + "success, no nft", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{ + ClassId: testClassID, + } + suite.TestSaveClass() + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) { + require.Len(res.Nfts, 0, "the error occurred on:%d", index) + }, + }, + { + "success, class id not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{ + ClassId: "kitty1", + } + n := nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + err := suite.app.NFTKeeper.Mint(suite.ctx, n, suite.addrs[0]) + require.NoError(err, "the error occurred on:%d", index) + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) { + require.Len(res.Nfts, 0, "the error occurred on:%d", index) + }, + }, + { + "success, owner not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{ + ClassId: testClassID, + Owner: suite.addrs[1].String(), + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) { + require.Len(res.Nfts, 0, "the error occurred on:%d", index) + }, + }, + { + "Success, query by classId", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{ + ClassId: testClassID, + } + nfts = []*nft.NFT{ + { + ClassId: testClassID, + Id: testID, + Uri: testURI, + }, + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) { + require.Equal(res.Nfts, nfts, "the error occurred on:%d", index) + }, + }, + { + "Success,query by classId and owner", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTsOfClassRequest{ + ClassId: testClassID, + Owner: suite.addrs[0].String(), + } + nfts = []*nft.NFT{ + { + ClassId: testClassID, + Id: testID, + Uri: testURI, + }, + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTsOfClassResponse) { + require.Equal(res.Nfts, nfts, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.NFTsOfClass(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result) + }) + } +} + +func (suite *TestSuite) TestNFT() { + var ( + req *nft.QueryNFTRequest + expNFT nft.NFT + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + postTest func(index int, require *require.Assertions, res *nft.QueryNFTResponse) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTRequest{} + }, + "invalid class id", + func(index int, require *require.Assertions, res *nft.QueryNFTResponse) {}, + }, + { + "fail empty nft id", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTRequest{ + ClassId: testClassID, + } + }, + "invalid nft id", + func(index int, require *require.Assertions, res *nft.QueryNFTResponse) {}, + }, + { + "fail ClassId not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTRequest{ + ClassId: "kitty1", + Id: testID, + } + suite.TestMint() + }, + "not found nft", + func(index int, require *require.Assertions, res *nft.QueryNFTResponse) {}, + }, + { + "fail nft id not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTRequest{ + ClassId: testClassID, + Id: "kitty2", + } + }, + "not found nft", + func(index int, require *require.Assertions, res *nft.QueryNFTResponse) {}, + }, + { + "success", + func(index int, require *require.Assertions) { + req = &nft.QueryNFTRequest{ + ClassId: testClassID, + Id: testID, + } + expNFT = nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryNFTResponse) { + require.Equal(*res.Nft, expNFT, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.NFT(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result) + }) + } +} + +func (suite *TestSuite) TestClass() { + var ( + req *nft.QueryClassRequest + class nft.Class + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + postTest func(index int, require *require.Assertions, res *nft.QueryClassResponse) + }{ + { + "fail empty ClassId", + func(index int, require *require.Assertions) { + req = &nft.QueryClassRequest{} + }, + "invalid class id", + func(index int, require *require.Assertions, res *nft.QueryClassResponse) {}, + }, + { + "fail ClassId not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryClassRequest{ + ClassId: "kitty1", + } + suite.TestSaveClass() + }, + "not found class", + func(index int, require *require.Assertions, res *nft.QueryClassResponse) {}, + }, + { + "success", + func(index int, require *require.Assertions) { + class = nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + req = &nft.QueryClassRequest{ + ClassId: testClassID, + } + }, + "", + func(index int, require *require.Assertions, res *nft.QueryClassResponse) { + require.Equal(*res.Class, class, "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.Class(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result) + }) + } +} + +func (suite *TestSuite) TestClasses() { + var ( + req *nft.QueryClassesRequest + classes []nft.Class + ) + testCases := []struct { + msg string + malleate func(index int, require *require.Assertions) + expError string + postTest func(index int, require *require.Assertions, res *nft.QueryClassesResponse) + }{ + { + "success Class not exist", + func(index int, require *require.Assertions) { + req = &nft.QueryClassesRequest{} + }, + "", + func(index int, require *require.Assertions, res *nft.QueryClassesResponse) { + require.Len(res.Classes, 0) + }, + }, + { + "success", + func(index int, require *require.Assertions) { + req = &nft.QueryClassesRequest{} + classes = []nft.Class{ + { + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + }, + } + suite.TestSaveClass() + }, + "", + func(index int, require *require.Assertions, res *nft.QueryClassesResponse) { + require.Len(res.Classes, 1, "the error occurred on:%d", index) + require.Equal(*res.Classes[0], classes[0], "the error occurred on:%d", index) + }, + }, + } + for index, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + require := suite.Require() + tc.malleate(index, require) + result, err := suite.queryClient.Classes(gocontext.Background(), req) + if tc.expError == "" { + require.NoError(err) + } else { + require.Error(err) + require.Contains(err.Error(), tc.expError) + } + tc.postTest(index, require, result) + }) + } +} diff --git a/x/nft/keeper/keeper_test.go b/x/nft/keeper/keeper_test.go index dafe49a88e9a..43cca3ff6e2f 100644 --- a/x/nft/keeper/keeper_test.go +++ b/x/nft/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtime "github.com/tendermint/tendermint/types/time" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/nft" @@ -37,9 +38,13 @@ func (s *TestSuite) SetupTest() { app := simapp.Setup(s.T(), false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) ctx = ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()}) + queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) + nft.RegisterQueryServer(queryHelper, app.NFTKeeper) + queryClient := nft.NewQueryClient(queryHelper) s.app = app s.ctx = ctx + s.queryClient = queryClient s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000)) } diff --git a/x/nft/validation.go b/x/nft/validation.go index 76621190f764..9ff72431a2e1 100644 --- a/x/nft/validation.go +++ b/x/nft/validation.go @@ -3,6 +3,8 @@ package nft import ( fmt "fmt" "regexp" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) var ( @@ -19,7 +21,7 @@ var ( // ValidateClassID returns whether the class id is valid func ValidateClassID(id string) error { if !reClassID.MatchString(id) { - return fmt.Errorf("invalid class id: %s", id) + return sdkerrors.Wrapf(ErrInvalidClassID, "invalid class id: %s", id) } return nil } @@ -27,7 +29,7 @@ func ValidateClassID(id string) error { // ValidateNFTID returns whether the nft id is valid func ValidateNFTID(id string) error { if !reNFTID.MatchString(id) { - return fmt.Errorf("invalid nft id: %s", id) + return sdkerrors.Wrapf(ErrInvalidID, "invalid nft id: %s", id) } return nil } From 08aa3f218cd408d128dadb6cac7162f41193e865 Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Mon, 8 Nov 2021 19:13:14 +0900 Subject: [PATCH 22/38] chore: fix typo in adr-014-proportional-slashing.md (#10492) occured -> occurred --- docs/architecture/adr-014-proportional-slashing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/adr-014-proportional-slashing.md b/docs/architecture/adr-014-proportional-slashing.md index 643b022e1fac..f7a063930253 100644 --- a/docs/architecture/adr-014-proportional-slashing.md +++ b/docs/architecture/adr-014-proportional-slashing.md @@ -49,7 +49,7 @@ Griefing, the act of intentionally getting oneself slashed in order to make anot ### Implementation -In the slashing module, we will add two queues that will track all of the recent slash events. For double sign faults, we will define "recent slashes" as ones that have occured within the last `unbonding period`. For liveness faults, we will define "recent slashes" as ones that have occured withing the last `jail period`. +In the slashing module, we will add two queues that will track all of the recent slash events. For double sign faults, we will define "recent slashes" as ones that have occurred within the last `unbonding period`. For liveness faults, we will define "recent slashes" as ones that have occurred withing the last `jail period`. ``` type SlashEvent struct { @@ -65,7 +65,7 @@ Whenever a new slash occurs, a `SlashEvent` struct is created with the faulting We then will iterate over all the SlashEvents in the queue, adding their `ValidatorVotingPercent` to calculate the new percent to slash all the validators in the queue at, using the "Square of Sum of Roots" formula introduced above. -Once we have the `NewSlashPercent`, we then iterate over all the `SlashEvent`s in the queue once again, and if `NewSlashPercent > SlashedSoFar` for that SlashEvent, we call the `staking.Slash(slashEvent.Address, slashEvent.Power, Math.Min(Math.Max(minSlashPercent, NewSlashPercent - SlashedSoFar), maxSlashPercent)` (we pass in the power of the validator before any slashes occured, so that we slash the right amount of tokens). We then set `SlashEvent.SlashedSoFar` amount to `NewSlashPercent`. +Once we have the `NewSlashPercent`, we then iterate over all the `SlashEvent`s in the queue once again, and if `NewSlashPercent > SlashedSoFar` for that SlashEvent, we call the `staking.Slash(slashEvent.Address, slashEvent.Power, Math.Min(Math.Max(minSlashPercent, NewSlashPercent - SlashedSoFar), maxSlashPercent)` (we pass in the power of the validator before any slashes occurred, so that we slash the right amount of tokens). We then set `SlashEvent.SlashedSoFar` amount to `NewSlashPercent`. ## Status From 3f2570f61da4c3e7658d31c1d3ba608de921bf63 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Mon, 8 Nov 2021 10:24:22 +0000 Subject: [PATCH 23/38] chore: golangci-linter github action setup (#10475) ## Description Closes: #10474 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- .github/workflows/lint.yml | 10 +++++++--- Makefile | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a205981912b2..09daa1b4d91a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/setup-go@v2.1.4 with: - go-version: 1.16 + go-version: 1.17 - uses: technote-space/get-diff-action@v5 id: git_diff with: @@ -22,6 +22,10 @@ jobs: **/**.go go.mod go.sum - - name: run go linters - run: make lint-go + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: latest + args: --out-format=tab + skip-go-installation: true if: env.GIT_DIFF diff --git a/Makefile b/Makefile index dadbf36df299..f19650b347a9 100644 --- a/Makefile +++ b/Makefile @@ -344,7 +344,7 @@ markdownLintImage=tmknom/markdownlint containerMarkdownLint=$(PROJECT_NAME)-markdownlint containerMarkdownLintFix=$(PROJECT_NAME)-markdownlint-fix -golangci_lint_cmd=go run github.com/golangci/golangci-lint/cmd/golangci-lint +golangci_lint_cmd=golangci-lint lint: lint-go @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLint}$$"; then docker start -a $(containerMarkdownLint); else docker run --name $(containerMarkdownLint) -i -v "$(CURDIR):/work" $(markdownLintImage); fi @@ -354,7 +354,7 @@ lint-fix: @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLintFix}$$"; then docker start -a $(containerMarkdownLintFix); else docker run --name $(containerMarkdownLintFix) -i -v "$(CURDIR):/work" $(markdownLintImage) . --fix; fi lint-go: - echo $(GIT_DIFF) + @@test -n "$$golangci-lint version | awk '$4 >= 1.42')" $(golangci_lint_cmd) run --out-format=tab $(GIT_DIFF) .PHONY: lint lint-fix From a9af2c3fc28700e9afdcfd2e9563363c467f7c7a Mon Sep 17 00:00:00 2001 From: Arijit Das Date: Mon, 8 Nov 2021 16:26:10 +0530 Subject: [PATCH 24/38] feat(mint): Implement custom inflation function. (#10441) ## Description We want to use this feature in [Akash Network](https://akash.network/). The [Akash whitepaper](https://whitepaper.io/document/632/akash-network-whitepaper) defines a time-based function for the inflation: `I(t)`. The way `cosmos-sdk` currently calculates inflation is different as compared to what the Akash whitepaper prescribes. So, we need the `cosmos-sdk` to accept a custom function to calculate inflation. When the custom function isn't provided, it should use the default inflation calculation logic as it currently does. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + simapp/app.go | 4 ++-- x/mint/abci.go | 4 ++-- x/mint/module.go | 21 +++++++++++++++------ x/mint/types/genesis.go | 16 ++++++++++++++++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 787ddee263c3..9fc9e797f3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (x/mint) [\#10441](https://github.com/cosmos/cosmos-sdk/pull/10441) The `NewAppModule` function now accepts an inflation calculation function as an argument. * [\#10295](https://github.com/cosmos/cosmos-sdk/pull/10295) Remove store type aliases from /types * [\#9695](https://github.com/cosmos/cosmos-sdk/pull/9695) Migrate keys from `Info` -> `Record` * Add new `codec.Codec` argument in: diff --git a/simapp/app.go b/simapp/app.go index 33fcab3e5cbe..6999b0cd5894 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -332,7 +332,7 @@ func NewSimApp( crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), @@ -384,7 +384,7 @@ func NewSimApp( capability.NewAppModule(appCodec, *app.CapabilityKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), diff --git a/x/mint/abci.go b/x/mint/abci.go index 410415d743b8..f8f0c8ce411f 100644 --- a/x/mint/abci.go +++ b/x/mint/abci.go @@ -10,7 +10,7 @@ import ( ) // BeginBlocker mints new tokens for the previous block. -func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { +func BeginBlocker(ctx sdk.Context, k keeper.Keeper, ic types.InflationCalculationFn) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) // fetch stored minter & params @@ -20,7 +20,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { // recalculate inflation rate totalStakingSupply := k.StakingTokenSupply(ctx) bondedRatio := k.BondedRatio(ctx) - minter.Inflation = minter.NextInflationRate(params, bondedRatio) + minter.Inflation = ic(ctx, minter, params, bondedRatio) minter.AnnualProvisions = minter.NextAnnualProvisions(params, totalStakingSupply) k.SetMinter(ctx, minter) diff --git a/x/mint/module.go b/x/mint/module.go index 27fb7beba05c..be5ba7fdf2f9 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -89,14 +89,23 @@ type AppModule struct { keeper keeper.Keeper authKeeper types.AccountKeeper + + // inflationCalculator is used to calculate the inflation rate during BeginBlock. + // If inflationCalculator is nil, the default inflation calculation logic is used. + inflationCalculator types.InflationCalculationFn } -// NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper) AppModule { +// NewAppModule creates a new AppModule object. If the InflationCalculationFn +// argument is nil, then the SDK's default inflation function will be used. +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper, ic types.InflationCalculationFn) AppModule { + if ic == nil { + ic = types.DefaultInflationCalculationFn + } return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc}, - keeper: keeper, - authKeeper: ak, + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + authKeeper: ak, + inflationCalculator: ic, } } @@ -149,7 +158,7 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } // BeginBlock returns the begin blocker for the mint module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - BeginBlocker(ctx, am.keeper) + BeginBlocker(ctx, am.keeper, am.inflationCalculator) } // EndBlock returns the end blocker for the mint module. It returns no validator diff --git a/x/mint/types/genesis.go b/x/mint/types/genesis.go index 3d2f761b4a6b..75c69502bb02 100644 --- a/x/mint/types/genesis.go +++ b/x/mint/types/genesis.go @@ -1,5 +1,21 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InflationCalculationFn defines the function required to calculate inflation rate during +// BeginBlock. It receives the minter and params stored in the keeper, along with the current +// bondedRatio and returns the newly calculated inflation rate. +// It can be used to specify a custom inflation calculation logic, instead of relying on the +// default logic provided by the sdk. +type InflationCalculationFn func(ctx sdk.Context, minter Minter, params Params, bondedRatio sdk.Dec) sdk.Dec + +// DefaultInflationCalculationFn is the default function used to calculate inflation. +func DefaultInflationCalculationFn(_ sdk.Context, minter Minter, params Params, bondedRatio sdk.Dec) sdk.Dec { + return minter.NextInflationRate(params, bondedRatio) +} + // NewGenesisState creates a new GenesisState object func NewGenesisState(minter Minter, params Params) *GenesisState { return &GenesisState{ From 5399e72f322c6e1c461aaf8e65060dfd24cde1d6 Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Mon, 8 Nov 2021 23:49:13 +0000 Subject: [PATCH 25/38] perf: store/cachekv: avoid a map lookup if unnecessary, clear maps fast (#10486) We can shave off some milliseconds, but also cut down some Megabytes of RAM consumed by only requesting from the cache if needed, but also using the map clearing idiom which is recognized by the compiler to make fast code. Noticed in profiles from Tharsis' Ethermint per https://github.com/tharsis/ethermint/issues/710 - Before * Memory profiles ```shell 19.50MB 19.50MB 134: store.cache = make(map[string]*cValue) 18.50MB 18.50MB 135: store.deleted = make(map[string]struct{}) 15.50MB 15.50MB 136: store.unsortedCache = make(map[string]struct{}) ``` * CPU profiles ```go . . 118: // TODO: Consider allowing usage of Batch, which would allow the write to . . 119: // at least happen atomically. 150ms 150ms 120: for _, key := range keys { 220ms 3.64s 121: cacheValue := store.cache[key] . . 122: . . 123: switch { . 250ms 124: case store.isDeleted(key): . . 125: store.parent.Delete([]byte(key)) 210ms 210ms 126: case cacheValue.value == nil: . . 127: // Skip, it already doesn't exist in parent. . . 128: default: 240ms 27.94s 129: store.parent.Set([]byte(key), cacheValue.value) . . 130: } . . 131: } ... 10ms 60ms 134: store.cache = make(map[string]*cValue) . 40ms 135: store.deleted = make(map[string]struct{}) . 50ms 136: store.unsortedCache = make(map[string]struct{}) . 110ms 137: store.sortedCache = dbm.NewMemDB() ``` - After * Memory profiles ```shell . . 130: // Clear the cache using the map clearing idiom . . 131: // and not allocating fresh objects. . . 132: // Please see https://bencher.orijtech.com/perfclinic/mapclearing/ . . 133: for key := range store.cache { . . 134: delete(store.cache, key) . . 135: } . . 136: for key := range store.deleted { . . 137: delete(store.deleted, key) . . 138: } . . 139: for key := range store.unsortedCache { . . 140: delete(store.unsortedCache, key) . . 141: } ``` * CPU profiles ```shell . . 111: // TODO: Consider allowing usage of Batch, which would allow the write to . . 112: // at least happen atomically. 110ms 110ms 113: for _, key := range keys { . 210ms 114: if store.isDeleted(key) { . . 115: // We use []byte(key) instead of conv.UnsafeStrToBytes because we cannot . . 116: // be sure if the underlying store might do a save with the byteslice or . . 117: // not. Once we get confirmation that .Delete is guaranteed not to . . 118: // save the byteslice, then we can assume only a read-only copy is sufficient. . . 119: store.parent.Delete([]byte(key)) . . 120: continue . . 121: } . . 122: 50ms 2.45s 123: cacheValue := store.cache[key] 910ms 920ms 124: if cacheValue.value != nil { . . 125: // It already exists in the parent, hence delete it. 120ms 29.56s 126: store.parent.Set([]byte(key), cacheValue.value) . . 127: } . . 128: } . . 129: . . 130: // Clear the cache using the map clearing idiom . . 131: // and not allocating fresh objects. . . 132: // Please see https://bencher.orijtech.com/perfclinic/mapclearing/ . 210ms 133: for key := range store.cache { . . 134: delete(store.cache, key) . . 135: } . 10ms 136: for key := range store.deleted { . . 137: delete(store.deleted, key) . . 138: } . 170ms 139: for key := range store.unsortedCache { . . 140: delete(store.unsortedCache, key) . . 141: } . 260ms 142: store.sortedCache = dbm.NewMemDB() . 10ms 143:} ``` Fixes #10487 Updates https://github.com/tharsis/ethermint/issues/710 --- CHANGELOG.md | 4 ++++ store/cachekv/store.go | 34 +++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc9e797f3a3..535c744cfb26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. * [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. +### Improvements + +* [\#10486](https://github.com/cosmos/cosmos-sdk/pull/10486) store/cachekv's `Store.Write` conservatively looks up keys, but also uses the [map clearing idiom](https://bencher.orijtech.com/perfclinic/mapclearing/) to reduce the RAM usage, CPU time usage, and garbage collection pressure from clearing maps, instead of allocating new maps. + ### API Breaking Changes * (x/mint) [\#10441](https://github.com/cosmos/cosmos-sdk/pull/10441) The `NewAppModule` function now accepts an inflation calculation function as an argument. diff --git a/store/cachekv/store.go b/store/cachekv/store.go index 471c2387cd99..68fe7213dbfa 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -114,22 +114,34 @@ func (store *Store) Write() { // TODO: Consider allowing usage of Batch, which would allow the write to // at least happen atomically. for _, key := range keys { - cacheValue := store.cache[key] - - switch { - case store.isDeleted(key): + if store.isDeleted(key) { + // We use []byte(key) instead of conv.UnsafeStrToBytes because we cannot + // be sure if the underlying store might do a save with the byteslice or + // not. Once we get confirmation that .Delete is guaranteed not to + // save the byteslice, then we can assume only a read-only copy is sufficient. store.parent.Delete([]byte(key)) - case cacheValue.value == nil: - // Skip, it already doesn't exist in parent. - default: + continue + } + + cacheValue := store.cache[key] + if cacheValue.value != nil { + // It already exists in the parent, hence delete it. store.parent.Set([]byte(key), cacheValue.value) } } - // Clear the cache - store.cache = make(map[string]*cValue) - store.deleted = make(map[string]struct{}) - store.unsortedCache = make(map[string]struct{}) + // Clear the cache using the map clearing idiom + // and not allocating fresh objects. + // Please see https://bencher.orijtech.com/perfclinic/mapclearing/ + for key := range store.cache { + delete(store.cache, key) + } + for key := range store.deleted { + delete(store.deleted, key) + } + for key := range store.unsortedCache { + delete(store.unsortedCache, key) + } store.sortedCache = dbm.NewMemDB() } From 17a88060e7f791ad7b86db4bc56d18ff3f16402e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Nov 2021 10:09:24 +0000 Subject: [PATCH 26/38] build(deps): Bump github.com/coinbase/rosetta-sdk-go from 0.7.0 to 0.7.1 (#10508) Bumps [github.com/coinbase/rosetta-sdk-go](https://github.com/coinbase/rosetta-sdk-go) from 0.7.0 to 0.7.1.
Release notes

Sourced from github.com/coinbase/rosetta-sdk-go's releases.

Update dependencies for security vulnerability and other minor fixes

This releases include some critical dependency upgrades and minor fixes

Change log

  • Always add accounts to inactive reconciler queue #350
  • update gjson and geth #342
  • [Chore] Add better logging for prefunding an address #336
Commits
  • 69e47a4 Always add accounts to inactive reconciler queue (#350)
  • 8ea678a Bump github.com/btcsuite/btcd from 0.21.0-beta to 0.22.0-beta (#346)
  • 8de73af Bump github.com/dgraph-io/badger/v2 from 2.2007.2 to 2.2007.4 (#348)
  • c9df9ee Bump github.com/tidwall/gjson from 1.10.2 to 1.11.0 (#349)
  • 3f3aeb4 Bump github.com/mitchellh/mapstructure from 1.3.3 to 1.4.2 (#332)
  • c913b2f Bump github.com/DataDog/zstd from 1.4.5 to 1.4.8 (#301)
  • 309dbb3 Bump github.com/vmihailenco/msgpack/v5 from 5.1.4 to 5.3.5 (#340)
  • f5328a1 Bump github.com/neilotoole/errgroup from 0.1.5 to 0.1.6 (#345)
  • 192b8f0 Bump github.com/tidwall/sjson from 1.1.4 to 1.2.3 (#343)
  • 3b5ab16 Bump github.com/tidwall/gjson from 1.6.7 to 1.10.2 (#344)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/coinbase/rosetta-sdk-go&package-manager=go_modules&previous-version=0.7.0&new-version=0.7.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 12 ++- go.sum | 226 ++++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 171 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 1a80aca713d6..b0e898b2007a 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/armon/go-metrics v0.3.10 github.com/bgentry/speakeasy v0.1.0 github.com/btcsuite/btcd v0.22.0-beta - github.com/coinbase/rosetta-sdk-go v0.7.0 + github.com/coinbase/rosetta-sdk-go v0.7.1 github.com/confio/ics23/go v0.6.6 github.com/cosmos/btcutil v1.0.4 github.com/cosmos/cosmos-proto v0.0.0-20210914142853-23ed61ac79ce @@ -23,11 +23,10 @@ require ( github.com/gorilla/mux v1.8.0 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 + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 github.com/improbable-eng/grpc-web v0.14.1 github.com/jhump/protoreflect v1.10.1 - github.com/kr/text v0.2.0 // indirect github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 github.com/magiconair/properties v1.8.5 github.com/mattn/go-isatty v0.0.14 @@ -59,7 +58,6 @@ require ( require ( filippo.io/edwards25519 v1.0.0-beta.2 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/DataDog/zstd v1.4.5 // indirect github.com/Workiva/go-datastructures v1.0.52 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -68,7 +66,7 @@ require ( github.com/danieljoos/wincred v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.2 // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -79,7 +77,7 @@ require ( github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - github.com/golang/snappy v0.0.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect @@ -110,7 +108,7 @@ require ( github.com/spf13/afero v1.6.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/zondax/hid v0.9.0 // indirect go.etcd.io/bbolt v1.3.5 // indirect diff --git a/go.sum b/go.sum index 682d6581ed61..6699b7c8817f 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,13 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= 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.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= 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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= 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= @@ -29,6 +31,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf 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/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= 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= @@ -42,6 +45,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo 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= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= @@ -65,10 +69,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= 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/DataDog/zstd v1.4.8/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= @@ -80,7 +84,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE 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-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= @@ -90,16 +94,18 @@ github.com/adlio/schema v1.1.13 h1:LeNMVg5Z1FX+Qgz8tJUijBLRdcpbFUElz+d1489On98= github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 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/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 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/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= 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= @@ -109,9 +115,17 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= 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= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -121,7 +135,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -142,6 +157,7 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -159,16 +175,18 @@ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ 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/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= 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/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= -github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= +github.com/coinbase/rosetta-sdk-go v0.7.1 h1:J1erjPiDnyDIHwscxXSrx9GnnFhzb8zDhx/On2j7JF8= +github.com/coinbase/rosetta-sdk-go v0.7.1/go.mod h1:MZX7tpDNCZOHm1WpydIfNwpHUDXJR1Pt4xeuABqfvQo= 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/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= @@ -207,64 +225,70 @@ 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/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= 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/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E= 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/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= 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/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= 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= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= +github.com/ethereum/go-ethereum v1.10.11/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 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/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -275,11 +299,16 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= 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= @@ -293,6 +322,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V 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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -300,8 +331,9 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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= @@ -314,8 +346,11 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E 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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 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= @@ -353,12 +388,14 @@ 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-0.20201103224600-674baa8c7fc3/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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 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/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -401,6 +438,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 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/google/uuid v1.1.5/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/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -415,12 +453,11 @@ 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-0.20190629185528-ae1634f6a989/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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 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.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -448,6 +485,7 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 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= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= @@ -468,8 +506,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -481,10 +519,11 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -492,8 +531,18 @@ github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8O github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -501,6 +550,8 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jhump/protoreflect v1.10.1 h1:iH+UZfsbRE6vpyZH7asAjTPWJf7RJbpZ9j/N3lDlKs0= github.com/jhump/protoreflect v1.10.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= 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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -515,36 +566,47 @@ github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMW github.com/json-iterator/go v1.1.11/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/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 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/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= 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/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/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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.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= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 h1:nDOkLO7klmnEw1s4AyKt1Arvpgyh33uj1JmkYlJaDsk= github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554/go.mod h1:9+Pb2/tg1PvEgW7aFx4bFhDE4bvbI03zuJ8kb7nJ9Jc= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -557,17 +619,21 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= 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.5-0.20180830101745-3fb116b82035/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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 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/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -575,7 +641,9 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= 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/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -593,10 +661,10 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 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/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -605,6 +673,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= 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= @@ -620,8 +689,7 @@ 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/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -631,8 +699,7 @@ 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-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -660,6 +727,7 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA 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= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -671,16 +739,18 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= 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.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= 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/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 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= @@ -689,6 +759,7 @@ 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/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -714,6 +785,7 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= 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= @@ -732,7 +804,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.3.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.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= @@ -743,14 +814,13 @@ github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzy github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= 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/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 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/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE= github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo= @@ -765,7 +835,10 @@ github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F7 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -810,8 +883,6 @@ github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= 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= @@ -819,6 +890,7 @@ 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 v1.2.0/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= @@ -829,8 +901,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -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/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/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= @@ -849,10 +922,14 @@ github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs 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/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= +github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= 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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -866,12 +943,17 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 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/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -907,6 +989,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= @@ -931,12 +1014,16 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh 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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 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= @@ -945,6 +1032,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 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-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 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= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -960,12 +1048,10 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -974,7 +1060,6 @@ 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= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1012,13 +1097,13 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/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-20200904194848-62affa334b73/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-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -1077,6 +1162,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/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-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1091,6 +1177,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w 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-20200107162124-548cf772de50/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= @@ -1111,7 +1198,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1125,9 +1212,12 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1139,6 +1229,7 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1158,7 +1249,11 @@ 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-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/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-20190206041539-40960b6deb8e/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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1185,7 +1280,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn 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-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/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-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1226,6 +1321,12 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1269,6 +1370,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 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= @@ -1276,6 +1378,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx 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-20200108215221-bd8f9a0ef82f/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= @@ -1346,8 +1449,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/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= @@ -1384,9 +1488,11 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh 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.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 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= From f21c77814fac6b9739893b0616ac8d6726696cce Mon Sep 17 00:00:00 2001 From: Tomas Tauber <2410580+tomtau@users.noreply.github.com> Date: Tue, 9 Nov 2021 20:03:29 +0800 Subject: [PATCH 27/38] feat: static checking for common bug patterns (#10488) ## Description Closes: #10190 added a basic GH Action pipeline for CodeQL that checks general security and code quality issues plus a few custom queries for Cosmos SDK defined in https://github.com/crypto-com/cosmos-sdk-codeql --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- .github/workflows/codeql-analysis.yml | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000000..1317d6c861cb --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,49 @@ +name: "CodeQL" + +on: + pull_request: + push: + branches: [ master ] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2.3.5 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: 'go' + queries: crypto-com/cosmos-sdk-codeql@main,security-and-quality + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 \ No newline at end of file From 3e2b203097f4d98539f8166afcb97220f7b03939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Nov 2021 13:02:37 +0000 Subject: [PATCH 28/38] build(deps): Bump github.com/improbable-eng/grpc-web from 0.14.1 to 0.15.0 (#10499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/improbable-eng/grpc-web](https://github.com/improbable-eng/grpc-web) from 0.14.1 to 0.15.0.
Release notes

Sourced from github.com/improbable-eng/grpc-web's releases.

v0.15.0

See CHANGELOG for details

Changelog

Sourced from github.com/improbable-eng/grpc-web's changelog.

0.15.0

Other changes

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/improbable-eng/grpc-web&package-manager=go_modules&previous-version=0.14.1&new-version=0.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b0e898b2007a..33f80e91cb69 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 - github.com/improbable-eng/grpc-web v0.14.1 + github.com/improbable-eng/grpc-web v0.15.0 github.com/jhump/protoreflect v1.10.1 github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 github.com/magiconair/properties v1.8.5 @@ -60,6 +60,7 @@ require ( github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/Workiva/go-datastructures v1.0.52 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect diff --git a/go.sum b/go.sum index 6699b7c8817f..797136585b6d 100644 --- a/go.sum +++ b/go.sum @@ -161,6 +161,8 @@ github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOC github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -527,8 +529,8 @@ github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSa github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= -github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= From 23942663d9f62e76cd19369ad6764f609aa772cb Mon Sep 17 00:00:00 2001 From: yaruwangway <69694322+yaruwangway@users.noreply.github.com> Date: Tue, 9 Nov 2021 15:15:43 +0100 Subject: [PATCH 29/38] refactor: import dependancy from upgrade module to cosmovisor module (#10442) ## Description Closes: #10378 Cosmovisor module copies the data type `UpgradeInfo` and constant `upgradeFilename` from upgrade module to cosmovisor module. This pr will directly import the datatype and const from cosmos-sdk/upgrade module: `UpgradeInfo` -> `upgradetypes.Plan` `upgradeFilename` -> `upgradekeeper.UpgradeInfoFilename` --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- cosmovisor/args.go | 15 +- cosmovisor/go.mod | 107 ++++- cosmovisor/go.sum | 875 ++++++++++++++++++++++++++++++++++++- cosmovisor/process.go | 6 +- cosmovisor/process_test.go | 13 +- cosmovisor/scanner.go | 23 +- cosmovisor/scanner_test.go | 20 +- cosmovisor/upgrade.go | 8 +- cosmovisor/upgrade_test.go | 19 +- 9 files changed, 1008 insertions(+), 78 deletions(-) diff --git a/cosmovisor/args.go b/cosmovisor/args.go index 0fbd2bda9ae9..fa5ef203617d 100644 --- a/cosmovisor/args.go +++ b/cosmovisor/args.go @@ -14,6 +14,8 @@ import ( "github.com/rs/zerolog" cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // environment variable names @@ -32,7 +34,6 @@ const ( genesisDir = "genesis" upgradesDir = "upgrades" currentLink = "current" - upgradeFilename = "upgrade-info.json" ) // must be the same as x/upgrade/types.UpgradeInfoFilename @@ -49,7 +50,7 @@ type Config struct { PreupgradeMaxRetries int // currently running upgrade - currentUpgrade UpgradeInfo + currentUpgrade upgradetypes.Plan } // Root returns the root directory where all info lives @@ -220,7 +221,7 @@ func (cfg *Config) validate() []error { } // SetCurrentUpgrade sets the named upgrade to be the current link, returns error if this binary doesn't exist -func (cfg *Config) SetCurrentUpgrade(u UpgradeInfo) error { +func (cfg *Config) SetCurrentUpgrade(u upgradetypes.Plan) error { // ensure named upgrade exists bin := cfg.UpgradeBin(u.Name) @@ -244,7 +245,7 @@ func (cfg *Config) SetCurrentUpgrade(u UpgradeInfo) error { } cfg.currentUpgrade = u - f, err := os.Create(filepath.Join(upgrade, upgradeFilename)) + f, err := os.Create(filepath.Join(upgrade, upgradekeeper.UpgradeInfoFileName)) if err != nil { return err } @@ -258,14 +259,14 @@ func (cfg *Config) SetCurrentUpgrade(u UpgradeInfo) error { return f.Close() } -func (cfg *Config) UpgradeInfo() UpgradeInfo { +func (cfg *Config) UpgradeInfo() upgradetypes.Plan { if cfg.currentUpgrade.Name != "" { return cfg.currentUpgrade } - filename := filepath.Join(cfg.Root(), currentLink, upgradeFilename) + filename := filepath.Join(cfg.Root(), currentLink, upgradekeeper.UpgradeInfoFileName) _, err := os.Lstat(filename) - var u UpgradeInfo + var u upgradetypes.Plan var bz []byte if err != nil { // no current directory goto returnError diff --git a/cosmovisor/go.mod b/cosmovisor/go.mod index b117b9a58689..a5af662bdb68 100644 --- a/cosmovisor/go.mod +++ b/cosmovisor/go.mod @@ -3,9 +3,11 @@ module github.com/cosmos/cosmos-sdk/cosmovisor go 1.17 require ( + github.com/cosmos/cosmos-sdk v0.44.3 github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-getter v1.4.1 - github.com/otiai10/copy v1.4.2 + github.com/otiai10/copy v1.6.0 + github.com/rs/zerolog v1.25.0 github.com/stretchr/testify v1.7.0 google.golang.org/api v0.44.0 // indirect google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect @@ -15,31 +17,112 @@ require ( require ( cloud.google.com/go v0.81.0 // indirect cloud.google.com/go/storage v1.10.0 // indirect - github.com/aws/aws-sdk-go v1.15.78 // indirect + filippo.io/edwards25519 v1.0.0-beta.2 // indirect + github.com/99designs/keyring v1.1.6 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/DataDog/zstd v1.4.5 // indirect + github.com/armon/go-metrics v0.3.9 // indirect + github.com/aws/aws-sdk-go v1.27.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/btcsuite/btcd v0.22.0-beta // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/confio/ics23/go v0.6.6 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/iavl v0.17.1 // indirect + github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect + github.com/cosmos/ledger-go v0.9.2 // indirect + github.com/danieljoos/wincred v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgraph-io/badger/v2 v2.2007.2 // indirect + github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect + github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-kit/kit v0.10.0 // indirect + github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 // indirect + github.com/google/btree v1.0.0 // indirect github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.1.0 // indirect - github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect + github.com/hashicorp/go-version v1.2.0 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect + github.com/jmhodges/levigo v1.0.0 // indirect github.com/jstemmer/go-junit-report v0.9.1 // indirect - github.com/mitchellh/go-homedir v1.0.0 // indirect + github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.25.0 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.29.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + github.com/regen-network/cosmos-proto v0.3.1 // indirect + github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cobra v1.2.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.8.1 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + github.com/tendermint/btcd v0.1.1 // indirect + github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/tendermint/tendermint v0.34.14 // indirect + github.com/tendermint/tm-db v0.6.4 // indirect github.com/ulikunitz/xz v0.5.5 // indirect + github.com/zondax/hid v0.9.0 // indirect + go.etcd.io/bbolt v1.3.5 // indirect go.opencensus.io v0.23.0 // indirect + golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect - golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 // indirect - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect - golang.org/x/text v0.3.5 // indirect + golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f // indirect + golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect + golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect + golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect + golang.org/x/text v0.3.6 // indirect golang.org/x/tools v0.1.5 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/grpc v1.38.0 // indirect - google.golang.org/protobuf v1.26.0 // indirect + google.golang.org/grpc v1.40.0 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) + +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/cosmovisor/go.sum b/cosmovisor/go.sum index 60188ba715d7..fd8eaa80ba4f 100644 --- a/cosmovisor/go.sum +++ b/cosmovisor/go.sum @@ -1,3 +1,4 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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= @@ -27,6 +28,7 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g 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= @@ -38,38 +40,278 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= +filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= +github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= +github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +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/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +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-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= +github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +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/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +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/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= +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.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= +github.com/armon/go-metrics v0.3.9/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/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= +github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.0 h1:0xphMHGMLBrPMfxR2AmVjZKcMEESEgWF8Kru94BNByk= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= +github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= +github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +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/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= 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/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +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/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM= +github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo= +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/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +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= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/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/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +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/cosmos-sdk v0.44.3 h1:F71n1jCqPi4F0wXg8AU4AUdUF8llw0x3D3o6aLt/j2A= +github.com/cosmos/cosmos-sdk v0.44.3/go.mod h1:bA3+VenaR/l/vDiYzaiwbWvRPWHMBX2jG0ygiFtiBp0= +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/iavl v0.17.1 h1:b/Cl8h1PRMvsu24+TYNlKchIu7W6tmxIBGe6E9u2Ybw= +github.com/cosmos/iavl v0.17.1/go.mod h1:7aisPZK8yCpQdy3PMvKeO+bhq1NwDjUwjzxwwROUxFk= +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= +github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +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/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +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-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/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +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/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/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/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +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= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= +github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +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.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +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/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= 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= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +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/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +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/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= 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 h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= @@ -82,7 +324,10 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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= @@ -100,7 +345,12 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 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-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg= +github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -114,11 +364,17 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= +github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +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= @@ -131,70 +387,491 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +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 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +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/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= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +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-0.20190629185528-ae1634f6a989/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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +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.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.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= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +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/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 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-getter v1.4.1 h1:3A2Mh8smGFcf5M+gmcv898mZdrxpseik45IpcyISLsA= github.com/hashicorp/go-getter v1.4.1/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +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-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-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= -github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +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/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= +github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= +github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= +github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= +github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +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/jhump/protoreflect v1.9.0/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/json-iterator/go v1.1.11/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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= 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/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +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/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +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.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= +github.com/klauspost/compress v1.11.7/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.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= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/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= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +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.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +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.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= +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/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +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/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-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= -github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= +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/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +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/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +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/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +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= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +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/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= +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/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +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-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.4.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.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +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= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= +github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +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.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +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/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= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/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 v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +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/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +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= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +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/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0 h1:3jqPBvKT4OHAbje2Ql7KeaaSicDBCxMYwEJU1zRJceE= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +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/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.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.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +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= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= +github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +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/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +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/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo= github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= +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/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/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/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +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/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/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +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.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +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/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= +github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +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 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= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +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/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= +github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= +github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= +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/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.13/go.mod h1:6RVVRBqwtKhA+H59APKumO+B7Nye4QXSFc6+TYxAxCI= +github.com/tendermint/tendermint v0.34.14 h1:GCXmlS8Bqd2Ix3TQCpwYLUNHe+Y+QyJsm5YE+S/FkPo= +github.com/tendermint/tendermint v0.34.14/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= +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/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= +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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +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/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= 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.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/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +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= @@ -203,14 +880,45 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +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/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +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.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +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= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 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= @@ -218,6 +926,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -235,28 +944,43 @@ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhp golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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-20190628185345-da137c7871d7/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= @@ -264,22 +988,30 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL 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-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/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-20200904194848-62affa334b73/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-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -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/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -291,8 +1023,9 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -304,19 +1037,42 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ 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-20180830151530-49385e6e1522/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= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-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-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= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/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= @@ -324,25 +1080,43 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w 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-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-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/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= @@ -350,17 +1124,21 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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/tools v0.0.0-20180828015842-6cd1fcedba52/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-20190114222345-bf090417da8b/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-20190311212946-11955173bddd/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-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= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -370,6 +1148,9 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/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-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-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= @@ -377,6 +1158,8 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 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-20200117012304-6edc0a871e69/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-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -391,7 +1174,10 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc 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-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/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-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -399,16 +1185,20 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 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= @@ -433,6 +1223,7 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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= @@ -441,10 +1232,12 @@ google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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-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= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 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= @@ -460,9 +1253,12 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG 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-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -471,9 +1267,12 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/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-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -481,10 +1280,16 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -494,13 +1299,17 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -511,18 +1320,48 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 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/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/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= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 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/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.27/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/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +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= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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.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/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= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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= @@ -530,6 +1369,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh 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= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= 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/cosmovisor/process.go b/cosmovisor/process.go index 23f7edf1c212..8c2d10104d55 100644 --- a/cosmovisor/process.go +++ b/cosmovisor/process.go @@ -14,6 +14,8 @@ import ( "time" "github.com/otiai10/copy" + + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type Launcher struct { @@ -111,7 +113,7 @@ func doBackup(cfg *Config) error { // take backup if `UNSAFE_SKIP_BACKUP` is not set. if !cfg.UnsafeSkipBackup { // check if upgrade-info.json is not empty. - var uInfo UpgradeInfo + var uInfo upgradetypes.Plan upgradeInfoFile, err := os.ReadFile(filepath.Join(cfg.Home, "data", "upgrade-info.json")) if err != nil { return fmt.Errorf("error while reading upgrade-info.json: %w", err) @@ -192,7 +194,7 @@ func executePreUpgradeCmd(cfg *Config) error { } // IsSkipUpgradeHeight checks if pre-upgrade script must be run. If the height in the upgrade plan matches any of the heights provided in --safe-skip-upgrade, the script is not run -func IsSkipUpgradeHeight(args []string, upgradeInfo UpgradeInfo) bool { +func IsSkipUpgradeHeight(args []string, upgradeInfo upgradetypes.Plan) bool { skipUpgradeHeights := UpgradeSkipHeights(args) for _, h := range skipUpgradeHeights { if h == int(upgradeInfo.Height) { diff --git a/cosmovisor/process_test.go b/cosmovisor/process_test.go index f86ea1eb0b60..b0c5ceb88a35 100644 --- a/cosmovisor/process_test.go +++ b/cosmovisor/process_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/cosmos/cosmos-sdk/cosmovisor" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type processTestSuite struct { @@ -133,27 +134,27 @@ func (s *processTestSuite) TestLaunchProcessWithDownloads() { func TestSkipUpgrade(t *testing.T) { cases := []struct { args []string - upgradeInfo cosmovisor.UpgradeInfo + upgradeInfo upgradetypes.Plan expectRes bool }{{ args: []string{"appb", "start", "--unsafe-skip-upgrades"}, - upgradeInfo: cosmovisor.UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 123}, + upgradeInfo: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 123}, expectRes: false, }, { args: []string{"appb", "start", "--unsafe-skip-upgrades", "--abcd"}, - upgradeInfo: cosmovisor.UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 123}, + upgradeInfo: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 123}, expectRes: false, }, { args: []string{"appb", "start", "--unsafe-skip-upgrades", "10", "--abcd"}, - upgradeInfo: cosmovisor.UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 11}, + upgradeInfo: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 11}, expectRes: false, }, { args: []string{"appb", "start", "--unsafe-skip-upgrades", "10", "20", "--abcd"}, - upgradeInfo: cosmovisor.UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 20}, + upgradeInfo: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 20}, expectRes: true, }, { args: []string{"appb", "start", "--unsafe-skip-upgrades", "10", "20", "--abcd", "34"}, - upgradeInfo: cosmovisor.UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 34}, + upgradeInfo: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 34}, expectRes: false, }} diff --git a/cosmovisor/scanner.go b/cosmovisor/scanner.go index d71cd3b1263b..4dbcb13d7f8d 100644 --- a/cosmovisor/scanner.go +++ b/cosmovisor/scanner.go @@ -7,21 +7,16 @@ import ( "os" "path/filepath" "time" -) -// UpgradeInfo is the update details created by `x/upgrade/keeper.DumpUpgradeInfoToDisk`. -type UpgradeInfo struct { - Name string `json:"name"` - Info string `json:"info"` - Height uint `json:"height"` -} + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" +) type fileWatcher struct { // full path to a watched file filename string interval time.Duration - currentInfo UpgradeInfo + currentInfo upgradetypes.Plan lastModTime time.Time cancel chan bool ticker *time.Ticker @@ -45,7 +40,7 @@ func newUpgradeFileWatcher(filename string, interval time.Duration) (*fileWatche return nil, fmt.Errorf("wrong path, %s must be an existing directory, [%w]", dirname, err) } - return &fileWatcher{filenameAbs, interval, UpgradeInfo{}, time.Time{}, make(chan bool), time.NewTicker(interval), false, false}, nil + return &fileWatcher{filenameAbs, interval, upgradetypes.Plan{}, time.Time{}, make(chan bool), time.NewTicker(interval), false, false}, nil } func (fw *fileWatcher) Stop() { @@ -55,7 +50,7 @@ func (fw *fileWatcher) Stop() { // pools the filesystem to check for new upgrade currentInfo. currentName is the name // of currently running upgrade. The check is rejected if it finds an upgrade with the same // name. -func (fw *fileWatcher) MonitorUpdate(currentUpgrade UpgradeInfo) <-chan struct{} { +func (fw *fileWatcher) MonitorUpdate(currentUpgrade upgradetypes.Plan) <-chan struct{} { fw.ticker.Reset(fw.interval) done := make(chan struct{}) fw.cancel = make(chan bool) @@ -80,7 +75,7 @@ func (fw *fileWatcher) MonitorUpdate(currentUpgrade UpgradeInfo) <-chan struct{} // CheckUpdate reads update plan from file and checks if there is a new update request // currentName is the name of currently running upgrade. The check is rejected if it finds // an upgrade with the same name. -func (fw *fileWatcher) CheckUpdate(currentUpgrade UpgradeInfo) bool { +func (fw *fileWatcher) CheckUpdate(currentUpgrade upgradetypes.Plan) bool { if fw.needsUpdate { return true } @@ -117,8 +112,8 @@ func (fw *fileWatcher) CheckUpdate(currentUpgrade UpgradeInfo) bool { return false } -func parseUpgradeInfoFile(filename string) (UpgradeInfo, error) { - var ui UpgradeInfo +func parseUpgradeInfoFile(filename string) (upgradetypes.Plan, error) { + var ui upgradetypes.Plan f, err := os.Open(filename) if err != nil { return ui, err @@ -131,7 +126,7 @@ func parseUpgradeInfoFile(filename string) (UpgradeInfo, error) { } // required values must be set if ui.Height == 0 || ui.Name == "" { - return UpgradeInfo{}, fmt.Errorf("invalid upgrade-info.json content. Name and Hight must be not empty. Got: %v", ui) + return upgradetypes.Plan{}, fmt.Errorf("invalid upgrade-info.json content. Name and Hight must be not empty. Got: %v", ui) } return ui, err } diff --git a/cosmovisor/scanner_test.go b/cosmovisor/scanner_test.go index cabaf8304479..f45dfafe85fd 100644 --- a/cosmovisor/scanner_test.go +++ b/cosmovisor/scanner_test.go @@ -5,44 +5,46 @@ import ( "testing" "github.com/stretchr/testify/require" + + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) func TestParseUpgradeInfoFile(t *testing.T) { cases := []struct { filename string - expectUpgrade UpgradeInfo + expectUpgrade upgradetypes.Plan expectErr bool }{{ filename: "f1-good.json", - expectUpgrade: UpgradeInfo{Name: "upgrade1", Info: "some info", Height: 123}, + expectUpgrade: upgradetypes.Plan{Name: "upgrade1", Info: "some info", Height: 123}, expectErr: false, }, { filename: "f2-bad-type.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "f2-bad-type-2.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "f3-empty.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "f4-empty-obj.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "f5-partial-obj-1.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "f5-partial-obj-2.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }, { filename: "unknown.json", - expectUpgrade: UpgradeInfo{}, + expectUpgrade: upgradetypes.Plan{}, expectErr: true, }} diff --git a/cosmovisor/upgrade.go b/cosmovisor/upgrade.go index a0009e6e8e25..a91b40cea8d8 100644 --- a/cosmovisor/upgrade.go +++ b/cosmovisor/upgrade.go @@ -12,12 +12,14 @@ import ( "github.com/hashicorp/go-getter" "github.com/otiai10/copy" + + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // DoUpgrade will be called after the log message has been parsed and the process has terminated. // We can now make any changes to the underlying directory without interference and leave it // in a state, so we can make a proper restart -func DoUpgrade(cfg *Config, info UpgradeInfo) error { +func DoUpgrade(cfg *Config, info upgradetypes.Plan) error { // Simplest case is to switch the link err := EnsureBinary(cfg.UpgradeBin(info.Name)) if err == nil { @@ -50,7 +52,7 @@ func DoUpgrade(cfg *Config, info UpgradeInfo) error { } // DownloadBinary will grab the binary and place it in the proper directory -func DownloadBinary(cfg *Config, info UpgradeInfo) error { +func DownloadBinary(cfg *Config, info upgradetypes.Plan) error { url, err := GetDownloadURL(info) if err != nil { return err @@ -103,7 +105,7 @@ type UpgradeConfig struct { } // GetDownloadURL will check if there is an arch-dependent binary specified in Info -func GetDownloadURL(info UpgradeInfo) (string, error) { +func GetDownloadURL(info upgradetypes.Plan) (string, error) { doc := strings.TrimSpace(info.Info) // if this is a url, then we download that and try to get a new doc with the real info if _, err := url.Parse(doc); err == nil { diff --git a/cosmovisor/upgrade_test.go b/cosmovisor/upgrade_test.go index faf7d7cff0de..d9d59c3b5142 100644 --- a/cosmovisor/upgrade_test.go +++ b/cosmovisor/upgrade_test.go @@ -10,12 +10,13 @@ import ( "strings" "testing" - "github.com/stretchr/testify/suite" - "github.com/otiai10/copy" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "github.com/cosmos/cosmos-sdk/cosmovisor" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type upgradeTestSuite struct { @@ -37,7 +38,7 @@ func (s *upgradeTestSuite) TestCurrentBin() { // ensure we cannot set this to an invalid value for _, name := range []string{"missing", "nobin", "noexec"} { - s.Require().Error(cfg.SetCurrentUpgrade(cosmovisor.UpgradeInfo{Name: name}), name) + s.Require().Error(cfg.SetCurrentUpgrade(upgradetypes.Plan{Name: name}), name) currentBin, err := cfg.CurrentBin() s.Require().NoError(err) @@ -48,7 +49,7 @@ func (s *upgradeTestSuite) TestCurrentBin() { // try a few times to make sure this can be reproduced for _, name := range []string{"chain2", "chain3", "chain2"} { // now set it to a valid upgrade and make sure CurrentBin is now set properly - err = cfg.SetCurrentUpgrade(cosmovisor.UpgradeInfo{Name: name}) + err = cfg.SetCurrentUpgrade(upgradetypes.Plan{Name: name}) s.Require().NoError(err) // we should see current point to the new upgrade dir currentBin, err := cfg.CurrentBin() @@ -67,7 +68,7 @@ func (s *upgradeTestSuite) TestCurrentAlwaysSymlinkToDirectory() { s.Require().Equal(cfg.GenesisBin(), currentBin) s.assertCurrentLink(cfg, "genesis") - err = cfg.SetCurrentUpgrade(cosmovisor.UpgradeInfo{Name: "chain2"}) + err = cfg.SetCurrentUpgrade(upgradetypes.Plan{Name: "chain2"}) s.Require().NoError(err) currentBin, err = cfg.CurrentBin() s.Require().NoError(err) @@ -100,7 +101,7 @@ func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() { // do upgrade ignores bad files for _, name := range []string{"missing", "nobin", "noexec"} { - info := cosmovisor.UpgradeInfo{Name: name} + info := upgradetypes.Plan{Name: name} err = cosmovisor.DoUpgrade(cfg, info) s.Require().Error(err, name) currentBin, err := cfg.CurrentBin() @@ -111,7 +112,7 @@ func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() { // make sure it updates a few times for _, upgrade := range []string{"chain2", "chain3"} { // now set it to a valid upgrade and make sure CurrentBin is now set properly - info := cosmovisor.UpgradeInfo{Name: upgrade} + info := upgradetypes.Plan{Name: upgrade} err = cosmovisor.DoUpgrade(cfg, info) s.Require().NoError(err) // we should see current point to the new upgrade dir @@ -175,7 +176,7 @@ func (s *upgradeTestSuite) TestGetDownloadURL() { for name, tc := range cases { s.Run(name, func() { - url, err := cosmovisor.GetDownloadURL(cosmovisor.UpgradeInfo{Info: tc.info}) + url, err := cosmovisor.GetDownloadURL(upgradetypes.Plan{Info: tc.info}) if tc.err != "" { s.Require().Error(err) s.Require().Contains(err.Error(), tc.err) @@ -248,7 +249,7 @@ func (s *upgradeTestSuite) TestDownloadBinary() { } upgrade := "amazonas" - info := cosmovisor.UpgradeInfo{ + info := upgradetypes.Plan{ Name: upgrade, Info: fmt.Sprintf(`{"binaries":{"%s": "%s"}}`, cosmovisor.OSArch(), url), } From b9c5a0578ba0941274e576c280fb355977dab687 Mon Sep 17 00:00:00 2001 From: fkneeland-figure <86616427+fkneeland-figure@users.noreply.github.com> Date: Tue, 9 Nov 2021 10:16:02 -0700 Subject: [PATCH 30/38] fix: Update ctx BlockTime for simulations (#10467) ## Description When running simulation tests with wasmd I am running into this error: https://github.com/CosmWasm/wasmd/blob/14e58bfa81ea2ade0ff00ebd067ac0bc75e37cf8/x/wasm/types/types.go#L258 This is because when we are running in simulation mode we randomly create a date before the year 9999. However, if a date is after the year 2262 `UnixNano` will overflow and possibly return a negative number. To fix this I updated how we set the random genesis start time to be between the epoch and 200 years from now which means this error won't show itself again for another 40+ years. Closes: #10466 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + types/simulation/rand_util.go | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 535c744cfb26..73235a201b9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -152,6 +152,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10239](https://github.com/cosmos/cosmos-sdk/pull/10239) Fixed x/bank/044 migrateDenomMetadata. * (x/upgrade) [\#10189](https://github.com/cosmos/cosmos-sdk/issues/10189) Removed potential sources of non-determinism in upgrades * [\#10258](https://github.com/cosmos/cosmos-sdk/issues/10258) Fixes issue related to segmentaiton fault on mac m1 arm64 +* [\#10466](https://github.com/cosmos/cosmos-sdk/issues/10466) Fixes error with simulation tests when genesis start time is randomly created after the year 2262 ### State Machine Breaking diff --git a/types/simulation/rand_util.go b/types/simulation/rand_util.go index 84cd4492c8a7..10926f0a132d 100644 --- a/types/simulation/rand_util.go +++ b/types/simulation/rand_util.go @@ -86,9 +86,16 @@ func RandomDecAmount(r *rand.Rand, max sdk.Dec) sdk.Dec { // RandTimestamp generates a random timestamp func RandTimestamp(r *rand.Rand) time.Time { - // json.Marshal breaks for timestamps greater with year greater than 9999 - unixTime := r.Int63n(253373529600) - return time.Unix(unixTime, 0) + // json.Marshal breaks for timestamps with year greater than 9999 + // UnixNano breaks with year greater than 2262 + start := time.Date(2062, time.Month(1), 1, 1, 1, 1, 1, time.UTC).UnixMilli() + + // Calculate a random amount of time in seconds between 0 and 200 years + unixTime := r.Int63n(60*60*24*365*200) * 1000 // convert to milliseconds + + // Get milliseconds for a time between Jan 1, 2062 and Jan 1, 2262 + rtime := time.UnixMilli(start + unixTime).UnixMilli() / 1000 + return time.Unix(rtime, 0) } // RandIntBetween returns a random int between two numbers inclusively. From c5b879a03dd7b456db4028b94bde71db04beb8b2 Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 9 Nov 2021 19:01:27 +0100 Subject: [PATCH 31/38] feat: Add Table-Store (aka ORM) package - Index and Iterator (#10451) ## Description ref: #9237, #9156 This PR is a follow-up of #10415 and #9751. It adds multi-key secondary indexes, iterator and pagination support. There will be one last follow-up PR for adding import/export genesis features. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- types/errors/errors.go | 27 - x/group/errors/math.go | 9 + x/group/errors/orm.go | 28 + x/group/go.mod | 12 +- x/group/go.sum | 237 ++++++-- x/group/internal/math/dec.go | 7 +- x/group/internal/orm/auto_uint64.go | 33 + x/group/internal/orm/auto_uint64_test.go | 164 +++++ x/group/internal/orm/example_test.go | 49 +- x/group/internal/orm/index.go | 254 ++++++++ x/group/internal/orm/index_test.go | 395 ++++++++++++ x/group/internal/orm/indexer.go | 211 +++++++ x/group/internal/orm/indexer_test.go | 570 ++++++++++++++++++ x/group/internal/orm/iterator.go | 308 ++++++++++ .../internal/orm/iterator_property_test.go | 121 ++++ x/group/internal/orm/iterator_test.go | 358 +++++++++++ x/group/internal/orm/key_codec.go | 29 +- x/group/internal/orm/orm_scenario_test.go | 80 ++- x/group/internal/orm/primary_key.go | 33 + x/group/internal/orm/primary_key_test.go | 192 +++++- x/group/internal/orm/sequence.go | 5 +- x/group/internal/orm/sequence_test.go | 2 +- x/group/internal/orm/spec/01_table.md | 12 +- .../internal/orm/spec/02_secondary_index.md | 24 + .../orm/spec/03_iterator_pagination.md | 28 + x/group/internal/orm/spec/README.md | 7 + x/group/internal/orm/table.go | 95 ++- x/group/internal/orm/table_test.go | 21 +- x/group/internal/orm/types.go | 61 +- x/group/internal/orm/types_test.go | 13 +- 30 files changed, 3231 insertions(+), 154 deletions(-) create mode 100644 x/group/errors/math.go create mode 100644 x/group/errors/orm.go create mode 100644 x/group/internal/orm/auto_uint64_test.go create mode 100644 x/group/internal/orm/indexer.go create mode 100644 x/group/internal/orm/indexer_test.go create mode 100644 x/group/internal/orm/iterator.go create mode 100644 x/group/internal/orm/iterator_property_test.go create mode 100644 x/group/internal/orm/iterator_test.go create mode 100644 x/group/internal/orm/spec/02_secondary_index.md create mode 100644 x/group/internal/orm/spec/03_iterator_pagination.md diff --git a/types/errors/errors.go b/types/errors/errors.go index ece008e10da1..62dab18adf8c 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -13,12 +13,6 @@ const RootCodespace = "sdk" // UndefinedCodespace when we explicitly declare no codespace const UndefinedCodespace = "undefined" -// mathCodespace is the codespace for all errors defined in math package -const mathCodespace = "math" - -// mathCodespace is the codespace for all errors defined in orm package -const ormCodespace = "orm" - var ( // errInternal should never be exposed, but we reserve this code for non-specified errors errInternal = Register(UndefinedCodespace, 1, "internal") @@ -153,27 +147,6 @@ var ( // ErrAppConfig defines an error occurred if min-gas-prices field in BaseConfig is empty. ErrAppConfig = Register(RootCodespace, 40, "error in app.toml") - - // ErrInvalidDecString defines an error for an invalid decimal string - ErrInvalidDecString = Register(mathCodespace, 41, "invalid decimal string") - - // ErrORMIteratorDone defines an error when an iterator is done - ErrORMIteratorDone = Register(ormCodespace, 42, "iterator done") - - // ErrORMInvalidIterator defines an error for an invalid iterator - ErrORMInvalidIterator = Register(ormCodespace, 43, "invalid iterator") - - // ErrORMUniqueConstraint defines an error when a value already exists at a given key - ErrORMUniqueConstraint = Register(ormCodespace, 44, "unique constraint violation") - - // ErrORMEmptyModel defines an error when an empty model is provided for building a table - ErrORMEmptyModel = Register(ormCodespace, 45, "invalid argument") - - // ErrORMKeyMaxLength defines an error when a key exceeds max length - ErrORMKeyMaxLength = Register(ormCodespace, 46, "key exceeds max length") - - // ErrORMEmptyKey defines an error for an empty key - ErrORMEmptyKey = Register(ormCodespace, 47, "cannot use empty key") ) // Register returns an error instance that should be used as the base for diff --git a/x/group/errors/math.go b/x/group/errors/math.go new file mode 100644 index 000000000000..ff753ed220c8 --- /dev/null +++ b/x/group/errors/math.go @@ -0,0 +1,9 @@ +package errors + +import "github.com/cosmos/cosmos-sdk/types/errors" + +// mathCodespace is the codespace for all errors defined in math package +const mathCodespace = "math" + +// ErrInvalidDecString defines an error for an invalid decimal string +var ErrInvalidDecString = errors.Register(mathCodespace, 10, "invalid decimal string") diff --git a/x/group/errors/orm.go b/x/group/errors/orm.go new file mode 100644 index 000000000000..84dab68eeba5 --- /dev/null +++ b/x/group/errors/orm.go @@ -0,0 +1,28 @@ +package errors + +import ( + "github.com/cosmos/cosmos-sdk/types/errors" +) + +// mathCodespace is the codespace for all errors defined in orm package +const ormCodespace = "orm" + +var ( + // ErrORMIteratorDone defines an error when an iterator is done + ErrORMIteratorDone = errors.Register(ormCodespace, 11, "iterator done") + + // ErrORMInvalidIterator defines an error for an invalid iterator + ErrORMInvalidIterator = errors.Register(ormCodespace, 12, "invalid iterator") + + // ErrORMUniqueConstraint defines an error when a value already exists at a given key + ErrORMUniqueConstraint = errors.Register(ormCodespace, 13, "unique constraint violation") + + // ErrORMInvalidArgument defines an error when an invalid argument is provided as part of ORM functions + ErrORMInvalidArgument = errors.Register(ormCodespace, 14, "invalid argument") + + // ErrORMKeyMaxLength defines an error when a key exceeds max length + ErrORMKeyMaxLength = errors.Register(ormCodespace, 15, "key exceeds max length") + + // ErrORMEmptyKey defines an error for an empty key + ErrORMEmptyKey = errors.Register(ormCodespace, 47, "cannot use empty key") +) diff --git a/x/group/go.mod b/x/group/go.mod index 5941713b48c5..3146302ddafa 100644 --- a/x/group/go.mod +++ b/x/group/go.mod @@ -16,7 +16,6 @@ require ( require github.com/tendermint/tm-db v0.6.4 require ( - github.com/DataDog/zstd v1.4.5 // indirect github.com/armon/go-metrics v0.3.10 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd v0.22.0-beta // indirect @@ -26,7 +25,7 @@ require ( github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/iavl v0.17.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/badger/v2 v2.2007.2 // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -35,16 +34,18 @@ require ( github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.0 // indirect github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/hashicorp/go-immutable-radix v1.0.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/klauspost/compress v1.12.3 // indirect + github.com/kr/text v0.2.0 // indirect github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 // indirect github.com/libp2p/go-buffer-pool v0.0.2 // indirect github.com/magiconair/properties v1.8.5 // indirect @@ -68,7 +69,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.9.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/tendermint v0.34.14 // indirect @@ -78,6 +79,7 @@ require ( golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/x/group/go.sum b/x/group/go.sum index fdb0cd5ac51a..bff845d6c9a3 100644 --- a/x/group/go.sum +++ b/x/group/go.sum @@ -1,11 +1,13 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= 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.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= 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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= 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= @@ -29,6 +31,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf 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/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= 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= @@ -42,6 +45,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo 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= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= @@ -66,10 +70,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= 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/DataDog/zstd v1.4.8/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= @@ -79,7 +83,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE 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-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= @@ -88,16 +92,18 @@ github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1: github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 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/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 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/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= 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= @@ -107,9 +113,17 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= 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= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -119,7 +133,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -140,6 +155,7 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -156,18 +172,20 @@ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ 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/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= 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/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= -github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= +github.com/coinbase/rosetta-sdk-go v0.7.1 h1:J1erjPiDnyDIHwscxXSrx9GnnFhzb8zDhx/On2j7JF8= +github.com/coinbase/rosetta-sdk-go v0.7.1/go.mod h1:MZX7tpDNCZOHm1WpydIfNwpHUDXJR1Pt4xeuABqfvQo= 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/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= @@ -203,62 +221,68 @@ 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/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= 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/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E= 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/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= 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/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= 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= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= +github.com/ethereum/go-ethereum v1.10.11/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 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/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -269,9 +293,14 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= 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= @@ -285,12 +314,15 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V 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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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= @@ -300,8 +332,11 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E 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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 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= @@ -339,12 +374,14 @@ 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-0.20201103224600-674baa8c7fc3/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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 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/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -387,6 +424,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 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/google/uuid v1.1.5/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/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -401,12 +439,11 @@ 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-0.20190629185528-ae1634f6a989/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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 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.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -434,6 +471,7 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 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= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= @@ -454,8 +492,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -467,10 +505,11 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -478,14 +517,26 @@ github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8O github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= 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/jhump/protoreflect v1.10.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= 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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -499,37 +550,49 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.11/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/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 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/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= 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/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/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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.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= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 h1:nDOkLO7klmnEw1s4AyKt1Arvpgyh33uj1JmkYlJaDsk= github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554/go.mod h1:9+Pb2/tg1PvEgW7aFx4bFhDE4bvbI03zuJ8kb7nJ9Jc= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/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= @@ -539,17 +602,21 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= 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.5-0.20180830101745-3fb116b82035/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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 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/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -557,7 +624,9 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= 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/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -576,16 +645,17 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 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/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= 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/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= 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= @@ -600,8 +670,7 @@ 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/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -611,8 +680,7 @@ 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-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -637,6 +705,7 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA 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= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -647,16 +716,18 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= 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.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= 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/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 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= @@ -665,6 +736,7 @@ 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/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -690,6 +762,7 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= 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= @@ -708,7 +781,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.3.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.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= @@ -719,17 +791,16 @@ github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzy github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= 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/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 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/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= -github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= +github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE= +github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo= 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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -741,7 +812,10 @@ github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F7 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -785,14 +859,13 @@ github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= 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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.0/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= @@ -803,8 +876,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -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/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/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= @@ -823,10 +897,14 @@ github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs 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/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= +github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= 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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -838,12 +916,17 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 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/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -851,6 +934,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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/yuin/goldmark v1.4.0/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= @@ -878,6 +962,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= @@ -902,12 +987,16 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh 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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 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= @@ -916,6 +1005,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 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-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 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= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -931,12 +1021,10 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -945,7 +1033,6 @@ 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= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -983,19 +1070,20 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/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-20200904194848-62affa334b73/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-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1047,6 +1135,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/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-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1061,6 +1150,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w 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-20200107162124-548cf772de50/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= @@ -1081,7 +1171,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1095,9 +1185,12 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1108,6 +1201,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1127,7 +1222,11 @@ 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-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/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-20190206041539-40960b6deb8e/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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1154,7 +1253,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn 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-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/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-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1189,11 +1288,18 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1237,6 +1343,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 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= @@ -1244,6 +1351,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx 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-20200108215221-bd8f9a0ef82f/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= @@ -1314,8 +1422,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/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= @@ -1352,11 +1461,13 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh 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.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 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= diff --git a/x/group/internal/math/dec.go b/x/group/internal/math/dec.go index dbdd9843354b..831d4430ca59 100644 --- a/x/group/internal/math/dec.go +++ b/x/group/internal/math/dec.go @@ -6,7 +6,8 @@ import ( "github.com/cockroachdb/apd/v2" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" ) // Dec is a wrapper struct around apd.Decimal that does no mutation of apd.Decimal's when performing @@ -38,7 +39,7 @@ func NewDecFromInt64(x int64) Dec { func (x Dec) Add(y Dec) (Dec, error) { var z Dec _, err := apd.BaseContext.Add(&z.dec, &x.dec, &y.dec) - return z, errors.Wrap(err, "decimal addition error") + return z, sdkerrors.Wrap(err, "decimal addition error") } // Sub returns a new Dec with value `x-y` without mutating any argument and error if @@ -46,7 +47,7 @@ func (x Dec) Add(y Dec) (Dec, error) { func (x Dec) Sub(y Dec) (Dec, error) { var z Dec _, err := apd.BaseContext.Sub(&z.dec, &x.dec, &y.dec) - return z, errors.Wrap(err, "decimal subtraction error") + return z, sdkerrors.Wrap(err, "decimal subtraction error") } func (x Dec) Int64() (int64, error) { diff --git a/x/group/internal/orm/auto_uint64.go b/x/group/internal/orm/auto_uint64.go index 62eb84cbbabc..78cfcd844a78 100644 --- a/x/group/internal/orm/auto_uint64.go +++ b/x/group/internal/orm/auto_uint64.go @@ -73,3 +73,36 @@ func (a AutoUInt64Table) GetOne(store sdk.KVStore, rowID uint64, dest codec.Prot } return rawRowID, nil } + +// PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(1, math.MaxUint64) +// +// WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. +// Example: +// it, err := idx.PrefixScan(ctx, start, end) +// if err !=nil { +// return err +// } +// const defaultLimit = 20 +// it = LimitIterator(it, defaultLimit) +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a AutoUInt64Table) PrefixScan(store sdk.KVStore, start, end uint64) (Iterator, error) { + return a.table.PrefixScan(store, EncodeSequence(start), EncodeSequence(end)) +} + +// ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(1, math.MaxUint64) +// +// WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. See `LimitIterator` +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a AutoUInt64Table) ReversePrefixScan(store sdk.KVStore, start uint64, end uint64) (Iterator, error) { + return a.table.ReversePrefixScan(store, EncodeSequence(start), EncodeSequence(end)) +} diff --git a/x/group/internal/orm/auto_uint64_test.go b/x/group/internal/orm/auto_uint64_test.go new file mode 100644 index 000000000000..529fce314e04 --- /dev/null +++ b/x/group/internal/orm/auto_uint64_test.go @@ -0,0 +1,164 @@ +package orm + +import ( + "math" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAutoUInt64PrefixScan(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + metadata := []byte("metadata") + t1 := testdata.TableModel{ + Id: 1, + Name: "my test 1", + Metadata: metadata, + } + t2 := testdata.TableModel{ + Id: 2, + Name: "my test 2", + Metadata: metadata, + } + t3 := testdata.TableModel{ + Id: 3, + Name: "my test 3", + Metadata: metadata, + } + for _, g := range []testdata.TableModel{t1, t2, t3} { + _, err := tb.Create(store, &g) + require.NoError(t, err) + } + + specs := map[string]struct { + start, end uint64 + expResult []testdata.TableModel + expRowIDs []RowID + expError *sdkerrors.Error + method func(store sdk.KVStore, start uint64, end uint64) (Iterator, error) + }{ + "first element": { + start: 1, + end: 2, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "first 2 elements": { + start: 1, + end: 3, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2}, + expRowIDs: []RowID{EncodeSequence(1), EncodeSequence(2)}, + }, + "first 3 elements": { + start: 1, + end: 4, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2, t3}, + expRowIDs: []RowID{EncodeSequence(1), EncodeSequence(2), EncodeSequence(3)}, + }, + "search with max end": { + start: 1, + end: math.MaxUint64, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2, t3}, + expRowIDs: []RowID{EncodeSequence(1), EncodeSequence(2), EncodeSequence(3)}, + }, + "2 to end": { + start: 2, + end: 5, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t2, t3}, + expRowIDs: []RowID{EncodeSequence(2), EncodeSequence(3)}, + }, + "start after end should fail": { + start: 2, + end: 1, + method: tb.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "start equals end should fail": { + start: 1, + end: 1, + method: tb.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse first element": { + start: 1, + end: 2, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "reverse first 2 elements": { + start: 1, + end: 3, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t2, t1}, + expRowIDs: []RowID{EncodeSequence(2), EncodeSequence(1)}, + }, + "reverse first 3 elements": { + start: 1, + end: 4, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2, t1}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2), EncodeSequence(1)}, + }, + "reverse search with max end": { + start: 1, + end: math.MaxUint64, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2, t1}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2), EncodeSequence(1)}, + }, + "reverse 2 to end": { + start: 2, + end: 5, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2)}, + }, + "reverse start after end should fail": { + start: 2, + end: 1, + method: tb.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse start equals end should fail": { + start: 1, + end: 1, + method: tb.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + it, err := spec.method(store, spec.start, spec.end) + require.True(t, spec.expError.Is(err), "expected #+v but got #+v", spec.expError, err) + if spec.expError != nil { + return + } + var loaded []testdata.TableModel + rowIDs, err := ReadAll(it, &loaded) + require.NoError(t, err) + assert.Equal(t, spec.expResult, loaded) + assert.Equal(t, spec.expRowIDs, rowIDs) + }) + } +} diff --git a/x/group/internal/orm/example_test.go b/x/group/internal/orm/example_test.go index a6bddf0b855b..d182efeb03c8 100644 --- a/x/group/internal/orm/example_test.go +++ b/x/group/internal/orm/example_test.go @@ -6,30 +6,61 @@ import ( ) type TestKeeper struct { - autoUInt64Table *AutoUInt64Table - primaryKeyTable *PrimaryKeyTable + autoUInt64Table *AutoUInt64Table + primaryKeyTable *PrimaryKeyTable + autoUInt64TableModelByMetadataIndex Index + primaryKeyTableModelByNameIndex Index + primaryKeyTableModelByNumberIndex Index + primaryKeyTableModelByMetadataIndex Index } var ( - AutoUInt64TableTablePrefix [2]byte = [2]byte{0x0} - PrimaryKeyTablePrefix [2]byte = [2]byte{0x1} - AutoUInt64TableSeqPrefix byte = 0x2 + AutoUInt64TablePrefix [2]byte = [2]byte{0x0} + PrimaryKeyTablePrefix [2]byte = [2]byte{0x1} + AutoUInt64TableSeqPrefix byte = 0x2 + AutoUInt64TableModelByMetadataPrefix byte = 0x4 + PrimaryKeyTableModelByNamePrefix byte = 0x5 + PrimaryKeyTableModelByNumberPrefix byte = 0x6 + PrimaryKeyTableModelByMetadataPrefix byte = 0x7 ) func NewTestKeeper(cdc codec.Codec) TestKeeper { k := TestKeeper{} + var err error - autoUInt64Table, err := NewAutoUInt64Table(AutoUInt64TableTablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + k.autoUInt64Table, err = NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + if err != nil { + panic(err.Error()) + } + k.autoUInt64TableModelByMetadataIndex, err = NewIndex(k.autoUInt64Table, AutoUInt64TableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) { + return []interface{}{val.(*testdata.TableModel).Metadata}, nil + }, testdata.TableModel{}.Metadata) if err != nil { panic(err.Error()) } - k.autoUInt64Table = autoUInt64Table - primaryKeyTable, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) + k.primaryKeyTable, err = NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) + if err != nil { + panic(err.Error()) + } + k.primaryKeyTableModelByNameIndex, err = NewIndex(k.primaryKeyTable, PrimaryKeyTableModelByNamePrefix, func(val interface{}) ([]interface{}, error) { + return []interface{}{val.(*testdata.TableModel).Name}, nil + }, testdata.TableModel{}.Name) + if err != nil { + panic(err.Error()) + } + k.primaryKeyTableModelByNumberIndex, err = NewIndex(k.primaryKeyTable, PrimaryKeyTableModelByNumberPrefix, func(val interface{}) ([]interface{}, error) { + return []interface{}{val.(*testdata.TableModel).Number}, nil + }, testdata.TableModel{}.Number) + if err != nil { + panic(err.Error()) + } + k.primaryKeyTableModelByMetadataIndex, err = NewIndex(k.primaryKeyTable, PrimaryKeyTableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) { + return []interface{}{val.(*testdata.TableModel).Metadata}, nil + }, testdata.TableModel{}.Metadata) if err != nil { panic(err.Error()) } - k.primaryKeyTable = primaryKeyTable return k } diff --git a/x/group/internal/orm/index.go b/x/group/internal/orm/index.go index 871d5e415fd9..55458fa03aee 100644 --- a/x/group/internal/orm/index.go +++ b/x/group/internal/orm/index.go @@ -1,5 +1,259 @@ package orm +import ( + "bytes" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/cosmos/cosmos-sdk/types/query" +) + +// indexer creates and modifies the second MultiKeyIndex based on the operations and changes on the primary object. +type indexer interface { + OnCreate(store sdk.KVStore, rowID RowID, value interface{}) error + OnDelete(store sdk.KVStore, rowID RowID, value interface{}) error + OnUpdate(store sdk.KVStore, rowID RowID, newValue, oldValue interface{}) error +} + +var _ Index = &MultiKeyIndex{} + +// MultiKeyIndex is an index where multiple entries can point to the same underlying object as opposite to a unique index +// where only one entry is allowed. +type MultiKeyIndex struct { + prefix byte + rowGetter RowGetter + indexer indexer + indexerFunc IndexerFunc + indexKey interface{} +} + +// NewIndex builds a MultiKeyIndex. +// Only single-field indexes are supported and `indexKey` represents such a field value, +// which can be []byte, string or uint64. +func NewIndex(tb Indexable, prefix byte, indexerF IndexerFunc, indexKey interface{}) (MultiKeyIndex, error) { + indexer, err := NewIndexer(indexerF) + if err != nil { + return MultiKeyIndex{}, err + } + return newIndex(tb, prefix, indexer, indexer.IndexerFunc(), indexKey) +} + +func newIndex(tb Indexable, prefix byte, indexer *Indexer, indexerF IndexerFunc, indexKey interface{}) (MultiKeyIndex, error) { + rowGetter := tb.RowGetter() + if rowGetter == nil { + return MultiKeyIndex{}, errors.ErrORMInvalidArgument.Wrap("rowGetter must not be nil") + } + if indexKey == nil { + return MultiKeyIndex{}, errors.ErrORMInvalidArgument.Wrap("indexKey must not be nil") + } + + // Verify indexKey type is bytes, string or uint64 + switch indexKey.(type) { + case []byte, string, uint64: + default: + return MultiKeyIndex{}, errors.ErrORMInvalidArgument.Wrap("indexKey must be []byte, string or uint64") + } + + idx := MultiKeyIndex{ + prefix: prefix, + rowGetter: rowGetter, + indexer: indexer, + indexerFunc: indexerF, + indexKey: indexKey, + } + tb.AddAfterSetInterceptor(idx.onSet) + tb.AddAfterDeleteInterceptor(idx.onDelete) + return idx, nil +} + +// Has checks if a key exists. Returns an error on nil key. +func (i MultiKeyIndex) Has(store sdk.KVStore, key interface{}) (bool, error) { + pStore := prefix.NewStore(store, []byte{i.prefix}) + encodedKey, err := keyPartBytes(key, false) + if err != nil { + return false, err + } + it := pStore.Iterator(PrefixRange(encodedKey)) + defer it.Close() + return it.Valid(), nil +} + +// Get returns a result iterator for the searchKey. Parameters must not be nil. +func (i MultiKeyIndex) Get(store sdk.KVStore, searchKey interface{}) (Iterator, error) { + pStore := prefix.NewStore(store, []byte{i.prefix}) + encodedKey, err := keyPartBytes(searchKey, false) + if err != nil { + return nil, err + } + it := pStore.Iterator(PrefixRange(encodedKey)) + return indexIterator{store: store, it: it, rowGetter: i.rowGetter, indexKey: i.indexKey}, nil +} + +// GetPaginated creates an iterator for the searchKey +// starting from pageRequest.Key if provided. +// The pageRequest.Key is the rowID while searchKey is a MultiKeyIndex key. +func (i MultiKeyIndex) GetPaginated(store sdk.KVStore, searchKey interface{}, pageRequest *query.PageRequest) (Iterator, error) { + pStore := prefix.NewStore(store, []byte{i.prefix}) + encodedKey, err := keyPartBytes(searchKey, false) + if err != nil { + return nil, err + } + start, end := PrefixRange(encodedKey) + + if pageRequest != nil && len(pageRequest.Key) != 0 { + var err error + start, err = buildKeyFromParts([]interface{}{searchKey, pageRequest.Key}) + if err != nil { + return nil, err + } + } + it := pStore.Iterator(start, end) + return indexIterator{store: store, it: it, rowGetter: i.rowGetter, indexKey: i.indexKey}, nil +} + +// PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. +// Example: +// it, err := idx.PrefixScan(ctx, start, end) +// if err !=nil { +// return err +// } +// const defaultLimit = 20 +// it = LimitIterator(it, defaultLimit) +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (i MultiKeyIndex) PrefixScan(store sdk.KVStore, startI interface{}, endI interface{}) (Iterator, error) { + start, err := getPrefixScanKeyBytes(startI) + if err != nil { + return nil, err + } + end, err := getPrefixScanKeyBytes(endI) + if err != nil { + return nil, err + } + + if start != nil && end != nil && bytes.Compare(start, end) >= 0 { + return NewInvalidIterator(), sdkerrors.Wrap(errors.ErrORMInvalidArgument, "start must be less than end") + } + pStore := prefix.NewStore(store, []byte{i.prefix}) + it := pStore.Iterator(start, end) + return indexIterator{store: store, it: it, rowGetter: i.rowGetter, indexKey: i.indexKey}, nil +} + +// ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. See `LimitIterator` +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (i MultiKeyIndex) ReversePrefixScan(store sdk.KVStore, startI interface{}, endI interface{}) (Iterator, error) { + start, err := getPrefixScanKeyBytes(startI) + if err != nil { + return nil, err + } + end, err := getPrefixScanKeyBytes(endI) + if err != nil { + return nil, err + } + + if start != nil && end != nil && bytes.Compare(start, end) >= 0 { + return NewInvalidIterator(), sdkerrors.Wrap(errors.ErrORMInvalidArgument, "start must be less than end") + } + pStore := prefix.NewStore(store, []byte{i.prefix}) + it := pStore.ReverseIterator(start, end) + return indexIterator{store: store, it: it, rowGetter: i.rowGetter, indexKey: i.indexKey}, nil +} + +func getPrefixScanKeyBytes(keyI interface{}) ([]byte, error) { + var ( + key []byte + err error + ) + // nil value are accepted in the context of PrefixScans + if keyI == nil { + return nil, nil + } + key, err = keyPartBytes(keyI, false) + if err != nil { + return nil, err + } + return key, nil +} + +func (i MultiKeyIndex) onSet(store sdk.KVStore, rowID RowID, newValue, oldValue codec.ProtoMarshaler) error { + pStore := prefix.NewStore(store, []byte{i.prefix}) + if oldValue == nil { + return i.indexer.OnCreate(pStore, rowID, newValue) + } + return i.indexer.OnUpdate(pStore, rowID, newValue, oldValue) +} + +func (i MultiKeyIndex) onDelete(store sdk.KVStore, rowID RowID, oldValue codec.ProtoMarshaler) error { + pStore := prefix.NewStore(store, []byte{i.prefix}) + return i.indexer.OnDelete(pStore, rowID, oldValue) +} + +type UniqueIndex struct { + MultiKeyIndex +} + +// NewUniqueIndex create a new Index object where duplicate keys are prohibited. +func NewUniqueIndex(tb Indexable, prefix byte, uniqueIndexerFunc UniqueIndexerFunc, indexKey interface{}) (UniqueIndex, error) { + uniqueIndexer, err := NewUniqueIndexer(uniqueIndexerFunc) + if err != nil { + return UniqueIndex{}, err + } + multiKeyIndex, err := newIndex(tb, prefix, uniqueIndexer, uniqueIndexer.IndexerFunc(), indexKey) + if err != nil { + return UniqueIndex{}, err + } + return UniqueIndex{ + MultiKeyIndex: multiKeyIndex, + }, nil +} + +// indexIterator uses rowGetter to lazy load new model values on request. +type indexIterator struct { + store sdk.KVStore + rowGetter RowGetter + it types.Iterator + indexKey interface{} +} + +// LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there +// are no more items the errors.ErrORMIteratorDone error is returned +// The key is the rowID and not any MultiKeyIndex key. +func (i indexIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { + if !i.it.Valid() { + return nil, errors.ErrORMIteratorDone + } + indexPrefixKey := i.it.Key() + rowID, err := stripRowID(indexPrefixKey, i.indexKey) + if err != nil { + return nil, err + } + i.it.Next() + return rowID, i.rowGetter(i.store, rowID, dest) +} + +// Close releases the iterator and should be called at the end of iteration +func (i indexIterator) Close() error { + i.it.Close() + return nil +} + // PrefixRange turns a prefix into a (start, end) range. The start is the given prefix value and // the end is calculated by adding 1 bit to the start value. Nil is not allowed as prefix. // Example: []byte{1, 3, 4} becomes []byte{1, 3, 5} diff --git a/x/group/internal/orm/index_test.go b/x/group/internal/orm/index_test.go index 01e43a221a21..521bb9d6c917 100644 --- a/x/group/internal/orm/index_test.go +++ b/x/group/internal/orm/index_test.go @@ -3,10 +3,405 @@ package orm import ( "testing" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var _ Indexable = &nilRowGetterBuilder{} + +type nilRowGetterBuilder struct{} + +func (b *nilRowGetterBuilder) RowGetter() RowGetter { + return nil +} +func (b *nilRowGetterBuilder) AddAfterSetInterceptor(AfterSetInterceptor) {} +func (b *nilRowGetterBuilder) AddAfterDeleteInterceptor(AfterDeleteInterceptor) {} + +func TestNewIndex(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + myTable, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + indexer := func(val interface{}) ([]interface{}, error) { + return []interface{}{val.(*testdata.TableModel).Metadata}, nil + } + + testCases := []struct { + name string + table Indexable + expectErr bool + expectedErr string + indexKey interface{} + }{ + { + name: "nil indexKey", + table: myTable, + expectErr: true, + expectedErr: "indexKey must not be nil", + indexKey: nil, + }, + { + name: "nil rowGetter", + table: &nilRowGetterBuilder{}, + expectErr: true, + expectedErr: "rowGetter must not be nil", + indexKey: []byte{}, + }, + { + name: "all not nil", + table: myTable, + expectErr: false, + indexKey: []byte{}, + }, + { + name: "index key type not allowed", + table: myTable, + expectErr: true, + indexKey: 1, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + index, err := NewIndex(tc.table, AutoUInt64TableSeqPrefix, indexer, tc.indexKey) + if tc.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + require.NotEmpty(t, index) + } + }) + } +} + +func TestIndexPrefixScan(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + idx, err := NewIndex(tb, AutoUInt64TableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) { + i := []interface{}{val.(*testdata.TableModel).Metadata} + return i, nil + }, testdata.TableModel{}.Metadata) + require.NoError(t, err) + strIdx, err := NewIndex(tb, 0x1, func(val interface{}) ([]interface{}, error) { + i := []interface{}{val.(*testdata.TableModel).Name} + return i, nil + }, testdata.TableModel{}.Name) + require.NoError(t, err) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + g1 := testdata.TableModel{ + Id: 1, + Name: "my test 1", + Metadata: []byte("metadata-a"), + } + g2 := testdata.TableModel{ + Id: 2, + Name: "my test 2", + Metadata: []byte("metadata-b"), + } + g3 := testdata.TableModel{ + Id: 3, + Name: "my test 3", + Metadata: []byte("metadata-b"), + } + for _, g := range []testdata.TableModel{g1, g2, g3} { + _, err := tb.Create(store, &g) + require.NoError(t, err) + } + + specs := map[string]struct { + start, end interface{} + expResult []testdata.TableModel + expRowIDs []RowID + expError *sdkerrors.Error + method func(store sdk.KVStore, start, end interface{}) (Iterator, error) + }{ + "exact match with a single result": { + start: []byte("metadata-a"), + end: []byte("metadata-b"), + method: idx.PrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "one result by prefix": { + start: []byte("metadata"), + end: []byte("metadata-b"), + method: idx.PrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "multi key elements by exact match": { + start: []byte("metadata-b"), + end: []byte("metadata-c"), + method: idx.PrefixScan, + expResult: []testdata.TableModel{g2, g3}, + expRowIDs: []RowID{EncodeSequence(2), EncodeSequence(3)}, + }, + "open end query": { + start: []byte("metadata-b"), + end: nil, + method: idx.PrefixScan, + expResult: []testdata.TableModel{g2, g3}, + expRowIDs: []RowID{EncodeSequence(2), EncodeSequence(3)}, + }, + "open start query": { + start: nil, + end: []byte("metadata-b"), + method: idx.PrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "open start and end query": { + start: nil, + end: nil, + method: idx.PrefixScan, + expResult: []testdata.TableModel{g1, g2, g3}, + expRowIDs: []RowID{EncodeSequence(1), EncodeSequence(2), EncodeSequence(3)}, + }, + "all matching prefix": { + start: []byte("admin"), + end: nil, + method: idx.PrefixScan, + expResult: []testdata.TableModel{g1, g2, g3}, + expRowIDs: []RowID{EncodeSequence(1), EncodeSequence(2), EncodeSequence(3)}, + }, + "non matching prefix": { + start: []byte("metadata-c"), + end: nil, + method: idx.PrefixScan, + expResult: []testdata.TableModel{}, + }, + "start equals end": { + start: []byte("any"), + end: []byte("any"), + method: idx.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "start after end": { + start: []byte("b"), + end: []byte("a"), + method: idx.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse: exact match with a single result": { + start: []byte("metadata-a"), + end: []byte("metadata-b"), + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "reverse: one result by prefix": { + start: []byte("metadata"), + end: []byte("metadata-b"), + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "reverse: multi key elements by exact match": { + start: []byte("metadata-b"), + end: []byte("metadata-c"), + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g3, g2}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2)}, + }, + "reverse: open end query": { + start: []byte("metadata-b"), + end: nil, + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g3, g2}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2)}, + }, + "reverse: open start query": { + start: nil, + end: []byte("metadata-b"), + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + "reverse: open start and end query": { + start: nil, + end: nil, + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g3, g2, g1}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2), EncodeSequence(1)}, + }, + "reverse: all matching prefix": { + start: []byte("admin"), + end: nil, + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{g3, g2, g1}, + expRowIDs: []RowID{EncodeSequence(3), EncodeSequence(2), EncodeSequence(1)}, + }, + "reverse: non matching prefix": { + start: []byte("metadata-c"), + end: nil, + method: idx.ReversePrefixScan, + expResult: []testdata.TableModel{}, + }, + "reverse: start equals end": { + start: []byte("any"), + end: []byte("any"), + method: idx.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse: start after end": { + start: []byte("b"), + end: []byte("a"), + method: idx.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "exact match with a single result using string based index": { + start: "my test 1", + end: "my test 2", + method: strIdx.PrefixScan, + expResult: []testdata.TableModel{g1}, + expRowIDs: []RowID{EncodeSequence(1)}, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + it, err := spec.method(store, spec.start, spec.end) + require.True(t, spec.expError.Is(err), "expected #+v but got #+v", spec.expError, err) + if spec.expError != nil { + return + } + var loaded []testdata.TableModel + rowIDs, err := ReadAll(it, &loaded) + require.NoError(t, err) + assert.Equal(t, spec.expResult, loaded) + assert.Equal(t, spec.expRowIDs, rowIDs) + }) + } +} + +func TestUniqueIndex(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + myTable, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + uniqueIdx, err := NewUniqueIndex(myTable, 0x10, func(val interface{}) (interface{}, error) { + return []byte{val.(*testdata.TableModel).Metadata[0]}, nil + }, []byte{}) + require.NoError(t, err) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + m := testdata.TableModel{ + Id: 1, + Name: "my test", + Metadata: []byte("metadata"), + } + err = myTable.Create(store, &m) + require.NoError(t, err) + + indexedKey := []byte{'m'} + + // Has + exists, err := uniqueIdx.Has(store, indexedKey) + require.NoError(t, err) + assert.True(t, exists) + + // Get + it, err := uniqueIdx.Get(store, indexedKey) + require.NoError(t, err) + var loaded testdata.TableModel + rowID, err := it.LoadNext(&loaded) + require.NoError(t, err) + require.Equal(t, RowID(PrimaryKey(&m)), rowID) + require.Equal(t, m, loaded) + + // GetPaginated + cases := map[string]struct { + pageReq *query.PageRequest + expErr bool + }{ + "nil key": { + pageReq: &query.PageRequest{Key: nil}, + expErr: false, + }, + "after indexed key": { + pageReq: &query.PageRequest{Key: indexedKey}, + expErr: true, + }, + } + + for testName, tc := range cases { + t.Run(testName, func(t *testing.T) { + it, err := uniqueIdx.GetPaginated(store, indexedKey, tc.pageReq) + require.NoError(t, err) + rowID, err := it.LoadNext(&loaded) + if tc.expErr { // iterator done + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, RowID(PrimaryKey(&m)), rowID) + require.Equal(t, m, loaded) + } + }) + } + + // PrefixScan match + it, err = uniqueIdx.PrefixScan(store, indexedKey, nil) + require.NoError(t, err) + rowID, err = it.LoadNext(&loaded) + require.NoError(t, err) + require.Equal(t, RowID(PrimaryKey(&m)), rowID) + require.Equal(t, m, loaded) + + // PrefixScan no match + it, err = uniqueIdx.PrefixScan(store, []byte{byte('n')}, nil) + require.NoError(t, err) + _, err = it.LoadNext(&loaded) + require.Error(t, errors.ErrORMIteratorDone, err) + + // ReversePrefixScan match + it, err = uniqueIdx.ReversePrefixScan(store, indexedKey, nil) + require.NoError(t, err) + rowID, err = it.LoadNext(&loaded) + require.NoError(t, err) + require.Equal(t, RowID(PrimaryKey(&m)), rowID) + require.Equal(t, m, loaded) + + // ReversePrefixScan no match + it, err = uniqueIdx.ReversePrefixScan(store, []byte{byte('l')}, nil) + require.NoError(t, err) + _, err = it.LoadNext(&loaded) + require.Error(t, errors.ErrORMIteratorDone, err) + // create with same index key should fail + new := testdata.TableModel{ + Id: 1, + Name: "my test", + Metadata: []byte("my-metadata"), + } + err = myTable.Create(store, &new) + require.Error(t, errors.ErrORMUniqueConstraint, err) + + // and when delete + err = myTable.Delete(store, &m) + require.NoError(t, err) + + // then no persistent element + exists, err = uniqueIdx.Has(store, indexedKey) + require.NoError(t, err) + assert.False(t, exists) +} + func TestPrefixRange(t *testing.T) { cases := map[string]struct { src []byte diff --git a/x/group/internal/orm/indexer.go b/x/group/internal/orm/indexer.go new file mode 100644 index 000000000000..67b3f13d2cc1 --- /dev/null +++ b/x/group/internal/orm/indexer.go @@ -0,0 +1,211 @@ +package orm + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" +) + +// IndexerFunc creates one or multiple index keys for the source object. +type IndexerFunc func(value interface{}) ([]interface{}, error) + +// IndexerFunc creates exactly one index key for the source object. +type UniqueIndexerFunc func(value interface{}) (interface{}, error) + +// Indexer manages the persistence of an Index based on searchable keys and operations. +type Indexer struct { + indexerFunc IndexerFunc + addFunc func(store sdk.KVStore, secondaryIndexKey interface{}, rowID RowID) error +} + +// NewIndexer returns an indexer that supports multiple reference keys for an entity. +func NewIndexer(indexerFunc IndexerFunc) (*Indexer, error) { + if indexerFunc == nil { + return nil, errors.ErrORMInvalidArgument.Wrap("Indexer func must not be nil") + } + return &Indexer{ + indexerFunc: pruneEmptyKeys(indexerFunc), + addFunc: multiKeyAddFunc, + }, nil +} + +// NewUniqueIndexer returns an indexer that requires exactly one reference keys for an entity. +func NewUniqueIndexer(f UniqueIndexerFunc) (*Indexer, error) { + if f == nil { + return nil, errors.ErrORMInvalidArgument.Wrap("Indexer func must not be nil") + } + adaptor := func(indexerFunc UniqueIndexerFunc) IndexerFunc { + return func(v interface{}) ([]interface{}, error) { + k, err := indexerFunc(v) + return []interface{}{k}, err + } + } + idx, err := NewIndexer(adaptor(f)) + if err != nil { + return nil, err + } + idx.addFunc = uniqueKeysAddFunc + return idx, nil +} + +// IndexerFunc returns the indexer IndexerFunc, +// ensuring it has been prune from empty keys. +func (i Indexer) IndexerFunc() IndexerFunc { + return i.indexerFunc +} + +// OnCreate persists the secondary index entries for the new object. +func (i Indexer) OnCreate(store sdk.KVStore, rowID RowID, value interface{}) error { + secondaryIndexKeys, err := i.indexerFunc(value) + if err != nil { + return err + } + + for _, secondaryIndexKey := range secondaryIndexKeys { + if err := i.addFunc(store, secondaryIndexKey, []byte(rowID)); err != nil { + return err + } + } + return nil +} + +// OnDelete removes the secondary index entries for the deleted object. +func (i Indexer) OnDelete(store sdk.KVStore, rowID RowID, value interface{}) error { + secondaryIndexKeys, err := i.indexerFunc(value) + if err != nil { + return err + } + + for _, secondaryIndexKey := range secondaryIndexKeys { + indexKey, err := buildKeyFromParts([]interface{}{secondaryIndexKey, []byte(rowID)}) + if err != nil { + return err + } + store.Delete(indexKey) + } + return nil +} + +// OnUpdate rebuilds the secondary index entries for the updated object. +func (i Indexer) OnUpdate(store sdk.KVStore, rowID RowID, newValue, oldValue interface{}) error { + oldSecIdxKeys, err := i.indexerFunc(oldValue) + if err != nil { + return err + } + newSecIdxKeys, err := i.indexerFunc(newValue) + if err != nil { + return err + } + oldKeys, err := difference(oldSecIdxKeys, newSecIdxKeys) + if err != nil { + return err + } + for _, oldIdxKey := range oldKeys { + indexKey, err := buildKeyFromParts([]interface{}{oldIdxKey, []byte(rowID)}) + if err != nil { + return err + } + store.Delete(indexKey) + } + newKeys, err := difference(newSecIdxKeys, oldSecIdxKeys) + if err != nil { + return err + } + for _, newIdxKey := range newKeys { + if err := i.addFunc(store, newIdxKey, rowID); err != nil { + return err + } + } + return nil +} + +// uniqueKeysAddFunc enforces keys to be unique +func uniqueKeysAddFunc(store sdk.KVStore, secondaryIndexKey interface{}, rowID RowID) error { + secondaryIndexKeyBytes, err := keyPartBytes(secondaryIndexKey, false) + if err != nil { + return err + } + if len(secondaryIndexKeyBytes) == 0 { + return sdkerrors.Wrap(errors.ErrORMInvalidArgument, "empty index key") + } + + it := store.Iterator(PrefixRange(secondaryIndexKeyBytes)) + defer it.Close() + if it.Valid() { + return errors.ErrORMUniqueConstraint + } + + indexKey, err := buildKeyFromParts([]interface{}{secondaryIndexKey, []byte(rowID)}) + if err != nil { + return err + } + + store.Set(indexKey, []byte{}) + return nil +} + +// multiKeyAddFunc allows multiple entries for a key +func multiKeyAddFunc(store sdk.KVStore, secondaryIndexKey interface{}, rowID RowID) error { + secondaryIndexKeyBytes, err := keyPartBytes(secondaryIndexKey, false) + if err != nil { + return err + } + if len(secondaryIndexKeyBytes) == 0 { + return sdkerrors.Wrap(errors.ErrORMInvalidArgument, "empty index key") + } + + encodedKey, err := buildKeyFromParts([]interface{}{secondaryIndexKey, []byte(rowID)}) + if err != nil { + return err + } + if len(encodedKey) == 0 { + return sdkerrors.Wrap(errors.ErrORMInvalidArgument, "empty index key") + } + + store.Set(encodedKey, []byte{}) + return nil +} + +// difference returns the list of elements that are in a but not in b. +func difference(a []interface{}, b []interface{}) ([]interface{}, error) { + set := make(map[interface{}]struct{}, len(b)) + for _, v := range b { + bt, err := keyPartBytes(v, true) + if err != nil { + return nil, err + } + set[string(bt)] = struct{}{} + } + var result []interface{} + for _, v := range a { + bt, err := keyPartBytes(v, true) + if err != nil { + return nil, err + } + if _, ok := set[string(bt)]; !ok { + result = append(result, v) + } + } + return result, nil +} + +// pruneEmptyKeys drops any empty key from IndexerFunc f returned +func pruneEmptyKeys(f IndexerFunc) IndexerFunc { + return func(v interface{}) ([]interface{}, error) { + keys, err := f(v) + if err != nil || keys == nil { + return keys, err + } + r := make([]interface{}, 0, len(keys)) + for i := range keys { + key, err := keyPartBytes(keys[i], true) + if err != nil { + return nil, err + } + if len(key) != 0 { + r = append(r, keys[i]) + } + } + return r, nil + } +} diff --git a/x/group/internal/orm/indexer_test.go b/x/group/internal/orm/indexer_test.go new file mode 100644 index 000000000000..d574fb63fd04 --- /dev/null +++ b/x/group/internal/orm/indexer_test.go @@ -0,0 +1,570 @@ +package orm + +import ( + stdErrors "errors" + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewIndexer(t *testing.T) { + testCases := []struct { + name string + indexerFunc IndexerFunc + expectErr bool + expectedErr string + }{ + { + name: "nil indexer func", + indexerFunc: nil, + expectErr: true, + expectedErr: "Indexer func must not be nil", + }, + { + name: "all not nil", + indexerFunc: func(interface{}) ([]interface{}, error) { return nil, nil }, + expectErr: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + indexer, err := NewIndexer(tc.indexerFunc) + if tc.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + require.NotNil(t, indexer) + } + }) + } +} + +func TestNewUniqueIndexer(t *testing.T) { + testCases := []struct { + name string + indexerFunc UniqueIndexerFunc + expectErr bool + expectedErr string + }{ + { + name: "nil indexer func", + indexerFunc: nil, + expectErr: true, + expectedErr: "Indexer func must not be nil", + }, + { + name: "all not nil", + indexerFunc: func(interface{}) (interface{}, error) { return nil, nil }, + expectErr: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + indexer, err := NewUniqueIndexer(tc.indexerFunc) + if tc.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + require.NotNil(t, indexer) + } + }) + } +} + +func TestIndexerOnCreate(t *testing.T) { + var myRowID RowID = EncodeSequence(1) + + specs := map[string]struct { + srcFunc IndexerFunc + expIndexKeys []interface{} + expRowIDs []RowID + expAddFuncCalled bool + expErr error + }{ + "single key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1)}, nil + }, + expAddFuncCalled: true, + expIndexKeys: []interface{}{uint64(1)}, + expRowIDs: []RowID{myRowID}, + }, + "multi key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1), uint64(128)}, nil + }, + expAddFuncCalled: true, + expIndexKeys: []interface{}{uint64(1), uint64(128)}, + expRowIDs: []RowID{myRowID, myRowID}, + }, + "empty key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{[]byte{}}, nil + }, + expAddFuncCalled: false, + }, + "nil key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{nil}, nil + }, + expErr: fmt.Errorf("type %T not allowed as key part", nil), + expAddFuncCalled: false, + }, + "empty key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{}, nil + }, + expAddFuncCalled: false, + }, + "nil key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, nil + }, + expAddFuncCalled: false, + }, + "error case": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, stdErrors.New("test") + }, + expErr: stdErrors.New("test"), + expAddFuncCalled: false, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + mockPolicy := &addFuncRecorder{} + idx, err := NewIndexer(spec.srcFunc) + require.NoError(t, err) + idx.addFunc = mockPolicy.add + + err = idx.OnCreate(nil, myRowID, nil) + if spec.expErr != nil { + require.Equal(t, spec.expErr, err) + return + } + require.NoError(t, err) + assert.Equal(t, spec.expIndexKeys, mockPolicy.secondaryIndexKeys) + assert.Equal(t, spec.expRowIDs, mockPolicy.rowIDs) + assert.Equal(t, spec.expAddFuncCalled, mockPolicy.called) + }) + } +} + +func TestIndexerOnDelete(t *testing.T) { + myRowID := EncodeSequence(1) + + var multiKeyIndex MultiKeyIndex + ctx := NewMockContext() + storeKey := sdk.NewKVStoreKey("test") + store := prefix.NewStore(ctx.KVStore(storeKey), []byte{multiKeyIndex.prefix}) + + specs := map[string]struct { + srcFunc IndexerFunc + expDeletedKeys []RowID + expErr error + }{ + "single key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1)}, nil + }, + expDeletedKeys: []RowID{append(EncodeSequence(1), myRowID...)}, + }, + "multi key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1), uint64(128)}, nil + }, + expDeletedKeys: []RowID{ + append(EncodeSequence(1), myRowID...), + append(EncodeSequence(128), myRowID...), + }, + }, + "empty key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{}, nil + }, + }, + "nil key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, nil + }, + }, + "empty key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{[]byte{}}, nil + }, + }, + "nil key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{nil}, nil + }, + expErr: fmt.Errorf("type %T not allowed as key part", nil), + }, + "error case": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, stdErrors.New("test") + }, + expErr: stdErrors.New("test"), + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + idx, err := NewIndexer(spec.srcFunc) + require.NoError(t, err) + + if spec.expErr == nil { + err = idx.OnCreate(store, myRowID, nil) + require.NoError(t, err) + for _, key := range spec.expDeletedKeys { + require.Equal(t, true, store.Has(key)) + } + } + + err = idx.OnDelete(store, myRowID, nil) + if spec.expErr != nil { + require.Equal(t, spec.expErr, err) + return + } + require.NoError(t, err) + for _, key := range spec.expDeletedKeys { + require.Equal(t, false, store.Has(key)) + } + }) + } +} +func TestIndexerOnUpdate(t *testing.T) { + myRowID := EncodeSequence(1) + + var multiKeyIndex MultiKeyIndex + ctx := NewMockContext() + storeKey := sdk.NewKVStoreKey("test") + store := prefix.NewStore(ctx.KVStore(storeKey), []byte{multiKeyIndex.prefix}) + + specs := map[string]struct { + srcFunc IndexerFunc + expAddedKeys []RowID + expDeletedKeys []RowID + expErr error + addFunc func(sdk.KVStore, interface{}, RowID) error + }{ + "single key - same key, no update": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1)}, nil + }, + }, + "single key - different key, replaced": { + srcFunc: func(value interface{}) ([]interface{}, error) { + keys := []uint64{1, 2} + return []interface{}{keys[value.(int)]}, nil + }, + expAddedKeys: []RowID{ + append(EncodeSequence(2), myRowID...), + }, + expDeletedKeys: []RowID{ + append(EncodeSequence(1), myRowID...), + }, + }, + "multi key - same key, no update": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{uint64(1), uint64(2)}, nil + }, + }, + "multi key - replaced": { + srcFunc: func(value interface{}) ([]interface{}, error) { + keys := []uint64{1, 2, 3, 4} + return []interface{}{keys[value.(int)], keys[value.(int)+2]}, nil + }, + expAddedKeys: []RowID{ + append(EncodeSequence(2), myRowID...), + append(EncodeSequence(4), myRowID...), + }, + expDeletedKeys: []RowID{ + append(EncodeSequence(1), myRowID...), + append(EncodeSequence(3), myRowID...), + }, + }, + "empty key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{}, nil + }, + }, + "nil key": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, nil + }, + }, + "empty key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{[]byte{}}, nil + }, + }, + "nil key in slice": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return []interface{}{nil}, nil + }, + expErr: fmt.Errorf("type %T not allowed as key part", nil), + }, + "error case with new value": { + srcFunc: func(value interface{}) ([]interface{}, error) { + return nil, stdErrors.New("test") + }, + expErr: stdErrors.New("test"), + }, + "error case with old value": { + srcFunc: func(value interface{}) ([]interface{}, error) { + var err error + if value.(int)%2 == 1 { + err = stdErrors.New("test") + } + return []interface{}{uint64(1)}, err + }, + expErr: stdErrors.New("test"), + }, + "error case on persisting new keys": { + srcFunc: func(value interface{}) ([]interface{}, error) { + keys := []uint64{1, 2} + return []interface{}{keys[value.(int)]}, nil + }, + addFunc: func(_ sdk.KVStore, _ interface{}, _ RowID) error { + return stdErrors.New("test") + }, + expErr: stdErrors.New("test"), + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + idx, err := NewIndexer(spec.srcFunc) + require.NoError(t, err) + + if spec.expErr == nil { + err = idx.OnCreate(store, myRowID, 0) + require.NoError(t, err) + } + + if spec.addFunc != nil { + idx.addFunc = spec.addFunc + } + err = idx.OnUpdate(store, myRowID, 1, 0) + if spec.expErr != nil { + require.Equal(t, spec.expErr, err) + return + } + require.NoError(t, err) + for _, key := range spec.expAddedKeys { + require.Equal(t, true, store.Has(key)) + } + for _, key := range spec.expDeletedKeys { + require.Equal(t, false, store.Has(key)) + } + }) + } +} + +func TestUniqueKeyAddFunc(t *testing.T) { + myRowID := EncodeSequence(1) + presetKeyPart := []byte("my-preset-key") + presetKey := append(AddLengthPrefix(presetKeyPart), myRowID...) + + specs := map[string]struct { + srcKey []byte + expErr *sdkerrors.Error + expExistingEntry []byte + }{ + + "create when not exists": { + srcKey: []byte("my-index-key"), + expExistingEntry: append(AddLengthPrefix([]byte("my-index-key")), myRowID...), + }, + "error when exists already": { + srcKey: presetKeyPart, + expErr: errors.ErrORMUniqueConstraint, + }, + "nil key not allowed": { + srcKey: nil, + expErr: errors.ErrORMInvalidArgument, + }, + "empty key not allowed": { + srcKey: []byte{}, + expErr: errors.ErrORMInvalidArgument, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + storeKey := sdk.NewKVStoreKey("test") + store := NewMockContext().KVStore(storeKey) + store.Set(presetKey, []byte{}) + + err := uniqueKeysAddFunc(store, spec.srcKey, myRowID) + require.True(t, spec.expErr.Is(err)) + if spec.expErr != nil { + return + } + assert.True(t, store.Has(spec.expExistingEntry), "not found") + }) + } +} + +func TestMultiKeyAddFunc(t *testing.T) { + myRowID := EncodeSequence(1) + presetKeyPart := []byte("my-preset-key") + presetKey := append(AddLengthPrefix(presetKeyPart), myRowID...) + + specs := map[string]struct { + srcKey []byte + expErr *sdkerrors.Error + expExistingEntry []byte + }{ + + "create when not exists": { + srcKey: []byte("my-index-key"), + expExistingEntry: append(AddLengthPrefix([]byte("my-index-key")), myRowID...), + }, + "noop when exists already": { + srcKey: presetKeyPart, + expExistingEntry: presetKey, + }, + "nil key not allowed": { + srcKey: nil, + expErr: errors.ErrORMInvalidArgument, + }, + "empty key not allowed": { + srcKey: []byte{}, + expErr: errors.ErrORMInvalidArgument, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + storeKey := sdk.NewKVStoreKey("test") + store := NewMockContext().KVStore(storeKey) + store.Set(presetKey, []byte{}) + + err := multiKeyAddFunc(store, spec.srcKey, myRowID) + require.True(t, spec.expErr.Is(err)) + if spec.expErr != nil { + return + } + assert.True(t, store.Has(spec.expExistingEntry)) + }) + } +} + +func TestDifference(t *testing.T) { + specs := map[string]struct { + srcA []interface{} + srcB []interface{} + expResult []interface{} + expErr bool + }{ + "all of A": { + srcA: []interface{}{"a", "b"}, + srcB: []interface{}{"c"}, + expResult: []interface{}{"a", "b"}, + }, + "A - B": { + srcA: []interface{}{"a", "b"}, + srcB: []interface{}{"b", "c", "d"}, + expResult: []interface{}{"a"}, + }, + "type in A not allowed": { + srcA: []interface{}{1}, + srcB: []interface{}{"b", "c", "d"}, + expErr: true, + }, + "type in B not allowed": { + srcA: []interface{}{"b", "c", "d"}, + srcB: []interface{}{1}, + expErr: true, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + got, err := difference(spec.srcA, spec.srcB) + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, spec.expResult, got) + } + }) + } +} + +func TestPruneEmptyKeys(t *testing.T) { + specs := map[string]struct { + srcFunc IndexerFunc + expResult []interface{} + expError error + }{ + "non empty": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return []interface{}{uint64(0), uint64(1)}, nil + }, + expResult: []interface{}{uint64(0), uint64(1)}, + }, + "empty": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return []interface{}{}, nil + }, + expResult: []interface{}{}, + }, + "nil": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return nil, nil + }, + }, + "empty in the beginning": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return []interface{}{[]byte{}, uint64(0), uint64(1)}, nil + }, + expResult: []interface{}{uint64(0), uint64(1)}, + }, + "empty in the middle": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return []interface{}{uint64(0), []byte{}, uint64(1)}, nil + }, + expResult: []interface{}{uint64(0), uint64(1)}, + }, + "empty at the end": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return []interface{}{uint64(0), uint64(1), []byte{}}, nil + }, + expResult: []interface{}{uint64(0), uint64(1)}, + }, + "error passed": { + srcFunc: func(v interface{}) ([]interface{}, error) { + return nil, stdErrors.New("test") + }, + expError: stdErrors.New("test"), + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + r, err := pruneEmptyKeys(spec.srcFunc)(nil) + require.Equal(t, spec.expError, err) + if spec.expError != nil { + return + } + assert.Equal(t, spec.expResult, r) + }) + } +} + +type addFuncRecorder struct { + secondaryIndexKeys []interface{} + rowIDs []RowID + called bool +} + +func (c *addFuncRecorder) add(_ sdk.KVStore, key interface{}, rowID RowID) error { + c.secondaryIndexKeys = append(c.secondaryIndexKeys, key) + c.rowIDs = append(c.rowIDs, rowID) + c.called = true + return nil +} diff --git a/x/group/internal/orm/iterator.go b/x/group/internal/orm/iterator.go new file mode 100644 index 000000000000..ae61d61c48e4 --- /dev/null +++ b/x/group/internal/orm/iterator.go @@ -0,0 +1,308 @@ +package orm + +import ( + "fmt" + "reflect" + + "github.com/cosmos/cosmos-sdk/codec" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/group/errors" +) + +// defaultPageLimit is the default limit value for pagination requests. +const defaultPageLimit = 100 + +// IteratorFunc is a function type that satisfies the Iterator interface +// The passed function is called on LoadNext operations. +type IteratorFunc func(dest codec.ProtoMarshaler) (RowID, error) + +// LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there +// are no more items the errors.ErrORMIteratorDone error is returned +// The key is the rowID and not any MultiKeyIndex key. +func (i IteratorFunc) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { + return i(dest) +} + +// Close always returns nil +func (i IteratorFunc) Close() error { + return nil +} + +func NewSingleValueIterator(rowID RowID, val []byte) Iterator { + var closed bool + return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + if dest == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil") + } + if closed || val == nil { + return nil, errors.ErrORMIteratorDone + } + closed = true + return rowID, dest.Unmarshal(val) + }) +} + +// Iterator that return ErrORMInvalidIterator only. +func NewInvalidIterator() Iterator { + return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return nil, errors.ErrORMInvalidIterator + }) +} + +// LimitedIterator returns up to defined maximum number of elements. +type LimitedIterator struct { + remainingCount int + parentIterator Iterator +} + +// LimitIterator returns a new iterator that returns max number of elements. +// The parent iterator must not be nil +// max can be 0 or any positive number +func LimitIterator(parent Iterator, max int) (*LimitedIterator, error) { + if max < 0 { + return nil, errors.ErrORMInvalidArgument.Wrap("quantity must not be negative") + } + if parent == nil { + return nil, errors.ErrORMInvalidArgument.Wrap("parent iterator must not be nil") + } + return &LimitedIterator{remainingCount: max, parentIterator: parent}, nil +} + +// LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there +// are no more items or the defined max number of elements was returned the `errors.ErrORMIteratorDone` error is returned +// The key is the rowID and not any MultiKeyIndex key. +func (i *LimitedIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { + if i.remainingCount == 0 { + return nil, errors.ErrORMIteratorDone + } + i.remainingCount-- + return i.parentIterator.LoadNext(dest) +} + +// Close releases the iterator and should be called at the end of iteration +func (i LimitedIterator) Close() error { + return i.parentIterator.Close() +} + +// First loads the first element into the given destination type and closes the iterator. +// When the iterator is closed or has no elements the according error is passed as return value. +func First(it Iterator, dest codec.ProtoMarshaler) (RowID, error) { + if it == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "iterator must not be nil") + } + defer it.Close() + binKey, err := it.LoadNext(dest) + if err != nil { + return nil, err + } + return binKey, nil +} + +// Paginate does pagination with a given Iterator based on the provided +// PageRequest and unmarshals the results into the dest interface that must be +// an non-nil pointer to a slice. +// +// If pageRequest is nil, then we will use these default values: +// - Offset: 0 +// - Key: nil +// - Limit: 100 +// - CountTotal: true +// +// If pageRequest.Key was provided, it got used beforehand to instantiate the Iterator, +// using for instance UInt64Index.GetPaginated method. Only one of pageRequest.Offset or +// pageRequest.Key should be set. Using pageRequest.Key is more efficient for querying +// the next page. +// +// If pageRequest.CountTotal is set, we'll visit all iterators elements. +// pageRequest.CountTotal is only respected when offset is used. +// +// This function will call it.Close(). +func Paginate( + it Iterator, + pageRequest *query.PageRequest, + dest ModelSlicePtr, +) (*query.PageResponse, error) { + // if the PageRequest is nil, use default PageRequest + if pageRequest == nil { + pageRequest = &query.PageRequest{} + } + + offset := pageRequest.Offset + key := pageRequest.Key + limit := pageRequest.Limit + countTotal := pageRequest.CountTotal + + if offset > 0 && key != nil { + return nil, fmt.Errorf("invalid request, either offset or key is expected, got both") + } + + if limit == 0 { + limit = defaultPageLimit + + // count total results when the limit is zero/not supplied + countTotal = true + } + + if it == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "iterator must not be nil") + } + defer it.Close() + + var destRef, tmpSlice reflect.Value + elemType, err := assertDest(dest, &destRef, &tmpSlice) + if err != nil { + return nil, err + } + + var end = offset + limit + var count uint64 + var nextKey []byte + for { + obj := reflect.New(elemType) + val := obj.Elem() + model := obj + if elemType.Kind() == reflect.Ptr { + val.Set(reflect.New(elemType.Elem())) + // if elemType is already a pointer (e.g. dest being some pointer to a slice of pointers, + // like []*GroupMember), then obj is a pointer to a pointer which might cause issues + // if we try to do obj.Interface().(codec.ProtoMarshaler). + // For that reason, we copy obj into model if we have a simple pointer + // but in case elemType.Kind() == reflect.Ptr, we overwrite it with model = val + // so we can safely call model.Interface().(codec.ProtoMarshaler) afterwards. + model = val + } + + modelProto, ok := model.Interface().(codec.ProtoMarshaler) + if !ok { + return nil, sdkerrors.Wrapf(errors.ErrORMInvalidArgument, "%s should implement codec.ProtoMarshaler", elemType) + } + binKey, err := it.LoadNext(modelProto) + if err != nil { + if errors.ErrORMIteratorDone.Is(err) { + break + } + return nil, err + } + + count++ + + // During the first loop, count value at this point will be 1, + // so if offset is >= 1, it will continue to load the next value until count > offset + // else (offset = 0, key might be set or not), + // it will start to append values to tmpSlice. + if count <= offset { + continue + } + + if count <= end { + tmpSlice = reflect.Append(tmpSlice, val) + } else if count == end+1 { + nextKey = binKey + + // countTotal is set to true to indicate that the result set should include + // a count of the total number of items available for pagination in UIs. + // countTotal is only respected when offset is used. It is ignored when key + // is set. + if !countTotal || len(key) != 0 { + break + } + } + } + destRef.Set(tmpSlice) + + res := &query.PageResponse{NextKey: nextKey} + if countTotal && len(key) == 0 { + res.Total = count + } + + return res, nil +} + +// ModelSlicePtr represents a pointer to a slice of models. Think of it as +// *[]Model Because of Go's type system, using []Model type would not work for us. +// Instead we use a placeholder type and the validation is done during the +// runtime. +type ModelSlicePtr interface{} + +// ReadAll consumes all values for the iterator and stores them in a new slice at the passed ModelSlicePtr. +// The slice can be empty when the iterator does not return any values but not nil. The iterator +// is closed afterwards. +// Example: +// var loaded []testdata.GroupInfo +// rowIDs, err := ReadAll(it, &loaded) +// require.NoError(t, err) +// +func ReadAll(it Iterator, dest ModelSlicePtr) ([]RowID, error) { + if it == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "iterator must not be nil") + } + defer it.Close() + + var destRef, tmpSlice reflect.Value + elemType, err := assertDest(dest, &destRef, &tmpSlice) + if err != nil { + return nil, err + } + + var rowIDs []RowID + for { + obj := reflect.New(elemType) + val := obj.Elem() + model := obj + if elemType.Kind() == reflect.Ptr { + val.Set(reflect.New(elemType.Elem())) + model = val + } + + binKey, err := it.LoadNext(model.Interface().(codec.ProtoMarshaler)) + switch { + case err == nil: + tmpSlice = reflect.Append(tmpSlice, val) + case errors.ErrORMIteratorDone.Is(err): + destRef.Set(tmpSlice) + return rowIDs, nil + default: + return nil, err + } + rowIDs = append(rowIDs, binKey) + } +} + +// assertDest checks that the provided dest is not nil and a pointer to a slice. +// It also verifies that the slice elements implement *codec.ProtoMarshaler. +// It overwrites destRef and tmpSlice using reflection. +func assertDest(dest ModelSlicePtr, destRef *reflect.Value, tmpSlice *reflect.Value) (reflect.Type, error) { + if dest == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination must not be nil") + } + tp := reflect.ValueOf(dest) + if tp.Kind() != reflect.Ptr { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination must be a pointer to a slice") + } + if tp.Elem().Kind() != reflect.Slice { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination must point to a slice") + } + + // Since dest is just an interface{}, we overwrite destRef using reflection + // to have an assignable copy of it. + *destRef = tp.Elem() + // We need to verify that we can call Set() on destRef. + if !destRef.CanSet() { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination not assignable") + } + + elemType := reflect.TypeOf(dest).Elem().Elem() + + protoMarshaler := reflect.TypeOf((*codec.ProtoMarshaler)(nil)).Elem() + if !elemType.Implements(protoMarshaler) && + !reflect.PtrTo(elemType).Implements(protoMarshaler) { + return nil, sdkerrors.Wrapf(errors.ErrORMInvalidArgument, "unsupported type :%s", elemType) + } + + // tmpSlice is a slice value for the specified type + // that we'll use for appending new elements. + *tmpSlice = reflect.MakeSlice(reflect.SliceOf(elemType), 0, 0) + + return elemType, nil +} diff --git a/x/group/internal/orm/iterator_property_test.go b/x/group/internal/orm/iterator_property_test.go new file mode 100644 index 000000000000..1f30fcb2278a --- /dev/null +++ b/x/group/internal/orm/iterator_property_test.go @@ -0,0 +1,121 @@ +package orm + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/require" + "pgregory.net/rapid" +) + +func TestPaginationProperty(t *testing.T) { + t.Run("TestPagination", rapid.MakeCheck(func(t *rapid.T) { + // Create a slice of group members + tableModels := rapid.SliceOf(genTableModel).Draw(t, "tableModels").([]*testdata.TableModel) + + // Choose a random limit for paging + upperLimit := uint64(len(tableModels)) + if upperLimit == 0 { + upperLimit = 1 + } + limit := rapid.Uint64Range(1, upperLimit).Draw(t, "limit").(uint64) + + // Reconstruct the slice from offset pages + reconstructedTableModels := make([]*testdata.TableModel, 0, len(tableModels)) + for offset := uint64(0); offset < uint64(len(tableModels)); offset += limit { + pageRequest := &query.PageRequest{ + Key: nil, + Offset: offset, + Limit: limit, + CountTotal: false, + Reverse: false, + } + end := offset + limit + if end > uint64(len(tableModels)) { + end = uint64(len(tableModels)) + } + dest := reconstructedTableModels[offset:end] + tableModelsIt := testTableModelIterator(tableModels, nil) + Paginate(tableModelsIt, pageRequest, &dest) + reconstructedTableModels = append(reconstructedTableModels, dest...) + } + + // Should be the same slice + require.Equal(t, len(tableModels), len(reconstructedTableModels)) + for i, gm := range tableModels { + require.Equal(t, *gm, *reconstructedTableModels[i]) + } + + // Reconstruct the slice from keyed pages + reconstructedTableModels = make([]*testdata.TableModel, 0, len(tableModels)) + var start uint64 = 0 + key := EncodeSequence(0) + for key != nil { + pageRequest := &query.PageRequest{ + Key: key, + Offset: 0, + Limit: limit, + CountTotal: false, + Reverse: false, + } + + end := start + limit + if end > uint64(len(tableModels)) { + end = uint64(len(tableModels)) + } + + dest := reconstructedTableModels[start:end] + tableModelsIt := testTableModelIterator(tableModels, key) + + resp, err := Paginate(tableModelsIt, pageRequest, &dest) + require.NoError(t, err) + key = resp.NextKey + + reconstructedTableModels = append(reconstructedTableModels, dest...) + + start += limit + } + + // Should be the same slice + require.Equal(t, len(tableModels), len(reconstructedTableModels)) + for i, gm := range tableModels { + require.Equal(t, *gm, *reconstructedTableModels[i]) + } + })) +} + +func testTableModelIterator(tms []*testdata.TableModel, key RowID) Iterator { + var closed bool + var index int + if key != nil { + index = int(DecodeSequence(key)) + } + return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + if dest == nil { + return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil") + } + + if index == len(tms) { + closed = true + } + + if closed { + return nil, errors.ErrORMIteratorDone + } + + rowID := EncodeSequence(uint64(index)) + + bytes, err := tms[index].Marshal() + if err != nil { + return nil, err + } + + index++ + + return rowID, dest.Unmarshal(bytes) + }) +} diff --git a/x/group/internal/orm/iterator_test.go b/x/group/internal/orm/iterator_test.go new file mode 100644 index 000000000000..b2abbaaa403c --- /dev/null +++ b/x/group/internal/orm/iterator_test.go @@ -0,0 +1,358 @@ +package orm + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestReadAll(t *testing.T) { + specs := map[string]struct { + srcIT Iterator + destSlice func() ModelSlicePtr + expErr *sdkerrors.Error + expIDs []RowID + expResult ModelSlicePtr + }{ + "all good with object slice": { + srcIT: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + destSlice: func() ModelSlicePtr { + x := make([]testdata.TableModel, 1) + return &x + }, + expIDs: []RowID{EncodeSequence(1)}, + expResult: &[]testdata.TableModel{{Name: "test"}}, + }, + "all good with pointer slice": { + srcIT: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + destSlice: func() ModelSlicePtr { + x := make([]*testdata.TableModel, 1) + return &x + }, + expIDs: []RowID{EncodeSequence(1)}, + expResult: &[]*testdata.TableModel{{Name: "test"}}, + }, + "dest slice empty": { + srcIT: mockIter(EncodeSequence(1), &testdata.TableModel{}), + destSlice: func() ModelSlicePtr { + x := make([]testdata.TableModel, 0) + return &x + }, + expIDs: []RowID{EncodeSequence(1)}, + expResult: &[]testdata.TableModel{{}}, + }, + "dest pointer with nil value": { + srcIT: mockIter(EncodeSequence(1), &testdata.TableModel{}), + destSlice: func() ModelSlicePtr { + return (*[]testdata.TableModel)(nil) + }, + expErr: errors.ErrORMInvalidArgument, + }, + "iterator is nil": { + srcIT: nil, + destSlice: func() ModelSlicePtr { return new([]testdata.TableModel) }, + expErr: errors.ErrORMInvalidArgument, + }, + "dest slice is nil": { + srcIT: noopIter(), + destSlice: func() ModelSlicePtr { return nil }, + expErr: errors.ErrORMInvalidArgument, + }, + "dest slice is not a pointer": { + srcIT: IteratorFunc(nil), + destSlice: func() ModelSlicePtr { return make([]testdata.TableModel, 1) }, + expErr: errors.ErrORMInvalidArgument, + }, + "error on loadNext is returned": { + srcIT: NewInvalidIterator(), + destSlice: func() ModelSlicePtr { + x := make([]testdata.TableModel, 1) + return &x + }, + expErr: errors.ErrORMInvalidIterator, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + loaded := spec.destSlice() + ids, err := ReadAll(spec.srcIT, loaded) + require.True(t, spec.expErr.Is(err), "expected %s but got %s", spec.expErr, err) + assert.Equal(t, spec.expIDs, ids) + if err == nil { + assert.Equal(t, spec.expResult, loaded) + } + }) + } +} + +func TestLimitedIterator(t *testing.T) { + specs := map[string]struct { + parent Iterator + max int + expectErr bool + expectedErr string + exp []testdata.TableModel + }{ + "nil parent": { + parent: nil, + max: 0, + expectErr: true, + expectedErr: "parent iterator must not be nil", + }, + "negative max": { + parent: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + max: -1, + expectErr: true, + expectedErr: "quantity must not be negative", + }, + "all from range with max > length": { + parent: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + max: 2, + exp: []testdata.TableModel{{Name: "test"}}, + }, + "up to max": { + parent: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + max: 1, + exp: []testdata.TableModel{{Name: "test"}}, + }, + "none when max = 0": { + parent: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + max: 0, + exp: []testdata.TableModel{}, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + src, err := LimitIterator(spec.parent, spec.max) + if spec.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), spec.expectedErr) + } else { + require.NoError(t, err) + var loaded []testdata.TableModel + _, err := ReadAll(src, &loaded) + require.NoError(t, err) + assert.EqualValues(t, spec.exp, loaded) + } + }) + } +} + +func TestFirst(t *testing.T) { + testCases := []struct { + name string + iterator Iterator + dest codec.ProtoMarshaler + expectErr bool + expectedErr string + expectedRowID RowID + expectedDest codec.ProtoMarshaler + }{ + { + name: "nil iterator", + iterator: nil, + dest: &testdata.TableModel{}, + expectErr: true, + expectedErr: "iterator must not be nil", + }, + { + name: "nil dest", + iterator: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + dest: nil, + expectErr: true, + expectedErr: "destination object must not be nil", + }, + { + name: "all not nil", + iterator: mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + dest: &testdata.TableModel{}, + expectErr: false, + expectedRowID: EncodeSequence(1), + expectedDest: &testdata.TableModel{Name: "test"}, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rowID, err := First(tc.iterator, tc.dest) + if tc.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + require.Equal(t, tc.expectedRowID, rowID) + require.Equal(t, tc.expectedDest, tc.dest) + } + }) + } +} + +func TestPaginate(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + idx, err := NewIndex(tb, AutoUInt64TableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) { + return []interface{}{[]byte(val.(*testdata.TableModel).Metadata)}, nil + }, testdata.TableModel{}.Metadata) + require.NoError(t, err) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + metadata := []byte("metadata") + t1 := testdata.TableModel{ + Id: 1, + Name: "my test 1", + Metadata: metadata, + } + t2 := testdata.TableModel{ + Id: 2, + Name: "my test 2", + Metadata: metadata, + } + t3 := testdata.TableModel{ + Id: 3, + Name: "my test 3", + Metadata: []byte("other-metadata"), + } + t4 := testdata.TableModel{ + Id: 4, + Name: "my test 4", + Metadata: metadata, + } + t5 := testdata.TableModel{ + Id: 5, + Name: "my test 5", + Metadata: []byte("other-metadata"), + } + + for _, g := range []testdata.TableModel{t1, t2, t3, t4, t5} { + _, err := tb.Create(store, &g) + require.NoError(t, err) + } + + specs := map[string]struct { + pageReq *query.PageRequest + expPageRes *query.PageResponse + exp []testdata.TableModel + key []byte + expErr bool + }{ + "one item": { + pageReq: &query.PageRequest{Key: nil, Limit: 1}, + exp: []testdata.TableModel{t1}, + expPageRes: &query.PageResponse{Total: 0, NextKey: EncodeSequence(2)}, + key: metadata, + }, + "with both key and offset": { + pageReq: &query.PageRequest{Key: EncodeSequence(2), Offset: 1}, + expErr: true, + key: metadata, + }, + "up to max": { + pageReq: &query.PageRequest{Key: nil, Limit: 3, CountTotal: true}, + exp: []testdata.TableModel{t1, t2, t4}, + expPageRes: &query.PageResponse{Total: 3, NextKey: nil}, + key: metadata, + }, + "no results": { + pageReq: &query.PageRequest{Key: nil, Limit: 2, CountTotal: true}, + exp: []testdata.TableModel{}, + expPageRes: &query.PageResponse{Total: 0, NextKey: nil}, + key: sdk.AccAddress([]byte("no-group-address")), + }, + "with offset and count total": { + pageReq: &query.PageRequest{Key: nil, Offset: 1, Limit: 2, CountTotal: true}, + exp: []testdata.TableModel{t2, t4}, + expPageRes: &query.PageResponse{Total: 3, NextKey: nil}, + key: metadata, + }, + "nil/default page req (limit = 100 > number of items)": { + pageReq: nil, + exp: []testdata.TableModel{t1, t2, t4}, + expPageRes: &query.PageResponse{Total: 3, NextKey: nil}, + key: metadata, + }, + "with key and limit < number of elem (count total is ignored in this case)": { + pageReq: &query.PageRequest{Key: EncodeSequence(2), Limit: 1, CountTotal: true}, + exp: []testdata.TableModel{t2}, + expPageRes: &query.PageResponse{Total: 0, NextKey: EncodeSequence(4)}, + key: metadata, + }, + "with key and limit >= number of elem": { + pageReq: &query.PageRequest{Key: EncodeSequence(2), Limit: 2}, + exp: []testdata.TableModel{t2, t4}, + expPageRes: &query.PageResponse{Total: 0, NextKey: nil}, + key: metadata, + }, + "with nothing left to iterate from key": { + pageReq: &query.PageRequest{Key: EncodeSequence(5)}, + exp: []testdata.TableModel{}, + expPageRes: &query.PageResponse{Total: 0, NextKey: nil}, + key: metadata, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + var loaded []testdata.TableModel + + it, err := idx.GetPaginated(store, spec.key, spec.pageReq) + require.NoError(t, err) + + res, err := Paginate(it, spec.pageReq, &loaded) + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.EqualValues(t, spec.exp, loaded) + assert.EqualValues(t, spec.expPageRes.Total, res.Total) + assert.EqualValues(t, spec.expPageRes.NextKey, res.NextKey) + } + + }) + } + + t.Run("nil iterator", func(t *testing.T) { + var loaded []testdata.TableModel + res, err := Paginate(nil, &query.PageRequest{}, &loaded) + require.Error(t, err) + require.Contains(t, err.Error(), "iterator must not be nil") + require.Nil(t, res) + }) + + t.Run("non-slice destination", func(t *testing.T) { + var loaded testdata.TableModel + res, err := Paginate( + mockIter(EncodeSequence(1), &testdata.TableModel{Name: "test"}), + &query.PageRequest{}, + &loaded, + ) + require.Error(t, err) + require.Contains(t, err.Error(), "destination must point to a slice") + require.Nil(t, res) + }) +} + +// mockIter encodes + decodes value object. +func mockIter(rowID RowID, val codec.ProtoMarshaler) Iterator { + b, err := val.Marshal() + if err != nil { + panic(err) + } + return NewSingleValueIterator(rowID, b) +} + +func noopIter() Iterator { + return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return nil, nil + }) +} diff --git a/x/group/internal/orm/key_codec.go b/x/group/internal/orm/key_codec.go index 099ed1571cf1..074b67b3ebc4 100644 --- a/x/group/internal/orm/key_codec.go +++ b/x/group/internal/orm/key_codec.go @@ -3,7 +3,8 @@ package orm import ( "fmt" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" ) // MaxBytesLen is the maximum allowed length for a key part of type []byte @@ -58,7 +59,7 @@ func keyPartBytes(part interface{}, last bool) ([]byte, error) { func AddLengthPrefix(bytes []byte) []byte { byteLen := len(bytes) if byteLen > MaxBytesLen { - panic(errors.Wrap(errors.ErrORMKeyMaxLength, "Cannot create key part with an []byte of length greater than 255 bytes. Try again with a smaller []byte.")) + panic(sdkerrors.Wrap(errors.ErrORMKeyMaxLength, "Cannot create key part with an []byte of length greater than 255 bytes. Try again with a smaller []byte.")) } prefixedBytes := make([]byte, 1+len(bytes)) @@ -73,3 +74,27 @@ func NullTerminatedBytes(s string) []byte { copy(bytes, s) return bytes } + +// stripRowID returns the RowID from the indexKey based on secondaryIndexKey type. +// It is the reverse operation to buildKeyFromParts for index keys +// where the first part is the encoded secondaryIndexKey and the second part is the RowID. +func stripRowID(indexKey []byte, secondaryIndexKey interface{}) (RowID, error) { + switch v := secondaryIndexKey.(type) { + case []byte: + searchableKeyLen := indexKey[0] + return indexKey[1+searchableKeyLen:], nil + case string: + searchableKeyLen := 0 + for i, b := range indexKey { + if b == 0 { + searchableKeyLen = i + break + } + } + return indexKey[1+searchableKeyLen:], nil + case uint64: + return indexKey[EncodedSeqLength:], nil + default: + return nil, fmt.Errorf("type %T not allowed as index key", v) + } +} diff --git a/x/group/internal/orm/orm_scenario_test.go b/x/group/internal/orm/orm_scenario_test.go index ad934349ff82..1f17e66095d1 100644 --- a/x/group/internal/orm/orm_scenario_test.go +++ b/x/group/internal/orm/orm_scenario_test.go @@ -8,7 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/testutil/testdata" @@ -45,8 +46,22 @@ func TestKeeperEndToEndWithAutoUInt64Table(t *testing.T) { require.Equal(t, rowID, binary.BigEndian.Uint64(binKey)) require.Equal(t, tm, loaded) + // and exists in MultiKeyIndex + exists, err = k.autoUInt64TableModelByMetadataIndex.Has(store, []byte("metadata")) + require.NoError(t, err) + require.True(t, exists) + + // and when loaded + it, err := k.autoUInt64TableModelByMetadataIndex.Get(store, []byte("metadata")) + require.NoError(t, err) + + // then + binKey, loaded = first(t, it) + assert.Equal(t, rowID, binary.BigEndian.Uint64(binKey)) + assert.Equal(t, tm, loaded) + // when updated - tm.Name = "new name" + tm.Metadata = []byte("new-metadata") err = k.autoUInt64Table.Update(store, rowID, &tm) require.NoError(t, err) @@ -56,12 +71,26 @@ func TestKeeperEndToEndWithAutoUInt64Table(t *testing.T) { require.Equal(t, rowID, binary.BigEndian.Uint64(binKey)) require.Equal(t, tm, loaded) + // then indexes are updated, too + exists, err = k.autoUInt64TableModelByMetadataIndex.Has(store, []byte("new-metadata")) + require.NoError(t, err) + require.True(t, exists) + + exists, err = k.autoUInt64TableModelByMetadataIndex.Has(store, []byte("metadata")) + require.NoError(t, err) + require.False(t, exists) + // when deleted err = k.autoUInt64Table.Delete(store, rowID) require.NoError(t, err) exists = k.autoUInt64Table.Has(store, rowID) require.False(t, exists) + + // and also removed from secondary MultiKeyIndex + exists, err = k.autoUInt64TableModelByMetadataIndex.Has(store, []byte("new-metadata")) + require.NoError(t, err) + require.False(t, exists) } func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) { @@ -95,6 +124,20 @@ func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) { // then values should match expectations require.Equal(t, tm, loaded) + // and then the data should exists in MultiKeyIndex + exists, err = k.primaryKeyTableModelByNumberIndex.Has(store, tm.Number) + require.NoError(t, err) + require.True(t, exists) + + // and when loaded from MultiKeyIndex + it, err := k.primaryKeyTableModelByNumberIndex.Get(store, tm.Number) + require.NoError(t, err) + + // then values should match as before + _, err = First(it, &loaded) + require.NoError(t, err) + assert.Equal(t, tm, loaded) + // and when we create another entry with the same primary key err = k.primaryKeyTable.Create(store, &tm) // then it should fail as the primary key must be unique @@ -126,8 +169,14 @@ func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) { err = k.primaryKeyTable.Delete(store, &tm) require.NoError(t, err) + // it is removed from primaryKeyTable exists = k.primaryKeyTable.Has(store, primaryKey) require.False(t, exists) + + // and removed from secondary MultiKeyIndex + exists, err = k.primaryKeyTableModelByNumberIndex.Has(store, tm.Number) + require.NoError(t, err) + require.False(t, exists) } func TestGasCostsPrimaryKeyTable(t *testing.T) { @@ -161,6 +210,16 @@ func TestGasCostsPrimaryKeyTable(t *testing.T) { require.NoError(t, err) t.Logf("gas consumed on get by primary key: %d", gCtx.GasConsumed()) + // get by secondary index + gCtx.ResetGasMeter() + // and when loaded from MultiKeyIndex + it, err := k.primaryKeyTableModelByNumberIndex.Get(gCtx.KVStore(store), tm.Number) + require.NoError(t, err) + var loadedSlice []testdata.TableModel + _, err = ReadAll(it, &loadedSlice) + require.NoError(t, err) + t.Logf("gas consumed on get by multi index key: %d", gCtx.GasConsumed()) + // delete gCtx.ResetGasMeter() err = k.primaryKeyTable.Delete(gCtx.KVStore(store), &tm) @@ -196,6 +255,16 @@ func TestGasCostsPrimaryKeyTable(t *testing.T) { t.Logf("%d: gas consumed on get by primary key: %d", i, gCtx.GasConsumed()) } + // get by secondary index + gCtx.ResetGasMeter() + // and when loaded from MultiKeyIndex + it, err = k.primaryKeyTableModelByNumberIndex.Get(gCtx.KVStore(store), tm.Number) + require.NoError(t, err) + _, err = ReadAll(it, &loadedSlice) + require.NoError(t, err) + require.Len(t, loadedSlice, 3) + t.Logf("gas consumed on get by multi index key: %d", gCtx.GasConsumed()) + // delete for i, m := range tms { gCtx.ResetGasMeter() @@ -205,3 +274,10 @@ func TestGasCostsPrimaryKeyTable(t *testing.T) { t.Logf("%d: gas consumed on delete: %d", i, gCtx.GasConsumed()) } } + +func first(t *testing.T, it Iterator) ([]byte, testdata.TableModel) { + var loaded testdata.TableModel + key, err := First(it, &loaded) + require.NoError(t, err) + return key, loaded +} diff --git a/x/group/internal/orm/primary_key.go b/x/group/internal/orm/primary_key.go index 8bfeae402dea..f347cd0d14ee 100644 --- a/x/group/internal/orm/primary_key.go +++ b/x/group/internal/orm/primary_key.go @@ -111,3 +111,36 @@ func (a PrimaryKeyTable) Contains(store sdk.KVStore, obj PrimaryKeyed) bool { func (a PrimaryKeyTable) GetOne(store sdk.KVStore, primKey RowID, dest codec.ProtoMarshaler) error { return a.table.GetOne(store, primKey, dest) } + +// PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. +// Example: +// it, err := idx.PrefixScan(ctx, start, end) +// if err !=nil { +// return err +// } +// const defaultLimit = 20 +// it = LimitIterator(it, defaultLimit) +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a PrimaryKeyTable) PrefixScan(store sdk.KVStore, start, end []byte) (Iterator, error) { + return a.table.PrefixScan(store, start, end) +} + +// ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. See `LimitIterator` +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a PrimaryKeyTable) ReversePrefixScan(store sdk.KVStore, start, end []byte) (Iterator, error) { + return a.table.ReversePrefixScan(store, start, end) +} diff --git a/x/group/internal/orm/primary_key_test.go b/x/group/internal/orm/primary_key_test.go index 6338fd5ce5b8..498e973c0c98 100644 --- a/x/group/internal/orm/primary_key_test.go +++ b/x/group/internal/orm/primary_key_test.go @@ -6,12 +6,202 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/testutil/testdata" ) +func TestPrimaryKeyTablePrefixScan(t *testing.T) { + interfaceRegistry := types.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(interfaceRegistry) + + tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) + require.NoError(t, err) + + ctx := NewMockContext() + store := ctx.KVStore(sdk.NewKVStoreKey("test")) + + metadata := []byte("metadata") + t1 := testdata.TableModel{ + Id: 1, + Name: "my test 1", + Metadata: metadata, + } + t2 := testdata.TableModel{ + Id: 2, + Name: "my test 2", + Metadata: metadata, + } + t3 := testdata.TableModel{ + Id: 3, + Name: "my test 3", + Metadata: metadata, + } + for _, g := range []testdata.TableModel{t1, t2, t3} { + require.NoError(t, tb.Create(store, &g)) + } + + specs := map[string]struct { + start, end []byte + expResult []testdata.TableModel + expRowIDs []RowID + expError *sdkerrors.Error + method func(store sdk.KVStore, start, end []byte) (Iterator, error) + }{ + "exact match with a single result": { + start: EncodeSequence(1), // == PrimaryKey(&t1) + end: EncodeSequence(2), // == PrimaryKey(&t2) + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{PrimaryKey(&t1)}, + }, + "one result by 1st byte": { + start: []byte{0}, + end: EncodeSequence(2), // == PrimaryKey(&t2) + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{PrimaryKey(&t1)}, + }, + "open end query": { + start: EncodeSequence(3), + end: nil, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t3}, + expRowIDs: []RowID{PrimaryKey(&t3)}, + }, + "open end query with all": { + start: EncodeSequence(1), + end: nil, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2, t3}, + expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)}, + }, + "open start query": { + start: nil, + end: EncodeSequence(3), + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2}, + expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2)}, + }, + "open start and end query": { + start: nil, + end: nil, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2, t3}, + expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)}, + }, + "all matching 1st byte": { + start: []byte{0}, + end: nil, + method: tb.PrefixScan, + expResult: []testdata.TableModel{t1, t2, t3}, + expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)}, + }, + "non matching 1st byte": { + start: []byte{1}, + end: nil, + method: tb.PrefixScan, + expResult: []testdata.TableModel{}, + }, + "start equals end": { + start: EncodeSequence(1), + end: EncodeSequence(1), + method: tb.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "start after end": { + start: EncodeSequence(2), + end: EncodeSequence(1), + method: tb.PrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse: exact match with a single result": { + start: EncodeSequence(1), // == PrimaryKey(&t1) + end: EncodeSequence(2), // == PrimaryKey(&t2) + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{PrimaryKey(&t1)}, + }, + "reverse: one result by 1st byte": { + start: []byte{0}, + end: EncodeSequence(2), // == PrimaryKey(&t2) + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t1}, + expRowIDs: []RowID{PrimaryKey(&t1)}, + }, + "reverse: open end query": { + start: EncodeSequence(3), + end: nil, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3}, + expRowIDs: []RowID{PrimaryKey(&t3)}, + }, + "reverse: open end query with all": { + start: EncodeSequence(1), + end: nil, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2, t1}, + expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)}, + }, + "reverse: open start query": { + start: nil, + end: EncodeSequence(3), + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t2, t1}, + expRowIDs: []RowID{PrimaryKey(&t2), PrimaryKey(&t1)}, + }, + "reverse: open start and end query": { + start: nil, + end: nil, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2, t1}, + expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)}, + }, + "reverse: all matching 1st byte": { + start: []byte{0}, + end: nil, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{t3, t2, t1}, + expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)}, + }, + "reverse: non matching prefix": { + start: []byte{1}, + end: nil, + method: tb.ReversePrefixScan, + expResult: []testdata.TableModel{}, + }, + "reverse: start equals end": { + start: EncodeSequence(1), + end: EncodeSequence(1), + method: tb.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + "reverse: start after end": { + start: EncodeSequence(2), + end: EncodeSequence(1), + method: tb.ReversePrefixScan, + expError: errors.ErrORMInvalidArgument, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + it, err := spec.method(store, spec.start, spec.end) + require.True(t, spec.expError.Is(err), "expected #+v but got #+v", spec.expError, err) + if spec.expError != nil { + return + } + var loaded []testdata.TableModel + rowIDs, err := ReadAll(it, &loaded) + require.NoError(t, err) + assert.Equal(t, spec.expResult, loaded) + assert.Equal(t, spec.expRowIDs, rowIDs) + }) + } +} + func TestContains(t *testing.T) { interfaceRegistry := types.NewInterfaceRegistry() cdc := codec.NewProtoCodec(interfaceRegistry) @@ -19,7 +209,7 @@ func TestContains(t *testing.T) { ctx := NewMockContext() store := ctx.KVStore(sdk.NewKVStoreKey("test")) - tb, err := NewPrimaryKeyTable([2]byte{0x1}, &testdata.TableModel{}, cdc) + tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc) require.NoError(t, err) obj := testdata.TableModel{ diff --git a/x/group/internal/orm/sequence.go b/x/group/internal/orm/sequence.go index a8d70f7243ac..5e7e986ae167 100644 --- a/x/group/internal/orm/sequence.go +++ b/x/group/internal/orm/sequence.go @@ -5,7 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" ) // sequenceStorageKey is a fix key to read/ write data on the storage layer @@ -55,7 +56,7 @@ func (s Sequence) PeekNextVal(store sdk.KVStore) uint64 { func (s Sequence) InitVal(store sdk.KVStore, seq uint64) error { pStore := prefix.NewStore(store, []byte{s.prefix}) if pStore.Has(sequenceStorageKey) { - return errors.Wrap(errors.ErrORMUniqueConstraint, "already initialized") + return sdkerrors.Wrap(errors.ErrORMUniqueConstraint, "already initialized") } pStore.Set(sequenceStorageKey, EncodeSequence(seq)) return nil diff --git a/x/group/internal/orm/sequence_test.go b/x/group/internal/orm/sequence_test.go index 023f7318dae2..a1a3ddef20ca 100644 --- a/x/group/internal/orm/sequence_test.go +++ b/x/group/internal/orm/sequence_test.go @@ -4,7 +4,7 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/x/group/internal/orm/spec/01_table.md b/x/group/internal/orm/spec/01_table.md index 7b159b482dc1..1c769cbcdd37 100644 --- a/x/group/internal/orm/spec/01_table.md +++ b/x/group/internal/orm/spec/01_table.md @@ -32,9 +32,11 @@ The model provided for creating a `PrimaryKeyTable` should implement the `Primar +++ https://github.com/cosmos/cosmos-sdk/blob/9f78f16ae75cc42fc5fe636bde18a453ba74831f/x/group/internal/orm/primary_key.go#L28-L41 `PrimaryKeyFields()` method returns the list of key parts for a given object. -The primary key parts can be []byte, string, and `uint64` types. - Key parts, except the last part, follow these rules: +The primary key parts can be []byte, string, and `uint64` types. -- []byte is encoded with a single byte length prefix -- strings are null-terminated -- `uint64` are encoded using 8 byte big endian. +### Key codec + +Key parts, except the last part, follow these rules: + - []byte is encoded with a single byte length prefix + - strings are null-terminated + - `uint64` are encoded using 8 byte big endian. diff --git a/x/group/internal/orm/spec/02_secondary_index.md b/x/group/internal/orm/spec/02_secondary_index.md new file mode 100644 index 000000000000..e104999a9d16 --- /dev/null +++ b/x/group/internal/orm/spec/02_secondary_index.md @@ -0,0 +1,24 @@ +# Secondary Index + +Secondary indexes can be used on `Indexable` [tables](01_table.md). Indeed, those tables implement the `Indexable` interface that provides a set of functions that can be called by indexes to register and interact with the tables, like callback functions that are called on entries creation, update or deletion to create, update or remove corresponding entries in the table secondary indexes. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/types.go#L88-L92 + +## MultiKeyIndex + +A `MultiKeyIndex` is an index where multiple entries can point to the same underlying object. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/index.go#L25-L31 + +Internally, it uses an `Indexer` that manages the persistence of the index based on searchable keys and create/update/delete operations. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/index.go#L15-L19 + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/indexer.go#L15-L18 + +The currently used implementation of an `indexer`, `Indexer`, relies on an `IndexerFunc` that should be provided when instantiating the index. Based on the source object, this function returns one or multiple index keys as `[]interface{}`. Such secondary index keys should be bytes, string or `uint64` in order to be handled properly by the [key codec](01_table.md#key-codec) which defines specific encoding for those types. +In the index prefix store, the keys are built based on the source object's `RowID` and its secondary index key(s) using the key codec and the values are set as empty bytes. + +## UniqueIndex + +As opposed to `MultiKeyIndex`, `UniqueIndex` is an index where duplicate keys are prohibited. \ No newline at end of file diff --git a/x/group/internal/orm/spec/03_iterator_pagination.md b/x/group/internal/orm/spec/03_iterator_pagination.md new file mode 100644 index 000000000000..ac0839623321 --- /dev/null +++ b/x/group/internal/orm/spec/03_iterator_pagination.md @@ -0,0 +1,28 @@ +# Iterator and Pagination + +Both [tables](01_table.md) and [secondary indexes](02_secondary_index.md) support iterating over a domain of keys, through `PrefixScan` or `ReversePrefixScan`, as well pagination. + +## Iterator + +An `Iterator` allows iteration through a sequence of key value pairs. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/types.go#L77-L83 + +Tables rely on a `typeSafeIterator` that is used by `PrefixScan` and `ReversePrefixScan` `table` methods to iterate through a range of `RowID`s. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/table.go#235-L239 + +Secondary indexes rely on an `indexIterator` that can strip the `RowID` from the full index key in order to get the underlying value in the table prefix store. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/index.go#L227-L232 + +Under the hood, both use a prefix store `Iterator` (alias for tm-db `Iterator`). + +## Pagination + +The `Paginate` function does pagination given an [`Iterator`](#iterator) and a `query.PageRequest`, and returns a `query.PageResponse`. +It unmarshals the results into the provided dest interface that should be a pointer to a slice of models. + ++++ https://github.com/cosmos/cosmos-sdk/blob/430163ed4eefcc0d67b706411ffc0b7c5414cd90/x/group/internal/orm/iterator.go#L117-L216 + +Secondary indexes have a `GetPaginated` method that returns an `Iterator` for the given searched secondary index key, starting from the `query.PageRequest` key if provided. It's important to note that this `query.PageRequest` key should be a `RowID` (that could have been returned by a previous paginated request). The returned `Iterator` can then be used with the `Paginate` function and the same `query.PageRequest`. diff --git a/x/group/internal/orm/spec/README.md b/x/group/internal/orm/spec/README.md index c8eccb01f596..5c77f712e94e 100644 --- a/x/group/internal/orm/spec/README.md +++ b/x/group/internal/orm/spec/README.md @@ -7,3 +7,10 @@ The orm package provides a framework for creating relational database tables wit 1. **[Table](01_table.md)** - [AutoUInt64Table](01_table.md#autouint64table) - [PrimaryKeyTable](01_table.md#primarykeytable) +2. **[Secondary Index](02_secondary_index.md)** + - [MultiKeyIndex](02_secondary_index.md#multikeyindex) + - [UniqueIndex](02_secondary_index.md#uniqueindex) +3. **[Iterator and Pagination](03_iterator_pagination.md)** + - [Iterator](03_iterator_pagination.md#iterator) + - [Pagination](03_iterator_pagination.md#pagination) + diff --git a/x/group/internal/orm/table.go b/x/group/internal/orm/table.go index f3611850045e..468077709d3e 100644 --- a/x/group/internal/orm/table.go +++ b/x/group/internal/orm/table.go @@ -1,12 +1,15 @@ package orm import ( + "bytes" "reflect" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" ) var _ Indexable = &table{} @@ -32,7 +35,7 @@ type table struct { // newTable creates a new table func newTable(prefix [2]byte, model codec.ProtoMarshaler, cdc codec.Codec) (*table, error) { if model == nil { - return nil, errors.ErrORMEmptyModel.Wrap("Model must not be nil") + return nil, errors.ErrORMInvalidArgument.Wrap("Model must not be nil") } tp := reflect.TypeOf(model) if tp.Kind() == reflect.Ptr { @@ -74,14 +77,14 @@ func (a table) Create(store sdk.KVStore, rowID RowID, obj codec.ProtoMarshaler) } // Update updates the given object under the rowID key. It expects the key to -// exists already and fails with an `errors.ErrNotFound` otherwise. Any caller must +// exists already and fails with an `sdkerrors.ErrNotFound` otherwise. Any caller must // therefore make sure that this contract is fulfilled. Parameters must not be // nil. // // Update triggers all "after set" hooks that may add or remove secondary index keys. func (a table) Update(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler) error { if !a.Has(store, rowID) { - return errors.ErrNotFound + return sdkerrors.ErrNotFound } return a.Set(store, rowID, newValue) @@ -113,13 +116,13 @@ func (a table) Set(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler newValueEncoded, err := a.cdc.Marshal(newValue) if err != nil { - return errors.Wrapf(err, "failed to serialize %T", newValue) + return sdkerrors.Wrapf(err, "failed to serialize %T", newValue) } pStore.Set(rowID, newValueEncoded) for i, itc := range a.afterSet { if err := itc(store, rowID, newValue, oldValue); err != nil { - return errors.Wrapf(err, "interceptor %d failed", i) + return sdkerrors.Wrapf(err, "interceptor %d failed", i) } } return nil @@ -135,7 +138,7 @@ func assertValid(obj codec.ProtoMarshaler) error { } // Delete removes the object under the rowID key. It expects the key to exists -// already and fails with a `errors.ErrNotFound` otherwise. Any caller must therefore +// already and fails with a `sdkerrors.ErrNotFound` otherwise. Any caller must therefore // make sure that this contract is fulfilled. // // Delete iterates through the registered callbacks that remove secondary index @@ -145,13 +148,13 @@ func (a table) Delete(store sdk.KVStore, rowID RowID) error { var oldValue = reflect.New(a.model).Interface().(codec.ProtoMarshaler) if err := a.GetOne(store, rowID, oldValue); err != nil { - return errors.Wrap(err, "load old value") + return sdkerrors.Wrap(err, "load old value") } pStore.Delete(rowID) for i, itc := range a.afterDelete { if err := itc(store, rowID, oldValue); err != nil { - return errors.Wrapf(err, "delete interceptor %d failed", i) + return sdkerrors.Wrapf(err, "delete interceptor %d failed", i) } } return nil @@ -170,12 +173,82 @@ func (a table) Has(store sdk.KVStore, key RowID) bool { } // GetOne load the object persisted for the given RowID into the dest parameter. -// If none exists or `rowID==nil` then `errors.ErrNotFound` is returned instead. +// If none exists or `rowID==nil` then `sdkerrors.ErrNotFound` is returned instead. // Parameters must not be nil - we don't allow creation of values with empty keys. func (a table) GetOne(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error { if len(rowID) == 0 { - return errors.ErrNotFound + return sdkerrors.ErrNotFound } x := NewTypeSafeRowGetter(a.prefix, a.model, a.cdc) return x(store, rowID, dest) } + +// PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. +// Example: +// it, err := idx.PrefixScan(ctx, start, end) +// if err !=nil { +// return err +// } +// const defaultLimit = 20 +// it = LimitIterator(it, defaultLimit) +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a table) PrefixScan(store sdk.KVStore, start, end RowID) (Iterator, error) { + if start != nil && end != nil && bytes.Compare(start, end) >= 0 { + return NewInvalidIterator(), sdkerrors.Wrap(errors.ErrORMInvalidArgument, "start must be before end") + } + pStore := prefix.NewStore(store, a.prefix[:]) + return &typeSafeIterator{ + store: store, + rowGetter: NewTypeSafeRowGetter(a.prefix, a.model, a.cdc), + it: pStore.Iterator(start, end), + }, nil +} + +// ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive. +// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. +// Iterator must be closed by caller. +// To iterate over entire domain, use PrefixScan(nil, nil) +// +// WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose +// this as an endpoint to the public without further limits. See `LimitIterator` +// +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +func (a table) ReversePrefixScan(store sdk.KVStore, start, end RowID) (Iterator, error) { + if start != nil && end != nil && bytes.Compare(start, end) >= 0 { + return NewInvalidIterator(), sdkerrors.Wrap(errors.ErrORMInvalidArgument, "start must be before end") + } + pStore := prefix.NewStore(store, a.prefix[:]) + return &typeSafeIterator{ + store: store, + rowGetter: NewTypeSafeRowGetter(a.prefix, a.model, a.cdc), + it: pStore.ReverseIterator(start, end), + }, nil +} + +// typeSafeIterator is initialized with a type safe RowGetter only. +type typeSafeIterator struct { + store sdk.KVStore + rowGetter RowGetter + it types.Iterator +} + +func (i typeSafeIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { + if !i.it.Valid() { + return nil, errors.ErrORMIteratorDone + } + rowID := i.it.Key() + i.it.Next() + return rowID, i.rowGetter(i.store, rowID, dest) +} + +func (i typeSafeIterator) Close() error { + i.it.Close() + return nil +} diff --git a/x/group/internal/orm/table_test.go b/x/group/internal/orm/table_test.go index aff91e22417e..44146c7fea8f 100644 --- a/x/group/internal/orm/table_test.go +++ b/x/group/internal/orm/table_test.go @@ -8,7 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -54,7 +55,7 @@ func TestCreate(t *testing.T) { specs := map[string]struct { rowID RowID src codec.ProtoMarshaler - expErr *errors.Error + expErr *sdkerrors.Error }{ "empty rowID": { rowID: []byte{}, @@ -77,7 +78,7 @@ func TestCreate(t *testing.T) { Moniker: "cat moniker", Lives: 10, }, - expErr: errors.ErrInvalidType, + expErr: sdkerrors.ErrInvalidType, }, "model validation fails": { rowID: EncodeSequence(1), @@ -110,7 +111,7 @@ func TestCreate(t *testing.T) { var loaded testdata.TableModel err = myTable.GetOne(store, spec.rowID, &loaded) if spec.expErr != nil { - require.True(t, errors.ErrNotFound.Is(err)) + require.True(t, sdkerrors.ErrNotFound.Is(err)) return } require.NoError(t, err) @@ -122,7 +123,7 @@ func TestCreate(t *testing.T) { func TestUpdate(t *testing.T) { specs := map[string]struct { src codec.ProtoMarshaler - expErr *errors.Error + expErr *sdkerrors.Error }{ "happy path": { src: &testdata.TableModel{ @@ -135,7 +136,7 @@ func TestUpdate(t *testing.T) { Moniker: "cat moniker", Lives: 10, }, - expErr: errors.ErrInvalidType, + expErr: sdkerrors.ErrInvalidType, }, "model validation fails": { src: &testdata.TableModel{ @@ -184,14 +185,14 @@ func TestUpdate(t *testing.T) { func TestDelete(t *testing.T) { specs := map[string]struct { rowId []byte - expErr *errors.Error + expErr *sdkerrors.Error }{ "happy path": { rowId: EncodeSequence(1), }, "not found": { rowId: []byte("not-found"), - expErr: errors.ErrNotFound, + expErr: sdkerrors.ErrNotFound, }, } for msg, spec := range specs { @@ -220,13 +221,13 @@ func TestDelete(t *testing.T) { // then var loaded testdata.TableModel - if spec.expErr == errors.ErrNotFound { + if spec.expErr == sdkerrors.ErrNotFound { require.NoError(t, myTable.GetOne(store, EncodeSequence(1), &loaded)) assert.Equal(t, initValue, loaded) } else { err := myTable.GetOne(store, EncodeSequence(1), &loaded) require.Error(t, err) - require.Equal(t, err, errors.ErrNotFound) + require.Equal(t, err, sdkerrors.ErrNotFound) } }) } diff --git a/x/group/internal/orm/types.go b/x/group/internal/orm/types.go index c06bbebd6de0..b5ca93b0ee95 100644 --- a/x/group/internal/orm/types.go +++ b/x/group/internal/orm/types.go @@ -10,7 +10,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/group/errors" ) // Unique identifier of a persistent table. @@ -27,12 +29,57 @@ type Validateable interface { ValidateBasic() error } +// Index allows efficient prefix scans is stored as key = concat(indexKeyBytes, rowIDUint64) with value empty +// so that the row PrimaryKey is allows a fixed with 8 byte integer. This allows the MultiKeyIndex key bytes to be +// variable length and scanned iteratively. +type Index interface { + // Has checks if a key exists. Panics on nil key. + Has(store sdk.KVStore, key interface{}) (bool, error) + + // Get returns a result iterator for the searchKey. + // searchKey must not be nil. + Get(store sdk.KVStore, searchKey interface{}) (Iterator, error) + + // GetPaginated returns a result iterator for the searchKey and optional pageRequest. + // searchKey must not be nil. + GetPaginated(store sdk.KVStore, searchKey interface{}, pageRequest *query.PageRequest) (Iterator, error) + + // PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive. + // Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. + // Iterator must be closed by caller. + // To iterate over entire domain, use PrefixScan(nil, nil) + // + // WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose + // this as an endpoint to the public without further limits. + // Example: + // it, err := idx.PrefixScan(ctx, start, end) + // if err !=nil { + // return err + // } + // const defaultLimit = 20 + // it = LimitIterator(it, defaultLimit) + // + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + PrefixScan(store sdk.KVStore, startI interface{}, endI interface{}) (Iterator, error) + + // ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive. + // Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned. + // Iterator must be closed by caller. + // To iterate over entire domain, use PrefixScan(nil, nil) + // + // WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose + // this as an endpoint to the public without further limits. See `LimitIterator` + // + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + ReversePrefixScan(store sdk.KVStore, startI interface{}, endI interface{}) (Iterator, error) +} + // Iterator allows iteration through a sequence of key value pairs type Iterator interface { // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items the ErrORMIteratorDone error is returned // The key is the rowID. - LoadNext(store sdk.KVStore, dest codec.ProtoMarshaler) (RowID, error) + LoadNext(dest codec.ProtoMarshaler) (RowID, error) // Close releases the iterator and should be called at the end of iteration io.Closer } @@ -52,14 +99,14 @@ type AfterSetInterceptor func(store sdk.KVStore, rowID RowID, newValue, oldValue type AfterDeleteInterceptor func(store sdk.KVStore, rowID RowID, value codec.ProtoMarshaler) error // RowGetter loads a persistent object by row ID into the destination object. The dest parameter must therefore be a pointer. -// Any implementation must return `errors.ErrNotFound` when no object for the rowID exists +// Any implementation must return `sdkerrors.ErrNotFound` when no object for the rowID exists type RowGetter func(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error // NewTypeSafeRowGetter returns a `RowGetter` with type check on the dest parameter. func NewTypeSafeRowGetter(prefixKey [2]byte, model reflect.Type, cdc codec.Codec) RowGetter { return func(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error { if len(rowID) == 0 { - return errors.Wrap(errors.ErrORMEmptyKey, "key must not be nil") + return sdkerrors.Wrap(errors.ErrORMEmptyKey, "key must not be nil") } if err := assertCorrectType(model, dest); err != nil { return err @@ -69,7 +116,7 @@ func NewTypeSafeRowGetter(prefixKey [2]byte, model reflect.Type, cdc codec.Codec it := pStore.Iterator(PrefixRange(rowID)) defer it.Close() if !it.Valid() { - return errors.ErrNotFound + return sdkerrors.ErrNotFound } return cdc.Unmarshal(it.Value(), dest) } @@ -78,10 +125,10 @@ func NewTypeSafeRowGetter(prefixKey [2]byte, model reflect.Type, cdc codec.Codec func assertCorrectType(model reflect.Type, obj codec.ProtoMarshaler) error { tp := reflect.TypeOf(obj) if tp.Kind() != reflect.Ptr { - return errors.Wrap(errors.ErrInvalidType, "model destination must be a pointer") + return sdkerrors.Wrap(sdkerrors.ErrInvalidType, "model destination must be a pointer") } if model != tp.Elem() { - return errors.Wrapf(errors.ErrInvalidType, "can not use %T with this bucket", obj) + return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "can not use %T with this bucket", obj) } return nil } diff --git a/x/group/internal/orm/types_test.go b/x/group/internal/orm/types_test.go index bf8e3648c913..9ef2472611c9 100644 --- a/x/group/internal/orm/types_test.go +++ b/x/group/internal/orm/types_test.go @@ -9,7 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/group/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -31,22 +32,22 @@ func TestTypeSafeRowGetter(t *testing.T) { srcRowID RowID srcModelType reflect.Type expObj interface{} - expErr *errors.Error + expErr *sdkerrors.Error }{ "happy path": { srcRowID: EncodeSequence(1), srcModelType: reflect.TypeOf(testdata.TableModel{}), expObj: md, }, - "unknown rowID should return errors.ErrNotFound": { + "unknown rowID should return sdkerrors.ErrNotFound": { srcRowID: EncodeSequence(2), srcModelType: reflect.TypeOf(testdata.TableModel{}), - expErr: errors.ErrNotFound, + expErr: sdkerrors.ErrNotFound, }, - "wrong type should cause errors.ErrInvalidType": { + "wrong type should cause sdkerrors.ErrInvalidType": { srcRowID: EncodeSequence(1), srcModelType: reflect.TypeOf(testdata.Cat{}), - expErr: errors.ErrInvalidType, + expErr: sdkerrors.ErrInvalidType, }, "empty rowID not allowed": { srcRowID: []byte{}, From bb70dca6b9465ebdbbb8682355bb22407b132f4f Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 10 Nov 2021 17:18:57 +0800 Subject: [PATCH 32/38] fix: install rocksdb in github actions (#10479) * fix: install rocksdb in github actions * install rocksdb 6.24.2 from source * go mod tidy * Run test-submodules on tm-db testing container rather than install rocksdb * cleanup Co-authored-by: Robert Zaremba --- .github/workflows/test.yml | 1 + db/go.mod | 4 ++-- db/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 099817208d38..be70b6abbd3b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,6 +48,7 @@ jobs: test-submodules: runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2.1.4 diff --git a/db/go.mod b/db/go.mod index 0577e38ffe87..cb719e3384d5 100644 --- a/db/go.mod +++ b/db/go.mod @@ -4,6 +4,7 @@ module github.com/cosmos/cosmos-sdk/db require ( github.com/dgraph-io/badger/v3 v3.2103.1 + github.com/dgraph-io/ristretto v0.1.0 github.com/google/btree v1.0.0 github.com/stretchr/testify v1.7.0 github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c @@ -13,7 +14,6 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect @@ -32,4 +32,4 @@ require ( // FIXME: gorocksdb bindings for OptimisticTransactionDB are not merged upstream, so we use a fork // See https://github.com/tecbot/gorocksdb/pull/216 -replace github.com/tecbot/gorocksdb => github.com/roysc/gorocksdb v1.1.0 +replace github.com/tecbot/gorocksdb => github.com/roysc/gorocksdb v1.1.1 diff --git a/db/go.sum b/db/go.sum index 2f70e947198e..58f54d547eaa 100644 --- a/db/go.sum +++ b/db/go.sum @@ -67,8 +67,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/roysc/gorocksdb v1.1.0 h1:+bPfxli0I3UhzJpghp/L8Y9oGR6SoDj4dFV5lPPHUvs= -github.com/roysc/gorocksdb v1.1.0/go.mod h1:b/U29r/CtguX3TF7mKG1Jjn4APDqh4wECshxXdiWHpA= +github.com/roysc/gorocksdb v1.1.1 h1:5qKNwi7V/AchRMjyVf5TMCcZP70ro+VyaRmQxzpRvd4= +github.com/roysc/gorocksdb v1.1.1/go.mod h1:b/U29r/CtguX3TF7mKG1Jjn4APDqh4wECshxXdiWHpA= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= From 3f3ca314f1877658cebb71dcc4da943e6f9758f6 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Wed, 10 Nov 2021 12:07:40 +0200 Subject: [PATCH 33/38] fix: recreate compat field, of null pubkeys in multisig (#10515) ## Description Closes: #10042 Port #10275 to master. This is addressing a regression issue for the previously merged #10061. Changelog entry and tests included in the merged #10061. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow-up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- crypto/keys/multisig/amino.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/crypto/keys/multisig/amino.go b/crypto/keys/multisig/amino.go index da95ee4a7ddc..c6d0aab1d745 100644 --- a/crypto/keys/multisig/amino.go +++ b/crypto/keys/multisig/amino.go @@ -78,11 +78,28 @@ func (m *LegacyAminoPubKey) UnmarshalAminoJSON(tmPk tmMultisig) error { // Instead of just doing `*m = *protoPk`, we prefer to modify in-place the // existing Anys inside `m` (instead of allocating new Anys), as so not to // break the `.compat` fields in the existing Anys. - m.PubKeys = make([]*types.Any, len(protoPk.PubKeys)) + if m.PubKeys == nil { + m.PubKeys = make([]*types.Any, len(tmPk.PubKeys)) + } for i := range m.PubKeys { - m.PubKeys[i] = &types.Any{} - m.PubKeys[i].TypeUrl = protoPk.PubKeys[i].TypeUrl - m.PubKeys[i].Value = protoPk.PubKeys[i].Value + if m.PubKeys[i] == nil { + // create the compat jsonBz value + bz, err := AminoCdc.MarshalJSON(tmPk.PubKeys[i]) + if err != nil { + return err + } + + m.PubKeys[i] = protoPk.PubKeys[i] + // UnmarshalJSON(): + // just sets the compat.jsonBz value. + // always succeeds: err == nil + if err := m.PubKeys[i].UnmarshalJSON(bz); err != nil { + return err + } + } else { + m.PubKeys[i].TypeUrl = protoPk.PubKeys[i].TypeUrl + m.PubKeys[i].Value = protoPk.PubKeys[i].Value + } } m.Threshold = protoPk.Threshold From 4ee10b6bd7eeca8fc59d3802bddf5038acd47967 Mon Sep 17 00:00:00 2001 From: Zhiqiang Zhang <745124335@qq.com> Date: Wed, 10 Nov 2021 21:00:10 +0800 Subject: [PATCH 34/38] feat: add command line for nft module (#10505) ## Description Add nft module command line and unit test,refer #9826 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- docs/core/proto-docs.md | 2 +- proto/cosmos/nft/v1beta1/query.proto | 2 +- x/nft/client/cli/query.go | 255 +++++++++++++ x/nft/client/cli/tx.go | 60 ++++ x/nft/client/testutil/cli_test.go | 15 + x/nft/client/testutil/grpc.go | 518 +++++++++++++++++++++++++++ x/nft/client/testutil/query.go | 475 ++++++++++++++++++++++++ x/nft/client/testutil/test_helper.go | 84 +++++ x/nft/client/testutil/tx.go | 166 +++++++++ x/nft/module/module.go | 10 +- x/nft/query.pb.go | 86 ++--- x/nft/query.pb.gw.go | 34 +- x/nft/validation.go | 6 +- 13 files changed, 1645 insertions(+), 68 deletions(-) create mode 100644 x/nft/client/cli/query.go create mode 100644 x/nft/client/cli/tx.go create mode 100644 x/nft/client/testutil/cli_test.go create mode 100644 x/nft/client/testutil/grpc.go create mode 100644 x/nft/client/testutil/query.go create mode 100644 x/nft/client/testutil/test_helper.go create mode 100644 x/nft/client/testutil/tx.go diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 04cffc6b13e9..47cfa54f6b8f 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -7614,7 +7614,7 @@ Query defines the gRPC querier service. | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Balance` | [QueryBalanceRequest](#cosmos.nft.v1beta1.QueryBalanceRequest) | [QueryBalanceResponse](#cosmos.nft.v1beta1.QueryBalanceResponse) | Balance queries the number of NFTs of a given class owned by the owner, same as balanceOf in ERC721 | GET|/cosmos/nft/v1beta1/balance/{class_id}/{owner}| +| `Balance` | [QueryBalanceRequest](#cosmos.nft.v1beta1.QueryBalanceRequest) | [QueryBalanceResponse](#cosmos.nft.v1beta1.QueryBalanceResponse) | Balance queries the number of NFTs of a given class owned by the owner, same as balanceOf in ERC721 | GET|/cosmos/nft/v1beta1/balance/{owner}/{class_id}| | `Owner` | [QueryOwnerRequest](#cosmos.nft.v1beta1.QueryOwnerRequest) | [QueryOwnerResponse](#cosmos.nft.v1beta1.QueryOwnerResponse) | Owner queries the owner of the NFT based on its class and id, same as ownerOf in ERC721 | GET|/cosmos/nft/v1beta1/owner/{class_id}/{id}| | `Supply` | [QuerySupplyRequest](#cosmos.nft.v1beta1.QuerySupplyRequest) | [QuerySupplyResponse](#cosmos.nft.v1beta1.QuerySupplyResponse) | Supply queries the number of NFTs from the given class, same as totalSupply of ERC721. | GET|/cosmos/nft/v1beta1/supply/{class_id}| | `NFTsOfClass` | [QueryNFTsOfClassRequest](#cosmos.nft.v1beta1.QueryNFTsOfClassRequest) | [QueryNFTsOfClassResponse](#cosmos.nft.v1beta1.QueryNFTsOfClassResponse) | NFTsOfClass queries all NFTs of a given class or optional owner, similar to tokenByIndex in ERC721Enumerable | GET|/cosmos/nft/v1beta1/nfts/{class_id}| diff --git a/proto/cosmos/nft/v1beta1/query.proto b/proto/cosmos/nft/v1beta1/query.proto index fb9b82ad59a1..4beb72e9aa28 100644 --- a/proto/cosmos/nft/v1beta1/query.proto +++ b/proto/cosmos/nft/v1beta1/query.proto @@ -11,7 +11,7 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/nft"; service Query { // Balance queries the number of NFTs of a given class owned by the owner, same as balanceOf in ERC721 rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { - option (google.api.http).get = "/cosmos/nft/v1beta1/balance/{class_id}/{owner}"; + option (google.api.http).get = "/cosmos/nft/v1beta1/balance/{owner}/{class_id}"; } // Owner queries the owner of the NFT based on its class and id, same as ownerOf in ERC721 diff --git a/x/nft/client/cli/query.go b/x/nft/client/cli/query.go new file mode 100644 index 000000000000..cb8a379d6ba5 --- /dev/null +++ b/x/nft/client/cli/query.go @@ -0,0 +1,255 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// Flag names and values +const ( + FlagOwner = "owner" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd() *cobra.Command { + nftQueryCmd := &cobra.Command{ + Use: nft.ModuleName, + Short: "Querying commands for the nft module", + Long: "", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + nftQueryCmd.AddCommand( + GetCmdQueryClass(), + GetCmdQueryClasses(), + GetCmdQueryNFT(), + GetCmdQueryNFTs(), + GetCmdQueryOwner(), + GetCmdQueryBalance(), + GetCmdQuerySupply(), + ) + return nftQueryCmd +} + +// GetCmdQueryClass implements the query class command. +func GetCmdQueryClass() *cobra.Command { + cmd := &cobra.Command{ + Use: "class [class-id]", + Args: cobra.ExactArgs(1), + Short: "query an NFT class based on its id", + Example: fmt.Sprintf(`$ %s query %s class `, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + res, err := queryClient.Class(cmd.Context(), &nft.QueryClassRequest{ + ClassId: args[0], + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryClasses implements the query classes command. +func GetCmdQueryClasses() *cobra.Command { + cmd := &cobra.Command{ + Use: "classes", + Short: "query all NFT classes", + Example: fmt.Sprintf(`$ %s query %s classes`, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + res, err := queryClient.Classes(cmd.Context(), &nft.QueryClassesRequest{ + Pagination: pageReq, + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "classes") + return cmd +} + +// GetCmdQueryNFT implements the query nft command. +func GetCmdQueryNFT() *cobra.Command { + cmd := &cobra.Command{ + Use: "nft [class-id] [nft-id]", + Args: cobra.ExactArgs(2), + Short: "query an NFT based on its class and id.", + Example: fmt.Sprintf(`$ %s query %s nft`, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + res, err := queryClient.NFT(cmd.Context(), &nft.QueryNFTRequest{ + ClassId: args[0], + Id: args[1], + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryNFTs implements the query nft command. +func GetCmdQueryNFTs() *cobra.Command { + cmd := &cobra.Command{ + Use: "nfts [class-id]", + Args: cobra.ExactArgs(1), + Short: "query all NFTs of a given class or owner address.", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all NFTs of a given class or owner address. If owner +is set, all nfts that belong to the owner are filtered out. +Examples: +$ %s query %s nfts --owner= +`, + version.AppName, nft.ModuleName), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + request := &nft.QueryNFTsOfClassRequest{ + ClassId: args[0], + Pagination: pageReq, + } + + owner, err := cmd.Flags().GetString(FlagOwner) + if err != nil { + return err + } + + if len(owner) > 0 { + request.Owner = owner + } + res, err := queryClient.NFTsOfClass(cmd.Context(), request) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "nfts") + cmd.Flags().String(FlagOwner, "", "The owner of the nft") + return cmd +} + +// GetCmdQueryOwner implements the query owner command. +func GetCmdQueryOwner() *cobra.Command { + cmd := &cobra.Command{ + Use: "owner [class-id] [nft-id]", + Args: cobra.ExactArgs(2), + Short: "query the owner of the NFT based on its class and id.", + Example: fmt.Sprintf(`$ %s query %s owner `, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + res, err := queryClient.Owner(cmd.Context(), &nft.QueryOwnerRequest{ + ClassId: args[0], + Id: args[1], + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryBalance implements the query balance command. +func GetCmdQueryBalance() *cobra.Command { + cmd := &cobra.Command{ + Use: "balance [owner] [class-id]", + Args: cobra.ExactArgs(2), + Short: "query the number of NFTs of a given class owned by the owner.", + Example: fmt.Sprintf(`$ %s query %s balance `, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + res, err := queryClient.Balance(cmd.Context(), &nft.QueryBalanceRequest{ + ClassId: args[1], + Owner: args[0], + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQuerySupply implements the query supply command. +func GetCmdQuerySupply() *cobra.Command { + cmd := &cobra.Command{ + Use: "supply [class-id]", + Args: cobra.ExactArgs(1), + Short: "query the number of nft based on the class.", + Example: fmt.Sprintf(`$ %s query %s supply `, version.AppName, nft.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := nft.NewQueryClient(clientCtx) + res, err := queryClient.Supply(cmd.Context(), &nft.QuerySupplyRequest{ + ClassId: args[0], + }) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/nft/client/cli/tx.go b/x/nft/client/cli/tx.go new file mode 100644 index 000000000000..45320a97a43e --- /dev/null +++ b/x/nft/client/cli/tx.go @@ -0,0 +1,60 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + nftTxCmd := &cobra.Command{ + Use: nft.ModuleName, + Short: "nft transactions subcommands", + Long: "Provides the most common nft logic for upper-level applications, compatible with Ethereum's erc721 contract", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + nftTxCmd.AddCommand( + NewCmdSend(), + ) + + return nftTxCmd +} + +func NewCmdSend() *cobra.Command { + cmd := &cobra.Command{ + Use: "send [class-id] [nft-id] [receiver] --from [sender]", + Args: cobra.ExactArgs(3), + Short: "transfer ownership of nft", + Long: strings.TrimSpace(fmt.Sprintf(` + $ %s tx %s send --from --chain-id `, version.AppName, nft.ModuleName), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := nft.MsgSend{ + ClassId: args[0], + Id: args[1], + Sender: clientCtx.GetFromAddress().String(), + Receiver: args[2], + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/nft/client/testutil/cli_test.go b/x/nft/client/testutil/cli_test.go new file mode 100644 index 000000000000..7f92bbeeff55 --- /dev/null +++ b/x/nft/client/testutil/cli_test.go @@ -0,0 +1,15 @@ +package testutil + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/testutil/network" +) + +func TestIntegrationTestSuite(t *testing.T) { + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + suite.Run(t, NewIntegrationTestSuite(cfg)) +} diff --git a/x/nft/client/testutil/grpc.go b/x/nft/client/testutil/grpc.go new file mode 100644 index 000000000000..e89196cbfabd --- /dev/null +++ b/x/nft/client/testutil/grpc.go @@ -0,0 +1,518 @@ +package testutil + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/testutil/rest" + "github.com/cosmos/cosmos-sdk/x/nft" +) + +func (s *IntegrationTestSuite) TestQueryBalanceGRPC() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassId string + Owner string + } + expectErr bool + errMsg string + expectValue uint64 + }{ + { + name: "fail not exist class id", + args: struct { + ClassId string + Owner string + }{ + ClassId: "invalid_class_id", + Owner: s.owner.String(), + }, + expectErr: true, + errMsg: "invalid class id", + expectValue: 0, + }, + { + name: "fail not exist owner", + args: struct { + ClassId string + Owner string + }{ + ClassId: ExpNFT.ClassId, + Owner: s.owner.String(), + }, + expectErr: false, + expectValue: 0, + }, + { + name: "success", + args: struct { + ClassId string + Owner string + }{ + ClassId: ExpNFT.ClassId, + Owner: val.Address.String(), + }, + expectErr: false, + expectValue: 1, + }, + } + balanceURL := val.APIAddress + "/cosmos/nft/v1beta1/balance/%s/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(balanceURL, tc.args.Owner, tc.args.ClassId) + s.Run(tc.name, func() { + resp, _ := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errMsg) + } else { + var g nft.QueryBalanceResponse + err := val.ClientCtx.Codec.UnmarshalJSON(resp, &g) + s.Require().NoError(err) + s.Require().Equal(tc.expectValue, g.Amount) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryOwnerGRPC() { + val := s.network.Validators[0] + + testCases := []struct { + name string + args struct { + ClassId string + Id string + } + expectErr bool + errMsg string + expectResult string + }{ + { + name: "class id is invalid", + args: struct { + ClassId string + Id string + }{ + ClassId: "invalid_class_id", + Id: ExpNFT.Id, + }, + expectErr: true, + errMsg: "invalid class id", + expectResult: "", + }, + { + name: "class id does not exist", + args: struct { + ClassId string + Id string + }{ + ClassId: "class-id", + Id: ExpNFT.Id, + }, + expectErr: false, + expectResult: "", + }, + { + name: "nft id is invalid", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: "invalid_nft_id", + }, + expectErr: true, + expectResult: "", + }, + { + name: "nft id does not exist", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: "nft-id", + }, + expectErr: false, + expectResult: "", + }, + { + name: "nft exist", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: ExpNFT.Id, + }, + expectErr: false, + expectResult: val.Address.String(), + }, + } + ownerURL := val.APIAddress + "/cosmos/nft/v1beta1/owner/%s/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(ownerURL, tc.args.ClassId, tc.args.Id) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errMsg) + } else { + s.Require().NoError(err) + var result nft.QueryOwnerResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQuerySupplyGRPC() { + val := s.network.Validators[0] + + testCases := []struct { + name string + args struct { + ClassId string + } + expectErr bool + errMsg string + expectResult uint64 + }{ + { + name: "class id is invalid", + args: struct { + ClassId string + }{ + ClassId: "invalid_class_id", + }, + expectErr: true, + errMsg: "invalid class id", + expectResult: 0, + }, + { + name: "class id does not exist", + args: struct { + ClassId string + }{ + ClassId: "class-id", + }, + expectErr: false, + expectResult: 0, + }, + { + name: "class id exist", + args: struct { + ClassId string + }{ + ClassId: ExpNFT.ClassId, + }, + expectErr: false, + expectResult: 1, + }, + } + supplyURL := val.APIAddress + "/cosmos/nft/v1beta1/supply/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(supplyURL, tc.args.ClassId) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errMsg) + } else { + s.Require().NoError(err) + var result nft.QuerySupplyResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Amount) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFTsByOwnerGRPC() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassId string + Owner string + } + expectErr bool + errorMsg string + expectResult []*nft.NFT + }{ + { + name: "class id is invalid", + args: struct { + ClassId string + Owner string + }{ + ClassId: "invalid_class_id", + Owner: s.owner.String(), + }, + expectErr: true, + errorMsg: "invalid class id", + expectResult: []*nft.NFT{}, + }, + { + name: "class id does not exist", + args: struct { + ClassId string + Owner string + }{ + ClassId: "class-id", + Owner: s.owner.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "owner does not exist", + args: struct { + ClassId string + Owner string + }{ + ClassId: ExpNFT.ClassId, + Owner: s.owner.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "nft exist", + args: struct { + ClassId string + Owner string + }{ + ClassId: ExpNFT.ClassId, + Owner: val.Address.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{&ExpNFT}, + }, + } + nftsOfClassURL := val.APIAddress + "/cosmos/nft/v1beta1/nfts/%s?owner=%s" + for _, tc := range testCases { + uri := fmt.Sprintf(nftsOfClassURL, tc.args.ClassId, tc.args.Owner) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errorMsg) + } else { + s.Require().NoError(err) + var result nft.QueryNFTsOfClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Nfts) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFTsOfClassGRPC() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassId string + } + expectErr bool + errorMsg string + expectResult []*nft.NFT + }{ + { + name: "class id is invalid", + args: struct { + ClassId string + }{ + ClassId: "invalid_class_id", + }, + expectErr: true, + expectResult: []*nft.NFT{}, + }, + { + name: "class id does not exist", + args: struct { + ClassId string + }{ + ClassId: "class-id", + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "class id exist", + args: struct { + ClassId string + }{ + ClassId: ExpNFT.ClassId, + }, + expectErr: false, + expectResult: []*nft.NFT{&ExpNFT}, + }, + } + nftsOfClassURL := val.APIAddress + "/cosmos/nft/v1beta1/nfts/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(nftsOfClassURL, tc.args.ClassId) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errorMsg) + } else { + s.Require().NoError(err) + var result nft.QueryNFTsOfClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Nfts) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFTGRPC() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassId string + Id string + } + expectErr bool + errorMsg string + }{ + { + name: "class id is invalid", + args: struct { + ClassId string + Id string + }{ + ClassId: "invalid_class_id", + Id: ExpNFT.Id, + }, + expectErr: true, + errorMsg: "invalid class id", + }, + { + name: "class id does not exist", + args: struct { + ClassId string + Id string + }{ + ClassId: "class", + Id: ExpNFT.Id, + }, + expectErr: true, + errorMsg: "not found nft", + }, + { + name: "nft id is invalid", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: "invalid_nft_id", + }, + expectErr: true, + errorMsg: "invalid nft id", + }, + { + name: "nft id does not exist", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: "nft-id", + }, + expectErr: true, + errorMsg: "not found nft", + }, + { + name: "exist nft", + args: struct { + ClassId string + Id string + }{ + ClassId: ExpNFT.ClassId, + Id: ExpNFT.Id, + }, + expectErr: false, + }, + } + nftURL := val.APIAddress + "/cosmos/nft/v1beta1/nfts/%s/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(nftURL, tc.args.ClassId, tc.args.Id) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errorMsg) + } else { + s.Require().NoError(err) + var result nft.QueryNFTResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().EqualValues(ExpNFT, *result.Nft) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryClassGRPC() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassId string + } + expectErr bool + errorMsg string + }{ + { + name: "class id does not exist", + args: struct { + ClassId string + }{ + ClassId: "class-id", + }, + expectErr: true, + errorMsg: "not found class", + }, + { + name: "class id exist", + args: struct { + ClassId string + }{ + ClassId: ExpNFT.ClassId, + }, + expectErr: false, + }, + } + classURL := val.APIAddress + "/cosmos/nft/v1beta1/classes/%s" + for _, tc := range testCases { + uri := fmt.Sprintf(classURL, tc.args.ClassId) + s.Run(tc.name, func() { + resp, err := rest.GetRequest(uri) + if tc.expectErr { + s.Require().Contains(string(resp), tc.errorMsg) + } else { + s.Require().NoError(err) + var result nft.QueryClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().EqualValues(ExpClass, *result.Class) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryClassesGRPC() { + val := s.network.Validators[0] + classURL := val.APIAddress + "/cosmos/nft/v1beta1/classes" + resp, err := rest.GetRequest(classURL) + s.Require().NoError(err) + var result nft.QueryClassesResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) + s.Require().NoError(err) + s.Require().Len(result.Classes, 1) + s.Require().EqualValues(ExpClass, *result.Classes[0]) +} diff --git a/x/nft/client/testutil/query.go b/x/nft/client/testutil/query.go new file mode 100644 index 000000000000..83588d524ba0 --- /dev/null +++ b/x/nft/client/testutil/query.go @@ -0,0 +1,475 @@ +package testutil + +import ( + "github.com/cosmos/cosmos-sdk/x/nft" +) + +func (s *IntegrationTestSuite) TestQueryClass() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + } + expectErr bool + }{ + { + name: "class id does not exist", + args: struct { + ClassID string + }{ + ClassID: "class", + }, + expectErr: true, + }, + { + name: "class id exist", + args: struct { + ClassID string + }{ + ClassID: testClassID, + }, + expectErr: false, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryClass(val, tc.args.ClassID) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(ExpClass, *result.Class) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryClasses() { + val := s.network.Validators[0] + testCases := []struct { + name string + expectErr bool + }{ + { + name: "no params", + expectErr: false, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryClasses(val) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryClassesResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().Len(result.Classes, 1) + s.Require().EqualValues(ExpClass, *result.Classes[0]) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFT() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + ID string + } + expectErr bool + }{ + { + name: "class id does not exist", + args: struct { + ClassID string + ID string + }{ + ClassID: "class", + ID: testID, + }, + expectErr: true, + }, + { + name: "nft id does not exist", + args: struct { + ClassID string + ID string + }{ + ClassID: testClassID, + ID: "id", + }, + expectErr: true, + }, + { + name: "exist nft", + args: struct { + ClassID string + ID string + }{ + ClassID: testClassID, + ID: testID, + }, + expectErr: false, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryNFT(val, tc.args.ClassID, tc.args.ID) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryNFTResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(ExpNFT, *result.Nft) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFTs() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + } + expectErr bool + expectResult []*nft.NFT + }{ + { + name: "class id does not exist", + args: struct { + ClassID string + }{ + ClassID: "class", + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "class id exist", + args: struct { + ClassID string + }{ + ClassID: testClassID, + }, + expectErr: false, + expectResult: []*nft.NFT{&ExpNFT}, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryNFTs(val, tc.args.ClassID) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryNFTsOfClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Nfts) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryNFTsByOwner() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + Owner string + } + expectErr bool + expectResult []*nft.NFT + }{ + { + name: "class id does not exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: "class", + Owner: val.Address.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "owner does not exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: testClassID, + Owner: s.owner.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{}, + }, + { + name: "nft exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: testClassID, + Owner: val.Address.String(), + }, + expectErr: false, + expectResult: []*nft.NFT{&ExpNFT}, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryNFTsByOwner(val, tc.args.ClassID, tc.args.Owner) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryNFTsOfClassResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Nfts) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryOwner() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + ID string + } + expectErr bool + errorMsg string + expectResult string + }{ + { + name: "class id is invalid", + args: struct { + ClassID string + ID string + }{ + ClassID: "invalid_class_id", + ID: testID, + }, + expectErr: true, + errorMsg: "invalid class id", + expectResult: "", + }, + { + name: "class id does not exist", + args: struct { + ClassID string + ID string + }{ + ClassID: "class", + ID: testID, + }, + expectErr: false, + expectResult: "", + }, + { + name: "nft id is invalid", + args: struct { + ClassID string + ID string + }{ + ClassID: testClassID, + ID: "invalid_nft_id", + }, + expectErr: true, + expectResult: "", + }, + { + name: "nft id does not exist", + args: struct { + ClassID string + ID string + }{ + ClassID: testClassID, + ID: "nft-id", + }, + expectErr: false, + expectResult: "", + }, + { + name: "nft exist", + args: struct { + ClassID string + ID string + }{ + ClassID: testClassID, + ID: testID, + }, + expectErr: false, + expectResult: val.Address.String(), + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryOwner(val, tc.args.ClassID, tc.args.ID) + if tc.expectErr { + s.Require().Contains(string(resp.Bytes()), tc.errorMsg) + } else { + s.Require().NoError(err) + var result nft.QueryOwnerResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Owner) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQueryBalance() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + Owner string + } + expectErr bool + errorMsg string + expectResult uint64 + }{ + { + name: "class id is invalid", + args: struct { + ClassID string + Owner string + }{ + ClassID: "invalid_class_id", + Owner: val.Address.String(), + }, + expectErr: true, + errorMsg: "invalid class id", + expectResult: 0, + }, + { + name: "class id does not exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: "class", + Owner: val.Address.String(), + }, + expectErr: false, + expectResult: 0, + }, + { + name: "owner does not exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: testClassID, + Owner: s.owner.String(), + }, + expectErr: false, + expectResult: 0, + }, + { + name: "nft exist", + args: struct { + ClassID string + Owner string + }{ + ClassID: testClassID, + Owner: val.Address.String(), + }, + expectErr: false, + expectResult: 1, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQueryBalance(val, tc.args.ClassID, tc.args.Owner) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QueryBalanceResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Amount) + } + }) + } +} + +func (s *IntegrationTestSuite) TestQuerySupply() { + val := s.network.Validators[0] + testCases := []struct { + name string + args struct { + ClassID string + } + expectErr bool + errorMsg string + expectResult uint64 + }{ + { + name: "class id is invalid", + args: struct { + ClassID string + }{ + ClassID: "invalid_class_id", + }, + expectErr: true, + errorMsg: "invalid class id", + expectResult: 0, + }, + { + name: "class id does not exist", + args: struct { + ClassID string + }{ + ClassID: "class", + }, + expectErr: false, + expectResult: 0, + }, + { + name: "class id exist", + args: struct { + ClassID string + }{ + ClassID: testClassID, + }, + expectErr: false, + expectResult: 1, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := ExecQuerySupply(val, tc.args.ClassID) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + var result nft.QuerySupplyResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &result) + s.Require().NoError(err) + s.Require().EqualValues(tc.expectResult, result.Amount) + } + }) + } +} diff --git a/x/nft/client/testutil/test_helper.go b/x/nft/client/testutil/test_helper.go new file mode 100644 index 000000000000..a3f43045c8aa --- /dev/null +++ b/x/nft/client/testutil/test_helper.go @@ -0,0 +1,84 @@ +package testutil + +import ( + "fmt" + + tmcli "github.com/tendermint/tendermint/libs/cli" + + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" + "github.com/cosmos/cosmos-sdk/x/nft/client/cli" +) + +func ExecSend(val *network.Validator, args []string) (testutil.BufferWriter, error) { + cmd := cli.NewCmdSend() + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryClass(val *network.Validator, classID string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryClass() + var args []string + args = append(args, classID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryClasses(val *network.Validator) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryClasses() + var args []string + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryNFT(val *network.Validator, classID, nftID string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryNFT() + var args []string + args = append(args, classID) + args = append(args, nftID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryNFTs(val *network.Validator, classID string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryNFTs() + var args []string + args = append(args, classID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryNFTsByOwner(val *network.Validator, classID, owner string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryNFTs() + var args []string + args = append(args, classID) + args = append(args, fmt.Sprintf("--%s=%s", cli.FlagOwner, owner)) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryOwner(val *network.Validator, classID, nftID string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryOwner() + var args []string + args = append(args, classID) + args = append(args, nftID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQueryBalance(val *network.Validator, classID, owner string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQueryBalance() + var args []string + args = append(args, owner) + args = append(args, classID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} + +func ExecQuerySupply(val *network.Validator, classID string) (testutil.BufferWriter, error) { + cmd := cli.GetCmdQuerySupply() + var args []string + args = append(args, classID) + args = append(args, fmt.Sprintf("--%s=json", tmcli.OutputFlag)) + return clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) +} diff --git a/x/nft/client/testutil/tx.go b/x/nft/client/testutil/tx.go new file mode 100644 index 000000000000..e95bbf6b13d1 --- /dev/null +++ b/x/nft/client/testutil/tx.go @@ -0,0 +1,166 @@ +package testutil + +import ( + "fmt" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + + "github.com/cosmos/cosmos-sdk/x/nft" +) + +const ( + OwnerName = "owner" + Owner = "cosmos1kznrznww4pd6gx0zwrpthjk68fdmqypjpkj5hp" + OwnerArmor = `-----BEGIN TENDERMINT PRIVATE KEY----- +salt: C3586B75587D2824187D2CDA22B6AFB6 +type: secp256k1 +kdf: bcrypt + +1+15OrCKgjnwym1zO3cjo/SGe3PPqAYChQ5wMHjdUbTZM7mWsH3/ueL6swgjzI3b +DDzEQAPXBQflzNW6wbne9IfT651zCSm+j1MWaGk= +=wEHs +-----END TENDERMINT PRIVATE KEY-----` + + testClassID = "kitty" + testClassName = "Crypto Kitty" + testClassSymbol = "kitty" + testClassDescription = "Crypto Kitty" + testClassURI = "class uri" + testID = "kitty1" + testURI = "kitty uri" +) + +var ( + ExpClass = nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + } + + ExpNFT = nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network + owner sdk.AccAddress +} + +func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite { + return &IntegrationTestSuite{cfg: cfg} +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + genesisState := s.cfg.GenesisState + nftGenesis := nft.GenesisState{ + Classes: []*nft.Class{&ExpClass}, + Entries: []*nft.Entry{{ + Owner: Owner, + Nfts: []*nft.NFT{&ExpNFT}, + }}, + } + + nftDataBz, err := s.cfg.Codec.MarshalJSON(&nftGenesis) + s.Require().NoError(err) + genesisState[nft.ModuleName] = nftDataBz + s.cfg.GenesisState = genesisState + s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) + s.Require().NoError(err) + + _, err = s.network.WaitForHeight(1) + s.Require().NoError(err) + + s.initAccount() + _, err = s.network.WaitForHeight(1) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s *IntegrationTestSuite) TestCLITxSend() { + val := s.network.Validators[0] + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, OwnerName), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + } + testCases := []struct { + name string + args []string + expectedCode uint32 + expectErr bool + }{ + { + "valid transaction", + []string{ + testClassID, + testID, + val.Address.String(), + }, + 0, + false, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + clientCtx := val.ClientCtx + args = append(args, tc.args...) + out, err := ExecSend( + val, + args, + ) + if tc.expectErr { + s.Require().Error(err) + } else { + var txResp sdk.TxResponse + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) + s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) initAccount() { + val := s.network.Validators[0] + ctx := val.ClientCtx + err := ctx.Keyring.ImportPrivKey(OwnerName, OwnerArmor, "1234567890") + s.Require().NoError(err) + + keyinfo, err := ctx.Keyring.Key(OwnerName) + s.Require().NoError(err) + + args := []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + } + + s.owner, err = keyinfo.GetAddress() + s.Require().NoError(err) + + amount := sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))) + _, err = banktestutil.MsgSendExec(ctx, val.Address, s.owner, amount, args...) + s.Require().NoError(err) +} diff --git a/x/nft/module/module.go b/x/nft/module/module.go index c68c5d28b87c..f1cd27b53f50 100644 --- a/x/nft/module/module.go +++ b/x/nft/module/module.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/nft" + "github.com/cosmos/cosmos-sdk/x/nft/client/cli" "github.com/cosmos/cosmos-sdk/x/nft/keeper" ) @@ -39,6 +40,7 @@ func (AppModuleBasic) Name() string { // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { nft.RegisterMsgServer(cfg.MsgServer(), am.keeper) + nft.RegisterQueryServer(cfg.QueryServer(), am.keeper) } // RegisterLegacyAminoCodec registers the nft module's types for the given codec. @@ -71,17 +73,19 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, r *mux.Rou // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the nft module. func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { - nft.RegisterQueryHandlerClient(context.Background(), mux, nft.NewQueryClient(clientCtx)) + if err := nft.RegisterQueryHandlerClient(context.Background(), mux, nft.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } // GetQueryCmd returns the cli query commands for the nft module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return nil + return cli.GetQueryCmd() } // GetTxCmd returns the transaction commands for the nft module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil + return cli.GetTxCmd() } // AppModule implements the sdk.AppModule interface diff --git a/x/nft/query.pb.go b/x/nft/query.pb.go index 6622888491a2..b25a1c9e400b 100644 --- a/x/nft/query.pb.go +++ b/x/nft/query.pb.go @@ -739,50 +739,50 @@ var fileDescriptor_0d24e0db697b0f9d = []byte{ // 734 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x4f, 0x4f, 0x13, 0x4f, 0x18, 0xc7, 0x99, 0x96, 0xd2, 0xdf, 0xef, 0x21, 0xf1, 0xcf, 0x48, 0xa4, 0x54, 0xdd, 0x90, 0x45, - 0xda, 0x42, 0x65, 0x96, 0x3f, 0x89, 0x27, 0xf4, 0x80, 0xb1, 0xc6, 0x0b, 0x68, 0xe5, 0x64, 0x62, - 0xcc, 0xb6, 0xdd, 0xd6, 0x8d, 0x65, 0x67, 0x61, 0xb6, 0x2a, 0x21, 0x1c, 0xe4, 0x60, 0xf4, 0x46, + 0xda, 0x42, 0x65, 0x86, 0x3f, 0x89, 0x27, 0xf4, 0x80, 0xb1, 0xc6, 0x0b, 0x68, 0xe5, 0x64, 0x62, + 0xcc, 0xb6, 0xdd, 0xd6, 0x8d, 0x65, 0x77, 0x61, 0xb6, 0x2a, 0x21, 0x1c, 0xe4, 0x60, 0xf4, 0x46, 0x14, 0xdf, 0x93, 0x47, 0x12, 0x2f, 0xde, 0x34, 0xe0, 0x0b, 0x31, 0x3b, 0xf3, 0x6c, 0xd9, 0x95, - 0xed, 0x6e, 0x43, 0x3c, 0x91, 0xd9, 0xf9, 0x3e, 0xcf, 0xf7, 0x33, 0xf3, 0x3c, 0xf3, 0x50, 0xd0, - 0x9a, 0x5c, 0x6c, 0x71, 0x61, 0x38, 0x6d, 0xcf, 0x78, 0xb3, 0xd4, 0xb0, 0x3c, 0x73, 0xc9, 0xd8, - 0xee, 0x59, 0x3b, 0xbb, 0xcc, 0xdd, 0xe1, 0x1e, 0xa7, 0x54, 0xed, 0x33, 0xa7, 0xed, 0x31, 0xdc, - 0x2f, 0xce, 0x63, 0x4c, 0xc3, 0x14, 0x96, 0x12, 0xf7, 0x43, 0x5d, 0xb3, 0x63, 0x3b, 0xa6, 0x67, - 0x73, 0x47, 0xc5, 0x17, 0x6f, 0x76, 0x38, 0xef, 0x74, 0x2d, 0xc3, 0x74, 0x6d, 0xc3, 0x74, 0x1c, - 0xee, 0xc9, 0x4d, 0x11, 0xec, 0xc6, 0xb8, 0xfb, 0x4e, 0x72, 0x57, 0xaf, 0xc1, 0xb5, 0xa7, 0x7e, - 0xf6, 0x35, 0xb3, 0x6b, 0x3a, 0x4d, 0xab, 0x6e, 0x6d, 0xf7, 0x2c, 0xe1, 0xd1, 0x29, 0xf8, 0xaf, - 0xd9, 0x35, 0x85, 0x78, 0x69, 0xb7, 0x0a, 0x64, 0x9a, 0x54, 0xfe, 0xaf, 0xe7, 0xe5, 0xfa, 0x71, - 0x8b, 0x4e, 0x40, 0x8e, 0xbf, 0x75, 0xac, 0x9d, 0x42, 0x46, 0x7e, 0x57, 0x0b, 0x9d, 0xc1, 0x44, - 0x34, 0x8f, 0x70, 0xb9, 0x23, 0x2c, 0x7a, 0x1d, 0xc6, 0xcc, 0x2d, 0xde, 0x73, 0x3c, 0x99, 0x66, - 0xb4, 0x8e, 0x2b, 0xfd, 0x3e, 0x5c, 0x95, 0xfa, 0x0d, 0x3f, 0x7a, 0x08, 0xd7, 0x4b, 0x90, 0xb1, - 0x5b, 0x68, 0x99, 0xb1, 0x5b, 0xfa, 0x3c, 0xd0, 0x70, 0x3c, 0xba, 0xf5, 0xd9, 0x48, 0x98, 0xcd, - 0x40, 0xed, 0xb3, 0x9e, 0xeb, 0x76, 0x77, 0xd3, 0xcd, 0xf4, 0x05, 0xbc, 0x94, 0x20, 0x20, 0xe5, - 0x2c, 0x9f, 0x09, 0x4c, 0x4a, 0xfd, 0x7a, 0x6d, 0x53, 0x6c, 0xb4, 0x1f, 0xf8, 0x59, 0x2e, 0x7a, - 0x91, 0xb4, 0x06, 0x70, 0x56, 0xe0, 0x42, 0x76, 0x9a, 0x54, 0xc6, 0x97, 0x4b, 0x0c, 0x3b, 0xc4, - 0xef, 0x06, 0xa6, 0x5a, 0x07, 0x4b, 0xc9, 0x9e, 0x98, 0x9d, 0xa0, 0x6a, 0xf5, 0x50, 0xa4, 0x7e, - 0x48, 0xa0, 0x70, 0x1e, 0x0a, 0x4f, 0x52, 0x85, 0x51, 0xa7, 0xed, 0x89, 0x02, 0x99, 0xce, 0x56, - 0xc6, 0x97, 0x27, 0xd9, 0xf9, 0x06, 0x64, 0xeb, 0xb5, 0xcd, 0xba, 0x14, 0xd1, 0x47, 0x11, 0xa2, - 0x8c, 0x24, 0x2a, 0xa7, 0x12, 0x29, 0xa7, 0x08, 0xd2, 0x2a, 0x5c, 0x0e, 0x88, 0x2e, 0x50, 0xf1, - 0x7b, 0x70, 0xe5, 0x2c, 0x1a, 0xcf, 0x31, 0x07, 0x59, 0xa7, 0xad, 0xca, 0x91, 0x70, 0x0c, 0x5f, - 0xa3, 0x33, 0x6c, 0xb8, 0x21, 0xab, 0xa3, 0x3f, 0xc4, 0xa6, 0x89, 0x5e, 0x9c, 0x01, 0x39, 0x29, - 0x40, 0xcb, 0xa9, 0x38, 0x4b, 0x15, 0xa1, 0x74, 0xfa, 0x0b, 0x6c, 0x25, 0xf9, 0xd1, 0xea, 0x1b, - 0x47, 0xab, 0x4c, 0x2e, 0x5c, 0xe5, 0x23, 0x82, 0xef, 0xae, 0x9f, 0x1f, 0x41, 0x57, 0x40, 0x9d, - 0xc4, 0x0a, 0x8a, 0x9c, 0x80, 0x1a, 0x28, 0xff, 0x59, 0xa5, 0x97, 0x7f, 0xe6, 0x21, 0x27, 0xb1, - 0xe8, 0x11, 0x81, 0x3c, 0xce, 0x04, 0x5a, 0x8e, 0x43, 0x88, 0x99, 0x3e, 0xc5, 0x4a, 0xba, 0x50, - 0x99, 0xea, 0x77, 0x0f, 0xbe, 0xff, 0xfe, 0x92, 0x59, 0xa4, 0xcc, 0x88, 0x99, 0x72, 0x0d, 0x25, - 0x36, 0xf6, 0x82, 0x1a, 0xef, 0x1b, 0x7b, 0xf2, 0x91, 0xed, 0xd3, 0x4f, 0x04, 0x72, 0x72, 0x74, - 0xd0, 0xd9, 0x81, 0x5e, 0xe1, 0xd1, 0x54, 0x2c, 0xa5, 0xc9, 0x10, 0x68, 0x49, 0x02, 0x55, 0xe9, - 0x5c, 0x1c, 0x90, 0x34, 0x8f, 0xe0, 0xd8, 0xad, 0x7d, 0xfa, 0x91, 0xc0, 0x98, 0x9a, 0x34, 0x74, - 0xb0, 0x4b, 0x64, 0x76, 0x15, 0xcb, 0xa9, 0x3a, 0xc4, 0x59, 0x90, 0x38, 0x65, 0x3a, 0x1b, 0x87, - 0x23, 0xa4, 0x36, 0xc4, 0x43, 0xbf, 0x12, 0x18, 0x0f, 0xcd, 0x0b, 0x5a, 0x1d, 0xe8, 0x73, 0x7e, - 0xd4, 0x15, 0xef, 0x0c, 0x27, 0x46, 0xb2, 0xaa, 0x24, 0x9b, 0xa5, 0x33, 0x46, 0xfc, 0xff, 0x27, - 0x11, 0xe6, 0x3a, 0x20, 0x90, 0x5d, 0xaf, 0x6d, 0xd2, 0x99, 0x24, 0x8b, 0x80, 0xe3, 0x76, 0xb2, - 0x08, 0xfd, 0x17, 0xa5, 0xff, 0x3c, 0xad, 0x0c, 0xe1, 0xaf, 0xea, 0xf4, 0x81, 0x40, 0x4e, 0x5d, - 0xcb, 0xe0, 0x9e, 0x89, 0x5c, 0x48, 0x29, 0x4d, 0x86, 0x28, 0x4c, 0xa2, 0x54, 0x68, 0x29, 0x0e, - 0x05, 0xdf, 0x66, 0xf8, 0x36, 0xde, 0x13, 0xc8, 0xe3, 0x7b, 0x4f, 0x78, 0x53, 0xd1, 0x89, 0x93, - 0xf0, 0xa6, 0xfe, 0x1a, 0x1d, 0xfa, 0x8c, 0xc4, 0xb9, 0x45, 0x6f, 0x24, 0xe0, 0xac, 0xad, 0x7e, - 0x3b, 0xd1, 0xc8, 0xf1, 0x89, 0x46, 0x7e, 0x9d, 0x68, 0xe4, 0xf0, 0x54, 0x1b, 0x39, 0x3e, 0xd5, - 0x46, 0x7e, 0x9c, 0x6a, 0x23, 0xcf, 0xf5, 0x8e, 0xed, 0xbd, 0xea, 0x35, 0x58, 0x93, 0x6f, 0x05, - 0x09, 0xd4, 0x9f, 0x05, 0xd1, 0x7a, 0x6d, 0xbc, 0xf3, 0xb3, 0x35, 0xc6, 0xe4, 0x8f, 0x8f, 0x95, - 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x08, 0xc1, 0xd7, 0x1a, 0x09, 0x00, 0x00, + 0xed, 0x6e, 0x43, 0x3c, 0x91, 0xd9, 0xf9, 0x3e, 0xf3, 0xfd, 0xcc, 0xf3, 0x3c, 0xf3, 0x50, 0xd0, + 0x9a, 0x8e, 0xd8, 0x72, 0x04, 0xb7, 0xdb, 0x1e, 0x7f, 0xb3, 0xd4, 0x30, 0x3d, 0x63, 0x89, 0x6f, + 0xf7, 0xcc, 0x9d, 0x5d, 0xe6, 0xee, 0x38, 0x9e, 0x43, 0xa9, 0xda, 0x67, 0x76, 0xdb, 0x63, 0xb8, + 0x5f, 0x9c, 0xc7, 0x98, 0x86, 0x21, 0x4c, 0x25, 0xee, 0x87, 0xba, 0x46, 0xc7, 0xb2, 0x0d, 0xcf, + 0x72, 0x6c, 0x15, 0x5f, 0xbc, 0xd9, 0x71, 0x9c, 0x4e, 0xd7, 0xe4, 0x86, 0x6b, 0x71, 0xc3, 0xb6, + 0x1d, 0x4f, 0x6e, 0x8a, 0x60, 0x37, 0xc6, 0xdd, 0x77, 0x92, 0xbb, 0x7a, 0x0d, 0xae, 0x3d, 0xf5, + 0x4f, 0x5f, 0x33, 0xba, 0x86, 0xdd, 0x34, 0xeb, 0xe6, 0x76, 0xcf, 0x14, 0x1e, 0x9d, 0x82, 0xff, + 0x9a, 0x5d, 0x43, 0x88, 0x97, 0x56, 0xab, 0x40, 0xa6, 0x49, 0xe5, 0xff, 0x7a, 0x5e, 0xae, 0x1f, + 0xb7, 0xe8, 0x04, 0xe4, 0x9c, 0xb7, 0xb6, 0xb9, 0x53, 0xc8, 0xc8, 0xef, 0x6a, 0xa1, 0x33, 0x98, + 0x88, 0x9e, 0x23, 0x5c, 0xc7, 0x16, 0x26, 0xbd, 0x0e, 0x63, 0xc6, 0x96, 0xd3, 0xb3, 0x3d, 0x79, + 0xcc, 0x68, 0x1d, 0x57, 0xfa, 0x7d, 0xb8, 0x2a, 0xf5, 0x1b, 0x7e, 0xf4, 0x10, 0xae, 0x97, 0x20, + 0x63, 0xb5, 0xd0, 0x32, 0x63, 0xb5, 0xf4, 0x79, 0xa0, 0xe1, 0x78, 0x74, 0xeb, 0xb3, 0x91, 0x30, + 0x1b, 0x47, 0xed, 0xb3, 0x9e, 0xeb, 0x76, 0x77, 0xd3, 0xcd, 0xf4, 0x05, 0x4c, 0x4a, 0x10, 0x90, + 0x72, 0x97, 0xcf, 0x04, 0x26, 0xa5, 0x7e, 0xbd, 0xb6, 0x29, 0x36, 0xda, 0x0f, 0xfc, 0x53, 0x2e, + 0x9a, 0x48, 0x5a, 0x03, 0x38, 0x2b, 0x70, 0x21, 0x3b, 0x4d, 0x2a, 0xe3, 0xcb, 0x25, 0x86, 0x1d, + 0xe2, 0x77, 0x03, 0x53, 0xad, 0x83, 0xa5, 0x64, 0x4f, 0x8c, 0x4e, 0x50, 0xb5, 0x7a, 0x28, 0x52, + 0x3f, 0x24, 0x50, 0x38, 0x0f, 0x85, 0x37, 0xa9, 0xc2, 0xa8, 0xdd, 0xf6, 0x44, 0x81, 0x4c, 0x67, + 0x2b, 0xe3, 0xcb, 0x93, 0xec, 0x7c, 0x03, 0xb2, 0xf5, 0xda, 0x66, 0x5d, 0x8a, 0xe8, 0xa3, 0x08, + 0x51, 0x46, 0x12, 0x95, 0x53, 0x89, 0x94, 0x53, 0x04, 0x69, 0x15, 0x2e, 0x07, 0x44, 0x17, 0xa8, + 0xf8, 0x3d, 0xb8, 0x72, 0x16, 0x8d, 0xf7, 0x98, 0x83, 0xac, 0xdd, 0x56, 0xe5, 0x48, 0xb8, 0x86, + 0xaf, 0xd1, 0x19, 0x36, 0xdc, 0x90, 0xd5, 0xd1, 0x1f, 0x62, 0xd3, 0x44, 0x13, 0xc7, 0x21, 0x27, + 0x05, 0x68, 0x39, 0x15, 0x67, 0xa9, 0x22, 0x94, 0x4e, 0x7f, 0x81, 0xad, 0x24, 0x3f, 0x9a, 0x7d, + 0xe3, 0x68, 0x95, 0xc9, 0x85, 0xab, 0x7c, 0x44, 0xf0, 0xdd, 0xf5, 0xcf, 0x47, 0xd0, 0x15, 0x50, + 0x37, 0x31, 0x83, 0x22, 0x27, 0xa0, 0x06, 0xca, 0x7f, 0x56, 0xe9, 0xe5, 0x9f, 0x79, 0xc8, 0x49, + 0x2c, 0x7a, 0x44, 0x20, 0x8f, 0x33, 0x81, 0x96, 0xe3, 0x10, 0x62, 0xa6, 0x4f, 0xb1, 0x92, 0x2e, + 0x54, 0xa6, 0xfa, 0xdd, 0x83, 0xef, 0xbf, 0xbf, 0x64, 0x16, 0x29, 0xe3, 0x31, 0x53, 0xae, 0xa1, + 0xc4, 0x7c, 0x4f, 0xbe, 0xac, 0x7d, 0xbe, 0x17, 0xd4, 0x7a, 0x9f, 0x7e, 0x22, 0x90, 0x93, 0xa3, + 0x83, 0xce, 0x0e, 0xf4, 0x0a, 0x8f, 0xa6, 0x62, 0x29, 0x4d, 0x86, 0x40, 0x4b, 0x12, 0xa8, 0x4a, + 0xe7, 0xe2, 0x80, 0x24, 0x47, 0x08, 0x83, 0xef, 0xf9, 0x2c, 0x1f, 0x09, 0x8c, 0xa9, 0x49, 0x43, + 0x07, 0xbb, 0x44, 0x66, 0x57, 0xb1, 0x9c, 0xaa, 0x43, 0x9c, 0x05, 0x89, 0x53, 0xa6, 0xb3, 0x71, + 0x38, 0x42, 0x6a, 0xc3, 0x69, 0xf9, 0x4a, 0x60, 0x3c, 0x34, 0x2f, 0x68, 0x75, 0xa0, 0xcf, 0xf9, + 0x51, 0x57, 0xbc, 0x33, 0x9c, 0x18, 0xc9, 0xaa, 0x92, 0x6c, 0x96, 0xce, 0xf0, 0xf8, 0xff, 0x4f, + 0x22, 0xcc, 0x75, 0x40, 0x20, 0xbb, 0x5e, 0xdb, 0xa4, 0x33, 0x49, 0x16, 0x01, 0xc7, 0xed, 0x64, + 0x11, 0xfa, 0x2f, 0x4a, 0xff, 0x79, 0x5a, 0x19, 0xc2, 0x5f, 0xd5, 0xe9, 0x03, 0x81, 0x9c, 0x4a, + 0xcb, 0xe0, 0x9e, 0x89, 0x24, 0xa4, 0x94, 0x26, 0x43, 0x14, 0x26, 0x51, 0x2a, 0xb4, 0x14, 0x87, + 0x82, 0x6f, 0x33, 0x9c, 0x8d, 0xf7, 0x04, 0xf2, 0xf8, 0xde, 0x13, 0xde, 0x54, 0x74, 0xe2, 0x24, + 0xbc, 0xa9, 0xbf, 0x46, 0x87, 0x3e, 0x23, 0x71, 0x6e, 0xd1, 0x1b, 0x09, 0x38, 0x6b, 0xab, 0xdf, + 0x4e, 0x34, 0x72, 0x7c, 0xa2, 0x91, 0x5f, 0x27, 0x1a, 0x39, 0x3c, 0xd5, 0x46, 0x8e, 0x4f, 0xb5, + 0x91, 0x1f, 0xa7, 0xda, 0xc8, 0x73, 0xbd, 0x63, 0x79, 0xaf, 0x7a, 0x0d, 0xd6, 0x74, 0xb6, 0x82, + 0x03, 0xd4, 0x9f, 0x05, 0xd1, 0x7a, 0xcd, 0xdf, 0xf9, 0xa7, 0x35, 0xc6, 0xe4, 0x8f, 0x8f, 0x95, + 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xed, 0xff, 0x2d, 0x1a, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/nft/query.pb.gw.go b/x/nft/query.pb.gw.go index 4121fae00718..67a634117c1e 100644 --- a/x/nft/query.pb.gw.go +++ b/x/nft/query.pb.gw.go @@ -42,26 +42,26 @@ func request_Query_Balance_0(ctx context.Context, marshaler runtime.Marshaler, c _ = err ) - val, ok = pathParams["class_id"] + val, ok = pathParams["owner"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "class_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") } - protoReq.ClassId, err = runtime.String(val) + protoReq.Owner, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "class_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) } - val, ok = pathParams["owner"] + val, ok = pathParams["class_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "class_id") } - protoReq.Owner, err = runtime.String(val) + protoReq.ClassId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "class_id", err) } msg, err := client.Balance(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -80,26 +80,26 @@ func local_request_Query_Balance_0(ctx context.Context, marshaler runtime.Marsha _ = err ) - val, ok = pathParams["class_id"] + val, ok = pathParams["owner"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "class_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") } - protoReq.ClassId, err = runtime.String(val) + protoReq.Owner, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "class_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) } - val, ok = pathParams["owner"] + val, ok = pathParams["class_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "class_id") } - protoReq.Owner, err = runtime.String(val) + protoReq.ClassId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "class_id", err) } msg, err := server.Balance(ctx, &protoReq) @@ -806,7 +806,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Balance_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmos", "nft", "v1beta1", "balance", "class_id", "owner"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Balance_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmos", "nft", "v1beta1", "balance", "owner", "class_id"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Owner_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmos", "nft", "v1beta1", "owner", "class_id", "id"}, "", runtime.AssumeColonVerbOpt(false))) diff --git a/x/nft/validation.go b/x/nft/validation.go index 9ff72431a2e1..189b6621e33d 100644 --- a/x/nft/validation.go +++ b/x/nft/validation.go @@ -9,12 +9,12 @@ import ( var ( // reClassIDString can be 3 ~ 100 characters long and support letters, followed by either - // a letter, a number or a slash ('/') or a colon (':'). - reClassIDString = `[a-zA-Z][a-zA-Z0-9/-:]{2,100}` + // a letter, a number or a slash ('/') or a colon (':') or ('-'). + reClassIDString = `[a-zA-Z][a-zA-Z0-9/:-]{2,100}` reClassID = regexp.MustCompile(fmt.Sprintf(`^%s$`, reClassIDString)) // reNFTIDString can be 3 ~ 100 characters long and support letters, followed by either - // a letter, a number or a slash ('/') or a colon (':'). + // a letter, a number or a slash ('/') or a colon (':') or ('-'). reNFTID = reClassID ) From 2b95c7ec01b9d42b4e6ba2456b18d135ee724993 Mon Sep 17 00:00:00 2001 From: Devashish Dixit Date: Wed, 10 Nov 2021 22:16:46 +0800 Subject: [PATCH 35/38] feat(x/nft): add data field in Class type of NFT module (#10501) ## Description Adds a `data` field in `Class` type of `x/nft`. Closes: #10494 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- docs/core/proto-docs.md | 1 + proto/cosmos/nft/v1beta1/nft.proto | 3 + x/nft/nft.pb.go | 103 +++++++++++++++++++++++------ 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 47cfa54f6b8f..7c23a5c4082d 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -7295,6 +7295,7 @@ Class defines the class of the nft type. | `description` | [string](#string) | | description is a brief description of nft classification,optional | | `uri` | [string](#string) | | uri is a URI may point to a JSON file that conforms to the nft classification Metadata JSON Schema.optional | | `uri_hash` | [string](#string) | | uri_hash is a hash of the document pointed to uri,optional | +| `data` | [google.protobuf.Any](#google.protobuf.Any) | | data is the metadata of NFT classification,optional | diff --git a/proto/cosmos/nft/v1beta1/nft.proto b/proto/cosmos/nft/v1beta1/nft.proto index b11dd7c699a4..83a6225ad439 100644 --- a/proto/cosmos/nft/v1beta1/nft.proto +++ b/proto/cosmos/nft/v1beta1/nft.proto @@ -24,6 +24,9 @@ message Class { // uri_hash is a hash of the document pointed to uri,optional string uri_hash = 6; + + // data is the metadata of NFT classification,optional + google.protobuf.Any data = 7; } // NFT defines the NFT. diff --git a/x/nft/nft.pb.go b/x/nft/nft.pb.go index 6c349f4bdfb5..d0e64ef18280 100644 --- a/x/nft/nft.pb.go +++ b/x/nft/nft.pb.go @@ -37,6 +37,8 @@ type Class struct { Uri string `protobuf:"bytes,5,opt,name=uri,proto3" json:"uri,omitempty"` // uri_hash is a hash of the document pointed to uri,optional UriHash string `protobuf:"bytes,6,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` + // data is the metadata of NFT classification,optional + Data *types.Any `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"` } func (m *Class) Reset() { *m = Class{} } @@ -114,6 +116,13 @@ func (m *Class) GetUriHash() string { return "" } +func (m *Class) GetData() *types.Any { + if m != nil { + return m.Data + } + return nil +} + // NFT defines the NFT. type NFT struct { // class_id defines the unique identifier of the NFT classification, similar to the contract address of ERC721 @@ -204,27 +213,27 @@ func init() { func init() { proto.RegisterFile("cosmos/nft/v1beta1/nft.proto", fileDescriptor_eb8ebf8e8053172c) } var fileDescriptor_eb8ebf8e8053172c = []byte{ - // 312 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0xc1, 0x4b, 0xfb, 0x30, - 0x18, 0x5d, 0xda, 0x6e, 0xfb, 0xfd, 0x32, 0x10, 0x09, 0x22, 0x99, 0x48, 0x18, 0x3b, 0xed, 0x62, - 0xc2, 0xf4, 0xea, 0x45, 0x05, 0xd1, 0x8b, 0x87, 0xe1, 0xc9, 0xcb, 0x48, 0x9b, 0x6e, 0x0d, 0xb6, - 0xcd, 0x68, 0x52, 0xb1, 0x7f, 0x81, 0x57, 0xf1, 0xaf, 0xf2, 0xb8, 0xa3, 0x47, 0x69, 0xff, 0x11, - 0x49, 0x5a, 0x87, 0x82, 0xa7, 0xef, 0x7d, 0xef, 0x3d, 0x1e, 0x8f, 0xef, 0x83, 0xc7, 0x91, 0xd2, - 0x99, 0xd2, 0x2c, 0x5f, 0x19, 0xf6, 0x34, 0x0f, 0x63, 0xc3, 0xe7, 0x16, 0xd3, 0x4d, 0xa1, 0x8c, - 0x42, 0xa8, 0x55, 0xa9, 0x65, 0x3a, 0xf5, 0x68, 0xbc, 0x56, 0x6a, 0x9d, 0xc6, 0xcc, 0x39, 0xc2, - 0x72, 0xc5, 0x78, 0x5e, 0xb5, 0xf6, 0xe9, 0x1b, 0x80, 0xfd, 0xab, 0x94, 0x6b, 0x8d, 0xf6, 0xa0, - 0x27, 0x05, 0x06, 0x13, 0x30, 0xfb, 0xbf, 0xf0, 0xa4, 0x40, 0x08, 0x06, 0x39, 0xcf, 0x62, 0xec, - 0x39, 0xc6, 0x61, 0x74, 0x08, 0x07, 0xba, 0xca, 0x42, 0x95, 0x62, 0xdf, 0xb1, 0xdd, 0x86, 0x26, - 0x70, 0x24, 0x62, 0x1d, 0x15, 0x72, 0x63, 0xa4, 0xca, 0x71, 0xe0, 0xc4, 0x9f, 0x14, 0xda, 0x87, - 0x7e, 0x59, 0x48, 0xdc, 0x77, 0x8a, 0x85, 0x68, 0x0c, 0xff, 0x95, 0x85, 0x5c, 0x26, 0x5c, 0x27, - 0x78, 0xe0, 0xe8, 0x61, 0x59, 0xc8, 0x1b, 0xae, 0x93, 0xe9, 0x0b, 0x80, 0xfe, 0xdd, 0xf5, 0xbd, - 0xb5, 0x44, 0xb6, 0xdb, 0x72, 0x57, 0x6c, 0xe8, 0xf6, 0x5b, 0xd1, 0xb5, 0xf5, 0x76, 0x6d, 0xbb, - 0x7c, 0xff, 0xef, 0xfc, 0xe0, 0x57, 0x3e, 0x9a, 0xc1, 0x40, 0x70, 0xc3, 0x31, 0x9c, 0x80, 0xd9, - 0xe8, 0xf4, 0x80, 0xb6, 0xe7, 0xa1, 0xdf, 0xe7, 0xa1, 0x17, 0x79, 0xb5, 0x70, 0x8e, 0xcb, 0xf3, - 0xf7, 0x9a, 0x80, 0x6d, 0x4d, 0xc0, 0x67, 0x4d, 0xc0, 0x6b, 0x43, 0x7a, 0xdb, 0x86, 0xf4, 0x3e, - 0x1a, 0xd2, 0x7b, 0x98, 0xae, 0xa5, 0x49, 0xca, 0x90, 0x46, 0x2a, 0x63, 0xdd, 0x43, 0xda, 0x71, - 0xa2, 0xc5, 0x23, 0x7b, 0xb6, 0x1f, 0x09, 0x07, 0x2e, 0xf1, 0xec, 0x2b, 0x00, 0x00, 0xff, 0xff, - 0x2e, 0x0d, 0x3c, 0x9b, 0xb2, 0x01, 0x00, 0x00, + // 317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xc1, 0x4a, 0xc3, 0x30, + 0x1c, 0xc6, 0x97, 0xb6, 0xdb, 0x34, 0x03, 0x91, 0x20, 0x92, 0x89, 0x84, 0xb1, 0xd3, 0x2e, 0x26, + 0x4c, 0xaf, 0x5e, 0x54, 0x10, 0xbd, 0x78, 0x18, 0x9e, 0xbc, 0x8c, 0xb4, 0xe9, 0xd6, 0xe0, 0xda, + 0x8c, 0x26, 0x15, 0xfb, 0x04, 0x5e, 0x7d, 0x20, 0x1f, 0xc0, 0xe3, 0x8e, 0x1e, 0xa5, 0x7d, 0x11, + 0x49, 0x5a, 0x87, 0x87, 0x81, 0xa7, 0xfc, 0xf3, 0x7d, 0x1f, 0x7f, 0x7e, 0x1f, 0x7f, 0x78, 0x1a, + 0x29, 0x9d, 0x2a, 0xcd, 0xb2, 0x85, 0x61, 0x2f, 0xd3, 0x30, 0x36, 0x7c, 0x6a, 0x67, 0xba, 0xce, + 0x95, 0x51, 0x08, 0x35, 0x2e, 0xb5, 0x4a, 0xeb, 0x9e, 0x0c, 0x97, 0x4a, 0x2d, 0x57, 0x31, 0x73, + 0x89, 0xb0, 0x58, 0x30, 0x9e, 0x95, 0x4d, 0x7c, 0xfc, 0x01, 0x60, 0xf7, 0x66, 0xc5, 0xb5, 0x46, + 0x07, 0xd0, 0x93, 0x02, 0x83, 0x11, 0x98, 0xec, 0xcf, 0x3c, 0x29, 0x10, 0x82, 0x41, 0xc6, 0xd3, + 0x18, 0x7b, 0x4e, 0x71, 0x33, 0x3a, 0x86, 0x3d, 0x5d, 0xa6, 0xa1, 0x5a, 0x61, 0xdf, 0xa9, 0xed, + 0x0f, 0x8d, 0xe0, 0x40, 0xc4, 0x3a, 0xca, 0xe5, 0xda, 0x48, 0x95, 0xe1, 0xc0, 0x99, 0x7f, 0x25, + 0x74, 0x08, 0xfd, 0x22, 0x97, 0xb8, 0xeb, 0x1c, 0x3b, 0xa2, 0x21, 0xdc, 0x2b, 0x72, 0x39, 0x4f, + 0xb8, 0x4e, 0x70, 0xcf, 0xc9, 0xfd, 0x22, 0x97, 0x77, 0x5c, 0x27, 0x68, 0x02, 0x03, 0xc1, 0x0d, + 0xc7, 0xfd, 0x11, 0x98, 0x0c, 0xce, 0x8f, 0x68, 0x83, 0x4f, 0x7f, 0xf1, 0xe9, 0x55, 0x56, 0xce, + 0x5c, 0x62, 0xfc, 0x06, 0xa0, 0xff, 0x70, 0xfb, 0x68, 0x97, 0x45, 0xb6, 0xc5, 0x7c, 0x5b, 0xa1, + 0xef, 0xfe, 0xf7, 0xa2, 0xed, 0xe5, 0x6d, 0x7b, 0xb5, 0x24, 0xfe, 0x6e, 0x92, 0x60, 0x37, 0x09, + 0xfc, 0x8f, 0xe4, 0xfa, 0xf2, 0xb3, 0x22, 0x60, 0x53, 0x11, 0xf0, 0x5d, 0x11, 0xf0, 0x5e, 0x93, + 0xce, 0xa6, 0x26, 0x9d, 0xaf, 0x9a, 0x74, 0x9e, 0xc6, 0x4b, 0x69, 0x92, 0x22, 0xa4, 0x91, 0x4a, + 0x59, 0x7b, 0xba, 0xe6, 0x39, 0xd3, 0xe2, 0x99, 0xbd, 0xda, 0xdb, 0x85, 0x3d, 0xb7, 0xf1, 0xe2, + 0x27, 0x00, 0x00, 0xff, 0xff, 0x94, 0x4b, 0x2c, 0xc3, 0xdc, 0x01, 0x00, 0x00, } func (m *Class) Marshal() (dAtA []byte, err error) { @@ -247,6 +256,18 @@ func (m *Class) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Data != nil { + { + size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNft(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } if len(m.UriHash) > 0 { i -= len(m.UriHash) copy(dAtA[i:], m.UriHash) @@ -396,6 +417,10 @@ func (m *Class) Size() (n int) { if l > 0 { n += 1 + l + sovNft(uint64(l)) } + if m.Data != nil { + l = m.Data.Size() + n += 1 + l + sovNft(uint64(l)) + } return n } @@ -655,6 +680,42 @@ func (m *Class) Unmarshal(dAtA []byte) error { } m.UriHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Data == nil { + m.Data = &types.Any{} + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipNft(dAtA[iNdEx:]) From a9ea38382efd0b91f860da120b18d98e55acf72b Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 10 Nov 2021 10:20:37 -0600 Subject: [PATCH 36/38] perf: store/cachekv: Correct the naming and implementation for existing benchmarks (#10116) ## Description Cref discussion in #10026, updates the CacheKV Benchmark naming and implementation to correspond to whats actually going on, and remove many irrelevant/incorrect components from being in the benchmarks timing. Basically the old Benchmark's iterator creation was very flawed, and never hit the complex case, only repeatedly performing the best case performance of the iterator. Instead it really benchmarked iterator set and next operations. This PR splits out the benchmarks for those two accordingly. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - N/A imo - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed - lint failure unrelated ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- store/cachekv/bench_helper_test.go | 44 ++++++++++++++ store/cachekv/store_bench_test.go | 92 ++++++++++++++++++++++-------- 2 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 store/cachekv/bench_helper_test.go diff --git a/store/cachekv/bench_helper_test.go b/store/cachekv/bench_helper_test.go new file mode 100644 index 000000000000..fe5be27fabc9 --- /dev/null +++ b/store/cachekv/bench_helper_test.go @@ -0,0 +1,44 @@ +package cachekv_test + +import "crypto/rand" + +func randSlice(sliceSize int) []byte { + bz := make([]byte, sliceSize) + _, _ = rand.Read(bz) + return bz +} + +func incrementByteSlice(bz []byte) { + for index := len(bz) - 1; index >= 0; index-- { + if bz[index] < 255 { + bz[index]++ + break + } else { + bz[index] = 0 + } + } +} + +// Generate many keys starting at startKey, and are in sequential order +func generateSequentialKeys(startKey []byte, numKeys int) [][]byte { + toReturn := make([][]byte, 0, numKeys) + cur := make([]byte, len(startKey)) + copy(cur, startKey) + for i := 0; i < numKeys; i++ { + newKey := make([]byte, len(startKey)) + copy(newKey, cur) + toReturn = append(toReturn, newKey) + incrementByteSlice(cur) + } + return toReturn +} + +// Generate many random, unsorted keys +func generateRandomKeys(keySize int, numKeys int) [][]byte { + toReturn := make([][]byte, 0, numKeys) + for i := 0; i < numKeys; i++ { + newKey := randSlice(keySize) + toReturn = append(toReturn, newKey) + } + return toReturn +} diff --git a/store/cachekv/store_bench_test.go b/store/cachekv/store_bench_test.go index 2957fe6a6503..040c4a77c97c 100644 --- a/store/cachekv/store_bench_test.go +++ b/store/cachekv/store_bench_test.go @@ -1,8 +1,6 @@ package cachekv_test import ( - "crypto/rand" - "sort" "testing" dbm "github.com/tendermint/tm-db" @@ -11,37 +9,85 @@ import ( "github.com/cosmos/cosmos-sdk/store/dbadapter" ) -func benchmarkCacheKVStoreIterator(numKVs int, b *testing.B) { +var sink interface{} + +const defaultValueSizeBz = 1 << 12 + +// This benchmark measures the time of iterator.Next() when the parent store is blank +func benchmarkBlankParentIteratorNext(b *testing.B, keysize int) { + mem := dbadapter.Store{DB: dbm.NewMemDB()} + kvstore := cachekv.NewStore(mem) + // Use a singleton for value, to not waste time computing it + value := randSlice(defaultValueSizeBz) + // Use simple values for keys, pick a random start, + // and take next b.N keys sequentially after.] + startKey := randSlice(32) + + // Add 1 to avoid issues when b.N = 1 + keys := generateSequentialKeys(startKey, b.N+1) + for _, k := range keys { + kvstore.Set(k, value) + } + b.ReportAllocs() + b.ResetTimer() + + iter := kvstore.Iterator(keys[0], keys[b.N]) + defer iter.Close() + + for _ = iter.Key(); iter.Valid(); iter.Next() { + // deadcode elimination stub + sink = iter + } +} + +// Benchmark setting New keys to a store, where the new keys are in sequence. +func benchmarkBlankParentAppend(b *testing.B, keysize int) { mem := dbadapter.Store{DB: dbm.NewMemDB()} - cstore := cachekv.NewStore(mem) - keys := make([]string, numKVs) + kvstore := cachekv.NewStore(mem) - for i := 0; i < numKVs; i++ { - key := make([]byte, 32) - value := make([]byte, 32) + // Use a singleton for value, to not waste time computing it + value := randSlice(32) + // Use simple values for keys, pick a random start, + // and take next b.N keys sequentially after. + startKey := randSlice(32) - _, _ = rand.Read(key) - _, _ = rand.Read(value) + keys := generateSequentialKeys(startKey, b.N) - keys[i] = string(key) - cstore.Set(key, value) + b.ReportAllocs() + b.ResetTimer() + + for _, k := range keys { + kvstore.Set(k, value) } +} - sort.Strings(keys) +// Benchmark setting New keys to a store, where the new keys are random. +// the speed of this function does not depend on the values in the parent store +func benchmarkRandomSet(b *testing.B, keysize int) { + mem := dbadapter.Store{DB: dbm.NewMemDB()} + kvstore := cachekv.NewStore(mem) - for n := 0; n < b.N; n++ { - iter := cstore.Iterator([]byte(keys[0]), []byte(keys[numKVs-1])) + // Use a singleton for value, to not waste time computing it + value := randSlice(defaultValueSizeBz) + keys := generateRandomKeys(keysize, b.N) - for _ = iter.Key(); iter.Valid(); iter.Next() { - } + b.ReportAllocs() + b.ResetTimer() - iter.Close() + for _, k := range keys { + kvstore.Set(k, value) } } -func BenchmarkCacheKVStoreIterator500(b *testing.B) { benchmarkCacheKVStoreIterator(500, b) } -func BenchmarkCacheKVStoreIterator1000(b *testing.B) { benchmarkCacheKVStoreIterator(1000, b) } -func BenchmarkCacheKVStoreIterator10000(b *testing.B) { benchmarkCacheKVStoreIterator(10000, b) } -func BenchmarkCacheKVStoreIterator50000(b *testing.B) { benchmarkCacheKVStoreIterator(50000, b) } -func BenchmarkCacheKVStoreIterator100000(b *testing.B) { benchmarkCacheKVStoreIterator(100000, b) } +func BenchmarkBlankParentIteratorNextKeySize32(b *testing.B) { + benchmarkBlankParentIteratorNext(b, 32) +} + +func BenchmarkBlankParentAppendKeySize32(b *testing.B) { + benchmarkBlankParentAppend(b, 32) +} + +func BenchmarkSetKeySize32(b *testing.B) { + benchmarkRandomSet(b, 32) +} From 2b02f066aae39cd2ece720e2616acf5b3308bf8e Mon Sep 17 00:00:00 2001 From: Tim Lind Date: Wed, 10 Nov 2021 19:15:01 +0200 Subject: [PATCH 37/38] fix: pass through broadcast mode for signing with amino flag (#10510) ## Description Fixes signing with amino flag. Closes: #9671 Passes through broadcast mode flag value. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- x/auth/client/cli/tx_sign.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x/auth/client/cli/tx_sign.go b/x/auth/client/cli/tx_sign.go index 08abeaa05972..6c869d4b97b2 100644 --- a/x/auth/client/cli/tx_sign.go +++ b/x/auth/client/cli/tx_sign.go @@ -263,6 +263,11 @@ func makeSignCmd() func(cmd *cobra.Command, args []string) error { return err } + bMode, err := f.GetString(flags.FlagBroadcastMode) + if err != nil { + return err + } + var json []byte if aminoJSON { stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBuilder.GetTx()) @@ -271,7 +276,7 @@ func makeSignCmd() func(cmd *cobra.Command, args []string) error { } req := BroadcastReq{ Tx: stdTx, - Mode: "block|sync|async", + Mode: bMode, } json, err = clientCtx.LegacyAmino.MarshalJSON(req) if err != nil { From 84860a8d15b54e4609d3a02b3a02002f94bcb988 Mon Sep 17 00:00:00 2001 From: fkneeland-figure <86616427+fkneeland-figure@users.noreply.github.com> Date: Thu, 11 Nov 2021 02:32:06 -0700 Subject: [PATCH 38/38] feat: Allow futureOps to queue more Ops (#10469) ## Description I modified where we handle queued operations to get all of the future operations from each queued operation that is executed. We then add any new futureOps to the queued ops list. This enables simulations to run chains of Operations rather than only being able to go one layer deep. This is helpful in the case of building simulations around smart contracts that require multiple operations occurring in order. Closes: #10468 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + x/simulation/simulate.go | 40 +++++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73235a201b9a..6565b5cdd74d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -130,6 +130,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#9699](https://github.com/cosmos/cosmos-sdk/pull/9699) Add `:`, `.`, `-`, and `_` as allowed characters in the default denom regular expression. * (genesis) [\#9697](https://github.com/cosmos/cosmos-sdk/pull/9697) Ensure `InitGenesis` returns with non-empty validator set. * [\#10341](https://github.com/cosmos/cosmos-sdk/pull/10341) Move from `io/ioutil` to `io` and `os` packages. +* [\#10468](https://github.com/cosmos/cosmos-sdk/pull/10468) Allow futureOps to queue additional operations in simulations ### Bug Fixes diff --git a/x/simulation/simulate.go b/x/simulation/simulate.go index e1ff8f1826b6..9b8c433be10a 100644 --- a/x/simulation/simulate.go +++ b/x/simulation/simulate.go @@ -168,17 +168,20 @@ func SimulateFromSeed( ctx := app.NewContext(false, header) // Run queued operations. Ignores blocksize if blocksize is too small - numQueuedOpsRan := runQueuedOperations( + numQueuedOpsRan, futureOps := runQueuedOperations( operationQueue, int(header.Height), tb, r, app, ctx, accs, logWriter, eventStats.Tally, config.Lean, config.ChainID, ) - numQueuedTimeOpsRan := runQueuedTimeOperations( + numQueuedTimeOpsRan, timeFutureOps := runQueuedTimeOperations( timeOperationQueue, int(header.Height), header.Time, tb, r, app, ctx, accs, logWriter, eventStats.Tally, config.Lean, config.ChainID, ) + futureOps = append(futureOps, timeFutureOps...) + queueOperations(operationQueue, timeOperationQueue, futureOps) + // run standard operations operations := blockSimulator(r, app, ctx, accs, header) opCount += operations + numQueuedOpsRan + numQueuedTimeOpsRan @@ -321,20 +324,23 @@ Comment: %s`, func runQueuedOperations(queueOps map[int][]simulation.Operation, height int, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simulation.Account, logWriter LogWriter, - event func(route, op, evResult string), lean bool, chainID string) (numOpsRan int) { + event func(route, op, evResult string), lean bool, chainID string) (numOpsRan int, allFutureOps []simulation.FutureOperation) { queuedOp, ok := queueOps[height] if !ok { - return 0 + return 0, nil } + // Keep all future operations + allFutureOps = make([]simulation.FutureOperation, 0) + numOpsRan = len(queuedOp) for i := 0; i < numOpsRan; i++ { + opMsg, futureOps, err := queuedOp[i](r, app, ctx, accounts, chainID) + if futureOps != nil && len(futureOps) > 0 { + allFutureOps = append(allFutureOps, futureOps...) + } - // For now, queued operations cannot queue more operations. - // If a need arises for us to support queued messages to queue more messages, this can - // be changed. - opMsg, _, err := queuedOp[i](r, app, ctx, accounts, chainID) opMsg.LogEvent(event) if !lean || opMsg.OK { @@ -348,22 +354,22 @@ func runQueuedOperations(queueOps map[int][]simulation.Operation, } delete(queueOps, height) - return numOpsRan + return numOpsRan, allFutureOps } func runQueuedTimeOperations(queueOps []simulation.FutureOperation, height int, currentTime time.Time, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simulation.Account, logWriter LogWriter, event func(route, op, evResult string), - lean bool, chainID string) (numOpsRan int) { + lean bool, chainID string) (numOpsRan int, allFutureOps []simulation.FutureOperation) { + + // Keep all future operations + allFutureOps = make([]simulation.FutureOperation, 0) numOpsRan = 0 for len(queueOps) > 0 && currentTime.After(queueOps[0].BlockTime) { + opMsg, futureOps, err := queueOps[0].Op(r, app, ctx, accounts, chainID) - // For now, queued operations cannot queue more operations. - // If a need arises for us to support queued messages to queue more messages, this can - // be changed. - opMsg, _, err := queueOps[0].Op(r, app, ctx, accounts, chainID) opMsg.LogEvent(event) if !lean || opMsg.OK { @@ -375,9 +381,13 @@ func runQueuedTimeOperations(queueOps []simulation.FutureOperation, tb.FailNow() } + if futureOps != nil && len(futureOps) > 0 { + allFutureOps = append(allFutureOps, futureOps...) + } + queueOps = queueOps[1:] numOpsRan++ } - return numOpsRan + return numOpsRan, allFutureOps }