Add SignatureV2 infrastructure (#6373)
* Updte tx generator * Add sigv2, PublicKeyCodec * revert changes * revert changes * updates * Updates * Integrate multisig support * Undo move * remove func * undo * godocs * godocs, cleanup * Cleanup * godocs, tests * lint * Re-enable VerifyBytes * Address comments * Fix imports * Update crypto/types/multisig/multisignature.go * Add test for MultiSignatureData * Add nested multisig case * Add test for AddSignatureV2 * Add changelog Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: sahith-narahari <sahithnarahari@gmail.com>
This commit is contained in:
co-authored by
Federico Kunze
sahith-narahari
parent
7871910359
commit
60f7edfe3d
@@ -306,7 +306,7 @@ func DefaultSigVerificationGasConsumer(
|
||||
return nil
|
||||
|
||||
case multisig.PubKeyMultisigThreshold:
|
||||
var multisignature multisig.Multisignature
|
||||
var multisignature multisig.AminoMultisignature
|
||||
legacy.Cdc.MustUnmarshalBinaryBare(sig, &multisignature)
|
||||
|
||||
ConsumeMultisignatureVerificationGas(meter, multisignature, pubkey, params)
|
||||
@@ -319,7 +319,7 @@ func DefaultSigVerificationGasConsumer(
|
||||
|
||||
// ConsumeMultisignatureVerificationGas consumes gas from a GasMeter for verifying a multisig pubkey signature
|
||||
func ConsumeMultisignatureVerificationGas(
|
||||
meter sdk.GasMeter, sig multisig.Multisignature, pubkey multisig.PubKeyMultisigThreshold, params types.Params,
|
||||
meter sdk.GasMeter, sig multisig.AminoMultisignature, pubkey multisig.PubKeyMultisigThreshold, params types.Params,
|
||||
) {
|
||||
|
||||
size := sig.BitArray.Size()
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
@@ -58,15 +60,21 @@ func TestSetPubKey(t *testing.T) {
|
||||
func TestConsumeSignatureVerificationGas(t *testing.T) {
|
||||
params := types.DefaultParams()
|
||||
msg := []byte{1, 2, 3, 4}
|
||||
_, cdc := simapp.MakeCodecs()
|
||||
|
||||
pkSet1, sigSet1 := generatePubKeysAndSignatures(5, msg, false)
|
||||
multisigKey1 := multisig.NewPubKeyMultisigThreshold(2, pkSet1)
|
||||
multisignature1 := multisig.NewMultisig(len(pkSet1))
|
||||
expectedCost1 := expectedGasCostByKeys(pkSet1)
|
||||
for i := 0; i < len(pkSet1); i++ {
|
||||
err := multisignature1.AddSignatureFromPubKey(sigSet1[i], pkSet1[i], pkSet1)
|
||||
stdSig := types.StdSignature{PubKey: pkSet1[i].Bytes(), Signature: sigSet1[i]}
|
||||
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
|
||||
require.NoError(t, err)
|
||||
err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
aminoMultisignature1, err := types.SignatureDataToAminoSignature(cdc, multisignature1)
|
||||
require.NoError(t, err)
|
||||
|
||||
type args struct {
|
||||
meter sdk.GasMeter
|
||||
@@ -82,7 +90,7 @@ func TestConsumeSignatureVerificationGas(t *testing.T) {
|
||||
}{
|
||||
{"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), nil, ed25519.GenPrivKey().PubKey(), params}, types.DefaultSigVerifyCostED25519, true},
|
||||
{"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), nil, secp256k1.GenPrivKey().PubKey(), params}, types.DefaultSigVerifyCostSecp256k1, false},
|
||||
{"Multisig", args{sdk.NewInfiniteGasMeter(), multisignature1.Marshal(), multisigKey1, params}, expectedCost1, false},
|
||||
{"Multisig", args{sdk.NewInfiniteGasMeter(), aminoMultisignature1, multisigKey1, params}, expectedCost1, false},
|
||||
{"unknown key", args{sdk.NewInfiniteGasMeter(), nil, nil, params}, 0, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -107,13 +107,24 @@ func makeMultiSignCmd(cdc *codec.Codec) func(cmd *cobra.Command, args []string)
|
||||
if ok := stdSig.GetPubKey().VerifyBytes(sigBytes, stdSig.Signature); !ok {
|
||||
return fmt.Errorf("couldn't verify signature")
|
||||
}
|
||||
if err := multisigSig.AddSignatureFromPubKey(stdSig.Signature, stdSig.GetPubKey(), multisigPub.PubKeys); err != nil {
|
||||
|
||||
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := multisig.AddSignatureV2(multisigSig, sigV2, multisigPub.PubKeys); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newStdSig := types.StdSignature{Signature: cdc.MustMarshalBinaryBare(multisigSig), PubKey: multisigPub.Bytes()} //nolint:staticcheck
|
||||
newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo()) //nolint:staticcheck
|
||||
sigBz, err := types.SignatureDataToAminoSignature(cdc, multisigSig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newStdSig := types.StdSignature{Signature: sigBz, PubKey: multisigPub.Bytes()} //nolint:staticcheck
|
||||
newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo()) //nolint:staticcheck
|
||||
|
||||
sigOnly := viper.GetBool(flagSigOnly)
|
||||
var json []byte
|
||||
|
||||
@@ -108,7 +108,7 @@ func printAndValidateSigs(
|
||||
|
||||
multiPK, ok := sig.GetPubKey().(multisig.PubKeyMultisigThreshold)
|
||||
if ok {
|
||||
var multiSig multisig.Multisignature
|
||||
var multiSig multisig.AminoMultisignature
|
||||
clientCtx.Codec.MustUnmarshalBinaryBare(sig.Signature, &multiSig)
|
||||
|
||||
var b strings.Builder
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@@ -16,19 +16,19 @@ type LegacyAminoJSONHandler struct{}
|
||||
var _ signing.SignModeHandler = LegacyAminoJSONHandler{}
|
||||
|
||||
// DefaultMode implements SignModeHandler.DefaultMode
|
||||
func (h LegacyAminoJSONHandler) DefaultMode() types.SignMode {
|
||||
return types.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
|
||||
func (h LegacyAminoJSONHandler) DefaultMode() signingtypes.SignMode {
|
||||
return signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
|
||||
}
|
||||
|
||||
// Modes implements SignModeHandler.Modes
|
||||
func (LegacyAminoJSONHandler) Modes() []types.SignMode {
|
||||
return []types.SignMode{types.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}
|
||||
func (LegacyAminoJSONHandler) Modes() []signingtypes.SignMode {
|
||||
return []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}
|
||||
}
|
||||
|
||||
// DefaultMode implements SignModeHandler.GetSignBytes
|
||||
func (LegacyAminoJSONHandler) GetSignBytes(mode types.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) {
|
||||
if mode != types.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
|
||||
return nil, fmt.Errorf("expected %s, got %s", types.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, mode)
|
||||
func (LegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) {
|
||||
if mode != signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
|
||||
return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, mode)
|
||||
}
|
||||
|
||||
feeTx, ok := tx.(ante.FeeTx)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing/amino"
|
||||
@@ -55,7 +55,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
|
||||
AccountNumber: accNum,
|
||||
AccountSequence: seqNum,
|
||||
}
|
||||
signBz, err := handler.GetSignBytes(txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedSignBz := auth.StdSignBytes(chainId, accNum, seqNum, fee, msgs, memo)
|
||||
@@ -63,16 +63,16 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
|
||||
require.Equal(t, expectedSignBz, signBz)
|
||||
|
||||
// expect error with wrong sign mode
|
||||
_, err = handler.GetSignBytes(txtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
|
||||
_, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestLegacyAminoJSONHandler_DefaultMode(t *testing.T) {
|
||||
handler := amino.LegacyAminoJSONHandler{}
|
||||
require.Equal(t, txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
|
||||
require.Equal(t, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
|
||||
}
|
||||
|
||||
func TestLegacyAminoJSONHandler_Modes(t *testing.T) {
|
||||
handler := amino.LegacyAminoJSONHandler{}
|
||||
require.Equal(t, []txtypes.SignMode{txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}, handler.Modes())
|
||||
require.Equal(t, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}, handler.Modes())
|
||||
}
|
||||
|
||||
@@ -3,24 +3,25 @@ package signing
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
)
|
||||
|
||||
// SignModeHandlerMap is SignModeHandler that aggregates multiple SignModeHandler's into
|
||||
// a single handler
|
||||
type SignModeHandlerMap struct {
|
||||
defaultMode types.SignMode
|
||||
modes []types.SignMode
|
||||
signModeHandlers map[types.SignMode]SignModeHandler
|
||||
defaultMode signing.SignMode
|
||||
modes []signing.SignMode
|
||||
signModeHandlers map[signing.SignMode]SignModeHandler
|
||||
}
|
||||
|
||||
var _ SignModeHandler = SignModeHandlerMap{}
|
||||
|
||||
// NewSignModeHandlerMap returns a new SignModeHandlerMap with the provided defaultMode and handlers
|
||||
func NewSignModeHandlerMap(defaultMode types.SignMode, handlers []SignModeHandler) SignModeHandlerMap {
|
||||
handlerMap := make(map[types.SignMode]SignModeHandler)
|
||||
var modes []types.SignMode
|
||||
func NewSignModeHandlerMap(defaultMode signing.SignMode, handlers []SignModeHandler) SignModeHandlerMap {
|
||||
handlerMap := make(map[signing.SignMode]SignModeHandler)
|
||||
var modes []signing.SignMode
|
||||
|
||||
for _, h := range handlers {
|
||||
for _, m := range h.Modes() {
|
||||
@@ -40,17 +41,17 @@ func NewSignModeHandlerMap(defaultMode types.SignMode, handlers []SignModeHandle
|
||||
}
|
||||
|
||||
// DefaultMode implements SignModeHandler.DefaultMode
|
||||
func (h SignModeHandlerMap) DefaultMode() types.SignMode {
|
||||
func (h SignModeHandlerMap) DefaultMode() signing.SignMode {
|
||||
return h.defaultMode
|
||||
}
|
||||
|
||||
// Modes implements SignModeHandler.Modes
|
||||
func (h SignModeHandlerMap) Modes() []types.SignMode {
|
||||
func (h SignModeHandlerMap) Modes() []signing.SignMode {
|
||||
return h.modes
|
||||
}
|
||||
|
||||
// DefaultMode implements SignModeHandler.GetSignBytes
|
||||
func (h SignModeHandlerMap) GetSignBytes(mode types.SignMode, data SignerData, tx sdk.Tx) ([]byte, error) {
|
||||
func (h SignModeHandlerMap) GetSignBytes(mode signing.SignMode, data SignerData, tx sdk.Tx) ([]byte, error) {
|
||||
handler, found := h.signModeHandlers[mode]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("can't verify sign mode %s", mode.String())
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing/amino"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
|
||||
func MakeTestHandlerMap() signing.SignModeHandler {
|
||||
return signing.NewSignModeHandlerMap(
|
||||
txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
[]signing.SignModeHandler{
|
||||
amino.LegacyAminoJSONHandler{},
|
||||
},
|
||||
@@ -66,27 +66,27 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
|
||||
AccountNumber: accNum,
|
||||
AccountSequence: seqNum,
|
||||
}
|
||||
signBz, err := handler.GetSignBytes(txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedSignBz, err := aminoJSONHandler.GetSignBytes(txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
expectedSignBz, err := aminoJSONHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, expectedSignBz, signBz)
|
||||
|
||||
// expect error with wrong sign mode
|
||||
_, err = aminoJSONHandler.GetSignBytes(txtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
|
||||
_, err = aminoJSONHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestHandlerMap_DefaultMode(t *testing.T) {
|
||||
handler := MakeTestHandlerMap()
|
||||
require.Equal(t, txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
|
||||
require.Equal(t, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
|
||||
}
|
||||
|
||||
func TestHandlerMap_Modes(t *testing.T) {
|
||||
handler := MakeTestHandlerMap()
|
||||
modes := handler.Modes()
|
||||
require.Contains(t, modes, txtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
|
||||
require.Contains(t, modes, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
|
||||
require.Len(t, modes, 1)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package signing
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
)
|
||||
|
||||
// SignModeHandler defines a interface to be implemented by types which will handle
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
type SignModeHandler interface {
|
||||
// DefaultMode is the default mode that is to be used with this handler if no
|
||||
// other mode is specified. This can be useful for testing and CLI usage
|
||||
DefaultMode() txtypes.SignMode
|
||||
DefaultMode() signing.SignMode
|
||||
|
||||
// Modes is the list of modes supporting by this handler
|
||||
Modes() []txtypes.SignMode
|
||||
Modes() []signing.SignMode
|
||||
|
||||
// GetSignBytes returns the sign bytes for the provided SignMode, SignerData and Tx,
|
||||
// or an error
|
||||
GetSignBytes(mode txtypes.SignMode, data SignerData, tx sdk.Tx) ([]byte, error)
|
||||
GetSignBytes(mode signing.SignMode, data SignerData, tx sdk.Tx) ([]byte, error)
|
||||
}
|
||||
|
||||
// SignerData is the specific information needed to sign a transaction that generally
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
@@ -356,3 +358,96 @@ func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StdSignatureToSignatureV2 converts a StdSignature to a SignatureV2
|
||||
func StdSignatureToSignatureV2(cdc *codec.Codec, sig StdSignature) (signing.SignatureV2, error) {
|
||||
pk := sig.GetPubKey()
|
||||
data, err := pubKeySigToSigData(cdc, pk, sig.Signature)
|
||||
if err != nil {
|
||||
return signing.SignatureV2{}, err
|
||||
}
|
||||
|
||||
return signing.SignatureV2{
|
||||
PubKey: pk,
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func pubKeySigToSigData(cdc *codec.Codec, key crypto.PubKey, sig []byte) (signing.SignatureData, error) {
|
||||
multiPK, ok := key.(multisig.PubKey)
|
||||
if !ok {
|
||||
return &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
Signature: sig,
|
||||
}, nil
|
||||
}
|
||||
var multiSig multisig.AminoMultisignature
|
||||
err := cdc.UnmarshalBinaryBare(sig, &multiSig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigs := multiSig.Sigs
|
||||
sigDatas := make([]signing.SignatureData, len(sigs))
|
||||
pubKeys := multiPK.GetPubKeys()
|
||||
bitArray := multiSig.BitArray
|
||||
n := multiSig.BitArray.Size()
|
||||
signatures := multisig.NewMultisig(n)
|
||||
sigIdx := 0
|
||||
for i := 0; i < n; i++ {
|
||||
if bitArray.GetIndex(i) {
|
||||
data, err := pubKeySigToSigData(cdc, pubKeys[i], multiSig.Sigs[sigIdx])
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(err, "Unable to convert Signature to SigData %d", sigIdx)
|
||||
}
|
||||
|
||||
sigDatas[sigIdx] = data
|
||||
multisig.AddSignature(signatures, data, sigIdx)
|
||||
sigIdx++
|
||||
}
|
||||
}
|
||||
|
||||
return signatures, nil
|
||||
}
|
||||
|
||||
// MultiSignatureDataToAminoMultisignature converts a MultiSignatureData to an AminoMultisignature.
|
||||
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
|
||||
func MultiSignatureDataToAminoMultisignature(cdc *codec.Codec, mSig *signing.MultiSignatureData) (multisig.AminoMultisignature, error) {
|
||||
n := len(mSig.Signatures)
|
||||
sigs := make([][]byte, n)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
var err error
|
||||
sigs[i], err = SignatureDataToAminoSignature(cdc, mSig.Signatures[i])
|
||||
if err != nil {
|
||||
return multisig.AminoMultisignature{}, sdkerrors.Wrapf(err, "Unable to convert Signature Data to signature %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
return multisig.AminoMultisignature{
|
||||
BitArray: mSig.BitArray,
|
||||
Sigs: sigs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignatureDataToAminoSignature converts a SignatureData to amino-encoded signature bytes.
|
||||
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
|
||||
func SignatureDataToAminoSignature(cdc *codec.Codec, data signing.SignatureData) ([]byte, error) {
|
||||
switch data := data.(type) {
|
||||
case *signing.SingleSignatureData:
|
||||
if data.SignMode != signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
|
||||
return nil, fmt.Errorf("expected %s, got %s", signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, data.SignMode)
|
||||
}
|
||||
|
||||
return data.Signature, nil
|
||||
case *signing.MultiSignatureData:
|
||||
aminoMSig, err := MultiSignatureDataToAminoMultisignature(cdc, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cdc.MarshalBinaryBare(aminoMSig)
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected signature data %T", data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
@@ -167,3 +172,58 @@ func TestStdSignatureMarshalYAML(t *testing.T) {
|
||||
require.Equal(t, tc.output, string(bz), "test case #%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureV2Conversions(t *testing.T) {
|
||||
_, pubKey, _ := KeyTestPubAddr()
|
||||
cdc := codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
RegisterCodec(cdc)
|
||||
dummy := []byte("dummySig")
|
||||
sig := StdSignature{PubKey: pubKey.Bytes(), Signature: dummy}
|
||||
|
||||
sigV2, err := StdSignatureToSignatureV2(cdc, sig)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubKey, sigV2.PubKey)
|
||||
require.Equal(t, &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
Signature: dummy,
|
||||
}, sigV2.Data)
|
||||
|
||||
sigBz, err := SignatureDataToAminoSignature(cdc, sigV2.Data)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dummy, sigBz)
|
||||
|
||||
// multisigs
|
||||
_, pubKey2, _ := KeyTestPubAddr()
|
||||
multiPK := multisig.NewPubKeyMultisigThreshold(1, []crypto.PubKey{
|
||||
pubKey, pubKey2,
|
||||
})
|
||||
dummy2 := []byte("dummySig2")
|
||||
bitArray := types.NewCompactBitArray(2)
|
||||
bitArray.SetIndex(0, true)
|
||||
bitArray.SetIndex(1, true)
|
||||
msigData := &signing.MultiSignatureData{
|
||||
BitArray: bitArray,
|
||||
Signatures: []signing.SignatureData{
|
||||
&signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
Signature: dummy,
|
||||
},
|
||||
&signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
Signature: dummy2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
msig, err := SignatureDataToAminoSignature(cdc, msigData)
|
||||
require.NoError(t, err)
|
||||
|
||||
sigV2, err = StdSignatureToSignatureV2(cdc, StdSignature{
|
||||
PubKey: multiPK.Bytes(),
|
||||
Signature: msig,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, multiPK, sigV2.PubKey)
|
||||
require.Equal(t, msigData, sigV2.Data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user