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 all 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 @@ -24,6 +24,7 @@
- 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)
- Improve debug_traceBlock calls performance and reduce output size [#8076](https://github.com/hyperledger/besu/pull/8076)
- 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 suppliedOverrides = new StateOverrideMap();
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");
suppliedOverrides.put(address, override);

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

Optional<StateOverrideMap> maybeOverrideMap = method.getAddressStateOverrideMap(request);
assertThat(maybeOverrideMap.isPresent()).isTrue();
StateOverrideMap actualOverrideMap = maybeOverrideMap.get();
assertThat(actualOverrideMap.keySet()).hasSize(1);
assertThat(actualOverrideMap.values()).hasSize(1);

assertThat(actualOverrideMap).containsKey(address);
assertThat(actualOverrideMap).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,30 @@
"method": "eth_call",
"params": [
{
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"data": "0x12a7b914"
"comment": "Call to ECREC Precompiled on a different address, expect the original behaviour of ECREC precompile",
"from": "0xc100000000000000000000000000000000000000",
"to": "0x0000000000000000000000000000000000123456",
"input": "0x82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd"
},
"latest",
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"0xc100000000000000000000000000000000000000": {
"balance": "0xde0b6b3a7640000",
"nonce": 88
},
"0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": {
"stateDiff": {
"0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7"
},
"movePrecompileToAddress":null
"0x0000000000000000000000000000000000000001": {
"comment": "Move ECREC Precompiled to address",
"code": "0x60003560010160005260206000f3",
"movePrecompileToAddress": "0x0000000000000000000000000000000000123456"
}
}
]
},
"response": {
"jsonrpc": "2.0",
"id": 3,
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
"comment": "The original ECREC precompile behaviour is expected, not the overridden one",
"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
@@ -0,0 +1,32 @@
{
"request": {
"id": 3,
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"from": "0xc100000000000000000000000000000000000000",
"comment": "Call to precompile ECREC (0x01), but code was modified to add 1 to input",
Copy link
Contributor

Choose a reason for hiding this comment

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

nice

"to": "0x0000000000000000000000000000000000000001",
"input": "0x0000000000000000000000000000000000000000000000000000000000000001"
},
"latest",
{
"0xc100000000000000000000000000000000000000": {
"balance": "0xde0b6b3a7640000"
},
"0x0000000000000000000000000000000000000001": {
"comment": "The code below adds one to input",
"code": "0x60003560010160005260206000f3",
"movePrecompileToAddress": "0x0000000000000000000000000000000000123456"
}
}
]
},
"response": {
"jsonrpc": "2.0",
"id": 3,
"result": "0x0000000000000000000000000000000000000000000000000000000000000002"
},
"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