-
Notifications
You must be signed in to change notification settings - Fork 308
[ethereum] - charge updateFee per number of updates #878
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
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ |
| uint requiredFee = getUpdateFee(updateData); | ||
| if (msg.value < requiredFee) revert PythErrors.InsufficientFee(); | ||
|
|
||
| uint8 totalNumUpdates = 0; |
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.
@ali-bahjati is uint8 enough for holding the total number of updates we could get in one 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.
yeah i'm not sure we can fit more gas-wise (the block gas limit). That's why on wire format it's u8. Do you think people will need more?
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 would be for summing up all the individual numUpdates so depends on how big updateData could potentially be. I think for now 255 would be enough but we could possibly need more in the future?
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 ok ok. I might just change it to uint. Since word-size in evm is 32 bytes it shouldn't change much gas-wise.
| if (totalNumUpdates > 0) { | ||
| return totalNumUpdates * singleUpdateFeeInWei(); | ||
| } else { | ||
| return updateData.length * singleUpdateFeeInWei(); | ||
| } |
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.
You can make an else statement above and add totalNumUpdates by 1 if it's not accumulator. It will be cleaner.
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 I think this should be consistent with the other places the fee is calculated. Use getRequiredFee (or whatever you refactor it to) everywhere so there's a single place with the calculation.
jayantk
left a comment
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! I have a couple suggestions to improve this, but should be quick to do.
| i++; | ||
| } | ||
| } | ||
| uint requiredFee = getRequiredFee(totalNumUpdates, updateData.length); |
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 getRequiredFee is a confusing method because it embeds some conditional logic that isn't very easy for the reader to understand. Imo a better solution would be to have getFeeAccumulator and getFeeBatch, call those functions in the respective cases of the if, and have them set the requiredFee as a variable.
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 about this instead?
if (totalNumUpdates == 0){
totalNumUpdates = updateData.length;
}
requiredFee = getTotalFee(totalNumUpdates);
the signatures between getFeeAccumulator & getFeeBatch are the same so for saving on bytesize maybe it would be best to not have 2 separate getFeeXXX methods?
| if (totalNumUpdates > 0) { | ||
| return totalNumUpdates * singleUpdateFeeInWei(); | ||
| } else { | ||
| return updateData.length * singleUpdateFeeInWei(); | ||
| } |
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 I think this should be consistent with the other places the fee is calculated. Use getRequiredFee (or whatever you refactor it to) everywhere so there's a single place with the calculation.
| numUpdates | ||
| ) = extractWormholeMerkleHeaderDigestAndNumUpdates(encoded); | ||
| numUpdates, | ||
| encoded |
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 don't like that this method returns encoded now -- it makes the method signature for this function extremely confusing.
BTW I find the overall handling of byte arrays in this code to be confusing. You're using two different techniques to slice out bytes (creating new arrays pointing to slices + offset indexes), so it's very hard for the reader to understand what an index into an array represents.
Imo the best way to handle this would be to have 1 byte array (the whole updateData) and 1 offset that increments as bytes are consumed.
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.
(please don't address the comment about overall handling of byte arrays in this PR. You can do that separately if you'd like)
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.
changing this to return encoded was a workaround for hitting the stack too deep error.
I spoke to @ali-bahjati regarding slicing out bytes vs just reading offsets and he said the implementation being used should be dependent on whether or not we're "throwing away" the data or need to possibly re-read it. I agree that there's areas where the implementation could be more consistent but there's also a few bytesize & gas cost considerations I'm also taking into account. I'll revisit this in a separate PR
| } | ||
| } | ||
|
|
||
| function parseWormholeMerkleHeaderNumUpdates( |
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.
IMO it's better to reuse the method above instead of adding this. I don't think getUpdateFee needs to be efficient now, since it's only used by off-chain callers.
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.
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.
ah yes good point about that on-chain usage.
|
@ali-bahjati @jayantk |
…lean up unused code
|
copying @jayantk's response to above question for records
|
Summary
getUpdateFeeto calculate the total fee based on the numUpdates for accumulator updates. Still uses same logic for batch pricediff between optimizer_runs = 2000 + this branch and main
getUpdateFeeWhMerkleXis high b/c the original implementation returned singleUpdateFee * updateData.lengthNote