Skip to content
This repository was archived by the owner on May 11, 2024. It is now read-only.

Commit d734626

Browse files
feat(sender): improve default values setting (#628)
1 parent 05100b3 commit d734626

File tree

5 files changed

+57
-54
lines changed

5 files changed

+57
-54
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.21
55
require (
66
github.com/btcsuite/btcd/btcec/v2 v2.3.2
77
github.com/cenkalti/backoff/v4 v4.1.3
8+
github.com/creasty/defaults v1.7.0
89
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
910
github.com/ethereum/go-ethereum v1.13.14
1011
github.com/go-resty/resty/v2 v2.7.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBS
196196
github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
197197
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
198198
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
199+
github.com/creasty/defaults v1.7.0 h1:eNdqZvc5B509z18lD8yc212CAqJNvfT1Jq6L8WowdBA=
200+
github.com/creasty/defaults v1.7.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM=
199201
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
200202
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
201203
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

pkg/sender/common.go

+4-19
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package sender
33
import (
44
"fmt"
55
"math/big"
6-
"time"
76

7+
"github.com/creasty/defaults"
88
"github.com/ethereum/go-ethereum/common"
99
"github.com/ethereum/go-ethereum/core/types"
1010
"github.com/ethereum/go-ethereum/log"
@@ -142,26 +142,11 @@ func (s *Sender) buildTxData(tx *types.Transaction) (types.TxData, error) {
142142
}
143143
}
144144

145-
// setDefault sets the default value if the given value is 0.
146-
func setDefault[T uint64 | time.Duration](src, dest T) T {
147-
if src == 0 {
148-
return dest
149-
}
150-
return src
151-
}
152-
153145
// setConfigWithDefaultValues sets the config with default values if the given config is nil.
154146
func setConfigWithDefaultValues(config *Config) *Config {
155147
if config == nil {
156-
return DefaultConfig
157-
}
158-
return &Config{
159-
ConfirmationDepth: setDefault(config.ConfirmationDepth, DefaultConfig.ConfirmationDepth),
160-
MaxRetrys: setDefault(config.MaxRetrys, DefaultConfig.MaxRetrys),
161-
MaxWaitingTime: setDefault(config.MaxWaitingTime, DefaultConfig.MaxWaitingTime),
162-
GasLimit: setDefault(config.GasLimit, DefaultConfig.GasLimit),
163-
GasGrowthRate: setDefault(config.GasGrowthRate, DefaultConfig.GasGrowthRate),
164-
MaxGasFee: setDefault(config.MaxGasFee, DefaultConfig.MaxGasFee),
165-
MaxBlobFee: setDefault(config.MaxBlobFee, DefaultConfig.MaxBlobFee),
148+
config = new(Config)
166149
}
150+
_ = defaults.Set(config)
151+
return config
167152
}

pkg/sender/common_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package sender
2+
3+
import (
4+
"math"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestSetConfigWithDefaultValues(t *testing.T) {
12+
cfg := setConfigWithDefaultValues(&Config{MaxRetrys: 1, MaxBlobFee: 1024})
13+
assert.Equal(t, uint64(50), cfg.GasGrowthRate)
14+
assert.Equal(t, uint64(1), cfg.MaxRetrys)
15+
assert.Equal(t, 5*time.Minute, cfg.MaxWaitingTime)
16+
assert.Equal(t, uint64(math.MaxUint64), cfg.MaxGasFee)
17+
assert.Equal(t, uint64(1024), cfg.MaxBlobFee)
18+
19+
cfg = setConfigWithDefaultValues(nil)
20+
assert.Equal(t, cfg.GasGrowthRate, uint64(50))
21+
}

pkg/sender/sender.go

+29-35
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sender
33
import (
44
"context"
55
"crypto/ecdsa"
6+
"errors"
67
"fmt"
78
"math/big"
89
"os"
@@ -13,7 +14,6 @@ import (
1314
"github.com/ethereum/go-ethereum"
1415
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1516
"github.com/ethereum/go-ethereum/common"
16-
"github.com/ethereum/go-ethereum/common/math"
1717
"github.com/ethereum/go-ethereum/core/types"
1818
"github.com/ethereum/go-ethereum/log"
1919
cmap "github.com/orcaman/concurrent-map/v2"
@@ -28,33 +28,26 @@ var (
2828
nonceIncorrectRetrys = 3
2929
unconfirmedTxsCheckInternal = 2 * time.Second
3030
chainHeadFetchInterval = 3 * time.Second
31-
errTimeoutInMempool = fmt.Errorf("transaction in mempool for too long")
32-
DefaultConfig = &Config{
33-
ConfirmationDepth: 0,
34-
MaxRetrys: 0,
35-
MaxWaitingTime: 5 * time.Minute,
36-
GasGrowthRate: 50,
37-
MaxGasFee: math.MaxUint64,
38-
MaxBlobFee: math.MaxUint64,
39-
}
31+
errTimeoutInMempool = errors.New("transaction in mempool for too long")
32+
errToManyPendings = errors.New("too many pending transactions")
4033
)
4134

4235
// Config represents the configuration of the transaction sender.
4336
type Config struct {
4437
// The minimum block confirmations to wait to confirm a transaction.
45-
ConfirmationDepth uint64
38+
ConfirmationDepth uint64 `default:"0"`
4639
// The maximum retry times when sending transactions.
47-
MaxRetrys uint64
40+
MaxRetrys uint64 `default:"0"`
4841
// The maximum waiting time for the inclusion of transactions.
49-
MaxWaitingTime time.Duration
50-
42+
MaxWaitingTime time.Duration `default:"5m"`
5143
// The gas limit for transactions.
52-
GasLimit uint64
44+
GasLimit uint64 `default:"0"`
5345
// The gas rate to increase the gas price, 20 means 20% gas growth rate.
54-
GasGrowthRate uint64
46+
GasGrowthRate uint64 `default:"50"`
5547
// The maximum gas fee can be used when sending transactions.
56-
MaxGasFee uint64
57-
MaxBlobFee uint64
48+
MaxGasFee uint64 `default:"0xffffffffffffffff"` // Use `math.MaxUint64` as default value
49+
// The maximum blob gas fee can be used when sending transactions.
50+
MaxBlobFee uint64 `default:"0xffffffffffffffff"` // Use `math.MaxUint64` as default value
5851
}
5952

6053
// TxToConfirm represents a transaction which is waiting for its confirmation.
@@ -149,6 +142,7 @@ func NewSender(ctx context.Context, cfg *Config, client *rpc.EthClient, priv *ec
149142
return sender, nil
150143
}
151144

145+
// CLose closes the sender.
152146
func (s *Sender) Close() {
153147
close(s.stopCh)
154148
s.wg.Wait()
@@ -205,13 +199,19 @@ func (s *Sender) SendRawTransaction(
205199
data []byte,
206200
sidecar *types.BlobTxSidecar,
207201
) (string, error) {
202+
// If there are too many pending transactions to be confirmed, return an error here.
208203
if s.unconfirmedTxs.Count() >= unconfirmedTxsCap {
209-
return "", fmt.Errorf("too many pending transactions")
204+
return "", errToManyPendings
205+
}
206+
if nonce == 0 {
207+
nonce = s.nonce
210208
}
211209

212210
var (
213211
originalTx types.TxData
214212
opts = s.GetOpts()
213+
gasLimit = s.GasLimit
214+
err error
215215
)
216216
if sidecar != nil {
217217
opts.Value = value
@@ -222,28 +222,26 @@ func (s *Sender) SendRawTransaction(
222222
if err != nil {
223223
return "", err
224224
}
225-
blobTx.Nonce = setDefault(nonce, s.nonce)
225+
blobTx.Nonce = nonce
226226
originalTx = blobTx
227227
} else {
228-
gasLimit := s.GasLimit
229228
if gasLimit == 0 {
230-
var err error
231-
gasLimit, err = s.client.EstimateGas(s.ctx, ethereum.CallMsg{
229+
if gasLimit, err = s.client.EstimateGas(s.ctx, ethereum.CallMsg{
232230
From: opts.From,
233231
To: target,
234232
Value: value,
235233
Data: data,
236234
GasTipCap: opts.GasTipCap,
237235
GasFeeCap: opts.GasFeeCap,
238-
})
239-
if err != nil {
236+
}); err != nil {
240237
return "", err
241238
}
242239
}
240+
243241
originalTx = &types.DynamicFeeTx{
244242
ChainID: s.client.ChainID,
245243
To: target,
246-
Nonce: setDefault(nonce, s.nonce),
244+
Nonce: nonce,
247245
GasFeeCap: opts.GasFeeCap,
248246
GasTipCap: opts.GasTipCap,
249247
Gas: gasLimit,
@@ -252,12 +250,11 @@ func (s *Sender) SendRawTransaction(
252250
}
253251
}
254252

255-
txToConfirm := &TxToConfirm{
256-
originalTx: originalTx,
257-
}
253+
txToConfirm := &TxToConfirm{originalTx: originalTx}
258254

259255
if err := s.send(txToConfirm, false); err != nil && !strings.Contains(err.Error(), "replacement transaction") {
260-
log.Error("Failed to send transaction",
256+
log.Error(
257+
"Failed to send transaction",
261258
"txId", txToConfirm.ID,
262259
"nonce", nonce,
263260
"err", err,
@@ -276,18 +273,15 @@ func (s *Sender) SendRawTransaction(
276273
// SendTransaction sends a transaction to the given Ethereum node.
277274
func (s *Sender) SendTransaction(tx *types.Transaction) (string, error) {
278275
if s.unconfirmedTxs.Count() >= unconfirmedTxsCap {
279-
return "", fmt.Errorf("too many pending transactions")
276+
return "", errToManyPendings
280277
}
281278

282279
txData, err := s.buildTxData(tx)
283280
if err != nil {
284281
return "", err
285282
}
286283

287-
txToConfirm := &TxToConfirm{
288-
originalTx: txData,
289-
CurrentTx: tx,
290-
}
284+
txToConfirm := &TxToConfirm{originalTx: txData, CurrentTx: tx}
291285

292286
if err = s.send(txToConfirm, true); err != nil && !strings.Contains(err.Error(), "replacement transaction") {
293287
log.Error(

0 commit comments

Comments
 (0)