Skip to content

Conversation

@lukelee-sl
Copy link
Contributor

Description:

Create a contract service interface that allows for the updating of the byte code for an EOA and use it from the token service.

Related issue(s):

Fixes #22409

Notes for reviewer:

Checklist

  • Documented (Code comments, README, etc.)
  • Tested (unit, integration, etc.)

Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
@lfdt-bot
Copy link

lfdt-bot commented Dec 4, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@lukelee-sl lukelee-sl marked this pull request as draft December 4, 2025 15:55
Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
@lukelee-sl lukelee-sl self-assigned this Dec 4, 2025
@lukelee-sl lukelee-sl added this to the v0.70 milestone Dec 4, 2025
Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
@codecov
Copy link

codecov bot commented Dec 4, 2025

Codecov Report

❌ Patch coverage is 32.69231% with 35 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...vice/contract/impl/ContractServiceApiProvider.java 4.76% 20 Missing ⚠️
...rvice/token/impl/handlers/CryptoCreateHandler.java 20.00% 2 Missing and 2 partials ⚠️
...rvice/token/impl/handlers/CryptoUpdateHandler.java 20.00% 2 Missing and 2 partials ⚠️
...ontract/impl/state/WritableContractStateStore.java 0.00% 3 Missing ⚠️
.../impl/exec/delegation/CodeDelegationProcessor.java 0.00% 1 Missing ⚠️
...act/impl/exec/delegation/CodeDelegationResult.java 50.00% 1 Missing ⚠️
...ract/impl/handlers/EthereumTransactionHandler.java 50.00% 0 Missing and 1 partial ⚠️
...ontract/impl/state/ReadableContractStateStore.java 0.00% 1 Missing ⚠️

Impacted file tree graph

@@                         Coverage Diff                          @@
##             feature/hedera-evm-pectra-support   #22429   +/-   ##
====================================================================
  Coverage                                     ?   70.84%           
  Complexity                                   ?    24497           
====================================================================
  Files                                        ?     2673           
  Lines                                        ?   104543           
  Branches                                     ?    11002           
====================================================================
  Hits                                         ?    74067           
  Misses                                       ?    26411           
  Partials                                     ?     4065           
Files with missing lines Coverage Δ Complexity Δ
.../hedera/node/app/workflows/FacilityInitModule.java 27.27% <100.00%> (ø) 5.00 <0.00> (?)
...ows/standalone/impl/StandaloneDispatchFactory.java 95.58% <100.00%> (ø) 5.00 <1.00> (?)
...app/service/contract/impl/ContractServiceImpl.java 97.05% <100.00%> (ø) 8.00 <1.00> (?)
...ontract/impl/exec/gas/HederaGasCalculatorImpl.java 96.55% <100.00%> (ø) 11.00 <1.00> (?)
...era/node/app/service/contract/ContractService.java 66.66% <ø> (ø) 2.00 <0.00> (?)
.../impl/exec/delegation/CodeDelegationProcessor.java 83.92% <0.00%> (ø) 20.00 <0.00> (?)
...act/impl/exec/delegation/CodeDelegationResult.java 88.88% <50.00%> (ø) 4.00 <1.00> (?)
...ract/impl/handlers/EthereumTransactionHandler.java 78.88% <50.00%> (ø) 15.00 <0.00> (?)
...ontract/impl/state/ReadableContractStateStore.java 88.23% <0.00%> (ø) 10.00 <0.00> (?)
...ontract/impl/state/WritableContractStateStore.java 86.36% <0.00%> (ø) 9.00 <0.00> (?)
... and 3 more

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codacy-production
Copy link

codacy-production bot commented Dec 4, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for 74bc9fb1 42.31%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (74bc9fb) Report Missing Report Missing Report Missing
Head commit (067f6be) 104448 78088 74.76%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#22429) 52 22 42.31%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
Signed-off-by: Luke Lee <luke.lee@hashgraph.com>
* If this field is set, a call to the account's address within a smart contract will
* result in the code of the authorized contract being executed.
*/
bytes delegation_address = 21;
Copy link
Contributor

@jsync-swirlds jsync-swirlds Dec 10, 2025

Choose a reason for hiding this comment

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

Just curious, wouldn't it be more efficient to store the contractID here (and in CryptoCreate)?

Also, do we need to update the Account definition with this new field?

Copy link
Contributor Author

@lukelee-sl lukelee-sl Dec 10, 2025

Choose a reason for hiding this comment

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

From the perspective of Hedera a contactID could make sense but from the perspective of the EVM, it does not, as everywhere it is used a 2 byte indicator plus the 20 byte EVM address is expected. Every place the indicator is used (including likely in the Besu code) we would have to construct these bytes from the contract alias if we used the contractID.

The ultimate storage location of these bytes is in the ContractStateStore which has a map of AccountID (key) to delegation indicator (the 24 bytes specified above). In order to achieve this storage, this pr introduces a Contract service api so that token service can ask the contract service to save the bytes away in the correct store. Having these bytes in the Account definition would not serve a purpose unless mirror node needs it by my understanding is that the updates in the state_changes.proto as well as the record produced by the crypto_update and crypto_create transaction body is enough to indicate that the delegation_indicator for the Account has changed. Please let me know if you think otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems there is some complexity here; so you are welcome to ping me for a short chat to discuss further if that would help.

Assuming that might not be optimal, I apologize in advance for the length of this response.

Let me try to understand this, and include some point-by-point thoughts.

  1. This is intended to support contract calls from the EVM, and is not in any way intended to support native Hiero clients
  2. This data is stored in the ContractStateStore, not in the Account.
  3. You are adding a field to the native Hiero account creation and update transactions for a value that is not part of the account and is not stored with the account.

Given that understanding, I believe this is the wrong place to add this data entirely. We should not, in my opinion, be trying to assign entries in the ContractStateStore via the creation and update of the native Account.
My recommendation would be that either this is a contract operation, implemented via the EVM and possibly a precompile, or it is a new transaction on the SmartContract service to add an account to delegate to a contract (e.g. something like addDelegatingAccount(Contract, AccountID)). In either case the data would then make perfect sense as being stored exclusively in the state managed by the Smart Contract service and would only be referred to when executing a smart contract call (the Smart Contract service would execute the relevant smart contract on encountering the account ID bytes rather than calling out to the native services).

The problem with the approach as described is twofold:

  1. Anything in a native account create or update is expected to be visible when querying that account, and this value is not. Generally any non-repeated value in an entity creation transaction is expected to be stored with that entity as well.
  2. This modifies the native Hiero API (HAPI) with a field that is completely irrelevant to a regular native HAPI Account and while it could be set; it's meaning and function are almost completely opaque to the native API user.

In summary that Adding this field to the native API here, but then storing it only with smart contracts and in such a manner that it is only ever useable from smart contracts, seems like it's either backwards or missing something important.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes there are some complexities with the definition. I understand your concerns but maybe a conversation will help clarify the intent.

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