Generalize auth/types.StdSignature (#4507)
New Signature interface available in the top level types package. auth.StdSignature implements such interface. User defined auth module can now define their own custom signature types. Work carried out in the context of the following issues: - #4488 - #4487
This commit is contained in:
@@ -46,6 +46,7 @@ var (
|
||||
NewStdTx = types.NewStdTx
|
||||
CountSubKeys = types.CountSubKeys
|
||||
NewStdFee = types.NewStdFee
|
||||
NewStdSignature = types.NewStdSignature
|
||||
StdSignBytes = types.StdSignBytes
|
||||
DefaultTxDecoder = types.DefaultTxDecoder
|
||||
DefaultTxEncoder = types.DefaultTxEncoder
|
||||
|
||||
+11
-10
@@ -136,7 +136,8 @@ func NewAnteHandler(ak AccountKeeper, fck FeeCollectionKeeper, sigGasConsumer Si
|
||||
|
||||
// check signature, return account with incremented nonce
|
||||
signBytes := GetSignBytes(newCtx.ChainID(), stdTx, signerAccs[i], isGenesis)
|
||||
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytes, simulate, params, sigGasConsumer)
|
||||
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytes,
|
||||
simulate, params, sigGasConsumer)
|
||||
if !res.IsOK() {
|
||||
return newCtx, res, true
|
||||
}
|
||||
@@ -165,7 +166,7 @@ func ValidateSigCount(stdTx StdTx, params Params) sdk.Result {
|
||||
|
||||
sigCount := 0
|
||||
for i := 0; i < len(stdSigs); i++ {
|
||||
sigCount += CountSubKeys(stdSigs[i].PubKey)
|
||||
sigCount += CountSubKeys(stdSigs[i].GetPubKey())
|
||||
if uint64(sigCount) > params.TxSigLimit {
|
||||
return sdk.ErrTooManySignatures(
|
||||
fmt.Sprintf("signatures: %d, limit: %d", sigCount, params.TxSigLimit),
|
||||
@@ -194,7 +195,7 @@ func ValidateMemo(stdTx StdTx, params Params) sdk.Result {
|
||||
// verify the signature and increment the sequence. If the account doesn't have
|
||||
// a pubkey, set it.
|
||||
func processSig(
|
||||
ctx sdk.Context, acc Account, sig StdSignature, signBytes []byte, simulate bool, params Params,
|
||||
ctx sdk.Context, acc Account, sig sdk.Signature, signBytes []byte, simulate bool, params Params,
|
||||
sigGasConsumer SignatureVerificationGasConsumer,
|
||||
) (updatedAcc Account, res sdk.Result) {
|
||||
|
||||
@@ -216,11 +217,11 @@ func processSig(
|
||||
consumeSimSigGas(ctx.GasMeter(), pubKey, sig, params)
|
||||
}
|
||||
|
||||
if res := sigGasConsumer(ctx.GasMeter(), sig.Signature, pubKey, params); !res.IsOK() {
|
||||
if res := sigGasConsumer(ctx.GasMeter(), sig.GetSignature(), pubKey, params); !res.IsOK() {
|
||||
return nil, res
|
||||
}
|
||||
|
||||
if !simulate && !pubKey.VerifyBytes(signBytes, sig.Signature) {
|
||||
if !simulate && !pubKey.VerifyBytes(signBytes, sig.GetSignature()) {
|
||||
return nil, sdk.ErrUnauthorized("signature verification failed; verify correct account sequence and chain-id").Result()
|
||||
}
|
||||
|
||||
@@ -231,9 +232,9 @@ func processSig(
|
||||
return acc, res
|
||||
}
|
||||
|
||||
func consumeSimSigGas(gasmeter sdk.GasMeter, pubkey crypto.PubKey, sig StdSignature, params Params) {
|
||||
simSig := StdSignature{PubKey: pubkey}
|
||||
if len(sig.Signature) == 0 {
|
||||
func consumeSimSigGas(gasmeter sdk.GasMeter, pubkey crypto.PubKey, sig sdk.Signature, params Params) {
|
||||
simSig := NewStdSignature(pubkey, nil)
|
||||
if len(sig.GetSignature()) == 0 {
|
||||
simSig.Signature = simSecp256k1Sig[:]
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ func consumeSimSigGas(gasmeter sdk.GasMeter, pubkey crypto.PubKey, sig StdSignat
|
||||
// ProcessPubKey verifies that the given account address matches that of the
|
||||
// StdSignature. In addition, it will set the public key of the account if it
|
||||
// has not been set.
|
||||
func ProcessPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey, sdk.Result) {
|
||||
func ProcessPubKey(acc Account, sig sdk.Signature, simulate bool) (crypto.PubKey, sdk.Result) {
|
||||
// If pubkey is not known for account, set it from the StdSignature.
|
||||
pubKey := acc.GetPubKey()
|
||||
if simulate {
|
||||
@@ -268,7 +269,7 @@ func ProcessPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey,
|
||||
}
|
||||
|
||||
if pubKey == nil {
|
||||
pubKey = sig.PubKey
|
||||
pubKey = sig.GetPubKey()
|
||||
if pubKey == nil {
|
||||
return nil, sdk.ErrInvalidPubKey("PubKey not found").Result()
|
||||
}
|
||||
|
||||
+7
-6
@@ -515,7 +515,8 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
|
||||
msgs = []sdk.Msg{msg}
|
||||
tx = NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee)
|
||||
sigs := tx.(types.StdTx).GetSignatures()
|
||||
sigs[0].PubKey = nil
|
||||
sig := sigs[0].(StdSignature)
|
||||
sig.PubKey = nil
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
|
||||
|
||||
acc2 = input.ak.GetAccount(ctx, addr2)
|
||||
@@ -551,11 +552,11 @@ func TestProcessPubKey(t *testing.T) {
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{"no sigs, simulate off", args{acc1, StdSignature{}, false}, true},
|
||||
{"no sigs, simulate on", args{acc1, StdSignature{}, true}, false},
|
||||
{"no sigs, account with pub, simulate on", args{acc2, StdSignature{}, true}, false},
|
||||
{"pubkey doesn't match addr, simulate off", args{acc1, StdSignature{PubKey: priv2.PubKey()}, false}, true},
|
||||
{"pubkey doesn't match addr, simulate on", args{acc1, StdSignature{PubKey: priv2.PubKey()}, true}, false},
|
||||
{"no sigs, simulate off", args{acc1, NewStdSignature(nil, nil), false}, true},
|
||||
{"no sigs, simulate on", args{acc1, NewStdSignature(nil, nil), true}, false},
|
||||
{"no sigs, account with pub, simulate on", args{acc2, NewStdSignature(nil, nil), true}, false},
|
||||
{"pubkey doesn't match addr, simulate off", args{acc1, NewStdSignature(priv2.PubKey(), nil), false}, true},
|
||||
{"pubkey doesn't match addr, simulate on", args{acc1, NewStdSignature(priv2.PubKey(), nil), true}, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
crkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
@@ -119,7 +120,8 @@ func makeMultiSignCmd(cdc *codec.Codec) func(cmd *cobra.Command, args []string)
|
||||
}
|
||||
|
||||
newStdSig := types.StdSignature{Signature: cdc.MustMarshalBinaryBare(multisigSig), PubKey: multisigPub}
|
||||
newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo())
|
||||
newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []sdk.Signature{newStdSig},
|
||||
stdTx.GetMemo())
|
||||
|
||||
sigOnly := viper.GetBool(flagSigOnly)
|
||||
var json []byte
|
||||
|
||||
@@ -206,7 +206,7 @@ func printAndValidateSigs(
|
||||
}
|
||||
|
||||
for i, sig := range sigs {
|
||||
sigAddr := sdk.AccAddress(sig.Address())
|
||||
sigAddr := sdk.AccAddress(sig.GetPubKey().Address())
|
||||
sigSanity := "OK"
|
||||
|
||||
var (
|
||||
@@ -233,16 +233,16 @@ func printAndValidateSigs(
|
||||
stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(),
|
||||
)
|
||||
|
||||
if ok := sig.VerifyBytes(sigBytes, sig.Signature); !ok {
|
||||
if ok := sig.GetPubKey().VerifyBytes(sigBytes, sig.GetSignature()); !ok {
|
||||
sigSanity = "ERROR: signature invalid"
|
||||
success = false
|
||||
}
|
||||
}
|
||||
|
||||
multiPK, ok := sig.PubKey.(multisig.PubKeyMultisigThreshold)
|
||||
multiPK, ok := sig.GetPubKey().(multisig.PubKeyMultisigThreshold)
|
||||
if ok {
|
||||
var multiSig multisig.Multisignature
|
||||
cliCtx.Codec.MustUnmarshalBinaryBare(sig.Signature, &multiSig)
|
||||
cliCtx.Codec.MustUnmarshalBinaryBare(sig.GetSignature(), &multiSig)
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString("\n MultiSig Signatures:\n")
|
||||
|
||||
@@ -3,10 +3,11 @@ package genaccounts
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
)
|
||||
|
||||
func TestSanitize(t *testing.T) {
|
||||
|
||||
@@ -13,6 +13,7 @@ func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterConcrete(&ContinuousVestingAccount{}, "auth/ContinuousVestingAccount", nil)
|
||||
cdc.RegisterConcrete(&DelayedVestingAccount{}, "auth/DelayedVestingAccount", nil)
|
||||
cdc.RegisterConcrete(StdTx{}, "auth/StdTx", nil)
|
||||
cdc.RegisterConcrete(StdSignature{}, "auth/StdSignature", nil)
|
||||
}
|
||||
|
||||
// RegisterBaseAccount most users shouldn't use this, but this comes in handy for tests.
|
||||
|
||||
+19
-7
@@ -12,7 +12,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Tx = (*StdTx)(nil)
|
||||
_ sdk.Tx = (*StdTx)(nil)
|
||||
_ sdk.Signature = (*StdSignature)(nil)
|
||||
|
||||
maxGasWanted = uint64((1 << 63) - 1)
|
||||
)
|
||||
@@ -20,13 +21,13 @@ var (
|
||||
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
||||
// NOTE: the first signature is the fee payer (Signatures must not be nil).
|
||||
type StdTx struct {
|
||||
Msgs []sdk.Msg `json:"msg"`
|
||||
Fee StdFee `json:"fee"`
|
||||
Signatures []StdSignature `json:"signatures"`
|
||||
Memo string `json:"memo"`
|
||||
Msgs []sdk.Msg `json:"msg"`
|
||||
Fee StdFee `json:"fee"`
|
||||
Signatures []sdk.Signature `json:"signatures"`
|
||||
Memo string `json:"memo"`
|
||||
}
|
||||
|
||||
func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx {
|
||||
func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []sdk.Signature, memo string) StdTx {
|
||||
return StdTx{
|
||||
Msgs: msgs,
|
||||
Fee: fee,
|
||||
@@ -104,7 +105,7 @@ func (tx StdTx) GetMemo() string { return tx.Memo }
|
||||
// CONTRACT: If the signature is missing (ie the Msg is
|
||||
// invalid), then the corresponding signature is
|
||||
// .Empty().
|
||||
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
|
||||
func (tx StdTx) GetSignatures() []sdk.Signature { return tx.Signatures }
|
||||
|
||||
//__________________________________________________________
|
||||
|
||||
@@ -191,6 +192,17 @@ type StdSignature struct {
|
||||
Signature []byte `json:"signature"`
|
||||
}
|
||||
|
||||
// NewStdSignature constructs a new StdSignature instance.
|
||||
func NewStdSignature(pubKey crypto.PubKey, signature []byte) StdSignature {
|
||||
return StdSignature{PubKey: pubKey, Signature: signature}
|
||||
}
|
||||
|
||||
// GetPubKey returns the embedded crypto.PubKey type.
|
||||
func (sig StdSignature) GetPubKey() crypto.PubKey { return sig.PubKey }
|
||||
|
||||
// GetSignature returns the embedded byte signature.
|
||||
func (sig StdSignature) GetSignature() []byte { return sig.Signature }
|
||||
|
||||
// DefaultTxDecoder logic for standard transaction decoding
|
||||
func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
|
||||
return func(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
@@ -22,7 +24,7 @@ var (
|
||||
func TestStdTx(t *testing.T) {
|
||||
msgs := []sdk.Msg{sdk.NewTestMsg(addr)}
|
||||
fee := NewTestStdFee()
|
||||
sigs := []StdSignature{}
|
||||
sigs := []sdk.Signature{}
|
||||
|
||||
tx := NewStdTx(msgs, fee, sigs, "")
|
||||
require.Equal(t, msgs, tx.GetMsgs())
|
||||
@@ -121,7 +123,7 @@ func TestDefaultTxEncoder(t *testing.T) {
|
||||
|
||||
msgs := []sdk.Msg{sdk.NewTestMsg(addr)}
|
||||
fee := NewTestStdFee()
|
||||
sigs := []StdSignature{}
|
||||
sigs := []sdk.Signature{}
|
||||
|
||||
tx := NewStdTx(msgs, fee, sigs, "")
|
||||
|
||||
@@ -133,3 +135,11 @@ func TestDefaultTxEncoder(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cdcBytes, encoderBytes)
|
||||
}
|
||||
|
||||
func TestNewStdSignature(t *testing.T) {
|
||||
pub := ed25519.GenPrivKey().PubKey()
|
||||
sigBytes := []byte("data")
|
||||
got := NewStdSignature(pub, sigBytes)
|
||||
require.True(t, bytes.Equal(got.GetSignature(), sigBytes))
|
||||
require.True(t, got.GetPubKey().Equals(pub))
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func KeyTestPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) {
|
||||
}
|
||||
|
||||
func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee) sdk.Tx {
|
||||
sigs := make([]StdSignature, len(privs))
|
||||
sigs := make([]sdk.Signature, len(privs))
|
||||
for i, priv := range privs {
|
||||
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, "")
|
||||
|
||||
@@ -79,7 +79,7 @@ func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
|
||||
sigs[i] = NewStdSignature(priv.PubKey(), sig)
|
||||
}
|
||||
|
||||
tx := NewStdTx(msgs, fee, sigs, "")
|
||||
@@ -87,7 +87,7 @@ func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums
|
||||
}
|
||||
|
||||
func NewTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, memo string) sdk.Tx {
|
||||
sigs := make([]StdSignature, len(privs))
|
||||
sigs := make([]sdk.Signature, len(privs))
|
||||
for i, priv := range privs {
|
||||
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, memo)
|
||||
|
||||
@@ -96,7 +96,7 @@ func NewTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey,
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
|
||||
sigs[i] = NewStdSignature(priv.PubKey(), sig)
|
||||
}
|
||||
|
||||
tx := NewStdTx(msgs, fee, sigs, memo)
|
||||
@@ -104,14 +104,14 @@ func NewTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey,
|
||||
}
|
||||
|
||||
func NewTestTxWithSignBytes(msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, signBytes []byte, memo string) sdk.Tx {
|
||||
sigs := make([]StdSignature, len(privs))
|
||||
sigs := make([]sdk.Signature, len(privs))
|
||||
for i, priv := range privs {
|
||||
sig, err := priv.Sign(signBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
|
||||
sigs[i] = NewStdSignature(priv.PubKey(), sig)
|
||||
}
|
||||
|
||||
tx := NewStdTx(msgs, fee, sigs, memo)
|
||||
|
||||
@@ -214,7 +214,7 @@ func (bldr TxBuilder) Sign(name, passphrase string, msg StdSignMsg) ([]byte, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bldr.txEncoder(NewStdTx(msg.Msgs, msg.Fee, []StdSignature{sig}, msg.Memo))
|
||||
return bldr.txEncoder(NewStdTx(msg.Msgs, msg.Fee, []sdk.Signature{sig}, msg.Memo))
|
||||
}
|
||||
|
||||
// BuildAndSign builds a single message to be signed, and signs a transaction
|
||||
@@ -237,7 +237,7 @@ func (bldr TxBuilder) BuildTxForSim(msgs []sdk.Msg) ([]byte, error) {
|
||||
}
|
||||
|
||||
// the ante handler will populate with a sentinel pubkey
|
||||
sigs := []StdSignature{{}}
|
||||
sigs := []sdk.Signature{NewStdSignature(nil, nil)}
|
||||
return bldr.txEncoder(NewStdTx(signMsg.Msgs, signMsg.Fee, sigs, signMsg.Memo))
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx StdTx, appendSig
|
||||
|
||||
sigs := stdTx.GetSignatures()
|
||||
if len(sigs) == 0 || !appendSig {
|
||||
sigs = []StdSignature{stdSignature}
|
||||
sigs = []sdk.Signature{stdSignature}
|
||||
} else {
|
||||
sigs = append(sigs, stdSignature)
|
||||
}
|
||||
@@ -271,8 +271,8 @@ func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx StdTx, appendSig
|
||||
}
|
||||
|
||||
// MakeSignature builds a StdSignature given keybase, key name, passphrase, and a StdSignMsg.
|
||||
func MakeSignature(keybase crkeys.Keybase, name, passphrase string,
|
||||
msg StdSignMsg) (sig StdSignature, err error) {
|
||||
func MakeSignature(keybase crkeys.Keybase, name,
|
||||
passphrase string, msg StdSignMsg) (sig sdk.Signature, err error) {
|
||||
if keybase == nil {
|
||||
keybase, err = keys.NewKeyBaseFromHomeFlag()
|
||||
if err != nil {
|
||||
@@ -284,8 +284,6 @@ func MakeSignature(keybase crkeys.Keybase, name, passphrase string,
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return StdSignature{
|
||||
PubKey: pubkey,
|
||||
Signature: sigBytes,
|
||||
}, nil
|
||||
|
||||
return NewStdSignature(pubkey, sigBytes), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user