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

Add support for movePrecompileToAddress in State Overrides (eth_call) #8115

Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Implement EIP-7840: Add blob schedule to config files [#8042](https://github.com/hyperledger/besu/pull/8042)
- Allow gasPrice (legacy) and 1559 gasPrice params to be specified simultaneously for `eth_call`, `eth_createAccessList`, and `eth_estimateGas` [#8059](https://github.com/hyperledger/besu/pull/8059)
- Add support for EIP-7702 transaction in the txpool [#8018](https://github.com/hyperledger/besu/pull/8018) [#7984](https://github.com/hyperledger/besu/pull/7984)
- Add support for `movePrecompileToAddress` in `StateOverrides` (`eth_call`)[8115](https://github.com/hyperledger/besu/pull/8115)

### Bug fixes
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ public class StateOverride {
private final Optional<Long> nonce;
private final Optional<String> code;
private final Optional<Map<String, String>> stateDiff;
private final Optional<Address> movePrecompileToAddress;

private StateOverride(
final Optional<Wei> balance,
final Optional<Long> nonce,
final Optional<String> code,
final Optional<Map<String, String>> stateDiff) {
final Optional<Map<String, String>> stateDiff,
final Optional<Address> movePrecompileToAddress) {
this.balance = balance;
this.nonce = nonce;
this.code = code;
this.stateDiff = stateDiff;
this.movePrecompileToAddress = movePrecompileToAddress;
}

/**
Expand Down Expand Up @@ -84,13 +87,23 @@ public Optional<Map<String, String>> getStateDiff() {
return stateDiff;
}

/**
* Gets the new address for the pre-compiled contract
*
* @return the new address for the pre-compiled contract if present
*/
public Optional<Address> getMovePrecompileToAddress() {
return movePrecompileToAddress;
}

/** Builder class for Account overrides */
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Builder {
private Optional<Wei> balance = Optional.empty();
private Optional<Long> nonce = Optional.empty();
private Optional<String> code = Optional.empty();
private Optional<Map<String, String>> stateDiff = Optional.empty();
private Optional<Address> movePrecompileToAddress = Optional.empty();

/** Default constructor. */
public Builder() {}
Expand Down Expand Up @@ -139,13 +152,24 @@ public Builder withStateDiff(final Map<String, String> stateDiff) {
return this;
}

/**
* Sets the new address for the pre-compiled contract
*
* @param newPrecompileAddress the new address for the pre-compile contract
* @return the builder
*/
public Builder withMovePrecompileToAddress(final Address newPrecompileAddress) {
this.movePrecompileToAddress = Optional.ofNullable(newPrecompileAddress);
return this;
}

/**
* build the account override from the builder
*
* @return account override
*/
public StateOverride build() {
return new StateOverride(balance, nonce, code, stateDiff);
return new StateOverride(balance, nonce, code, stateDiff, movePrecompileToAddress);
}
}

Expand Down Expand Up @@ -195,6 +219,8 @@ public String toString() {
+ code
+ ", stateDiff="
+ stateDiff
+ ", movePrecompileToAddress="
+ movePrecompileToAddress
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult;

import java.util.Map;
import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;
Expand Down Expand Up @@ -123,6 +124,33 @@ public void someStateOverrides() {
assertThat(overrideMap).containsValue(override);
}

@Test
public void fullStateOverrides() {
StateOverrideMap expectedOverrides = new StateOverrideMap();
Gabriel-Trintinalia marked this conversation as resolved.
Show resolved Hide resolved
StateOverride override =
new StateOverride.Builder()
.withNonce(new UnsignedLongParameter("0x9e"))
.withBalance(Wei.of(100))
.withCode("0x1234")
.withStateDiff(Map.of("0x1234", "0x5678"))
.withMovePrecompileToAddress(Address.fromHexString("0x1234"))
.build();
final Address address = Address.fromHexString("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3");
expectedOverrides.put(address, override);

final JsonRpcRequestContext request =
ethCallRequestWithStateOverrides(callParameter(), "latest", expectedOverrides);

Optional<StateOverrideMap> maybeOverrideMap = method.getAddressStateOverrideMap(request);
assertThat(maybeOverrideMap.isPresent()).isTrue();
StateOverrideMap overrideMap = maybeOverrideMap.get();
Gabriel-Trintinalia marked this conversation as resolved.
Show resolved Hide resolved
assertThat(overrideMap.keySet()).hasSize(1);
assertThat(overrideMap.values()).hasSize(1);

assertThat(overrideMap).containsKey(address);
assertThat(overrideMap).containsValue(override);
}

@Test
public void shouldReturnInternalErrorWhenProcessorReturnsEmpty() {
final JsonRpcRequestContext request = ethCallRequest(callParameter(), "latest");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,28 @@
"method": "eth_call",
"params": [
{
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"data": "0x12a7b914"
"comment" : "Call to ECREC Precompiled on a different address",
"from":"0xc100000000000000000000000000000000000000",
"to":"0xc000000000000000000000000000000000000001",
"input":"0x82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd"
},
"latest",
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"0xc100000000000000000000000000000000000000": {
"balance": "0xde0b6b3a7640000",
"nonce": 88
},
"0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": {
"stateDiff": {
"0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7"
},
"movePrecompileToAddress":null
"0x0000000000000000000000000000000000000001": {
"comment" : "Move ECREC Precompiled to address",
"movePrecompileToAddress": "0xc000000000000000000000000000000000000001"
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we also need a test that moves the precompile AND changes the code?

Copy link
Contributor

Choose a reason for hiding this comment

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

wait, what is this testing, if the address and the movePrecompileToAddress are the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This tests if the original behaviour of the precompile can be called at the new address

Copy link
Contributor Author

Choose a reason for hiding this comment

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

maybe we also need a test that moves the precompile AND changes the code?

Done

}
}
]
},
"response": {
"jsonrpc": "2.0",
"id": 3,
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
"result": "0x000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"request": {
"id": 3,
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"data": "0x12a7b914"
},
"latest",
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0xde0b6b3a7640000",
"nonce": 88
},
"0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": {
"stateDiff": {
"0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7"
},
"movePrecompileToAddress":null
}
}
]
},
"response": {
"jsonrpc": "2.0",
"id": 3,
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,17 @@ public static ProtocolSpecBuilder atlantisDefinition(
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
true,
false,
evmConfiguration.evmStackSize(),
feeMarket,
CoinbaseFeePriceCalculator.frontier()))
MainnetTransactionProcessor.builder()
.gasCalculator(gasCalculator)
.transactionValidatorFactory(transactionValidatorFactory)
.contractCreationProcessor(contractCreationProcessor)
.messageCallProcessor(messageCallProcessor)
.clearEmptyAccounts(true)
.warmCoinbase(false)
.maxStackSize(evmConfiguration.evmStackSize())
.feeMarket(feeMarket)
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
.build())
.name("Atlantis");
}

Expand Down Expand Up @@ -357,16 +358,17 @@ public static ProtocolSpecBuilder spiralDefinition(
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
true,
true,
evmConfiguration.evmStackSize(),
feeMarket,
CoinbaseFeePriceCalculator.frontier()))
MainnetTransactionProcessor.builder()
.gasCalculator(gasCalculator)
.transactionValidatorFactory(transactionValidatorFactory)
.contractCreationProcessor(contractCreationProcessor)
.messageCallProcessor(messageCallProcessor)
.clearEmptyAccounts(true)
.warmCoinbase(true)
.maxStackSize(evmConfiguration.evmStackSize())
.feeMarket(feeMarket)
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
.build())
.name("Spiral");
}
}
Loading
Loading