Skip to content

Commit 618fece

Browse files
authored
fix(go/client): gas calculation for tx broadcast (#124)
derive parent tx factory to preserve parameters send via cli Signed-off-by: Artur Troian <[email protected]>
1 parent 3d15fce commit 618fece

File tree

1 file changed

+76
-36
lines changed
  • go/node/client/v1beta2

1 file changed

+76
-36
lines changed

go/node/client/v1beta2/tx.go

+76-36
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ import (
2727
)
2828

2929
var (
30-
ErrNotRunning = errors.New("tx client: not running")
31-
ErrSyncTimedOut = errors.New("tx client: timed-out waiting for sequence sync")
32-
ErrNodeCatchingUp = errors.New("tx client: cannot sync from catching up node")
33-
ErrAdjustGas = errors.New("tx client: couldn't adjust gas")
34-
ErrOffline = errors.New("tx client: cannot broadcast in offline mode")
30+
ErrNotRunning = errors.New("tx client: not running")
31+
ErrSyncTimedOut = errors.New("tx client: timed-out waiting for sequence sync")
32+
ErrNodeCatchingUp = errors.New("tx client: cannot sync from catching up node")
33+
ErrAdjustGas = errors.New("tx client: couldn't adjust gas")
34+
ErrSimulateOffline = errors.New("tx client: cannot simulate tx in offline mode")
35+
ErrBroadcastOffline = errors.New("tx client: cannot broadcast tx in offline mode")
3536
)
3637

3738
const (
@@ -118,13 +119,11 @@ func newSerialTx(ctx context.Context, cctx sdkclient.Context, flags *pflag.FlagS
118119
}
119120

120121
// populate account number, current sequence number
121-
poptxf, err := PrepareFactory(cctx, txf)
122+
txf, err = PrepareFactory(cctx, txf)
122123
if err != nil {
123124
return nil, err
124125
}
125126

126-
poptxf = poptxf.WithSimulateAndExecute(true)
127-
128127
client := &serialBroadcaster{
129128
ctx: ctx,
130129
cctx: cctx,
@@ -140,7 +139,7 @@ func newSerialTx(ctx context.Context, cctx sdkclient.Context, flags *pflag.FlagS
140139

141140
go client.lc.WatchContext(ctx)
142141
go client.run()
143-
go client.broadcaster(poptxf)
142+
go client.broadcaster(txf)
144143

145144
if !client.cctx.Offline {
146145
go client.sequenceSync()
@@ -234,20 +233,20 @@ loop:
234233
}
235234
}
236235

237-
func (c *serialBroadcaster) broadcaster(txf tx.Factory) {
238-
syncSequence := func(rErr error) bool {
236+
func (c *serialBroadcaster) broadcaster(ptxf tx.Factory) {
237+
syncSequence := func(f tx.Factory, rErr error) (uint64, bool) {
239238
if rErr != nil {
240239
if sdkerrors.ErrWrongSequence.Is(rErr) {
241240
// attempt to sync account sequence
242-
if rSeq, err := c.syncAccountSequence(txf.Sequence()); err == nil {
243-
txf = txf.WithSequence(rSeq + 1)
241+
if rSeq, err := c.syncAccountSequence(f.Sequence()); err == nil {
242+
return rSeq + 1, true
244243
}
245244

246-
return true
245+
return f.Sequence(), true
247246
}
248247
}
249248

250-
return false
249+
return f.Sequence(), false
251250
}
252251

253252
for {
@@ -258,12 +257,19 @@ func (c *serialBroadcaster) broadcaster(txf tx.Factory) {
258257
var err error
259258
var resp interface{}
260259

261-
resp, txf, err = AdjustGas(c.cctx, txf, req.msgs...)
262-
if err == nil && !c.cctx.Simulate {
260+
if c.cctx.GenerateOnly {
261+
resp, err = c.generateTxs(ptxf, req.msgs...)
262+
} else {
263263
done:
264264
for i := 0; i < 2; i++ {
265-
resp, txf, err = c.broadcastTxs(txf, req.msgs...)
266-
if !syncSequence(err) {
265+
var rseq uint64
266+
resp, rseq, err = c.broadcastTxs(ptxf, req.msgs...)
267+
ptxf = ptxf.WithSequence(rseq)
268+
269+
rSeq, synced := syncSequence(ptxf, err)
270+
ptxf = ptxf.WithSequence(rSeq)
271+
272+
if !synced {
267273
break done
268274
}
269275
}
@@ -275,8 +281,9 @@ func (c *serialBroadcaster) broadcaster(txf tx.Factory) {
275281
}
276282

277283
terr := &sdkerrors.Error{}
278-
if errors.Is(err, terr) {
279-
_ = syncSequence(err)
284+
if !c.cctx.GenerateOnly && errors.Is(err, terr) {
285+
rSeq, _ := syncSequence(ptxf, err)
286+
ptxf = ptxf.WithSequence(rSeq)
280287
}
281288

282289
select {
@@ -326,51 +333,84 @@ func (c *serialBroadcaster) sequenceSync() {
326333
}
327334
}
328335

329-
func (c *serialBroadcaster) broadcastTxs(txf tx.Factory, msgs ...sdk.Msg) (interface{}, tx.Factory, error) {
330-
var err error
336+
func (c *serialBroadcaster) generateTxs(txf tx.Factory, msgs ...sdk.Msg) ([]byte, error) {
337+
if txf.SimulateAndExecute() {
338+
if c.cctx.Offline {
339+
return nil, ErrSimulateOffline
340+
}
331341

332-
txn, err := tx.BuildUnsignedTx(txf, msgs...)
342+
_, adjusted, err := tx.CalculateGas(c.cctx, txf, msgs...)
343+
if err != nil {
344+
return nil, err
345+
}
346+
347+
txf = txf.WithGas(adjusted)
348+
}
349+
350+
utx, err := tx.BuildUnsignedTx(txf, msgs...)
333351
if err != nil {
334-
return nil, txf, err
352+
return nil, err
335353
}
336354

337-
txn.SetFeeGranter(c.cctx.GetFeeGranterAddress())
355+
data, err := c.cctx.TxConfig.TxJSONEncoder()(utx.GetTx())
356+
if err != nil {
357+
return nil, err
358+
}
359+
360+
return data, nil
361+
}
338362

339-
if c.cctx.GenerateOnly {
340-
bytes, err := c.cctx.TxConfig.TxJSONEncoder()(txn.GetTx())
363+
func (c *serialBroadcaster) broadcastTxs(txf tx.Factory, msgs ...sdk.Msg) (interface{}, uint64, error) {
364+
var err error
365+
var resp proto.Message
366+
367+
if txf.SimulateAndExecute() || c.cctx.Simulate {
368+
var adjusted uint64
369+
resp, adjusted, err = tx.CalculateGas(c.cctx, txf, msgs...)
341370
if err != nil {
342-
return nil, txf, err
371+
return nil, txf.Sequence(), err
343372
}
344373

345-
return bytes, txf, nil
374+
txf = txf.WithGas(adjusted)
375+
}
376+
377+
if c.cctx.Simulate {
378+
return resp, txf.Sequence(), nil
379+
}
380+
381+
txn, err := tx.BuildUnsignedTx(txf, msgs...)
382+
if err != nil {
383+
return nil, txf.Sequence(), err
346384
}
347385

348386
if c.cctx.Offline {
349-
return nil, txf, ErrOffline
387+
return nil, txf.Sequence(), ErrBroadcastOffline
350388
}
351389

390+
txn.SetFeeGranter(c.cctx.GetFeeGranterAddress())
391+
352392
err = tx.Sign(txf, c.info.GetName(), txn, true)
353393
if err != nil {
354-
return nil, txf, err
394+
return nil, txf.Sequence(), err
355395
}
356396

357397
bytes, err := c.cctx.TxConfig.TxEncoder()(txn.GetTx())
358398
if err != nil {
359-
return nil, txf, err
399+
return nil, txf.Sequence(), err
360400
}
361401

362402
response, err := c.doBroadcast(c.cctx, bytes, c.broadcastTimeout)
363403
if err != nil {
364-
return response, txf, err
404+
return response, txf.Sequence(), err
365405
}
366406

367407
if response.Code != 0 {
368-
return response, txf, sdkerrors.ABCIError(response.Codespace, response.Code, response.RawLog)
408+
return response, txf.Sequence(), sdkerrors.ABCIError(response.Codespace, response.Code, response.RawLog)
369409
}
370410

371411
txf = txf.WithSequence(txf.Sequence() + 1)
372412

373-
return response, txf, nil
413+
return response, txf.Sequence(), nil
374414
}
375415

376416
func (c *serialBroadcaster) syncAccountSequence(lSeq uint64) (uint64, error) {

0 commit comments

Comments
 (0)