-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
generalized fee estimation interface #8561
generalized fee estimation interface #8561
Conversation
66d6f7f
to
625c44f
Compare
I see that you haven't updated any CHANGELOG files. Would it make sense to do so? |
1a16b68
to
1a7ed11
Compare
0b7a3f3
to
68f7dad
Compare
Can you link the ticket in the PR description? |
Done. Added in the main comment |
core/chains/evm/gas/models.go
Outdated
type PriorAttempt interface { | ||
GetGasPrice() *assets.Wei | ||
DynamicFee() DynamicFee | ||
type PriorAttempt[FEE any, HASH any] interface { |
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.
Are all the below functions for PriorAttempt needed by generic components?
I see most are only needed by the EVM gas estimators.
Could we try to expose here only the minimum set of fields?
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.
The PriorAttempt
is kind of interesting since all of the methods defined in that interface are only used by gas estimators. The TXM directly interacts with the TxAttempt
struct underneath and provides these interfaces for the estimators to access the data. It seems like the opposite to the headtracker where the headtracker service defines the head struct/object and the txm + estimators are consumers vs the estimators are consumers of the tx object the txm creates
I think as I'm working on the TxAttemptBuilder I will have to look at this part again since we might be able to remove that interface abstraction and use a generically typed object...either way the user shouldn't need to define functionality for PriorAttempt
as for a minimum set of fields, I think it's already pretty minimal with returning the fee, tx type, tx hash, fee limit, block number restrictions
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.
Sounds good. Let us look at it while doing the TxAttemtBuilder.
if err != nil { | ||
return errors.Wrap(err, "tryAgainWithNewEstimation failed to estimate gas"), true | ||
} | ||
lgr.Warnw("L2 rejected transaction due to incorrect fee, re-estimated and will try again", | ||
"etxID", etx.ID, "err", err, "newGasPrice", gasPrice, "newGasLimit", gasLimit) | ||
return eb.tryAgainWithNewLegacyGas(ctx, lgr, etx, attempt, initialBroadcastAt, gasPrice, gasLimit) | ||
|
||
// TODO: nil handling for gasPrice.Legacy? will this ever be reached where EIP1559 is enabled on a L2 but a legacy tx? |
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.
I think the TxType is already decided when we initialize a chain, so this shouldn't ever happen.
We should actually extract out legacy/dynamic fees from here eventually, and even in EVM specific gas estimators, they can be instantiated once, with config option telling whether they're on legacy fees, or dynamic.
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.
the scenario I was thinking of is if we are already running on a chain and it enables EIP1559 fees, and we still have legacy txs in the DB - is that possible?
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.
also this abstraction will be done in the TxBuilder since it has to do with assembling the tx 😄
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.
Yes, good point about DB containing prior legacy attempts.
We could ask Node operators at the time of upgrade, to clear pending txes and attempts, but that is not ideal.
) | ||
|
||
// PriorAttempt provides a generic interface for reading tx data to be used in the fee esimators | ||
type PriorAttempt[FEE any, HASH any] interface { |
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.
Btw, I don't think there is any reason for the common TxMgr components to use PriorAttempt interface.
It already doesn't use it, except to pass it to Estimator.BumpGas().
I believe we could always just pass in previous Attempts in the form of a generic TxAttempt. And the chain specific code should know what to extract from it, to bump gas correctly.
Not for this PR, but for later, let us aim to completely do away with this interface, and just reuse TxAttempt.
If you want, create a separate subtask or ticket for this, for later.
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.
👍🏼 I will take a look at this part when I'm working with the TxBuilder
// FeeEstimator provides a generic interface for fee estimation | ||
// | ||
//go:generate mockery --quiet --name FeeEstimator --output ./mocks/ --case=underscore | ||
type FeeEstimator[HEAD any, FEE any, MAXPRICE any, HASH any] interface { |
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.
The MAXPRICE actually is also never needed to be passed in to estimator by the generic txmgr.
The Txmgr just reads a static config, and passes it in. Ideally it should be fetched directly by the estimator.
I would say, create a sub-task or ticket, to remove it from generic interface here later.
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.
How would it be fetched directly?
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.
This is used on a job-specific basis
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.
I would agree with Sam, I think it's still needed as it's a different config variable then the global chain configs and can be different for each tx
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.
This value is a keySpecfic config currently. GasEstimator can directly fetch that from config, if it has the Key available..
Here is a place where TxMgr currently fetches it:
keySpecificMaxGasPriceWei := ec.config.KeySpecificMaxGasPriceWei(etx.FromAddress) |
Doing this just makes it clear that the interface between coreTxm <--> GasEstimator doesn't require this value to be passed in.
This value is a static config defined for each Key.
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.
but then each gas estimator would need knowledge of the FromAddress
for each key. it seems simpler to just pass gas parameters instead of having the estimators have knowledge of additional configs + addresses
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.
I think this should be passed in. It is used in keepers I think, specifically (or used to be)
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.
For now, changes look good.
The pending things, we can tackle later, as doing it in 1 PR will just bloat this one.
// FeeEstimator provides a generic interface for fee estimation | ||
// | ||
//go:generate mockery --quiet --name FeeEstimator --output ./mocks/ --case=underscore | ||
type FeeEstimator[HEAD any, FEE any, MAXPRICE any, HASH any] interface { |
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.
I think this should be passed in. It is used in keepers I think, specifically (or used to be)
goal: all fee estimation logic should be handled by the estimator rather than the txm/broadcaster/confirmer logic
Estimator
interface =>EvmEstimator
Associated tickets:
https://smartcontract-it.atlassian.net/browse/BCI-888
https://smartcontract-it.atlassian.net/browse/BCI-873