github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/auth/ibc-tx/builder.go (about)

     1  package ibc_tx
     2  
     3  import (
     4  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
     5  	codectypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
     6  	cryptotypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/types"
     7  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     8  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     9  	ibcmsg "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter"
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx"
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx/signing"
    12  	sigtx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibcsigning"
    13  	"github.com/gogo/protobuf/proto"
    14  )
    15  
    16  // wrapper is a wrapper around the tx.Tx proto.Message which retain the raw
    17  // body and auth_info bytes.
    18  type wrapper struct {
    19  	tx *tx.Tx
    20  
    21  	// bodyBz represents the protobuf encoding of TxBody. This should be encoding
    22  	// from the client using TxRaw if the tx was decoded from the wire
    23  	bodyBz []byte
    24  
    25  	// authInfoBz represents the protobuf encoding of TxBody. This should be encoding
    26  	// from the client using TxRaw if the tx was decoded from the wire
    27  	authInfoBz []byte
    28  
    29  	txBodyHasUnknownNonCriticals bool
    30  }
    31  
    32  var (
    33  	//_ authsigning.Tx             = &wrapper{}
    34  	//_ client.TxBuilder           = &wrapper{}
    35  	//_ ante.HasExtensionOptionsTx = &wrapper{}
    36  	_ ExtensionOptionsTxBuilder = &wrapper{}
    37  )
    38  
    39  // ExtensionOptionsTxBuilder defines a TxBuilder that can also set extensions.
    40  type ExtensionOptionsTxBuilder interface {
    41  	client.TxBuilder
    42  
    43  	SetExtensionOptions(...*codectypes.Any)
    44  	SetNonCriticalExtensionOptions(...*codectypes.Any)
    45  }
    46  
    47  func newBuilder() *wrapper {
    48  	return &wrapper{
    49  		tx: &tx.Tx{
    50  			Body: &tx.TxBody{},
    51  			AuthInfo: &tx.AuthInfo{
    52  				Fee: &tx.Fee{},
    53  			},
    54  		},
    55  	}
    56  }
    57  
    58  func (w *wrapper) GetMsgs() []ibcmsg.Msg {
    59  	return w.tx.GetMsgs()
    60  }
    61  
    62  func (w *wrapper) ValidateBasic() error {
    63  	return w.tx.ValidateBasic()
    64  }
    65  
    66  func (w *wrapper) getBodyBytes() []byte {
    67  	if len(w.bodyBz) == 0 {
    68  		// if bodyBz is empty, then marshal the body. bodyBz will generally
    69  		// be set to nil whenever SetBody is called so the result of calling
    70  		// this method should always return the correct bytes. Note that after
    71  		// decoding bodyBz is derived from TxRaw so that it matches what was
    72  		// transmitted over the wire
    73  		var err error
    74  		w.bodyBz, err = proto.Marshal(w.tx.Body)
    75  		if err != nil {
    76  			panic(err)
    77  		}
    78  	}
    79  	return w.bodyBz
    80  }
    81  
    82  func (w *wrapper) getAuthInfoBytes() []byte {
    83  	if len(w.authInfoBz) == 0 {
    84  		// if authInfoBz is empty, then marshal the body. authInfoBz will generally
    85  		// be set to nil whenever SetAuthInfo is called so the result of calling
    86  		// this method should always return the correct bytes. Note that after
    87  		// decoding authInfoBz is derived from TxRaw so that it matches what was
    88  		// transmitted over the wire
    89  		var err error
    90  		w.authInfoBz, err = proto.Marshal(w.tx.AuthInfo)
    91  		if err != nil {
    92  			panic(err)
    93  		}
    94  	}
    95  	return w.authInfoBz
    96  }
    97  
    98  func (w *wrapper) GetSigners() []sdk.AccAddress {
    99  	return w.tx.GetSigners()
   100  }
   101  
   102  func (w *wrapper) GetPubKeys() ([]cryptotypes.PubKey, error) {
   103  	signerInfos := w.tx.AuthInfo.SignerInfos
   104  	pks := make([]cryptotypes.PubKey, len(signerInfos))
   105  
   106  	for i, si := range signerInfos {
   107  		// NOTE: it is okay to leave this nil if there is no PubKey in the SignerInfo.
   108  		// PubKey's can be left unset in SignerInfo.
   109  		if si.PublicKey == nil {
   110  			continue
   111  		}
   112  
   113  		pkAny := si.PublicKey.GetCachedValue()
   114  		pk, ok := pkAny.(cryptotypes.PubKey)
   115  		if ok {
   116  			pks[i] = pk
   117  		} else {
   118  			return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "Expecting PubKey, got: %T", pkAny)
   119  		}
   120  	}
   121  
   122  	return pks, nil
   123  }
   124  
   125  func (w *wrapper) GetGas() uint64 {
   126  	return w.tx.AuthInfo.Fee.GasLimit
   127  }
   128  
   129  func (w *wrapper) GetFee() sdk.CoinAdapters {
   130  	return w.tx.AuthInfo.Fee.Amount
   131  }
   132  
   133  func (w *wrapper) FeePayer() sdk.AccAddress {
   134  	feePayer := w.tx.AuthInfo.Fee.Payer
   135  	if feePayer != "" {
   136  		payerAddr, err := sdk.AccAddressFromBech32(feePayer)
   137  		if err != nil {
   138  			panic(err)
   139  		}
   140  		return payerAddr
   141  	}
   142  	// use first signer as default if no payer specified
   143  	return w.GetSigners()[0]
   144  }
   145  
   146  func (w *wrapper) FeeGranter() sdk.AccAddress {
   147  	feePayer := w.tx.AuthInfo.Fee.Granter
   148  	if feePayer != "" {
   149  		granterAddr, err := sdk.AccAddressFromBech32(feePayer)
   150  		if err != nil {
   151  			panic(err)
   152  		}
   153  		return granterAddr
   154  	}
   155  	return nil
   156  }
   157  
   158  func (w *wrapper) GetMemo() string {
   159  	return w.tx.Body.Memo
   160  }
   161  
   162  // GetTimeoutHeight returns the transaction's timeout height (if set).
   163  func (w *wrapper) GetTimeoutHeight() uint64 {
   164  	return w.tx.Body.TimeoutHeight
   165  }
   166  
   167  func (w *wrapper) GetSignaturesV2() ([]signing.SignatureV2, error) {
   168  	signerInfos := w.tx.AuthInfo.SignerInfos
   169  	sigs := w.tx.Signatures
   170  	pubKeys, err := w.GetPubKeys()
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	n := len(signerInfos)
   175  	res := make([]signing.SignatureV2, n)
   176  
   177  	for i, si := range signerInfos {
   178  		// handle nil signatures (in case of simulation)
   179  		if si.ModeInfo == nil {
   180  			res[i] = signing.SignatureV2{
   181  				PubKey: pubKeys[i],
   182  			}
   183  		} else {
   184  			var err error
   185  			sigData, err := ModeInfoAndSigToSignatureData(si.ModeInfo, sigs[i])
   186  			if err != nil {
   187  				return nil, err
   188  			}
   189  			res[i] = signing.SignatureV2{
   190  				PubKey:   pubKeys[i],
   191  				Data:     sigData,
   192  				Sequence: si.GetSequence(),
   193  			}
   194  
   195  		}
   196  	}
   197  
   198  	return res, nil
   199  }
   200  
   201  func (w *wrapper) SetMsgs(msgs ...ibcmsg.Msg) error {
   202  	anys := make([]*codectypes.Any, len(msgs))
   203  
   204  	for i, msg := range msgs {
   205  		var err error
   206  		anys[i], err = codectypes.NewAnyWithValue(msg)
   207  		if err != nil {
   208  			return err
   209  		}
   210  	}
   211  
   212  	w.tx.Body.Messages = anys
   213  
   214  	// set bodyBz to nil because the cached bodyBz no longer matches tx.Body
   215  	w.bodyBz = nil
   216  
   217  	return nil
   218  }
   219  
   220  // SetTimeoutHeight sets the transaction's height timeout.
   221  func (w *wrapper) SetTimeoutHeight(height uint64) {
   222  	w.tx.Body.TimeoutHeight = height
   223  
   224  	// set bodyBz to nil because the cached bodyBz no longer matches tx.Body
   225  	w.bodyBz = nil
   226  }
   227  
   228  func (w *wrapper) SetMemo(memo string) {
   229  	w.tx.Body.Memo = memo
   230  
   231  	// set bodyBz to nil because the cached bodyBz no longer matches tx.Body
   232  	w.bodyBz = nil
   233  }
   234  
   235  func (w *wrapper) SetGasLimit(limit uint64) {
   236  	if w.tx.AuthInfo.Fee == nil {
   237  		w.tx.AuthInfo.Fee = &tx.Fee{}
   238  	}
   239  
   240  	w.tx.AuthInfo.Fee.GasLimit = limit
   241  
   242  	// set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo
   243  	w.authInfoBz = nil
   244  }
   245  
   246  func (w *wrapper) SetFeeAmount(coins sdk.CoinAdapters) {
   247  	if w.tx.AuthInfo.Fee == nil {
   248  		w.tx.AuthInfo.Fee = &tx.Fee{}
   249  	}
   250  
   251  	w.tx.AuthInfo.Fee.Amount = coins
   252  
   253  	// set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo
   254  	w.authInfoBz = nil
   255  }
   256  
   257  func (w *wrapper) SetFeePayer(feePayer sdk.AccAddress) {
   258  	if w.tx.AuthInfo.Fee == nil {
   259  		w.tx.AuthInfo.Fee = &tx.Fee{}
   260  	}
   261  
   262  	w.tx.AuthInfo.Fee.Payer = feePayer.String()
   263  
   264  	// set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo
   265  	w.authInfoBz = nil
   266  }
   267  
   268  func (w *wrapper) SetFeeGranter(feeGranter sdk.AccAddress) {
   269  	if w.tx.AuthInfo.Fee == nil {
   270  		w.tx.AuthInfo.Fee = &tx.Fee{}
   271  	}
   272  
   273  	w.tx.AuthInfo.Fee.Granter = feeGranter.String()
   274  
   275  	// set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo
   276  	w.authInfoBz = nil
   277  }
   278  
   279  func (w *wrapper) SetSignatures(signatures ...signing.SignatureV2) error {
   280  	n := len(signatures)
   281  	signerInfos := make([]*tx.SignerInfo, n)
   282  	rawSigs := make([][]byte, n)
   283  
   284  	for i, sig := range signatures {
   285  		var modeInfo *tx.ModeInfo
   286  		modeInfo, rawSigs[i] = SignatureDataToModeInfoAndSig(sig.Data)
   287  		any, err := codectypes.NewAnyWithValue(sig.PubKey)
   288  		if err != nil {
   289  			return err
   290  		}
   291  		signerInfos[i] = &tx.SignerInfo{
   292  			PublicKey: any,
   293  			ModeInfo:  modeInfo,
   294  			Sequence:  sig.Sequence,
   295  		}
   296  	}
   297  
   298  	w.setSignerInfos(signerInfos)
   299  	w.setSignatures(rawSigs)
   300  
   301  	return nil
   302  }
   303  
   304  func (w *wrapper) setSignerInfos(infos []*tx.SignerInfo) {
   305  	w.tx.AuthInfo.SignerInfos = infos
   306  	// set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo
   307  	w.authInfoBz = nil
   308  }
   309  
   310  func (w *wrapper) setSignatures(sigs [][]byte) {
   311  	w.tx.Signatures = sigs
   312  }
   313  
   314  func (w *wrapper) GetTx() sigtx.Tx {
   315  	return w
   316  }
   317  
   318  func (w *wrapper) GetProtoTx() *tx.Tx {
   319  	return w.tx
   320  }
   321  
   322  // Deprecated: AsAny extracts proto Tx and wraps it into Any.
   323  // NOTE: You should probably use `GetProtoTx` if you want to serialize the transaction.
   324  func (w *wrapper) AsAny() *codectypes.Any {
   325  	return codectypes.UnsafePackAny(w.tx)
   326  }
   327  
   328  // WrapTx creates a TxBuilder wrapper around a tx.Tx proto message.
   329  //func WrapTx(protoTx *tx.Tx) client.TxBuilder {
   330  //	return &wrapper{
   331  //		tx: protoTx,
   332  //	}
   333  //}
   334  
   335  func (w *wrapper) GetExtensionOptions() []*codectypes.Any {
   336  	return w.tx.Body.ExtensionOptions
   337  }
   338  
   339  func (w *wrapper) GetNonCriticalExtensionOptions() []*codectypes.Any {
   340  	return w.tx.Body.NonCriticalExtensionOptions
   341  }
   342  
   343  func (w *wrapper) SetExtensionOptions(extOpts ...*codectypes.Any) {
   344  	w.tx.Body.ExtensionOptions = extOpts
   345  	w.bodyBz = nil
   346  }
   347  
   348  func (w *wrapper) SetNonCriticalExtensionOptions(extOpts ...*codectypes.Any) {
   349  	w.tx.Body.NonCriticalExtensionOptions = extOpts
   350  	w.bodyBz = nil
   351  }