Skip to content

Commit

Permalink
EIP-7002: Add exits/exits_root to block/block_header (hyperledger#6801)
Browse files Browse the repository at this point in the history
Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
  • Loading branch information
lucassaldanha committed Apr 4, 2024
1 parent a7b10db commit 1e77a6c
Show file tree
Hide file tree
Showing 69 changed files with 1,095 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public static BlockHeader createBlockHeader(
null,
null,
null,
null,
blockHeaderFunctions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"transactions": [],
"withdrawals": [],
"depositReceipts": [],
"exits": [],
"blockNumber": "0x2",
"blockHash": "0xc8255831601171a628ef17f6601d3d1d30ff9b382e77592ed1af32354f6dafbb",
"blockHash": "0x194d190af2a85c418947fecca405eb168c832481f33f618b0c36326ba65d4767",
"blobGasUsed": "0x0",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
"depositReceipts" : [
{"amount":"0x773594000","index":"0x0","pubkey":"0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9","signature":"0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9","withdrawalCredentials":"0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2"}
],
"exits": [],
"blockNumber": "0x2",
"blockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"blockHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
"blobGasUsed": "0x0"
},
Expand All @@ -37,7 +38,7 @@
"id": 67,
"result": {
"status": "VALID",
"latestValidHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"latestValidHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"validationError": null
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"safeBlockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"headBlockHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"safeBlockHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
Expand All @@ -24,10 +24,10 @@
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"latestValidHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"validationError": null
},
"payloadId": "0x282643db882670cf"
"payloadId": "0x282643f559414ecf"
}
},
"statusCode" : 200
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"jsonrpc": "2.0",
"method": "engine_getPayloadV4",
"params": [
"0x282643db882670cf"
"0x282643f559414ecf"
],
"id": 67
},
Expand All @@ -12,7 +12,7 @@
"id": 67,
"result": {
"executionPayload": {
"parentHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"parentHash": "0x84e13dc50074ba4be5841bd7e453a87b6f77261a8907518a78f3de8c9d877ee7",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x14208ac0e218167936e220b72d5d5887a963cb858ea2f2d268518f014a3da3fa",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -27,8 +27,9 @@
"transactions": [],
"withdrawals": [],
"depositReceipts": [],
"exits": [],
"blockNumber": "0x3",
"blockHash": "0xf1e7093b5d229885caab11a3acb95412af80f9077b742020a8014cf81c8c75f2",
"blockHash": "0xec4741580be2d83cde0dcd6346a67a71636d915f5da592f39d4470aecef72020",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed": "0x0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() {
null,
null,
null,
null,
getBlockHeaderFunctions());
final Block block1 = new Block(header1, BlockBody.empty());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() {
null,
null,
null,
null,
new CliqueBlockHeaderFunctions());
final Block block1 = new Block(header1, BlockBody.empty());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private void setSyncTarget() {
mock(EthPeer.class),
new org.hyperledger.besu.ethereum.core.BlockHeader(
null, null, null, null, null, null, null, null, 1, 1, 1, 1, null, null, null, 1, null,
null, null, null, null, null));
null, null, null, null, null, null));
}

private void clearSyncTarget() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class ProposalTest {
Collections.emptyList(),
Collections.emptyList(),
Optional.of(Collections.emptyList()),
Optional.empty(),
Optional.empty()));

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ public enum JsonRpcResponseKey {
TRANSACTION_ROOT,
BASEFEE,
WITHDRAWALS_ROOT,
DEPOSITS_ROOT
DEPOSITS_ROOT,
EXITS_ROOT
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.COINBASE;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.DEPOSITS_ROOT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.DIFFICULTY;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.EXITS_ROOT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.EXTRA_DATA;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.GAS_LIMIT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.GAS_USED;
Expand Down Expand Up @@ -106,6 +107,7 @@ public JsonRpcResponse response(
values.containsKey(WITHDRAWALS_ROOT) ? hash(values.get(WITHDRAWALS_ROOT)) : null;
final Hash depositsRoot =
values.containsKey(DEPOSITS_ROOT) ? hash(values.get(DEPOSITS_ROOT)) : null;
final Hash exitsRoot = values.containsKey(EXITS_ROOT) ? hash(values.get(EXITS_ROOT)) : null;
final List<JsonNode> ommers = new ArrayList<>();

final BlockHeader header =
Expand All @@ -131,6 +133,7 @@ public JsonRpcResponse response(
null, // ToDo 4844: set with the value of excess_blob_gas field
null, // TODO 4788: set with the value of the parent beacon block root field
depositsRoot,
exitsRoot,
blockHeaderFunctions);

return new JsonRpcSuccessResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.SYNCING;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.DepositsValidatorProvider.getDepositsValidator;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.ValidatorExitsValidatorProvider.getValidatorExitsValidator;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS;

Expand All @@ -36,6 +37,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ValidatorExitParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
Expand All @@ -50,6 +52,7 @@
import org.hyperledger.besu.ethereum.core.Deposit;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.ValidatorExit;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
Expand Down Expand Up @@ -167,6 +170,17 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
return new JsonRpcErrorResponse(reqId, new JsonRpcError(INVALID_PARAMS, "Invalid deposits"));
}

final Optional<List<ValidatorExit>> maybeExits =
Optional.ofNullable(blockParam.getExits())
.map(
exits ->
exits.stream().map(ValidatorExitParameter::toValidatorExit).collect(toList()));
if (!getValidatorExitsValidator(
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
.validateValidatorExitParameter(maybeExits)) {
return new JsonRpcErrorResponse(reqId, new JsonRpcError(INVALID_PARAMS, "Invalid exits"));
}

if (mergeContext.get().isSyncing()) {
LOG.debug("We are syncing");
return respondWith(reqId, blockParam, null, SYNCING);
Expand Down Expand Up @@ -235,6 +249,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
: BlobGas.fromHexString(blockParam.getExcessBlobGas()),
maybeParentBeaconBlockRoot.orElse(null),
maybeDeposits.map(BodyValidation::depositsRoot).orElse(null),
maybeExits.map(BodyValidation::exitsRoot).orElse(null),
headerFunctions);

// ensure the block hash matches the blockParam hash
Expand Down Expand Up @@ -297,7 +312,12 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
final var block =
new Block(
newBlockHeader,
new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeDeposits));
new BlockBody(
transactions,
Collections.emptyList(),
maybeWithdrawals,
maybeDeposits,
maybeExits));

if (maybeParentHeader.isEmpty()) {
LOG.atDebug()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;

import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidatorExitsValidator;

import java.util.Optional;

public class ValidatorExitsValidatorProvider {

static ValidatorExitsValidator getValidatorExitsValidator(
final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) {

final BlockHeader blockHeader =
BlockHeaderBuilder.createDefault()
.timestamp(blockTimestamp)
.number(blockNumber)
.buildBlockHeader();
return getValidatorExitsValidator(protocolSchedule.getByBlockHeader(blockHeader));
}

private static ValidatorExitsValidator getValidatorExitsValidator(
final ProtocolSpec protocolSchedule) {
return Optional.ofNullable(protocolSchedule)
.map(ProtocolSpec::getExitsValidator)
.orElseGet(ValidatorExitsValidator.ProhibitedExits::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class EnginePayloadParameter {
private final Long blobGasUsed;
private final String excessBlobGas;
private final List<DepositParameter> deposits;
private final List<ValidatorExitParameter> exits;

/**
* Creates an instance of EnginePayloadParameter.
Expand All @@ -66,6 +67,7 @@ public class EnginePayloadParameter {
* @param blobGasUsed QUANTITY, 64 Bits
* @param excessBlobGas QUANTITY, 64 Bits
* @param deposits List of deposit parameters.
* @param exits List of exits parameters.
*/
@JsonCreator
public EnginePayloadParameter(
Expand All @@ -86,7 +88,8 @@ public EnginePayloadParameter(
@JsonProperty("withdrawals") final List<WithdrawalParameter> withdrawals,
@JsonProperty("blobGasUsed") final UnsignedLongParameter blobGasUsed,
@JsonProperty("excessBlobGas") final String excessBlobGas,
@JsonProperty("depositReceipts") final List<DepositParameter> deposits) {
@JsonProperty("depositReceipts") final List<DepositParameter> deposits,
@JsonProperty("exits") final List<ValidatorExitParameter> exits) {
this.blockHash = blockHash;
this.parentHash = parentHash;
this.feeRecipient = feeRecipient;
Expand All @@ -105,6 +108,7 @@ public EnginePayloadParameter(
this.blobGasUsed = blobGasUsed == null ? null : blobGasUsed.getValue();
this.excessBlobGas = excessBlobGas;
this.deposits = deposits;
this.exits = exits;
}

public Hash getBlockHash() {
Expand Down Expand Up @@ -178,4 +182,8 @@ public String getExcessBlobGas() {
public List<DepositParameter> getDeposits() {
return deposits;
}

public List<ValidatorExitParameter> getExits() {
return exits;
}
}
Loading

0 comments on commit 1e77a6c

Please sign in to comment.