-
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
billing config override #12536
billing config override #12536
Conversation
I see you updated files related to |
if (address(billingConfigOverridden.priceFeed) != ZERO_ADDRESS) { | ||
// use the overridden configs | ||
paymentParams.billingToken.gasFeePPB = billingConfigOverridden.gasFeePPB; | ||
paymentParams.billingToken.flatFeeMicroLink = billingConfigOverridden.flatFeeMicroLink; |
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.
@RyanRHall comparing the BillingConfig struct and this PaymentsParams struct, I think only these 2 configs are override-able. Let me know if anything else to override?
also, since the _calculatePaymentAmount
func is upkeepID agnostic, i hope it is okay to override before the _calculatePaymentAmount call.
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.
hey sorry this was a bit confusing. I think you could define a new struct, something like...
struct BillingOverrides {
gasFeePPB;
flatFeeMicroLink; // note this will become flatFeeMilliCents soon
}
@@ -705,6 +710,8 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { | |||
maxL1Fee = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(maxCalldataSize); | |||
} | |||
|
|||
// TODO: this is for checkupkeep, I guess we also need to override the billing config based on upkeep ID? |
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.
IIUC, we also need to override for checkUpkeep too.
Go solidity wrappers are out-of-date, regenerate them via the |
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.
looks great 👍 just a couple small requests :)
*/ | ||
struct BillingOverrides { | ||
uint32 gasFeePPB; | ||
uint24 flatFeeMicroLink; |
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.
Update to flatFeeMilliCents after rebase :)
if (s_upkeep[upkeepId].overridesEnabled) { | ||
BillingOverrides memory billingOverrides = s_billingOverrides[upkeepId]; | ||
// use the overridden configs | ||
paymentParams.gasFeePPB = billingOverrides.gasFeePPB; | ||
paymentParams.flatFeeMicroLink = billingOverrides.flatFeeMicroLink; | ||
} |
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.
what do you think of moving this code into _calculatePaymentAmount()
? We could add upkeepID
and overridesEnabled
as fields of PaymentParams
? this way the override code is all in one place and we don't have to write the same logic twice. Not a strong opinion!
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.
100% agreed on reusing code wherever possible. I actually thought (see in another comment) about moving the overriding logic to _calculatePaymentAmount()
, but figured that it is dryer to have the override outside of it.
The main reason is that struct PaymentParams
, struct BillingTokenPaymentParams
and _calculatePaymentAmount()
are all pure payment related and agnostic to upkeep ID. I feel better if we just do the override beforehand, get the right PaymentParams
and pass in to the _calculate
func and structs. so the payment related structs/func are not tied to upkeepID.
Also not a strong opinion, I do see the pros and cons on both sides...
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 to me, happy to leave it as it 👍
@@ -944,6 +966,13 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { | |||
PaymentParams memory paymentParams, | |||
uint256 upkeepId | |||
) internal returns (PaymentReceipt memory) { | |||
if (s_upkeep[upkeepId].overridesEnabled) { |
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 an extra SLOAD
- can we have this function accept this overridedEnabled
as an argument? We read the whole upkeep struct into memory in handleReport()
see above comment about adding overridedEnabled
and upkeepID
to PaymentParams
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.
adding overridedEnabled and upkeepID to PaymentParams
if the goal is to save gas, then I totally missed this. I think this is in hot path, gas usage should be prioritized.
In this _handlePayment()
func, we do have other places SLOAD
from s_upkeep
, do you think it worth putting them closer in one word? E.g.
uint96 balance = s_upkeep[upkeepId].balance;
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.
ooo yeah I think we can save two SLOADs here! Let's change handlePayment()
to have this sig...
function _handlePayment(
HotVars memory hotVars,
PaymentParams memory paymentParams,
uint256 upkeepId,
Upkeep memory upkeep
)
and then in _handleReport()
we just pass the upkeep separately like this...
_handlePayment(
hotVars,
PaymentParams({
// ...
}),
report.upkeepIds[i],
upkeepTransmitInfo[i].upkeep
);
* @param id the upkeepID | ||
* @param billingOverrides the override-able billing config | ||
*/ | ||
function setBillingOverrides(uint256 id, BillingOverrides calldata billingOverrides) external { |
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.
great use of calldata 👍
function setBillingOverrides(uint256 id, BillingOverrides calldata billingOverrides) external { | ||
_onlyPrivilegeManagerAllowed(); | ||
|
||
s_upkeep[id].overridesEnabled = true; | ||
s_billingOverrides[id] = billingOverrides; | ||
emit BillingConfigOverridden(id); | ||
} |
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.
in this function, could we add a check for valid upkeepID? aka revert if the upkeepID does not exist.
if (msg.sender != s_storage.upkeepPrivilegeManager) { | ||
revert OnlyCallableByUpkeepPrivilegeManager(); | ||
} | ||
_onlyPrivilegeManagerAllowed(); |
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.
nice, much cleaner 👍
Go solidity wrappers are out-of-date, regenerate them via the |
I see you updated files related to |
@@ -672,6 +672,7 @@ describe('AutomationRegistry2_3', () => { | |||
) | |||
|
|||
const conditionalPrice = await registry.getMaxPaymentForGas( | |||
upkeepId, |
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 use another PR to haul all those getMaxPaymentForGas
ts tests to foundry, so we can also further test the overrides logic. I hope that is okay.
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.
totally fine!
@@ -251,10 +253,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { | |||
*/ | |||
struct Upkeep { | |||
bool paused; | |||
bool overridesEnabled; |
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.
Note: this newly added field will not exist in IAutomationRegistryMaster2_3.sol -> UpkeepInfoLegacy
. But this shouldnt be a backward compatible issue.
Quality Gate passedIssues Measures |
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.
LGTM 🎉
@@ -428,6 +439,8 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { | |||
} | |||
|
|||
event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); | |||
event BillingConfigOverridden(uint256 indexed id); |
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.
can we add the BillingConfigOverride to this event?
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.
Do you mean renaming this event from BillingConfigOverridden
to BillingConfigOverride
?
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.
oh sorry I meant like event BillingConfigOverridden(uint256 indexed id, BillingConfigOverride override);
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.
Got it!
No description provided.