Clean Any interface (#8167)

* Clean Any interface

+ removed Any.Pack method. This method is not needed, because we have specialized
  functions for createing new Any values. It could be used inappropriately with existing
  Any objects.

* removed deprecated PackAny function

* fix linter issue

* update nil handling

* NewAnyWithValue returns error on nil instead of panic

* NewMsgCreateValidator: handle nil pubkey

* Remove AsAny and tx builder workarounds

* fix linter issue

* Add AsAny methods to TxBuilder and StdTxConfig, but keep intoAny interface private

* remove tx.PubKeyToAny

* cosmetic updates

* fix method interface

* move ProtoTxProvider to x/auth/tx
This commit is contained in:
Robert Zaremba
2020-12-18 14:55:25 +00:00
committed by GitHub
parent f602e9e977
commit b18a033a17
21 changed files with 97 additions and 146 deletions
+13 -19
View File
@@ -89,7 +89,7 @@ func QueryTx(clientCtx client.Context, hashHexStr string) (*sdk.TxResponse, erro
return nil, err
}
out, err := formatTxResult(clientCtx.TxConfig, resTx, resBlocks[resTx.Height])
out, err := mkTxResult(clientCtx.TxConfig, resTx, resBlocks[resTx.Height])
if err != nil {
return out, err
}
@@ -102,7 +102,7 @@ func formatTxResults(txConfig client.TxConfig, resTxs []*ctypes.ResultTx, resBlo
var err error
out := make([]*sdk.TxResponse, len(resTxs))
for i := range resTxs {
out[i], err = formatTxResult(txConfig, resTxs[i], resBlocks[resTxs[i].Height])
out[i], err = mkTxResult(txConfig, resTxs[i], resBlocks[resTxs[i].Height])
if err != nil {
return nil, err
}
@@ -133,27 +133,21 @@ func getBlocksForTxResults(clientCtx client.Context, resTxs []*ctypes.ResultTx)
return resBlocks, nil
}
func formatTxResult(txConfig client.TxConfig, resTx *ctypes.ResultTx, resBlock *ctypes.ResultBlock) (*sdk.TxResponse, error) {
anyTx, err := parseTx(txConfig, resTx.Tx)
func mkTxResult(txConfig client.TxConfig, resTx *ctypes.ResultTx, resBlock *ctypes.ResultBlock) (*sdk.TxResponse, error) {
txb, err := txConfig.TxDecoder()(resTx.Tx)
if err != nil {
return nil, err
}
return sdk.NewResponseResultTx(resTx, anyTx.AsAny(), resBlock.Block.Time.Format(time.RFC3339)), nil
}
func parseTx(txConfig client.TxConfig, txBytes []byte) (codectypes.IntoAny, error) {
var tx sdk.Tx
tx, err := txConfig.TxDecoder()(txBytes)
if err != nil {
return nil, err
}
anyTx, ok := tx.(codectypes.IntoAny)
p, ok := txb.(intoAny)
if !ok {
return nil, fmt.Errorf("tx cannot be packed into Any")
return nil, fmt.Errorf("expecting a type implementing intoAny, got: %T", txb)
}
any := p.AsAny()
return sdk.NewResponseResultTx(resTx, any, resBlock.Block.Time.Format(time.RFC3339)), nil
}
return anyTx, nil
// Deprecated: this interface is used only internally for scenario we are
// deprecating (StdTxConfig support)
type intoAny interface {
AsAny() *codectypes.Any
}
+6 -5
View File
@@ -16,10 +16,9 @@ import (
// Interface implementation checks
var (
_ sdk.Tx = (*StdTx)(nil)
_ codectypes.IntoAny = (*StdTx)(nil)
_ sdk.TxWithMemo = (*StdTx)(nil)
_ sdk.FeeTx = (*StdTx)(nil)
_ sdk.Tx = (*StdTx)(nil)
_ sdk.TxWithMemo = (*StdTx)(nil)
_ sdk.FeeTx = (*StdTx)(nil)
)
// StdFee includes the amount of coins paid in fees and the maximum
@@ -172,7 +171,9 @@ func (tx StdTx) ValidateBasic() error {
return nil
}
// AsAny implements IntoAny.AsAny.
// Deprecated: AsAny implements intoAny. It doesn't work for protobuf serialization,
// so it can't be saved into protobuf configured storage. We are using it only for API
// compatibility.
func (tx *StdTx) AsAny() *codectypes.Any {
return codectypes.UnsafePackAny(tx)
}
+1 -2
View File
@@ -4,7 +4,6 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v039"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
v040auth "github.com/cosmos/cosmos-sdk/x/auth/types"
v040vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
)
@@ -16,7 +15,7 @@ func convertBaseAccount(old *v039auth.BaseAccount) *v040auth.BaseAccount {
// just leave it nil.
if old.PubKey != nil {
var err error
any, err = tx.PubKeyToAny(old.PubKey)
any, err = codectypes.NewAnyWithValue(old.PubKey)
if err != nil {
panic(err)
}
+11 -8
View File
@@ -34,7 +34,7 @@ var (
_ client.TxBuilder = &wrapper{}
_ ante.HasExtensionOptionsTx = &wrapper{}
_ ExtensionOptionsTxBuilder = &wrapper{}
_ codectypes.IntoAny = &wrapper{}
_ ProtoTxProvider = &wrapper{}
)
// ExtensionOptionsTxBuilder defines a TxBuilder that can also set extensions.
@@ -284,7 +284,7 @@ func (w *wrapper) SetSignatures(signatures ...signing.SignatureV2) error {
for i, sig := range signatures {
var modeInfo *tx.ModeInfo
modeInfo, rawSigs[i] = SignatureDataToModeInfoAndSig(sig.Data)
any, err := PubKeyToAny(sig.PubKey)
any, err := codectypes.NewAnyWithValue(sig.PubKey)
if err != nil {
return err
}
@@ -315,10 +315,13 @@ func (w *wrapper) GetTx() authsigning.Tx {
return w
}
// GetProtoTx returns the tx as a proto.Message.
func (w *wrapper) GetProtoTx() *tx.Tx {
return w.tx
}
// Deprecated: AsAny extracts proto Tx and wraps it into Any.
// NOTE: You should probably use `GetProtoTx` if you want to serialize the transaction.
func (w *wrapper) AsAny() *codectypes.Any {
// We're sure here that w.tx is a proto.Message, so this will call
// codectypes.NewAnyWithValue under the hood.
return codectypes.UnsafePackAny(w.tx)
}
@@ -347,7 +350,7 @@ func (w *wrapper) SetNonCriticalExtensionOptions(extOpts ...*codectypes.Any) {
w.bodyBz = nil
}
// PubKeyToAny converts a cryptotypes.PubKey to a proto Any.
func PubKeyToAny(key cryptotypes.PubKey) (*codectypes.Any, error) {
return codectypes.NewAnyWithValue(key)
// ProtoTxProvider is a type which can provide a proto transaction.
type ProtoTxProvider interface {
GetProtoTx() *tx.Tx
}
+1 -2
View File
@@ -24,8 +24,7 @@ func TestTxBuilder(t *testing.T) {
memo := "sometestmemo"
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
accSeq := uint64(2) // Arbitrary account sequence
any, err := PubKeyToAny(pubkey)
any, err := codectypes.NewAnyWithValue(pubkey)
require.NoError(t, err)
var signerInfo []*txtypes.SignerInfo
+1 -2
View File
@@ -27,8 +27,7 @@ func TestDirectModeHandler(t *testing.T) {
memo := "sometestmemo"
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
accSeq := uint64(2) // Arbitrary account sequence
any, err := PubKeyToAny(pubkey)
any, err := codectypes.NewAnyWithValue(pubkey)
require.NoError(t, err)
var signerInfo []*txtypes.SignerInfo
+4 -14
View File
@@ -10,7 +10,6 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil/network"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -20,6 +19,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@@ -456,20 +456,10 @@ func (s IntegrationTestSuite) mkTxBuilder() client.TxBuilder {
// txBuilderToProtoTx converts a txBuilder into a proto tx.Tx.
func txBuilderToProtoTx(txBuilder client.TxBuilder) (*tx.Tx, error) { // nolint
intoAnyTx, ok := txBuilder.(codectypes.IntoAny)
protoProvider, ok := txBuilder.(authtx.ProtoTxProvider)
if !ok {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx)
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected proto tx builder, got %T", txBuilder)
}
any := intoAnyTx.AsAny().GetCachedValue()
if any == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "any's cached value is empty")
}
protoTx, ok := any.(*tx.Tx)
if !ok {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx)
}
return protoTx, nil
return protoProvider.GetProtoTx(), nil
}
+2 -2
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
@@ -109,8 +110,7 @@ func (g config) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error)
for i, sig := range sigs {
descData := signing.SignatureDataToProto(sig.Data)
any, err := PubKeyToAny(sig.PubKey)
any, err := codectypes.NewAnyWithValue(sig.PubKey)
if err != nil {
return nil, err
}
+8 -5
View File
@@ -84,12 +84,15 @@ func (acc BaseAccount) GetPubKey() (pk cryptotypes.PubKey) {
// SetPubKey - Implements sdk.AccountI.
func (acc *BaseAccount) SetPubKey(pubKey cryptotypes.PubKey) error {
any, err := codectypes.PackAny(pubKey)
if err != nil {
return err
if pubKey == nil {
acc.PubKey = nil
return nil
}
acc.PubKey = any
return nil
any, err := codectypes.NewAnyWithValue(pubKey)
if err == nil {
acc.PubKey = any
}
return err
}
// GetAccountNumber - Implements AccountI