diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04e0f76e4a..072a84c2ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
- --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead
- --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead
- `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead
+- Allow configuration of Withdrawal Request Contract Address via genesis configuration [#7356](https://github.com/hyperledger/besu/pull/7356)
### Breaking Changes
diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java
index 849b121186..d6323ee9bf 100644
--- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java
+++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java
@@ -525,6 +525,13 @@ public interface GenesisConfigOptions {
*/
boolean isFixedBaseFee();
+ /**
+ * The withdrawal request predeploy address
+ *
+ * @return the withdrawal request predeploy address
+ */
+ Optional
getWithdrawalRequestContractAddress();
+
/**
* The deposit contract address that should be in the logger field in Receipt of Deposit
* transaction
diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java
index b418a67851..67114b29bf 100644
--- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java
+++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java
@@ -49,6 +49,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
private static final String CHECKPOINT_CONFIG_KEY = "checkpoint";
private static final String ZERO_BASE_FEE_KEY = "zerobasefee";
private static final String FIXED_BASE_FEE_KEY = "fixedbasefee";
+ private static final String WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY =
+ "withdrawalrequestcontractaddress";
private static final String DEPOSIT_CONTRACT_ADDRESS_KEY = "depositcontractaddress";
private final ObjectNode configRoot;
@@ -438,6 +440,13 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
return getOptionalBoolean(FIXED_BASE_FEE_KEY).orElse(false);
}
+ @Override
+ public Optional getWithdrawalRequestContractAddress() {
+ Optional inputAddress =
+ JsonUtil.getString(configRoot, WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY);
+ return inputAddress.map(Address::fromHexString);
+ }
+
@Override
public Optional getDepositContractAddress() {
Optional inputAddress = JsonUtil.getString(configRoot, DEPOSIT_CONTRACT_ADDRESS_KEY);
@@ -492,6 +501,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
getEvmStackSize().ifPresent(l -> builder.put("evmstacksize", l));
getEcip1017EraRounds().ifPresent(l -> builder.put("ecip1017EraRounds", l));
+ getWithdrawalRequestContractAddress()
+ .ifPresent(l -> builder.put("withdrawalRequestContractAddress", l));
getDepositContractAddress().ifPresent(l -> builder.put("depositContractAddress", l));
if (isClique()) {
diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java
index 24f3331029..efe56a086d 100644
--- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java
+++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java
@@ -457,6 +457,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
return Collections.emptyList();
}
+ @Override
+ public Optional getWithdrawalRequestContractAddress() {
+ return Optional.empty();
+ }
+
@Override
public Optional getDepositContractAddress() {
return Optional.empty();
diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java
index ed313ad6cf..219ea4fcf8 100644
--- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java
+++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java
@@ -332,6 +332,32 @@ class GenesisConfigOptionsTest {
assertThat(config.asMap()).containsOnlyKeys("fixedBaseFee").containsValue(true);
}
+ @Test
+ void shouldGetWithdrawalRequestContractAddress() {
+ final GenesisConfigOptions config =
+ fromConfigOptions(
+ singletonMap(
+ "withdrawalRequestContractAddress", "0x00000000219ab540356cbb839cbe05303d7705fa"));
+ assertThat(config.getWithdrawalRequestContractAddress())
+ .hasValue(Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"));
+ }
+
+ @Test
+ void shouldNotHaveWithdrawalRequestContractAddressWhenEmpty() {
+ final GenesisConfigOptions config = fromConfigOptions(emptyMap());
+ assertThat(config.getWithdrawalRequestContractAddress()).isEmpty();
+ }
+
+ @Test
+ void asMapIncludesWithdrawalRequestContractAddress() {
+ final GenesisConfigOptions config =
+ fromConfigOptions(Map.of("withdrawalRequestContractAddress", "0x0"));
+
+ assertThat(config.asMap())
+ .containsOnlyKeys("withdrawalRequestContractAddress")
+ .containsValue(Address.ZERO);
+ }
+
@Test
void shouldGetDepositContractAddress() {
final GenesisConfigOptions config =
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
index 36d8257ffb..a96ca58fdd 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsProcessors;
import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator;
+import static org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestProcessor.DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.PowAlgorithm;
@@ -766,6 +767,10 @@ public abstract class MainnetProtocolSpecs {
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
+ final Address withdrawalRequestContractAddress =
+ genesisConfigOptions
+ .getWithdrawalRequestContractAddress()
+ .orElse(DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS);
final Address depositContractAddress =
genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
@@ -791,7 +796,8 @@ public abstract class MainnetProtocolSpecs {
// EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests
.requestsValidator(pragueRequestsValidator(depositContractAddress))
// EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests
- .requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress))
+ .requestProcessorCoordinator(
+ pragueRequestsProcessors(withdrawalRequestContractAddress, depositContractAddress))
// change to accept EIP-7702 transactions
.transactionValidatorFactoryBuilder(
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java
index d855544ede..6e61a0343c 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java
@@ -28,9 +28,11 @@ public class MainnetRequestsValidator {
}
public static RequestProcessorCoordinator pragueRequestsProcessors(
- final Address depositContractAddress) {
+ final Address withdrawalRequestContractAddress, final Address depositContractAddress) {
return new RequestProcessorCoordinator.Builder()
- .addProcessor(RequestType.WITHDRAWAL, new WithdrawalRequestProcessor())
+ .addProcessor(
+ RequestType.WITHDRAWAL,
+ new WithdrawalRequestProcessor(withdrawalRequestContractAddress))
.addProcessor(RequestType.CONSOLIDATION, new ConsolidationRequestProcessor())
.addProcessor(RequestType.DEPOSIT, new DepositRequestProcessor(depositContractAddress))
.build();
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java
index b230a6d610..d4021c9a10 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java
@@ -26,7 +26,7 @@ import org.apache.tuweni.units.bigints.UInt64;
public class WithdrawalRequestProcessor
extends AbstractSystemCallRequestProcessor {
- public static final Address WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS =
+ public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS =
Address.fromHexString("0x00A3ca265EBcb825B45F985A16CEFB49958cE017");
private static final int ADDRESS_BYTES = 20;
@@ -35,6 +35,12 @@ public class WithdrawalRequestProcessor
private static final int WITHDRAWAL_REQUEST_BYTES_SIZE =
ADDRESS_BYTES + PUBLIC_KEY_BYTES + AMOUNT_BYTES;
+ private final Address withdrawalRequestContractAddress;
+
+ public WithdrawalRequestProcessor(final Address withdrawalRequestContractAddress) {
+ this.withdrawalRequestContractAddress = withdrawalRequestContractAddress;
+ }
+
/**
* Gets the call address for withdrawal requests.
*
@@ -42,7 +48,7 @@ public class WithdrawalRequestProcessor
*/
@Override
protected Address getCallAddress() {
- return WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS;
+ return withdrawalRequestContractAddress;
}
/**