github.com/Finschia/finschia-sdk@v0.48.1/types/tx/types.go (about)

     1  package tx
     2  
     3  import (
     4  	"fmt"
     5  
     6  	codectypes "github.com/Finschia/finschia-sdk/codec/types"
     7  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
     8  	sdk "github.com/Finschia/finschia-sdk/types"
     9  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    10  )
    11  
    12  // MaxGasWanted defines the max gas allowed.
    13  const MaxGasWanted = uint64((1 << 63) - 1)
    14  
    15  // Interface implementation checks.
    16  var _, _, _, _ codectypes.UnpackInterfacesMessage = &Tx{}, &TxBody{}, &AuthInfo{}, &SignerInfo{}
    17  var _ sdk.Tx = &Tx{}
    18  
    19  // GetMsgs implements the GetMsgs method on sdk.Tx.
    20  func (t *Tx) GetMsgs() []sdk.Msg {
    21  	if t == nil || t.Body == nil {
    22  		return nil
    23  	}
    24  
    25  	anys := t.Body.Messages
    26  	res := make([]sdk.Msg, len(anys))
    27  	for i, any := range anys {
    28  		cached := any.GetCachedValue()
    29  		if cached == nil {
    30  			panic("Any cached value is nil. Transaction messages must be correctly packed Any values.")
    31  		}
    32  		res[i] = cached.(sdk.Msg)
    33  	}
    34  	return res
    35  }
    36  
    37  // ValidateBasic implements the ValidateBasic method on sdk.Tx.
    38  func (t *Tx) ValidateBasic() error {
    39  	if t == nil {
    40  		return fmt.Errorf("bad Tx")
    41  	}
    42  
    43  	body := t.Body
    44  	if body == nil {
    45  		return fmt.Errorf("missing TxBody")
    46  	}
    47  
    48  	authInfo := t.AuthInfo
    49  	if authInfo == nil {
    50  		return fmt.Errorf("missing AuthInfo")
    51  	}
    52  
    53  	fee := authInfo.Fee
    54  	if fee == nil {
    55  		return fmt.Errorf("missing fee")
    56  	}
    57  
    58  	if fee.GasLimit > MaxGasWanted {
    59  		return sdkerrors.Wrapf(
    60  			sdkerrors.ErrInvalidRequest,
    61  			"invalid gas supplied; %d > %d", fee.GasLimit, MaxGasWanted,
    62  		)
    63  	}
    64  
    65  	if fee.Amount.IsAnyNil() {
    66  		return sdkerrors.Wrapf(
    67  			sdkerrors.ErrInsufficientFee,
    68  			"invalid fee provided: null",
    69  		)
    70  	}
    71  
    72  	if fee.Amount.IsAnyNegative() {
    73  		return sdkerrors.Wrapf(
    74  			sdkerrors.ErrInsufficientFee,
    75  			"invalid fee provided: %s", fee.Amount,
    76  		)
    77  	}
    78  
    79  	if fee.Payer != "" {
    80  		_, err := sdk.AccAddressFromBech32(fee.Payer)
    81  		if err != nil {
    82  			return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid fee payer address (%s)", err)
    83  		}
    84  	}
    85  
    86  	sigs := t.Signatures
    87  
    88  	if len(sigs) == 0 {
    89  		return sdkerrors.ErrNoSignatures
    90  	}
    91  
    92  	if len(sigs) != len(t.GetSigners()) {
    93  		return sdkerrors.Wrapf(
    94  			sdkerrors.ErrUnauthorized,
    95  			"wrong number of signers; expected %d, got %d", len(t.GetSigners()), len(sigs),
    96  		)
    97  	}
    98  
    99  	return nil
   100  }
   101  
   102  // GetSigners retrieves all the signers of a tx.
   103  // This includes all unique signers of the messages (in order),
   104  // as well as the FeePayer (if specified and not already included).
   105  func (t *Tx) GetSigners() []sdk.AccAddress {
   106  	var signers []sdk.AccAddress
   107  	seen := map[string]bool{}
   108  
   109  	for _, msg := range t.GetMsgs() {
   110  		for _, addr := range msg.GetSigners() {
   111  			if !seen[addr.String()] {
   112  				signers = append(signers, addr)
   113  				seen[addr.String()] = true
   114  			}
   115  		}
   116  	}
   117  
   118  	// ensure any specified fee payer is included in the required signers (at the end)
   119  	feePayer := t.AuthInfo.Fee.Payer
   120  	if feePayer != "" && !seen[feePayer] {
   121  		payerAddr := sdk.MustAccAddressFromBech32(feePayer)
   122  		signers = append(signers, payerAddr)
   123  		seen[feePayer] = true
   124  	}
   125  
   126  	return signers
   127  }
   128  
   129  func (t *Tx) GetGas() uint64 {
   130  	return t.AuthInfo.Fee.GasLimit
   131  }
   132  
   133  func (t *Tx) GetFee() sdk.Coins {
   134  	return t.AuthInfo.Fee.Amount
   135  }
   136  
   137  func (t *Tx) FeePayer() sdk.AccAddress {
   138  	feePayer := t.AuthInfo.Fee.Payer
   139  	if feePayer != "" {
   140  		return sdk.MustAccAddressFromBech32(feePayer)
   141  	}
   142  	// use first signer as default if no payer specified
   143  	return t.GetSigners()[0]
   144  }
   145  
   146  func (t *Tx) FeeGranter() sdk.AccAddress {
   147  	feePayer := t.AuthInfo.Fee.Granter
   148  	if feePayer != "" {
   149  		return sdk.MustAccAddressFromBech32(feePayer)
   150  	}
   151  	return nil
   152  }
   153  
   154  // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method
   155  func (t *Tx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   156  	if t.Body != nil {
   157  		if err := t.Body.UnpackInterfaces(unpacker); err != nil {
   158  			return err
   159  		}
   160  	}
   161  
   162  	if t.AuthInfo != nil {
   163  		return t.AuthInfo.UnpackInterfaces(unpacker)
   164  	}
   165  
   166  	return nil
   167  }
   168  
   169  // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method
   170  func (m *TxBody) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   171  	for _, any := range m.Messages {
   172  		var msg sdk.Msg
   173  		err := unpacker.UnpackAny(any, &msg)
   174  		if err != nil {
   175  			return err
   176  		}
   177  	}
   178  
   179  	return nil
   180  }
   181  
   182  // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method
   183  func (m *AuthInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   184  	for _, signerInfo := range m.SignerInfos {
   185  		err := signerInfo.UnpackInterfaces(unpacker)
   186  		if err != nil {
   187  			return err
   188  		}
   189  	}
   190  	return nil
   191  }
   192  
   193  // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method
   194  func (m *SignerInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   195  	return unpacker.UnpackAny(m.PublicKey, new(cryptotypes.PubKey))
   196  }
   197  
   198  // RegisterInterfaces registers the sdk.Tx interface.
   199  func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
   200  	registry.RegisterInterface("cosmos.tx.v1beta1.Tx", (*sdk.Tx)(nil))
   201  	registry.RegisterImplementations((*sdk.Tx)(nil), &Tx{})
   202  }