github.com/Finschia/finschia-sdk@v0.49.1/x/auth/legacy/legacytx/stdtx.go (about)

     1  package legacytx
     2  
     3  import (
     4  	"github.com/Finschia/finschia-sdk/codec/legacy"
     5  	codectypes "github.com/Finschia/finschia-sdk/codec/types"
     6  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
     7  	sdk "github.com/Finschia/finschia-sdk/types"
     8  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
     9  	txtypes "github.com/Finschia/finschia-sdk/types/tx"
    10  	"github.com/Finschia/finschia-sdk/types/tx/signing"
    11  )
    12  
    13  // Interface implementation checks
    14  var (
    15  	_ sdk.Tx                             = (*StdTx)(nil)
    16  	_ sdk.TxWithMemo                     = (*StdTx)(nil)
    17  	_ sdk.FeeTx                          = (*StdTx)(nil)
    18  	_ codectypes.UnpackInterfacesMessage = (*StdTx)(nil)
    19  
    20  	_ codectypes.UnpackInterfacesMessage = (*StdSignature)(nil)
    21  )
    22  
    23  // StdFee includes the amount of coins paid in fees and the maximum
    24  // gas to be used by the transaction. The ratio yields an effective "gasprice",
    25  // which must be above some miminum to be accepted into the mempool.
    26  // [Deprecated]
    27  type StdFee struct {
    28  	Amount sdk.Coins `json:"amount" yaml:"amount"`
    29  	Gas    uint64    `json:"gas" yaml:"gas"`
    30  }
    31  
    32  // Deprecated: NewStdFee returns a new instance of StdFee
    33  func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
    34  	return StdFee{
    35  		Amount: amount,
    36  		Gas:    gas,
    37  	}
    38  }
    39  
    40  // GetGas returns the fee's (wanted) gas.
    41  func (fee StdFee) GetGas() uint64 {
    42  	return fee.Gas
    43  }
    44  
    45  // GetAmount returns the fee's amount.
    46  func (fee StdFee) GetAmount() sdk.Coins {
    47  	return fee.Amount
    48  }
    49  
    50  // Bytes returns the encoded bytes of a StdFee.
    51  func (fee StdFee) Bytes() []byte {
    52  	if len(fee.Amount) == 0 {
    53  		fee.Amount = sdk.NewCoins()
    54  	}
    55  
    56  	bz, err := legacy.Cdc.MarshalJSON(fee)
    57  	if err != nil {
    58  		panic(err)
    59  	}
    60  
    61  	return bz
    62  }
    63  
    64  // GasPrices returns the gas prices for a StdFee.
    65  //
    66  // NOTE: The gas prices returned are not the true gas prices that were
    67  // originally part of the submitted transaction because the fee is computed
    68  // as fee = ceil(gasWanted * gasPrices).
    69  func (fee StdFee) GasPrices() sdk.DecCoins {
    70  	return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas)))
    71  }
    72  
    73  // StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures.
    74  // It only works with Amino, please prefer the new protobuf Tx in types/tx.
    75  // NOTE: the first signature is the fee payer (Signatures must not be nil).
    76  // Deprecated
    77  type StdTx struct {
    78  	Msgs          []sdk.Msg      `json:"msg" yaml:"msg"`
    79  	Fee           StdFee         `json:"fee" yaml:"fee"`
    80  	Signatures    []StdSignature `json:"signatures" yaml:"signatures"`
    81  	Memo          string         `json:"memo" yaml:"memo"`
    82  	TimeoutHeight uint64         `json:"timeout_height" yaml:"timeout_height"`
    83  }
    84  
    85  // Deprecated
    86  func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx {
    87  	return StdTx{
    88  		Msgs:       msgs,
    89  		Fee:        fee,
    90  		Signatures: sigs,
    91  		Memo:       memo,
    92  	}
    93  }
    94  
    95  // GetMsgs returns the all the transaction's messages.
    96  func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs }
    97  
    98  // ValidateBasic does a simple and lightweight validation check that doesn't
    99  // require access to any other information.
   100  func (tx StdTx) ValidateBasic() error {
   101  	stdSigs := tx.GetSignatures()
   102  
   103  	if tx.Fee.Gas > txtypes.MaxGasWanted {
   104  		return sdkerrors.Wrapf(
   105  			sdkerrors.ErrInvalidRequest,
   106  			"invalid gas supplied; %d > %d", tx.Fee.Gas, txtypes.MaxGasWanted,
   107  		)
   108  	}
   109  	if tx.Fee.Amount.IsAnyNegative() {
   110  		return sdkerrors.Wrapf(
   111  			sdkerrors.ErrInsufficientFee,
   112  			"invalid fee provided: %s", tx.Fee.Amount,
   113  		)
   114  	}
   115  	if len(stdSigs) == 0 {
   116  		return sdkerrors.ErrNoSignatures
   117  	}
   118  	if len(stdSigs) != len(tx.GetSigners()) {
   119  		return sdkerrors.Wrapf(
   120  			sdkerrors.ErrUnauthorized,
   121  			"wrong number of signers; expected %d, got %d", len(tx.GetSigners()), len(stdSigs),
   122  		)
   123  	}
   124  
   125  	return nil
   126  }
   127  
   128  // Deprecated: AsAny implements intoAny. It doesn't work for protobuf serialization,
   129  // so it can't be saved into protobuf configured storage. We are using it only for API
   130  // compatibility.
   131  func (tx *StdTx) AsAny() *codectypes.Any {
   132  	return codectypes.UnsafePackAny(tx)
   133  }
   134  
   135  // GetSigners returns the addresses that must sign the transaction.
   136  // Addresses are returned in a deterministic order.
   137  // They are accumulated from the GetSigners method for each Msg
   138  // in the order they appear in tx.GetMsgs().
   139  // Duplicate addresses will be omitted.
   140  func (tx StdTx) GetSigners() []sdk.AccAddress {
   141  	var signers []sdk.AccAddress
   142  	seen := map[string]bool{}
   143  
   144  	for _, msg := range tx.GetMsgs() {
   145  		for _, addr := range msg.GetSigners() {
   146  			if !seen[addr.String()] {
   147  				signers = append(signers, addr)
   148  				seen[addr.String()] = true
   149  			}
   150  		}
   151  	}
   152  
   153  	return signers
   154  }
   155  
   156  // GetMemo returns the memo
   157  func (tx StdTx) GetMemo() string { return tx.Memo }
   158  
   159  // GetTimeoutHeight returns the transaction's timeout height (if set).
   160  func (tx StdTx) GetTimeoutHeight() uint64 {
   161  	return tx.TimeoutHeight
   162  }
   163  
   164  // GetSignatures returns the signature of signers who signed the Msg.
   165  // CONTRACT: Length returned is same as length of
   166  // pubkeys returned from MsgKeySigners, and the order
   167  // matches.
   168  // CONTRACT: If the signature is missing (ie the Msg is
   169  // invalid), then the corresponding signature is
   170  // .Empty().
   171  func (tx StdTx) GetSignatures() [][]byte {
   172  	sigs := make([][]byte, len(tx.Signatures))
   173  	for i, stdSig := range tx.Signatures {
   174  		sigs[i] = stdSig.Signature
   175  	}
   176  	return sigs
   177  }
   178  
   179  // GetSignaturesV2 implements SigVerifiableTx.GetSignaturesV2
   180  func (tx StdTx) GetSignaturesV2() ([]signing.SignatureV2, error) {
   181  	res := make([]signing.SignatureV2, len(tx.Signatures))
   182  
   183  	for i, sig := range tx.Signatures {
   184  		var err error
   185  		res[i], err = StdSignatureToSignatureV2(legacy.Cdc, sig)
   186  		if err != nil {
   187  			return nil, sdkerrors.Wrapf(err, "Unable to convert signature %v to V2", sig)
   188  		}
   189  	}
   190  
   191  	return res, nil
   192  }
   193  
   194  // GetPubkeys returns the pubkeys of signers if the pubkey is included in the signature
   195  // If pubkey is not included in the signature, then nil is in the slice instead
   196  func (tx StdTx) GetPubKeys() ([]cryptotypes.PubKey, error) {
   197  	pks := make([]cryptotypes.PubKey, len(tx.Signatures))
   198  
   199  	for i, stdSig := range tx.Signatures {
   200  		pks[i] = stdSig.GetPubKey()
   201  	}
   202  
   203  	return pks, nil
   204  }
   205  
   206  // GetGas returns the Gas in StdFee
   207  func (tx StdTx) GetGas() uint64 { return tx.Fee.Gas }
   208  
   209  // GetFee returns the FeeAmount in StdFee
   210  func (tx StdTx) GetFee() sdk.Coins { return tx.Fee.Amount }
   211  
   212  // FeePayer returns the address that is responsible for paying fee
   213  // StdTx returns the first signer as the fee payer
   214  // If no signers for tx, return empty address
   215  func (tx StdTx) FeePayer() sdk.AccAddress {
   216  	if tx.GetSigners() != nil {
   217  		return tx.GetSigners()[0]
   218  	}
   219  	return sdk.AccAddress{}
   220  }
   221  
   222  // FeeGranter always returns nil for StdTx
   223  func (tx StdTx) FeeGranter() sdk.AccAddress {
   224  	return nil
   225  }
   226  
   227  func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   228  	for _, m := range tx.Msgs {
   229  		err := codectypes.UnpackInterfaces(m, unpacker)
   230  		if err != nil {
   231  			return err
   232  		}
   233  	}
   234  
   235  	// Signatures contain PubKeys, which need to be unpacked.
   236  	for _, s := range tx.Signatures {
   237  		err := s.UnpackInterfaces(unpacker)
   238  		if err != nil {
   239  			return err
   240  		}
   241  	}
   242  
   243  	return nil
   244  }