7702 refactor, remove CodeDelegationAccount abstraction#8408
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR refactors code delegation handling by removing the CodeDelegationAccount abstraction and centralizing delegation logic into helper classes and services. Key changes include:
- Removal of CodeDelegationAccount, MutableCodeDelegationDelegationAccount, and related files.
- Introduction of CodeDelegationHelper and a simplified CodeDelegationService.
- Updates to tests, protocol spec configurations, and transaction processing logic to use the new delegation approach.
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| evm/src/main/java/org/hyperledger/besu/evm/operation/InsufficientGasException.java | New exception class for signaling insufficient gas during delegation resolution. |
| evm/src/main/java/org/hyperledger/besu/evm/worldstate/CodeDelegationHelper.java | Introduces helper methods for code delegation resolution. |
| ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationProcessor.java | Refactored to use WorldUpdater and a newly instantiated CodeDelegationService. |
| evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java | Updates to delegate code resolution, integrating the new helper methods and exception handling. |
| Other files | Removal of legacy code delegation account abstractions and adjustments in tests and transaction processing. |
Comments suppressed due to low confidence (1)
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java:264
- Consider replacing RuntimeException with a more specific exception type to clearly indicate the missing target account condition and improve downstream error handling.
throw new RuntimeException("A delegated code account must have a target account");
f8b0f59 to
b7304b2
Compare
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
2888729 to
1897206
Compare
...um/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
Outdated
Show resolved
Hide resolved
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/worldstate/CodeDelegationHelper.java
Show resolved
Hide resolved
| if (maybeTargetAccount.isEmpty()) { | ||
| throw new RuntimeException("A delegated code account must have a target account"); | ||
| } |
There was a problem hiding this comment.
I'm struggling to reconcile this error case with with the EIP spec or EELS - can you point out the relevant part of the spec please?
There was a problem hiding this comment.
Also think we are doing it twice: here and in CodeDelegationGasCostHelper.codeDelegationGasCost
There was a problem hiding this comment.
That is not part of the spec, just defensive programming. So whenever we get an optional we should check if it's empty before calling get()
There was a problem hiding this comment.
Is this a condition where we could diverge from other client behaviour and it could lead to consensus issues? If there are error conditions missing should we update the spec?
There was a problem hiding this comment.
I don't think so . Theoretically between line 259 where we call hasCodeDelegation() and between 266 where we call maybeTargetAccount.isEmpty() a bit could flip in memory and we are unable to recover the target account. I've just added it because AFAIK it best practive to always call isPresent() / !isEMpty() before getting an optional, but I can remove it if you think it's confusing.
There was a problem hiding this comment.
I don't think we should code around hardware bugs. But I think the error conditions should match across client implementations, and ideally be part of the spec.
If this can truly never happen then maybe it shouldn't be Optional?
There was a problem hiding this comment.
I've only just now realized that maybeTargetAccount isn't needed any further down the code and have completely removed it. It seems it was a leftover from a refactoring.
In any case I've removed the Optional from getTargetAccount to make it clear that it should only be used with accounts that have code delegation.
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/operation/InsufficientGasException.java
Outdated
Show resolved
Hide resolved
...um/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
Outdated
Show resolved
Hide resolved
…the constructor Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
…t of gas during code delegation resolution Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
...um/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
Show resolved
Hide resolved
matkt
left a comment
There was a problem hiding this comment.
Added comment but I will take more time tomorrow to check the code
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java
Outdated
Show resolved
Hide resolved
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java
Outdated
Show resolved
Hide resolved
…rdered balance check for code delegation resolution, reordered recId check Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
…too deep to be spec compliant Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
|
running hive tests on this PR - docker image 25.3-develop-07da3dc locally ran some other randomly chosen EIPs, no failures |
|
full run all passed |
…s with empty code hashes, remove unused methods from AccountState, reorder processCodeFromAccount to make it easier to read Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
| .thenReturn(ValidationResult.valid()); | ||
| when(worldState.getOrCreateSenderAccount(senderAddress)).thenReturn(senderAccount); | ||
| when(worldState.get(toAddress.get())).thenReturn(receiverAccount); | ||
| when(receiverAccount.getCodeHash()).thenReturn(Hash.fromHexStringLenient("0x1")); |
There was a problem hiding this comment.
The test assumes that messageCallProcessor.getCodeFromEVM() is called and prepares the mock for it in line 186. Therefor we need to return an non-empty code hash when receiverAccount.getCodeHash() is called.
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
Outdated
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
Show resolved
Hide resolved
evm/src/main/java/org/hyperledger/besu/evm/worldstate/CodeDelegationGasCostHelper.java
Outdated
Show resolved
Hide resolved
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>

PR description
Removes the CodeDelegationAbstraction to avoid calling
Account.getCode()every time that we retrieve an account.Fixed Issue(s)
fixes #8392
Thanks for sending a pull request! Have you done the following?
doc-change-requiredlabel to this PR if updates are required.Locally, you can run these tests to catch failures early:
./gradlew spotlessApply./gradlew build./gradlew acceptanceTest./gradlew integrationTest./gradlew ethereum:referenceTests:referenceTests