-
Notifications
You must be signed in to change notification settings - Fork 14
Oev 671 txm improvements #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
976ba44
e533378
a822f17
91c5a2d
81ef8e6
64f4d2f
7ef98a2
c3d4502
115e871
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package txm | |
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
| "math/big" | ||
|
|
||
|
|
@@ -13,24 +14,34 @@ import ( | |
| "github.com/smartcontractkit/chainlink-evm/pkg/gas" | ||
| "github.com/smartcontractkit/chainlink-evm/pkg/keys" | ||
| "github.com/smartcontractkit/chainlink-evm/pkg/txm/types" | ||
| "github.com/smartcontractkit/chainlink-framework/chains/fees" | ||
| ) | ||
|
|
||
| // maxBumpThreshold controls the maximum number of bumps for an attempt. | ||
| const maxBumpThreshold = 5 | ||
|
|
||
| type attemptBuilder struct { | ||
| gas.EvmFeeEstimator | ||
| priceMaxKey func(common.Address) *assets.Wei | ||
| keystore keys.TxSigner | ||
| priceMaxKey func(common.Address) *assets.Wei | ||
| keystore keys.TxSigner | ||
| emptyTxLimitDefault uint64 | ||
| } | ||
|
|
||
| func NewAttemptBuilder(priceMaxKey func(common.Address) *assets.Wei, estimator gas.EvmFeeEstimator, keystore keys.TxSigner) *attemptBuilder { | ||
| func NewAttemptBuilder(priceMaxKey func(common.Address) *assets.Wei, estimator gas.EvmFeeEstimator, keystore keys.TxSigner, emptyTxLimitDefault uint64) *attemptBuilder { | ||
| return &attemptBuilder{ | ||
| priceMaxKey: priceMaxKey, | ||
| EvmFeeEstimator: estimator, | ||
| keystore: keystore, | ||
| priceMaxKey: priceMaxKey, | ||
| EvmFeeEstimator: estimator, | ||
| keystore: keystore, | ||
| emptyTxLimitDefault: emptyTxLimitDefault, | ||
| } | ||
| } | ||
|
|
||
| func (a *attemptBuilder) NewAttempt(ctx context.Context, lggr logger.Logger, tx *types.Transaction, dynamic bool) (*types.Attempt, error) { | ||
| fee, estimatedGasLimit, err := a.EvmFeeEstimator.GetFee(ctx, tx.Data, tx.SpecifiedGasLimit, a.priceMaxKey(tx.FromAddress), &tx.FromAddress, &tx.ToAddress) | ||
| gasLimit := tx.SpecifiedGasLimit | ||
| if tx.IsPurgeable { | ||
| gasLimit = a.emptyTxLimitDefault | ||
| } | ||
| fee, estimatedGasLimit, err := a.EvmFeeEstimator.GetFee(ctx, tx.Data, gasLimit, a.priceMaxKey(tx.FromAddress), &tx.FromAddress, &tx.ToAddress) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
@@ -42,13 +53,52 @@ func (a *attemptBuilder) NewAttempt(ctx context.Context, lggr logger.Logger, tx | |
| } | ||
|
|
||
| func (a *attemptBuilder) NewBumpAttempt(ctx context.Context, lggr logger.Logger, tx *types.Transaction, previousAttempt types.Attempt) (*types.Attempt, error) { | ||
| bumpedFee, bumpedFeeLimit, err := a.EvmFeeEstimator.BumpFee(ctx, previousAttempt.Fee, tx.SpecifiedGasLimit, a.priceMaxKey(tx.FromAddress), nil) | ||
| gasLimit := tx.SpecifiedGasLimit | ||
| if tx.IsPurgeable { | ||
| gasLimit = a.emptyTxLimitDefault | ||
| } | ||
| bumpedFee, bumpedFeeLimit, err := a.EvmFeeEstimator.BumpFee(ctx, previousAttempt.Fee, gasLimit, a.priceMaxKey(tx.FromAddress), nil) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return a.newCustomAttempt(ctx, tx, bumpedFee, bumpedFeeLimit, previousAttempt.Type, lggr) | ||
| } | ||
|
|
||
| func (a *attemptBuilder) NewAgnosticBumpAttempt(ctx context.Context, lggr logger.Logger, tx *types.Transaction, dynamic bool) (*types.Attempt, error) { | ||
| attempt, err := a.NewAttempt(ctx, lggr, tx, dynamic) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // bump purge attempts | ||
| if tx.IsPurgeable { | ||
| // TODO: add better handling | ||
| for { | ||
| bumpedAttempt, err := a.NewBumpAttempt(ctx, lggr, tx, *attempt) | ||
| if err != nil { | ||
| if errors.Is(err, fees.ErrConnectivity) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm looking at the error choice. I believe this is due to the code located here It feels slightly counterintuitive to return ErrConnectivity for a value check, where ErrBumpFeeExceedsLimit might seem more natural. Is the intention to treat priorityFeeThreshold as a sanity guardrail (implying the network/estimator is broken if fees get this high) rather than a budget limit (implying the tx just needs to pay more)? If so, adding a small comment explaining why this triggers a 'connectivity' error would be helpful for readability. |
||
| return attempt, nil | ||
| } | ||
| return nil, fmt.Errorf("error bumping attempt for txID: %v, err: %w", tx.ID, err) | ||
| } | ||
| attempt = bumpedAttempt | ||
| } | ||
| } else { | ||
| // bump regular attempts | ||
| bumps := min(maxBumpThreshold, tx.AttemptCount) | ||
| for range bumps { | ||
| bumpedAttempt, err := a.NewBumpAttempt(ctx, lggr, tx, *attempt) | ||
| if err != nil { | ||
| lggr.Errorf("error bumping attempt: %v for txID: %v", err, tx.ID) | ||
| return attempt, nil | ||
| } | ||
| attempt = bumpedAttempt | ||
| } | ||
| } | ||
|
|
||
| return attempt, nil | ||
| } | ||
|
|
||
| func (a *attemptBuilder) newCustomAttempt( | ||
| ctx context.Context, | ||
| tx *types.Transaction, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to make a separate ticket with an explanation of what would be better here