cosmos-sdk/x/auth/client/cli/validate_sigs.go

137 lines
3.9 KiB
Go
Raw Normal View History

package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)
func GetValidateSignaturesCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "validate-signatures [file]",
Short: "validate transactions signatures",
Long: `Print the addresses that must sign the transaction, those who have already
signed it, and make sure that signatures are in the correct order.
The command would check whether all required signers have signed the transactions, whether
the signatures were collected in the right order, and if the signature is valid over the
given transaction. If the --offline flag is also set, signature validation over the
transaction will be not be performed as that will require RPC communication with a full node.
`,
PreRun: preSignCmd,
RunE: makeValidateSignaturesCmd(),
Args: cobra.ExactArgs(1),
}
cmd.Flags().String(flags.FlagChainID, "", "The network chain ID")
flags.AddTxFlagsToCmd(cmd)
return cmd
}
func makeValidateSignaturesCmd() func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
clientCtx, txBldr, stdTx, err := readTxAndInitContexts(clientCtx, cmd, args[0])
if err != nil {
return err
}
if !printAndValidateSigs(cmd, clientCtx, txBldr.ChainID(), stdTx, clientCtx.Offline) {
return fmt.Errorf("signatures validation failed")
}
return nil
}
}
// printAndValidateSigs will validate the signatures of a given transaction over its
// expected signers. In addition, if offline has not been supplied, the signature is
// verified over the transaction sign bytes. Returns false if the validation fails.
func printAndValidateSigs(
cmd *cobra.Command, clientCtx client.Context, chainID string, tx sdk.Tx, offline bool,
) bool {
sigTx := tx.(authsigning.SigVerifiableTx)
signModeHandler := clientCtx.TxConfig.SignModeHandler()
cmd.Println("Signers:")
signers := sigTx.GetSigners()
for i, signer := range signers {
cmd.Printf(" %v: %v\n", i, signer.String())
}
success := true
sigs, err := sigTx.GetSignaturesV2()
if err != nil {
panic(err)
}
cmd.Println("")
cmd.Println("Signatures:")
if len(sigs) != len(signers) {
success = false
}
for i, sig := range sigs {
var (
pubKey = sig.PubKey
multiSigHeader string
multiSigMsg string
sigAddr = sdk.AccAddress(pubKey.Address())
sigSanity = "OK"
)
if i >= len(signers) || !sigAddr.Equals(signers[i]) {
sigSanity = "ERROR: signature does not match its respective signer"
success = false
}
// validate the actual signature over the transaction bytes since we can
// reach out to a full node to query accounts.
if !offline && success {
accNum, accSeq, err := clientCtx.AccountRetriever.GetAccountNumberSequence(clientCtx, sigAddr)
if err != nil {
cmd.Printf("failed to get account: %s\n", sigAddr)
return false
}
signingData := authsigning.SignerData{
Put AccountSequence in SignerInfo (#6997) * WIP test the grounds * Update ADR020 * Fix compile errors * Fix ADR * Make ante tests pass * Fix remaining ante handler tests * Simplify code * Fix x/bank app_test * Fix tests * Remove useless accSeq from signerdata * Fix test * Update simapp/helpers/test_helpers.go Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> * Update simapp/helpers/test_helpers.go Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> * Update x/auth/client/cli/tx_multisign.go Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> * Address rewview * Update x/auth/ante/sigverify.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/ante/sigverify_test.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/tx/builder_test.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/tx/builder_test.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/tx/direct_test.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update x/auth/tx/builder_test.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * AccSeq -> Seq * Address reviews * Better variable naming * Fix variable assign * Remove old SetSignerInfo * Fix test * proto-gen * Make proto-gen * Reput gw comment * Add Changelog * Update x/bank/app_test.go Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> * Update x/bank/app_test.go Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: SaReN <sahithnarahari@gmail.com> Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com>
2020-08-21 07:20:47 -07:00
ChainID: chainID,
AccountNumber: accNum,
Sequence: accSeq,
}
err = authsigning.VerifySignature(pubKey, signingData, sig.Data, signModeHandler, sigTx)
if err != nil {
return false
}
}
cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg)
}
cmd.Println("")
return success
}
func readTxAndInitContexts(clientCtx client.Context, cmd *cobra.Command, filename string) (client.Context, tx.Factory, sdk.Tx, error) {
stdTx, err := authclient.ReadTxFromFile(clientCtx, filename)
if err != nil {
return clientCtx, tx.Factory{}, nil, err
}
txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags())
return clientCtx, txFactory, stdTx, nil
}