Skip to content

Conversation

@lu-pinto
Copy link
Member

@lu-pinto lu-pinto commented Mar 31, 2025

PR description

Implement new PAY opcode

Fixed Issue(s)

fixes #8438

Thanks for sending a pull request! Have you done the following?

  • Checked out our contribution guidelines?
  • Considered documentation and added the doc-change-required label to this PR if updates are required.
  • Considered the changelog and included an update if required.
  • For database changes (e.g. KeyValueSegmentIdentifier) considered compatibility and performed forwards and backwards compatibility tests

Locally, you can run these tests to catch failures early:

  • spotless: ./gradlew spotlessApply
  • unit tests: ./gradlew build
  • acceptance tests: ./gradlew acceptanceTest
  • integration tests: ./gradlew integrationTest
  • reference tests: ./gradlew ethereum:referenceTests:referenceTests

Copy link

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

Saw this on discord, did a quick skim-through of this :)

final boolean accountIsWarm = frame.warmUpAddress(to);

if (frame.isStatic() && hasValue && !Objects.equals(frame.getSenderAddress(), to)) {
return new OperationResult(cost(to, true, recipient, true), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE);

Choose a reason for hiding this comment

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

EIP will need clarification for this, but if you use the CALL opcode and you send value (also to self) in a static context, this is not allowed and will throw.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes but isn't it what StaticCall actually is? A Call with no value that does not change any state. But EIP should be clarified for sure

Copy link
Member Author

Choose a reason for hiding this comment

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

One can argue that static calls don't do logs though so you be correct

Choose a reason for hiding this comment

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

Yes but isn't it what StaticCall actually is? A Call with no value that does not change any state. But EIP should be clarified for sure

Note that I'm talking about a PAY with value, but the PAY is actually to the current address. So the state does not change. The EIP will need clarification for this. But, note for the CALL opcode that if value is being sent in a STATICCALL context, the opcode will exceptionally abort (so even though no state is changed if it would be executed).

I will open a PR for this against the EIP.


final Bytes toAddressBytes = frame.getStackItem(1);
if (toAddressBytes.size() > 20
&& toAddressBytes.numberOfLeadingZeroBytes() < 12) {

Choose a reason for hiding this comment

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

Does the stack trim zeros by default? If not, what if I push 21 bytes to the stack with a leading 0 and an address of 20 nonzero bytes? This throws, but should be valid.

Choose a reason for hiding this comment

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

PUSH0 PUSH21 00<20 nonzero bytes> PAY maybe?

}

final Address to = Words.toAddress(toAddressBytes);
final Wei value = Wei.wrap(frame.getStackItem(0));

Choose a reason for hiding this comment

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

I believe the stack is [addr, val, ...] and it seems to be implemented [val, addr, ...] here. So stack[0] should be val and stack[1] addr.
image

}
if (accountIsWarm
//TODO: what about precompile accounts?
|| gasCalculator().isPrecompile(to)) {

Choose a reason for hiding this comment

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

Precompiles are added to warm addresses by default
image

https://eips.ethereum.org/EIPS/eip-2929#parameters

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, thanks good to know. This is just the way Besu does it not sure why but in the end it's the same thing.

@lu-pinto lu-pinto force-pushed the implement-PAY-opcode branch from cd7bd61 to 8a9e838 Compare April 2, 2025 15:10
@lu-pinto
Copy link
Member Author

lu-pinto commented Apr 2, 2025

Saw this on discord, did a quick skim-through of this :)

Thanks for the review, fixes a few things based on that

@jflo jflo added this to Osaka May 1, 2025
@jflo jflo moved this to Todo in Osaka May 1, 2025
@jflo jflo moved this from Todo to In Progress in Osaka May 1, 2025
@github-actions
Copy link

github-actions bot commented May 4, 2025

This pr is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the Stale label May 4, 2025
Copy link
Contributor

@macfarla macfarla left a comment

Choose a reason for hiding this comment

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

@lu-pinto what do we have to change to make this independent of EOF?

@lu-pinto
Copy link
Member Author

@lu-pinto what do we have to change to make this independent of EOF?

Just adding it at the right hardfork configuration and aligning the return value with current EVM opcodes (*CALL).
There are also some changes happening to PAY as we speak that haven't been merge which I haven't had the time to check: ethereum/EIPs#9590

@github-actions github-actions bot removed the Stale label May 13, 2025
@lu-pinto lu-pinto force-pushed the implement-PAY-opcode branch 2 times, most recently from 76adc11 to 7c9b02b Compare May 15, 2025 09:31
@macfarla macfarla added Osaka Osaka fork related - part of Fusaka and removed Fusaka labels May 20, 2025
@lu-pinto lu-pinto force-pushed the implement-PAY-opcode branch from d26b61b to 42876ba Compare May 20, 2025 15:40
@lu-pinto lu-pinto marked this pull request as ready for review May 20, 2025 15:40
lu-pinto added 8 commits May 21, 2025 17:26
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
@lu-pinto lu-pinto force-pushed the implement-PAY-opcode branch from 91e61a3 to 8056897 Compare May 21, 2025 16:29
@lu-pinto lu-pinto merged commit 731e940 into hyperledger:main May 21, 2025
48 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Osaka May 21, 2025
@lu-pinto lu-pinto self-assigned this Dec 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Osaka Osaka fork related - part of Fusaka

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

Implement PAY opcode

4 participants