Skip to content
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

Ethereum: add optimized verification endpoint to the core bridge #3366

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

gator-boi
Copy link
Contributor

@gator-boi gator-boi commented Sep 8, 2023

The purpose of this PR is to add an optimized parseAndVerify endpoint to Messages.sol along with various other optimizations. See the following table for the estimated gas savings:

call before after savings
parseAndVerify 129k 83k 46k
parseVM 26.5k 16.2k 10.3k

SEJeff
SEJeff previously approved these changes Sep 27, 2023
Copy link
Collaborator

@SEJeff SEJeff left a comment

Choose a reason for hiding this comment

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

Feel free to tag me when it is actually ready to review if you want a re-ack.

ethereum/contracts/Getters.sol Outdated Show resolved Hide resolved
ethereum/contracts/GovernanceStructs.sol Outdated Show resolved Hide resolved
ethereum/contracts/Messages.sol Show resolved Hide resolved
ethereum/contracts/Messages.sol Outdated Show resolved Hide resolved
ethereum/contracts/Messages.sol Outdated Show resolved Hide resolved
ethereum/contracts/Setters.sol Show resolved Hide resolved
uint32 guardianSetIndex
) internal view returns (bytes memory signedTransfer) {
// construct `TransferWithPayload` Wormhole message
Structs.VM memory vm;
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you're ok with it, would you mind renaming vm --> vm_? It just makes me cringe a bit to shadow the forge test vm cheatcode god object.

vm.consistencyLevel = 15;
vm.payload = payload;

// encode the bservation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// encode the bservation
// encode the observation

@@ -161,4 +256,69 @@ contract TestMessages is Test {
assertEq(valid, false);
assertEq(reason, "vm.hash doesn't match body");
}

function testParseGuardianSetOptimized(uint8 guardianCount) public view {
vm.assume(guardianCount > 0 && guardianCount <= 19);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
vm.assume(guardianCount > 0 && guardianCount <= 19);
guardianCount = bound(guardianCount, 0, 19);

Per the forge docs for the assume cheatcode, for integers, it is best to use the bound cheatcode when fuzzing.

The way assume works with the fuzzer is that it tosses every fuzz test where the assume condition is false. Alternatively, bound simply constrains the integer within the given range. At high fuzz runs, more assumes will cause the fuzz test run to fail with max rejects.

ethereum/contracts/Messages.sol Outdated Show resolved Hide resolved
function parseGuardianSet(bytes calldata guardianSetData) public pure returns (Structs.GuardianSet memory guardianSet) {
// Fetch the guardian set length.
uint256 endGuardianKeyIndex = guardianSetData.length - 4;
uint256 guardianCount = endGuardianKeyIndex / 20;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it would be nice to specify that this 20 is the size of an address, perhaps with an ADDRESS_SIZE constant or something equivalent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed.

/// @dev Obtain the current guardianSet for the guardianSetIndex provided
Structs.GuardianSet memory guardianSet = getGuardianSet(vm.guardianSetIndex);

function verifyVMInternal(Structs.VM memory vm, Structs.GuardianSet memory guardianSet, bool checkHash) internal view returns (bool valid, string memory reason) {
Copy link
Collaborator

@scnale scnale Oct 5, 2023

Choose a reason for hiding this comment

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

I wonder, wouldn't it be better to actually have observer functions that let you parse a guardian key just in time instead of reading them all into an unpacked struct array like this?

@evan-gray evan-gray added the evm label Mar 14, 2024
}
_state.guardianSets[index] = set;
_state.guardianSets[index] = set;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: trailing spaces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants