Skip to content

Conversation

@swimricky
Copy link
Contributor

@swimricky swimricky commented Jun 12, 2023

Summary

  • change getUpdateFee to calculate the total fee based on the numUpdates for accumulator updates. Still uses same logic for batch price
  • lowers optimizer_runs to 2000 in order to get the bytesize down
    • optimizer_runs = 5000 had deployment size of 25046
      image
      diff between optimizer_runs = 2000 + this branch and main
      image
  • getUpdateFeeWhMerkleX is high b/c the original implementation returned singleUpdateFee * updateData.length

Note

  • Will make separate PR for optimizing bytesize further and increasing optimizer_runs to get as close to original 5000 runs

@vercel
Copy link

vercel bot commented Jun 12, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Ignored Deployments
Name Status Preview Comments Updated (UTC)
example-oracle-amm ⬜️ Ignored (Inspect) Jun 12, 2023 8:22pm
xc-admin-frontend ⬜️ Ignored (Inspect) Jun 12, 2023 8:22pm

uint requiredFee = getUpdateFee(updateData);
if (msg.value < requiredFee) revert PythErrors.InsufficientFee();

uint8 totalNumUpdates = 0;
Copy link
Contributor Author

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?

Copy link
Collaborator

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?

Copy link
Contributor Author

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?

Copy link
Collaborator

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.

@swimricky swimricky requested review from ali-behjati and jayantk and removed request for ali-behjati June 12, 2023 16:09
Comment on lines 124 to 128
if (totalNumUpdates > 0) {
return totalNumUpdates * singleUpdateFeeInWei();
} else {
return updateData.length * singleUpdateFeeInWei();
}
Copy link
Collaborator

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.

Copy link
Contributor

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.

Copy link
Contributor

@jayantk jayantk left a 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);
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Comment on lines 124 to 128
if (totalNumUpdates > 0) {
return totalNumUpdates * singleUpdateFeeInWei();
} else {
return updateData.length * singleUpdateFeeInWei();
}
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor

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)

Copy link
Contributor Author

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(
Copy link
Contributor

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jayantk I know that gas-aware protocols don't call this but I believe there are some people using getUpdateFee and it is also in our example contracts. (like this). So let's keep it.

Copy link
Contributor

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.

@swimricky
Copy link
Contributor Author

@ali-bahjati @jayantk
would not changing the batch price attestation updateFee to also be based on numAttestations possibly cause users to continue using batch prices due to cheaper fee?

@swimricky swimricky requested review from ali-behjati and jayantk June 12, 2023 18:48
@swimricky swimricky merged commit 19b77e2 into main Jun 13, 2023
@swimricky swimricky deleted the update-fee-num-updates branch June 13, 2023 14:25
@swimricky
Copy link
Contributor Author

copying @jayantk's response to above question for records

i think that outcome is unlikely because (a) the fee is so tiny right now that it doesn't matter, and (b) we're going to turn off batch prices so it won't be possible to use them soon enough

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants