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

EIP-7002: Validator Exit contract helper and adding exits to created blocks #6883

Merged
merged 27 commits into from
Apr 17, 2024

Conversation

lucassaldanha
Copy link
Member

@lucassaldanha lucassaldanha commented Apr 4, 2024

Sorry for the big PR! I tried to keep it more concise but lots of the pieces kinda work together so it was hard to separate them! Hopefully, it isn't too bad to review as a bulk of the changes are adding a parameter to a constructor or something like that... ❤️

This is an experimental implementation of EIP-7002 logic for adding exits from the Validator Exit smart contract into blocks (and including them on the execution payload object of the Engine API).

Summary of changes

  • Updated engine API method and ExecutionPayload structure to support exits
  • Implemented Validator Exit Contract Helper (contract storage manipulation)
  • Updated BlockCreator to include exits from the validator exit contract

fixes #6881 and #6882

Open Questions/Future Improvements

  • Do we need extra validation on AbstractBlockProcessor (e.g. check that we do not have more exits than expected). I have a feeling we do not need to as we are running the system logic as part of processing, so any difference between the exits in the block we are validating would be caught by a different exits_root post our processing. But I might be wrong. The same question applies to MainnetBlockBodyValidator. validateBodyLight().
  • The Validator Exits contract address might need to be parameterized for each network. The same applies to things like the maximum number of exits per block, etc.
  • Do we need to have ValidatorExitContractHelper behind a protocol schedule setup in case the contract goes through some changes in future upgrades?
  • We need to properly implement a system call to the Validator Exit contract, replacing the exiting contract storage manipulation in the Validator Exit Contract Helper. EIP-7002: Implement Validator Exit Contract system call #6918

Engine API changes

Most of the logic was already there, few pieces had to be added (e.g. constructor parameters but the core of the logic hasn't changed). The more important change is how GetPayloadV4 includes the exits in the execution payload.

Validator Exit Contract Helper

This is an initial implementation based on the work done by lightclient on the Validator Exit smart contract (https://github.com/lightclient/7002asm), and also using the bytecode defined in the EIP (https://eips.ethereum.org/EIPS/eip-7002#deployment).

Each exit uses 3 storage slots (each slot has 32 bytes). There is a bit of trickery to ensure they fit in exactly on 3 slots (some right/left padding depending on the field). The detailed diagram of the expected storage can be seen in this code.

UPDATE: contract manipulation is not the best way of implementing this. The smart contract actually has all the logic to handle the system call. All we need to do is implement the mechanism to perform "send a tx" from the system account. I believe we do not have this logic in Besu at the moment, the closest thing I can think of is how we use a fake transaction in the TransactionSimulator, but we would need a way of ensuring that changes in contract storage are persisted. See #6918

Including exits on blocks

The system call logic has been implemented in a way that manipulates the contract storage as if we were executing the call through the EVM (although no EVM is involved). This seems to be the expected behaviour for system calls. The heart of this is how AbstractBlockCreator uses ValidatorExitContractHelper.popExitsFromQueue(..).

@lucassaldanha lucassaldanha force-pushed the eip-7002-with-precompile branch 2 times, most recently from ced776d to 53758f0 Compare April 4, 2024 21:35
@lucassaldanha lucassaldanha changed the title Implemented Validator Exit contract helper EIP-7002: Validator Exit contract helper and adding exits to created blocks Apr 4, 2024
…tion payload for engineV4 methods

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
…ocks

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
@lucassaldanha lucassaldanha marked this pull request as ready for review April 9, 2024 11:05
Copy link
Contributor

@Gabriel-Trintinalia Gabriel-Trintinalia left a comment

Choose a reason for hiding this comment

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

Nice testing, PR looks good. I have added some comments.

Comment on lines +113 to +115
if (!validateExits(block, body.getExits().get())) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit:

Suggested change
if (!validateExits(block, body.getExits().get())) {
return false;
}
return validateExits(block, body.getExits().get());

Comment on lines 33 to 38
/**
* Helper for interacting with the Validator Exit Contract (https://eips.ethereum.org/EIPS/eip-7002)
*
* <p>Please note that this is not the spec-way of interacting with the Validator Exit contract. See
* https://github.com/hyperledger/besu/issues/6918 for more information.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/**
* Helper for interacting with the Validator Exit Contract (https://eips.ethereum.org/EIPS/eip-7002)
*
* <p>Please note that this is not the spec-way of interacting with the Validator Exit contract. See
* https://github.com/hyperledger/besu/issues/6918 for more information.
*/
/**
* Helper for interacting with the Validator Exit Contract (<a
* href="https://eips.ethereum.org/EIPS/eip-7002">eip-7002</a>)
*
* <p>TODO: Please note that this is not the spec-way of interacting with the Validator Exit
* contract. See <a href="https://github.com/hyperledger/besu/issues/6918">#6918</a> for more
* information.
*/

}

final List<ValidatorExit> exitsInBlock = block.getBody().getExits().get();
// TODO Do we need to allow for customization? (e.g. if the value changes in the next fork)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: We could rename it to PrageExitsValidator, and make it a standalone class. If the next fork needs to change this we can easily abstract a class override what we need.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Also, giving the validations, the semantics here are more like a RequiredExitsValidator than an AllowedExistsValidator.

@@ -197,6 +197,12 @@ public BlockProcessingResult processBlock(
}
}

final ValidatorExitsValidator exitsValidator = protocolSpec.getExitsValidator();
if (exitsValidator instanceof ValidatorExitsValidator.AllowedExits) {
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 that the verification to perform the popping should belong to the validator/processor itself and not the blockprocessor. Maybe an extra method allowExists()?

Comment on lines 87 to 90
if (block.getHeader().getExitsRoot().isEmpty()) {
LOG.warn("Block {} must contain exits_root", blockHash);
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This piece should be probably in a headervalidationrules instead of here

Comment on lines 105 to 110
final Hash expectedExitsRoot = BodyValidation.exitsRoot(exitsInBlock);
if (!expectedExitsRoot.equals(block.getHeader().getExitsRoot().get())) {
LOG.warn(
"Block {} exits_root does not match expected hash root for exits in block", blockHash);
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

s.a

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Copy link
Contributor

@Gabriel-Trintinalia Gabriel-Trintinalia left a comment

Choose a reason for hiding this comment

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

LGTM

@lucassaldanha lucassaldanha enabled auto-merge (squash) April 17, 2024 20:31
@lucassaldanha lucassaldanha merged commit 6143283 into hyperledger:main Apr 17, 2024
42 checks passed
@lucassaldanha lucassaldanha deleted the eip-7002-with-precompile branch April 17, 2024 21:00
amsmota pushed a commit to Citi/besu that referenced this pull request Apr 18, 2024
…blocks (hyperledger#6883)

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Signed-off-by: Antonio Mota <antonio.mota@citi.com>
macfarla pushed a commit to macfarla/besu that referenced this pull request Apr 26, 2024
…blocks (hyperledger#6883)

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
matthew1001 pushed a commit to kaleido-io/besu that referenced this pull request Jun 7, 2024
…blocks (hyperledger#6883)

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
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.

EIP-7002 - Implement Validator Exit contract helper
2 participants