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 }