|
1 | 1 | package client
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "bytes" |
5 | 4 | "encoding/json"
|
6 |
| - "fmt" |
7 | 5 | "strings"
|
8 | 6 | "sync"
|
9 | 7 | "sync/atomic"
|
10 | 8 | "time"
|
11 | 9 |
|
12 | 10 | "github.com/cosmos/cosmos-sdk/client"
|
13 |
| - "github.com/cosmos/cosmos-sdk/client/flags" |
14 | 11 | "github.com/cosmos/cosmos-sdk/client/tx"
|
15 | 12 | sdk "github.com/cosmos/cosmos-sdk/types"
|
16 | 13 | "github.com/pkg/errors"
|
@@ -214,25 +211,80 @@ func (c *cosmosClient) broadcastTx(
|
214 | 211 | msgs ...sdk.Msg,
|
215 | 212 | ) (*sdk.TxResponse, error) {
|
216 | 213 |
|
| 214 | + txf, err := c.prepareFactory(clientCtx, txf) |
| 215 | + if err != nil { |
| 216 | + err = errors.Wrap(err, "failed to prepareFactory") |
| 217 | + return nil, err |
| 218 | + } |
217 | 219 |
|
218 |
| - if await { |
219 |
| - clientCtx.BroadcastMode = flags.BroadcastBlock |
220 |
| - } else { |
221 |
| - clientCtx.BroadcastMode = flags.BroadcastSync |
| 220 | + if txf.SimulateAndExecute() || clientCtx.Simulate { |
| 221 | + _, adjusted, err := tx.CalculateGas(clientCtx, txf, msgs...) |
| 222 | + if err != nil { |
| 223 | + err = errors.Wrap(err, "failed to CalculateGas") |
| 224 | + return nil, err |
| 225 | + } |
| 226 | + |
| 227 | + txf = txf.WithGas(adjusted) |
| 228 | + } |
| 229 | + |
| 230 | + txn, err := tx.BuildUnsignedTx(txf, msgs...) |
| 231 | + if err != nil { |
| 232 | + err = errors.Wrap(err, "failed to BuildUnsignedTx") |
| 233 | + return nil, err |
| 234 | + } |
| 235 | + |
| 236 | + txn.SetFeeGranter(clientCtx.GetFeeGranterAddress()) |
| 237 | + err = tx.Sign(txf, clientCtx.GetFromName(), txn, true) |
| 238 | + if err != nil { |
| 239 | + err = errors.Wrap(err, "failed to Sign Tx") |
| 240 | + return nil, err |
222 | 241 | }
|
223 |
| - var buf bytes.Buffer |
224 |
| - clientCtx = clientCtx.WithOutput(&buf) |
225 |
| - if err := tx.BroadcastTx(clientCtx, txf, msgs...); err != nil { |
| 242 | + |
| 243 | + txBytes, err := clientCtx.TxConfig.TxEncoder()(txn.GetTx()) |
| 244 | + if err != nil { |
| 245 | + err = errors.Wrap(err, "failed TxEncoder to encode Tx") |
226 | 246 | return nil, err
|
227 | 247 | }
|
228 |
| - var resp sdk.TxResponse |
229 | 248 |
|
230 |
| - if err := clientCtx.JSONCodec.UnmarshalJSON(buf.Bytes(), &resp); err != nil { |
231 |
| - fmt.Println("❌ couldn't UnmarshalJSON") |
232 |
| - return nil, nil |
| 249 | + // broadcast to a Tendermint node |
| 250 | + if await { |
| 251 | + // BroadcastTxCommit - full synced commit with await |
| 252 | + res, err := clientCtx.BroadcastTxCommit(txBytes) |
| 253 | + return res, err |
| 254 | + } |
| 255 | + |
| 256 | + // BroadcastTxSync - only CheckTx, don't wait confirmation |
| 257 | + return clientCtx.BroadcastTxSync(txBytes) |
| 258 | +} |
| 259 | + |
| 260 | +// prepareFactory ensures the account defined by ctx.GetFromAddress() exists and |
| 261 | +// if the account number and/or the account sequence number are zero (not set), |
| 262 | +// they will be queried for and set on the provided Factory. A new Factory with |
| 263 | +// the updated fields will be returned. |
| 264 | +func (c *cosmosClient) prepareFactory(clientCtx client.Context, txf tx.Factory) (tx.Factory, error) { |
| 265 | + from := clientCtx.GetFromAddress() |
| 266 | + |
| 267 | + if err := txf.AccountRetriever().EnsureExists(clientCtx, from); err != nil { |
| 268 | + return txf, err |
| 269 | + } |
| 270 | + |
| 271 | + initNum, initSeq := txf.AccountNumber(), txf.Sequence() |
| 272 | + if initNum == 0 || initSeq == 0 { |
| 273 | + num, seq, err := txf.AccountRetriever().GetAccountNumberSequence(clientCtx, from) |
| 274 | + if err != nil { |
| 275 | + return txf, err |
| 276 | + } |
| 277 | + |
| 278 | + if initNum == 0 { |
| 279 | + txf = txf.WithAccountNumber(num) |
| 280 | + } |
| 281 | + |
| 282 | + if initSeq == 0 { |
| 283 | + txf = txf.WithSequence(seq) |
| 284 | + } |
233 | 285 | }
|
234 | 286 |
|
235 |
| - return &resp, nil |
| 287 | + return txf, nil |
236 | 288 | }
|
237 | 289 |
|
238 | 290 | func (c *cosmosClient) QueueBroadcastMsg(msgs ...sdk.Msg) error {
|
|
0 commit comments