forked from tranvictor/walletarmy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecution_context.go
More file actions
170 lines (146 loc) · 4.59 KB
/
execution_context.go
File metadata and controls
170 lines (146 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package walletarmy
import (
"math/big"
"time"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
jarviscommon "github.com/tranvictor/jarvis/common"
"github.com/tranvictor/jarvis/networks"
)
// TxExecutionContext holds the state and parameters for transaction execution
type TxExecutionContext struct {
// Retry tracking
actualRetryCount int
// Configuration
numRetries int
sleepDuration time.Duration
txCheckInterval time.Duration
// Transaction parameters
txType uint8
from, to common.Address
value *big.Int
gasLimit uint64
extraGasLimit uint64
data []byte
network networks.Network
// Gas pricing (mutable during retries)
retryGasPrice float64
extraGasPrice float64
retryTipCap float64
extraTipCapGwei float64
// Gas price protection limits (caller-defined)
maxGasPrice float64
maxTipCap float64
// Transaction state
oldTxs map[string]*types.Transaction
retryNonce *big.Int
// Hooks
beforeSignAndBroadcastHook Hook
afterSignAndBroadcastHook Hook
gasEstimationFailedHook GasEstimationFailedHook
abis []abi.ABI
}
// NewTxExecutionContext creates a new transaction execution context
func NewTxExecutionContext(
numRetries int,
sleepDuration time.Duration,
txCheckInterval time.Duration,
txType uint8,
from, to common.Address,
value *big.Int,
gasLimit uint64, extraGasLimit uint64,
gasPrice float64, extraGasPrice float64,
tipCapGwei float64, extraTipCapGwei float64,
maxGasPrice float64, maxTipCap float64,
data []byte,
network networks.Network,
beforeSignAndBroadcastHook Hook,
afterSignAndBroadcastHook Hook,
abis []abi.ABI,
gasEstimationFailedHook GasEstimationFailedHook,
) (*TxExecutionContext, error) {
// Validate inputs
if numRetries < 0 {
numRetries = 0
}
if sleepDuration <= 0 {
sleepDuration = DefaultSleepDuration
}
if txCheckInterval <= 0 {
txCheckInterval = DefaultTxCheckInterval
}
// Validate addresses
if from == (common.Address{}) {
return nil, ErrFromAddressZero
}
// Validate network
if network == nil {
return nil, ErrNetworkNil
}
// Initialize value if nil
if value == nil {
value = big.NewInt(0)
}
// Set default maxGasPrice and maxTipCap if they are 0 (to avoid infinite loop)
if maxGasPrice == 0 {
maxGasPrice = gasPrice * MaxCapMultiplier
}
if maxTipCap == 0 {
maxTipCap = tipCapGwei * MaxCapMultiplier
}
return &TxExecutionContext{
actualRetryCount: 0,
numRetries: numRetries,
sleepDuration: sleepDuration,
txCheckInterval: txCheckInterval,
txType: txType,
from: from,
to: to,
value: value,
gasLimit: gasLimit,
extraGasLimit: extraGasLimit,
retryGasPrice: gasPrice,
extraGasPrice: extraGasPrice,
retryTipCap: tipCapGwei,
extraTipCapGwei: extraTipCapGwei,
maxGasPrice: maxGasPrice,
maxTipCap: maxTipCap,
data: data,
network: network,
oldTxs: make(map[string]*types.Transaction),
retryNonce: nil,
beforeSignAndBroadcastHook: beforeSignAndBroadcastHook,
afterSignAndBroadcastHook: afterSignAndBroadcastHook,
abis: abis,
gasEstimationFailedHook: gasEstimationFailedHook,
}, nil
}
// adjustGasPricesForSlowTx adjusts gas prices when a transaction is slow
// Returns true if adjustment was applied, false if limits were reached
func (ctx *TxExecutionContext) adjustGasPricesForSlowTx(tx *types.Transaction) bool {
if tx == nil {
return false
}
// Increase gas price by configured percentage
currentGasPrice := jarviscommon.BigToFloat(tx.GasPrice(), 9)
newGasPrice := currentGasPrice * GasPriceIncreasePercent
// Check if new gas price would exceed the caller-defined maximum
if ctx.maxGasPrice > 0 && newGasPrice > ctx.maxGasPrice {
// Gas price would exceed limit - stop trying
return false
}
ctx.retryGasPrice = newGasPrice
// Increase tip cap by configured percentage
currentTipCap := jarviscommon.BigToFloat(tx.GasTipCap(), 9)
newTipCap := currentTipCap * TipCapIncreasePercent
// Check if new tip cap would exceed the caller-defined maximum
if ctx.maxTipCap > 0 && newTipCap > ctx.maxTipCap {
// Tip cap would exceed limit - stop trying
return false
}
ctx.retryTipCap = newTipCap
// Keep the same nonce
ctx.retryNonce = big.NewInt(int64(tx.Nonce()))
return true
}