From dcd958b6c4fec75cb581b757e1bf3aac27ff5ff7 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Mon, 3 Apr 2023 12:41:02 +0800 Subject: [PATCH 01/36] Initial commit Signed-off-by: Navie Chan --- .../hyperledger/besu/datatypes/Address.java | 3 + .../engine/AbstractEngineNewPayload.java | 20 +- .../engine/DepositsValidatorProvider.java | 32 +++ .../parameters/EnginePayloadParameter.java | 9 +- .../internal/results/BlockResultFactory.java | 1 + .../results/EngineGetPayloadResultV2.java | 19 +- .../engine/AbstractEngineGetPayloadTest.java | 11 + .../engine/AbstractEngineNewPayloadTest.java | 125 +++++++++-- .../engine/EngineGetPayloadV2Test.java | 55 +++++ .../engine/EngineNewPayloadV1Test.java | 2 +- .../blockcreation/AbstractBlockCreator.java | 10 +- ethereum/core/build.gradle | 1 + .../besu/ethereum/core/DepositContract.java | 47 +++++ .../core/encoding/DepositDecoder.java | 19 ++ .../ethereum/mainnet/DepositsValidator.java | 42 +++- .../mainnet/MainnetBlockBodyValidator.java | 17 +- .../ethereum/core/BlockHeaderTestFixture.java | 7 + .../core/encoding/DepositDecoderTest.java | 22 ++ .../mainnet/DepositsValidatorTest.java | 194 +++++++++++++++++- 19 files changed, 596 insertions(+), 40 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java index 8862d9461e2..04b1155a8b7 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java @@ -74,6 +74,9 @@ public class Address extends DelegatingBytes { public static final Address KZG_POINT_EVAL = Address.precompiled(0x14); /** The constant ZERO. */ public static final Address ZERO = Address.fromHexString("0x0"); + /** The deposit address. */ + public static final Address DEPOSIT_ADDRESS = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); /** * Instantiates a new Address. diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index b6102ad1a59..a0e85c60478 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -20,6 +20,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID_BLOCK_HASH; 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.WithdrawalsValidatorProvider.getWithdrawalsValidator; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_PARAMS; @@ -30,6 +31,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; 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.WithdrawalParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; @@ -41,6 +43,7 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; +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.Withdrawal; @@ -111,6 +114,14 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) return new JsonRpcErrorResponse(reqId, INVALID_PARAMS); } + final Optional> maybeDeposits = + Optional.ofNullable(blockParam.getDeposits()) + .map(ds -> ds.stream().map(DepositParameter::toDeposit).collect(toList())); + if (!getDepositsValidator(timestampSchedule, blockParam.getTimestamp()) + .validateDepositParameters(maybeDeposits)) { + return new JsonRpcErrorResponse(reqId, INVALID_PARAMS); + } + if (mergeContext.get().isSyncing()) { LOG.debug("We are syncing"); return respondWith(reqId, blockParam, null, SYNCING); @@ -161,7 +172,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 0, maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null), null, - null, + maybeDeposits.map(BodyValidation::depositsRoot).orElse(null), headerFunctions); // ensure the block hash matches the blockParam hash @@ -205,8 +216,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) final var block = new Block( newBlockHeader, - new BlockBody( - transactions, Collections.emptyList(), maybeWithdrawals, Optional.empty())); + new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeDeposits)); if (maybeParentHeader.isEmpty()) { LOG.atDebug() @@ -340,6 +350,10 @@ private void logImportedBlockInfo(final Block block, final double timeInS) { message.append(" / %d ws"); messageArgs.add(block.getBody().getWithdrawals().get().size()); } + if (block.getBody().getDeposits().isPresent()) { + message.append(" / %d ds"); + messageArgs.add(block.getBody().getDeposits().get().size()); + } message.append(" / base fee %s / %,d (%01.1f%%) gas / (%s) in %01.3fs. Peers: %d"); messageArgs.addAll( List.of( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java new file mode 100644 index 00000000000..5759c9dca34 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java @@ -0,0 +1,32 @@ +/* + * 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.mainnet.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule; + +public class DepositsValidatorProvider { + + static DepositsValidator getDepositsValidator( + final TimestampSchedule timestampSchedule, final long newPayloadTimestamp) { + + return timestampSchedule + .getByTimestamp(newPayloadTimestamp) + .map(ProtocolSpec::getDepositsValidator) + .orElseGet(DepositsValidator.ProhibitedDeposits::new); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java index d6e5923b539..13197d92b93 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java @@ -47,6 +47,7 @@ public class EnginePayloadParameter { private final LogsBloomFilter logsBloom; private final List transactions; private final List withdrawals; + private final List deposits; @JsonCreator public EnginePayloadParameter( @@ -64,7 +65,8 @@ public EnginePayloadParameter( @JsonProperty("logsBloom") final LogsBloomFilter logsBloom, @JsonProperty("prevRandao") final String prevRandao, @JsonProperty("transactions") final List transactions, - @JsonProperty("withdrawals") final List withdrawals) { + @JsonProperty("withdrawals") final List withdrawals, + @JsonProperty("deposits") final List deposits) { this.blockHash = blockHash; this.parentHash = parentHash; this.feeRecipient = feeRecipient; @@ -80,6 +82,7 @@ public EnginePayloadParameter( this.prevRandao = Bytes32.fromHexString(prevRandao); this.transactions = transactions; this.withdrawals = withdrawals; + this.deposits = deposits; } public Hash getBlockHash() { @@ -141,4 +144,8 @@ public List getTransactions() { public List getWithdrawals() { return withdrawals; } + + public List getDeposits() { + return deposits; + } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java index 2685f888a37..0b6d112dade 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java @@ -115,6 +115,7 @@ public EngineGetPayloadResultV2 payloadTransactionCompleteV2( blockWithReceipts.getHeader(), txs, blockWithReceipts.getBlock().getBody().getWithdrawals(), + blockWithReceipts.getBlock().getBody().getDeposits(), Quantity.create(blockValue)); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV2.java index e3919517f3b..b5e9fafabe2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV2.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV2.java @@ -14,8 +14,10 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Withdrawal; import java.util.List; @@ -39,8 +41,9 @@ public EngineGetPayloadResultV2( final BlockHeader header, final List transactions, final Optional> withdrawals, + final Optional> deposits, final String blockValue) { - this.executionPayload = new PayloadResult(header, transactions, withdrawals); + this.executionPayload = new PayloadResult(header, transactions, withdrawals, deposits); this.blockValue = blockValue; } @@ -71,11 +74,13 @@ public static class PayloadResult { private final String baseFeePerGas; protected final List transactions; private final List withdrawals; + private final List deposits; public PayloadResult( final BlockHeader header, final List transactions, - final Optional> withdrawals) { + final Optional> withdrawals, + final Optional> deposits) { this.blockNumber = Quantity.create(header.getNumber()); this.blockHash = header.getHash().toString(); this.parentHash = header.getParentHash().toString(); @@ -98,6 +103,11 @@ public PayloadResult( .map(WithdrawalParameter::fromWithdrawal) .collect(Collectors.toList())) .orElse(null); + this.deposits = + deposits + .map( + ds -> ds.stream().map(DepositParameter::fromDeposit).collect(Collectors.toList())) + .orElse(null); } @JsonGetter(value = "blockNumber") @@ -170,6 +180,11 @@ public List getWithdrawals() { return withdrawals; } + @JsonGetter(value = "deposits") + public List getDeposits() { + return deposits; + } + @JsonGetter(value = "feeRecipient") @JsonInclude(JsonInclude.Include.NON_NULL) public String getFeeRecipient() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java index 923892829d8..477ff10edff 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java @@ -87,9 +87,20 @@ public AbstractEngineGetPayloadTest(final MethodFactory methodFactory) { Collections.emptyList(), Optional.of(Collections.emptyList()), Optional.empty())); + private static final Block mockBlockWithDeposits = + new Block( + mockHeader, + new BlockBody( + Collections.emptyList(), + Collections.emptyList(), + Optional.empty(), + Optional.of(Collections.emptyList()))); protected static final BlockWithReceipts mockBlockWithReceiptsAndWithdrawals = new BlockWithReceipts(mockBlockWithWithdrawals, Collections.emptyList()); + protected static final BlockWithReceipts mockBlockWithReceiptsAndDeposits = + new BlockWithReceipts(mockBlockWithDeposits, Collections.emptyList()); + @Mock private ProtocolContext protocolContext; @Mock protected MergeContext mergeContext; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java index 83d0f480237..f9793c1c151 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java @@ -19,9 +19,11 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID; 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.parameters.DepositParameterTestFixture.DEPOSIT_PARAM_1; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameterTestFixture.WITHDRAWAL_PARAM_1; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_PARAMS; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -40,6 +42,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; 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.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; @@ -54,9 +57,11 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; +import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; @@ -123,6 +128,8 @@ public void before() { when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolSpec.getWithdrawalsValidator()) .thenReturn(new WithdrawalsValidator.ProhibitedWithdrawals()); + when(protocolSpec.getDepositsValidator()) + .thenReturn(new DepositsValidator.ProhibitedDeposits()); when(timestampSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); when(ethPeers.peerCount()).thenReturn(1); this.method = @@ -143,6 +150,7 @@ public void shouldReturnValid() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + Optional.empty(), Optional.empty()); var resp = resp(mockPayload(mockHeader, Collections.emptyList())); @@ -153,7 +161,8 @@ public void shouldReturnValid() { @Test public void shouldReturnInvalidOnBlockExecutionError() { BlockHeader mockHeader = - setupValidPayload(new BlockProcessingResult("error 42"), Optional.empty()); + setupValidPayload( + new BlockProcessingResult("error 42"), Optional.empty(), Optional.empty()); var resp = resp(mockPayload(mockHeader, Collections.emptyList())); @@ -166,7 +175,7 @@ public void shouldReturnInvalidOnBlockExecutionError() { @Test public void shouldReturnAcceptedOnLatestValidAncestorEmpty() { - BlockHeader mockHeader = createBlockHeader(Optional.empty()); + BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty()); when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty()); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); @@ -201,7 +210,7 @@ public void shouldReturnSuccessOnAlreadyPresent() { @Test public void shouldReturnInvalidWithLatestValidHashIsABadBlock() { - BlockHeader mockHeader = createBlockHeader(Optional.empty()); + BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty()); Hash latestValidHash = Hash.hash(Bytes32.fromHexStringLenient("0xcafebabe")); when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty()); @@ -222,6 +231,7 @@ public void shouldNotReturnInvalidOnStorageException() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.empty(), new StorageException("database bedlam")), + Optional.empty(), Optional.empty()); var resp = resp(mockPayload(mockHeader, Collections.emptyList())); @@ -237,6 +247,7 @@ public void shouldNotReturnInvalidOnHandledMerkleTrieException() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.empty(), new MerkleTrieException("missing leaf")), + Optional.empty(), Optional.empty()); var resp = resp(mockPayload(mockHeader, Collections.emptyList())); @@ -249,7 +260,7 @@ public void shouldNotReturnInvalidOnHandledMerkleTrieException() { @Test public void shouldNotReturnInvalidOnThrownMerkleTrieException() { - BlockHeader mockHeader = createBlockHeader(Optional.empty()); + BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty()); when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty()); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); @@ -405,9 +416,10 @@ public void shouldReturnInvalidIfWithdrawalsIsNotNull_WhenWithdrawalsProhibited( var resp = resp( mockPayload( - createBlockHeader(Optional.of(Collections.emptyList())), + createBlockHeader(Optional.of(Collections.emptyList()), Optional.empty()), Collections.emptyList(), - withdrawals)); + withdrawals, + null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); @@ -422,9 +434,10 @@ public void shouldReturnValidIfWithdrawalsIsNull_WhenWithdrawalsProhibited() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + Optional.empty(), Optional.empty()); - var resp = resp(mockPayload(mockHeader, Collections.emptyList(), withdrawals)); + var resp = resp(mockPayload(mockHeader, Collections.emptyList(), withdrawals, null)); assertValidResponse(mockHeader, resp); } @@ -437,7 +450,11 @@ public void shouldReturnInvalidIfWithdrawalsIsNull_WhenWithdrawalsAllowed() { var resp = resp( - mockPayload(createBlockHeader(Optional.empty()), Collections.emptyList(), withdrawals)); + mockPayload( + createBlockHeader(Optional.empty(), Optional.empty()), + Collections.emptyList(), + withdrawals, + null)); assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode()); verify(engineCallListener, times(1)).executionEngineCalled(); @@ -452,9 +469,78 @@ public void shouldReturnValidIfWithdrawalsIsNotNull_WhenWithdrawalsAllowed() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), - Optional.of(withdrawals)); + Optional.of(withdrawals), + Optional.empty()); + + var resp = resp(mockPayload(mockHeader, Collections.emptyList(), withdrawalsParam, null)); + + assertValidResponse(mockHeader, resp); + } + + @Test + public void shouldReturnInvalidIfDepositsIsNotNull_WhenDepositsProhibited() { + final List deposits = List.of(); + when(protocolSpec.getDepositsValidator()) + .thenReturn(new DepositsValidator.ProhibitedDeposits()); + + var resp = + resp( + mockPayload( + createBlockHeader(Optional.empty(), Optional.of(Collections.emptyList())), + Collections.emptyList(), + null, + deposits)); + + final JsonRpcError jsonRpcError = fromErrorResp(resp); + assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + + @Test + public void shouldReturnValidIfDepositsIsNull_WhenDepositsProhibited() { + final List deposits = null; + when(protocolSpec.getDepositsValidator()) + .thenReturn(new DepositsValidator.ProhibitedDeposits()); + BlockHeader mockHeader = + setupValidPayload( + new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + Optional.empty(), + Optional.empty()); + + var resp = resp(mockPayload(mockHeader, Collections.emptyList(), null, deposits)); + + assertValidResponse(mockHeader, resp); + } + + @Test + public void shouldReturnInvalidIfDepositsIsNull_WhenDepositsAllowed() { + final List deposits = null; + when(protocolSpec.getDepositsValidator()).thenReturn(new DepositsValidator.AllowedDeposits()); + + var resp = + resp( + mockPayload( + createBlockHeader(Optional.empty(), Optional.empty()), + Collections.emptyList(), + null, + deposits)); + + assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode()); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + + @Test + public void shouldReturnValidIfDepositsIsNotNull_WhenDepositsAllowed() { + final List depositsParam = List.of(DEPOSIT_PARAM_1); + final List deposits = List.of(DEPOSIT_PARAM_1.toDeposit()); + when(protocolSpec.getDepositsValidator()).thenReturn(new DepositsValidator.AllowedDeposits()); + BlockHeader mockHeader = + setupValidPayload( + new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + Optional.empty(), + Optional.of(deposits)); - var resp = resp(mockPayload(mockHeader, Collections.emptyList(), withdrawalsParam)); + var resp = resp(mockPayload(mockHeader, Collections.emptyList(), null, depositsParam)); assertValidResponse(mockHeader, resp); } @@ -465,6 +551,7 @@ public void shouldReturnValidIfTimestampScheduleIsEmpty() { BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + Optional.empty(), Optional.empty()); var resp = resp(mockPayload(mockHeader, Collections.emptyList())); @@ -495,13 +582,15 @@ protected EnginePayloadParameter mockPayload(final BlockHeader header, final Lis header.getLogsBloom(), header.getPrevRandao().map(Bytes32::toHexString).orElse("0x0"), txs, + null, null); } private EnginePayloadParameter mockPayload( final BlockHeader header, final List txs, - final List withdrawals) { + final List withdrawals, + final List deposits) { return new EnginePayloadParameter( header.getHash(), header.getParentHash(), @@ -517,13 +606,16 @@ private EnginePayloadParameter mockPayload( header.getLogsBloom(), header.getPrevRandao().map(Bytes32::toHexString).orElse("0x0"), txs, - withdrawals); + withdrawals, + deposits); } @NotNull private BlockHeader setupValidPayload( - final BlockProcessingResult value, final Optional> maybeWithdrawals) { - BlockHeader mockHeader = createBlockHeader(maybeWithdrawals); + final BlockProcessingResult value, + final Optional> maybeWithdrawals, + final Optional> maybeDeposits) { + BlockHeader mockHeader = createBlockHeader(maybeWithdrawals, maybeDeposits); when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty()); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); @@ -562,7 +654,9 @@ private JsonRpcError fromErrorResp(final JsonRpcResponse resp) { .get(); } - protected BlockHeader createBlockHeader(final Optional> maybeWithdrawals) { + protected BlockHeader createBlockHeader( + final Optional> maybeWithdrawals, + final Optional> maybeDeposits) { BlockHeader parentBlockHeader = new BlockHeaderTestFixture().baseFeePerGas(Wei.ONE).buildHeader(); BlockHeader mockHeader = @@ -572,6 +666,7 @@ protected BlockHeader createBlockHeader(final Optional> maybeWi .number(parentBlockHeader.getNumber() + 1) .timestamp(parentBlockHeader.getTimestamp() + 1) .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null)) + .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) .buildHeader(); return mockHeader; } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java index c4c4253ecdd..08a0174661c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java @@ -67,6 +67,28 @@ public void shouldReturnBlockForKnownPayloadId() { .isEqualTo(mockHeader.getPrevRandao().map(Bytes32::toString).orElse("")); }); verify(engineCallListener, times(1)).executionEngineCalled(); + + + // should return deposits for a post-V6110 block + when(mergeContext.retrieveBlockById(mockPid)) + .thenReturn(Optional.of(mockBlockWithReceiptsAndDeposits)); + + final var resp2 = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); + assertThat(resp2).isInstanceOf(JsonRpcSuccessResponse.class); + Optional.of(resp2) + .map(JsonRpcSuccessResponse.class::cast) + .ifPresent( + r -> { + assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class); + final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult(); + assertThat(res.getExecutionPayload().getDeposits()).isNotNull(); + assertThat(res.getExecutionPayload().getHash()) + .isEqualTo(mockHeader.getHash().toString()); + assertThat(res.getBlockValue()).isEqualTo(Quantity.create(0)); + assertThat(res.getExecutionPayload().getPrevRandao()) + .isEqualTo(mockHeader.getPrevRandao().map(Bytes32::toString).orElse("")); + }); + verify(engineCallListener, times(2)).executionEngineCalled(); } @Test @@ -84,6 +106,39 @@ public void shouldReturnExecutionPayloadWithoutWithdrawals_PreShanghaiBlock() { verify(engineCallListener, times(1)).executionEngineCalled(); } + @Test + public void shouldReturnExecutionPayloadWithoutDeposits_PreShanghaiBlock() { + final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); + assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class); + Optional.of(resp) + .map(JsonRpcSuccessResponse.class::cast) + .ifPresent( + r -> { + assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class); + final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult(); + assertThat(res.getExecutionPayload().getDeposits()).isNull(); + }); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + + @Test + public void shouldReturnExecutionPayloadWithoutDeposits_PreV6110Block() { + when(mergeContext.retrieveBlockById(mockPid)) + .thenReturn(Optional.of(mockBlockWithReceiptsAndWithdrawals)); + + final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); + assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class); + Optional.of(resp) + .map(JsonRpcSuccessResponse.class::cast) + .ifPresent( + r -> { + assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class); + final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult(); + assertThat(res.getExecutionPayload().getDeposits()).isNull(); + }); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + @Override protected String getMethodName() { return RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV1Test.java index 09f4ab16daf..f9a9200d57e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV1Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV1Test.java @@ -51,7 +51,7 @@ public void shouldReturnExpectedMethodName() { @Test public void shouldReturnInvalidOnBadTerminalBlock() { - BlockHeader mockHeader = createBlockHeader(Optional.empty()); + BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty()); when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty()); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index d5e693220a9..27150a478a7 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.SealableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; +import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; @@ -195,8 +196,13 @@ protected BlockCreationResult createBlock( throwIfStopped(); + final List depositsFromReceipts = + transactionResults.getReceipts().stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .map(DepositDecoder::decodeFromLog) + .toList(); final Optional> maybeDeposits = - Optional.empty(); // TODO 6110: Extract deposits from transaction receipts + depositsFromReceipts.isEmpty() ? Optional.empty() : Optional.of(depositsFromReceipts); if (rewardCoinbase && !rewardBeneficiary( @@ -232,7 +238,7 @@ protected BlockCreationResult createBlock( withdrawalsCanBeProcessed ? BodyValidation.withdrawalsRoot(maybeWithdrawals.get()) : null) - .depositsRoot(null) // TODO 6110: Derive deposit roots from deposits + .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) .excessDataGas(newExcessDataGas) .buildSealableBlockHeader(); diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle index 99a0f7d1787..eef92ddaacd 100644 --- a/ethereum/core/build.gradle +++ b/ethereum/core/build.gradle @@ -29,6 +29,7 @@ jar { dependencies { api 'org.slf4j:slf4j-api' + api 'org.web3j:core' annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess' diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java new file mode 100644 index 00000000000..09ed4ff4a9a --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java @@ -0,0 +1,47 @@ +package org.hyperledger.besu.ethereum.core; + +import org.hyperledger.besu.evm.log.LogTopic; + +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Event; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import org.web3j.tx.gas.ContractGasProvider; + +public class DepositContract extends Contract { + + public static final Event DEPOSITEVENT_EVENT = + new Event( + "DepositEvent", + Arrays.asList( + new TypeReference() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference() {})); + + protected DepositContract( + final String contractBinary, + final String contractAddress, + final Web3j web3j, + final TransactionManager transactionManager, + final ContractGasProvider gasProvider) { + super(contractBinary, contractAddress, web3j, transactionManager, gasProvider); + } + + public static EventValuesWithLog staticExtractDepositEventWithLog( + final org.hyperledger.besu.evm.log.Log log) { + Log web3jLog = new Log(); + web3jLog.setTopics( + log.getTopics().stream().map(LogTopic::toHexString).collect(Collectors.toList())); + web3jLog.setData(log.getData().toHexString()); + + return staticExtractEventParametersWithLog(DEPOSITEVENT_EVENT, web3jLog); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java index 90b4b482c15..341753c7780 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java @@ -18,12 +18,15 @@ import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.DepositContract; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; +import org.hyperledger.besu.evm.log.Log; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; +import org.web3j.tx.Contract; public class DepositDecoder { @@ -39,6 +42,22 @@ public static Deposit decode(final RLPInput rlpInput) { return new Deposit(publicKey, depositWithdrawalCredential, amount, signature, index); } + public static Deposit decodeFromLog(final Log log) { + Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log); + byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue(); + byte[] rawWithdrawalCredential = (byte[]) eventValues.getNonIndexedValues().get(1).getValue(); + byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue(); + byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue(); + byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue(); + + return new Deposit( + BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)), + Bytes32.wrap(Bytes.wrap(rawWithdrawalCredential)), + GWei.of(Bytes.wrap(rawAmount).reverse().toLong()), + BLSSignature.wrap(Bytes.wrap(rawSignature)), + UInt64.valueOf(Bytes.wrap(rawIndex).reverse().toLong())); + } + public static Deposit decodeOpaqueBytes(final Bytes input) { return decode(RLP.input(input)); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index 30c0694a45d..8720d22301e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -18,10 +18,15 @@ import static com.google.common.base.Preconditions.checkArgument; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; +import org.hyperledger.besu.evm.log.Log; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -30,7 +35,8 @@ public interface DepositsValidator { - boolean validateDeposits(Optional> deposits); + boolean validateDepositParameters(Optional> deposits); + boolean validateDeposits(Block block, List receipts); boolean validateDepositsRoot(Block block); @@ -39,7 +45,13 @@ class ProhibitedDeposits implements DepositsValidator { private static final Logger LOG = LoggerFactory.getLogger(ProhibitedDeposits.class); @Override - public boolean validateDeposits(final Optional> deposits) { + public boolean validateDepositParameters(final Optional> deposits) { + return deposits.isEmpty(); + } + + @Override + public boolean validateDeposits(final Block block, final List receipts) { + Optional> deposits = block.getBody().getDeposits(); final boolean isValid = deposits.isEmpty(); if (!isValid) { LOG.warn("Deposits must be null when Deposits are prohibited but were: {}", deposits); @@ -66,8 +78,30 @@ class AllowedDeposits implements DepositsValidator { private static final Logger LOG = LoggerFactory.getLogger(AllowedDeposits.class); @Override - public boolean validateDeposits(final Optional> deposits) { - return true; // TODO 6110: Validate deposits in the next PR + public boolean validateDepositParameters(final Optional> deposits) { + return deposits != null; + } + + @Override + public boolean validateDeposits(final Block block, final List receipts) { + if (block.getBody().getDeposits().isEmpty()) { + LOG.warn("Deposits must not be null when Deposits are activated"); + return false; + } + + List actualDeposits = new ArrayList<>(block.getBody().getDeposits().get()); + List expectedDeposits = new ArrayList<>(); + + for (TransactionReceipt receipt : receipts) { + for (Log log : receipt.getLogsList()) { + if (Address.DEPOSIT_ADDRESS.equals(log.getLogger())) { + Deposit deposit = DepositDecoder.decodeFromLog(log); + expectedDeposits.add(deposit); + } + } + } + + return actualDeposits.equals(expectedDeposits); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java index d82347c5373..bb97f218e42 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java @@ -104,7 +104,7 @@ public boolean validateBodyLight( return false; } - if (!validateDeposits(block)) { + if (!validateDeposits(block, receipts)) { return false; } @@ -309,7 +309,18 @@ private boolean validateWithdrawals(final Block block) { return true; } - private boolean validateDeposits(final Block unusedBlock) { - return true; // TODO 6110: Implement deposit validation + private boolean validateDeposits(final Block block, final List receipts) { + final DepositsValidator depositsValidator = + protocolSchedule.getByBlockHeader(block.getHeader()).getDepositsValidator(); + + if (!depositsValidator.validateDeposits(block, receipts)) { + return false; + } + + if (!depositsValidator.validateDepositsRoot(block)) { + return false; + } + + return true; } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java index 4976184a8a7..d6778a2eaa4 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java @@ -49,6 +49,7 @@ public class BlockHeaderTestFixture { private Hash mixHash = Hash.EMPTY; private long nonce = 0; private Optional withdrawalsRoot = Optional.empty(); + private Optional depositsRoot = Optional.empty(); private BlockHeaderFunctions blockHeaderFunctions = new MainnetBlockHeaderFunctions(); public BlockHeader buildHeader() { @@ -71,6 +72,7 @@ public BlockHeader buildHeader() { builder.mixHash(mixHash); builder.nonce(nonce); withdrawalsRoot.ifPresent(builder::withdrawalsRoot); + depositsRoot.ifPresent(builder::depositsRoot); builder.blockHeaderFunctions(blockHeaderFunctions); return builder.buildBlockHeader(); @@ -166,6 +168,11 @@ public BlockHeaderTestFixture withdrawalsRoot(final Hash withdrawalsRoot) { return this; } + public BlockHeaderTestFixture depositsRoot(final Hash depositsRoot) { + this.depositsRoot = Optional.ofNullable(depositsRoot); + return this; + } + public BlockHeaderTestFixture blockHeaderFunctions( final BlockHeaderFunctions blockHeaderFunctions) { this.blockHeaderFunctions = blockHeaderFunctions; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java index d2aba9bdd1f..9514fbaaec1 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java @@ -16,10 +16,15 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BLSPublicKey; import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.evm.log.Log; +import org.hyperledger.besu.evm.log.LogTopic; + +import java.util.List; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -47,4 +52,21 @@ void shouldDecodeDeposit() { assertThat(deposit).isEqualTo(expectedDeposit); } + + @Test + void shouldDecodeDepositFromLog() { + Address address = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + List topics = + List.of( + LogTopic.fromHexString( + "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")); + Bytes data = + Bytes.fromHexString( + "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"); + + Log log = new Log(address, data, topics); + Deposit deposit = DepositDecoder.decodeFromLog(log); + + System.out.println(deposit); + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java index 16d3dac1cbd..b5bb7d43b97 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java @@ -15,25 +15,87 @@ package org.hyperledger.besu.ethereum.mainnet; -import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.BLSPublicKey; +import org.hyperledger.besu.datatypes.BLSSignature; +import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockDataGenerator; +import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.evm.log.Log; +import org.hyperledger.besu.evm.log.LogTopic; import java.util.Collections; +import java.util.List; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt64; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; public class DepositsValidatorTest { private final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); + private static Deposit DEPOSIT_1; + private static Deposit DEPOSIT_2; + private static Log LOG_1; + private static Log LOG_2; + + @BeforeAll + public static void setup() { + System.out.println("setting"); + DEPOSIT_1 = + new Deposit( + BLSPublicKey.fromHexString( + "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), + Bytes32.fromHexString( + "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), + GWei.of(32000000000L), + BLSSignature.fromHexString( + "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), + UInt64.valueOf(539967)); + + DEPOSIT_2 = + new Deposit( + BLSPublicKey.fromHexString( + "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243"), + Bytes32.fromHexString( + "0x006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271"), + GWei.of(32000000000L), + BLSSignature.fromHexString( + "0x801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b07"), + UInt64.valueOf(559887)); + + LOG_1 = + new Log( + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"), + Bytes.fromHexString( + "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"), + List.of( + LogTopic.fromHexString( + "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); + + LOG_2 = + new Log( + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"), + Bytes.fromHexString( + "0x00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000308706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b0700000000000000000000000000000000000000000000000000000000000000080f8b080000000000000000000000000000000000000000000000000000000000"), + List.of( + LogTopic.fromHexString( + "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); + } @Test public void validateProhibitedDeposits() { - assertThat(new DepositsValidator.ProhibitedDeposits().validateDeposits(Optional.empty())) - .isTrue(); + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create().setDeposits(Optional.empty()); + final Block block = blockDataGenerator.block(blockOptions); + assertThat(new DepositsValidator.ProhibitedDeposits().validateDeposits(block, null)).isTrue(); } @Test @@ -44,9 +106,10 @@ public void validateProhibitedDepositsRoot() { @Test public void invalidateProhibitedDeposits() { - assertThat( - new DepositsValidator.ProhibitedDeposits().validateDeposits(Optional.of(emptyList()))) - .isFalse(); + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); + final Block block = blockDataGenerator.block(blockOptions); + assertThat(new DepositsValidator.ProhibitedDeposits().validateDeposits(block, null)).isFalse(); } @Test @@ -59,7 +122,34 @@ public void invalidateProhibitedDepositsRoot() { @Test public void validateAllowedDeposits() { - // TODO 6110: Validate deposits in AllowedDeposits to be included in next PR + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt = + new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); + + assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt))) + .isTrue(); + } + + @Test + public void validateAllowedDeposits2() { + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_1), Optional.empty()); + final TransactionReceipt receipt2 = + new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); + + assertThat( + new DepositsValidator.AllowedDeposits() + .validateDeposits(block, List.of(receipt1, receipt2))) + .isTrue(); } @Test @@ -74,11 +164,97 @@ public void validateAllowedDepositsRoot() { @Test public void invalidateAllowedDeposits() { - // TODO 6110: Validate deposits in AllowedDeposits to be included in next PR + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); + + assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + .isFalse(); + } + + @Test + public void invalidateAllowedDeposits2() { + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); + + assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + .isFalse(); + } + + @Test + public void invalidateAllowedDeposits3() { + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); + + assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + .isFalse(); + } + + @Test + public void invalidateAllowedDeposits4() { + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_2, LOG_1), Optional.empty()); + + assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + .isFalse(); } @Test public void invalidateAllowedDepositsRoot() { - // TODO 6110: Validate deposits in AllowedDeposits to be included in next PR + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(Collections.emptyList())) + .setDepositsRoot(Hash.ZERO); // this is invalid it should be empty trie hash + final Block block = blockDataGenerator.block(blockOptions); + assertThat(new DepositsValidator.AllowedDeposits().validateDepositsRoot(block)).isFalse(); + } + + @Test + public void validateProhibitedDepositParams() { + final Optional> deposits = Optional.empty(); + assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameters(deposits)) + .isTrue(); + } + + @Test + public void invalidateProhibitedDepositParams() { + final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); + assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameters(deposits)) + .isFalse(); + } + + @Test + public void validateAllowedDepositParams() { + final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) + .isTrue(); + + final Optional> emptyDeposits = Optional.empty(); + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(emptyDeposits)) + .isTrue(); + } + + @Test + public void invalidateAllowedDepositParams() { + final Optional> deposits = null; + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) + .isFalse(); } } From ee3e2aeab44bee1d0d186e658aa92e1e09b510c6 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Mon, 3 Apr 2023 13:04:29 +0800 Subject: [PATCH 02/36] Spotless Apply Signed-off-by: Navie Chan --- .../org/hyperledger/besu/datatypes/Address.java | 4 ++-- .../engine/AbstractEngineNewPayloadTest.java | 1 - .../methods/engine/EngineGetPayloadV2Test.java | 1 - .../besu/ethereum/core/DepositContract.java | 16 ++++++++++++++++ .../besu/ethereum/mainnet/DepositsValidator.java | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java index 04b1155a8b7..cd4ee6aadf4 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java @@ -75,8 +75,8 @@ public class Address extends DelegatingBytes { /** The constant ZERO. */ public static final Address ZERO = Address.fromHexString("0x0"); /** The deposit address. */ - public static final Address DEPOSIT_ADDRESS = - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + public static final Address DEPOSIT_ADDRESS = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); /** * Instantiates a new Address. diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java index f9793c1c151..9a8a94a624f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java @@ -23,7 +23,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameterTestFixture.WITHDRAWAL_PARAM_1; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_PARAMS; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java index 08a0174661c..f381b218cbb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java @@ -68,7 +68,6 @@ public void shouldReturnBlockForKnownPayloadId() { }); verify(engineCallListener, times(1)).executionEngineCalled(); - // should return deposits for a post-V6110 block when(mergeContext.retrieveBlockById(mockPid)) .thenReturn(Optional.of(mockBlockWithReceiptsAndDeposits)); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java index 09ed4ff4a9a..6537af928c6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java @@ -1,3 +1,19 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * + * 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.core; import org.hyperledger.besu.evm.log.LogTopic; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index 8720d22301e..a3259fd1d4e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -36,6 +36,7 @@ public interface DepositsValidator { boolean validateDepositParameters(Optional> deposits); + boolean validateDeposits(Block block, List receipts); boolean validateDepositsRoot(Block block); From e62b6f50307591570fba25b8ef5ead3438a1fe07 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Mon, 3 Apr 2023 19:58:07 +0800 Subject: [PATCH 03/36] Update test Signed-off-by: Navie Chan --- .../tests/src/test/resources/jsonrpc/engine/genesis.json | 1 + .../jsonrpc/engine/test-cases/12_shanghai_get_payload.json | 1 + 2 files changed, 2 insertions(+) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json index 98a1201c9aa..ae26e56839b 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json @@ -13,6 +13,7 @@ "berlinBlock":0, "londonBlock":0, "shanghaiTime":10, + "experimentaleipstime":20, "clique": { "period": 5, "epoch": 30000 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json index 7f405ef47bb..bd2712b51c0 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json @@ -37,6 +37,7 @@ "amount": "0x2" } ], + "deposits" : null, "blockNumber": "0x2", "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" From d25ad53d0b6751fe81acf773b45e73cc55763d6c Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 4 Apr 2023 01:24:55 +0800 Subject: [PATCH 04/36] Added rpc tests. Update block creator rule for deposits Signed-off-by: Navie Chan --- ...oad.json => 18_v6110_prepare_payload.json} | 10 ++++----- ...payload.json => 19_v6110_get_payload.json} | 14 ++++++------ .../blockcreation/AbstractBlockCreator.java | 22 +++++++++++++------ 3 files changed, 27 insertions(+), 19 deletions(-) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{11_shanghai_prepare_payload.json => 18_v6110_prepare_payload.json} (74%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{12_shanghai_get_payload.json => 19_v6110_get_payload.json} (80%) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json similarity index 74% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json index cf5117dfb9a..ee80851dbe0 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json @@ -4,12 +4,12 @@ "method": "engine_forkchoiceUpdatedV2", "params": [ { - "headBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", - "safeBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "headBlockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "safeBlockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, { - "timestamp": "0x10", + "timestamp": "0x20", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "withdrawals": [ @@ -36,10 +36,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "latestValidHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "validationError": null }, - "payloadId": "0x0065bd32d4f95410" + "payloadId": "0x0065bd48ff13b2e0" } }, "statusCode" : 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json similarity index 80% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json index bd2712b51c0..4ef6a7c9ff3 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV2", "params": [ - "0x0065bd32d4f95410" + "0x0065bd48ff13b2e0" ], "id": 67 }, @@ -12,14 +12,14 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x7a6f2e03f2348dc75731e6e767c97a88da50430748a030874e27f7c3fac3d49d", + "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", "gasUsed": "0x0", - "timestamp": "0x10", + "timestamp": "0x20", "extraData": "0x", "baseFeePerGas": "0x7", "transactions": [], @@ -37,9 +37,9 @@ "amount": "0x2" } ], - "deposits" : null, - "blockNumber": "0x2", - "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "deposits" : [], + "blockNumber": "0x3", + "blockHash": "0x299b9dbc0670aa8b029ea11195e1d365308c456e120e62c5dc39507944be394b", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, "blockValue": "0x0" diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 27150a478a7..3218f0ed193 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; +import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.DifficultyCalculator; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -196,13 +197,20 @@ protected BlockCreationResult createBlock( throwIfStopped(); - final List depositsFromReceipts = - transactionResults.getReceipts().stream() - .flatMap(receipt -> receipt.getLogsList().stream()) - .map(DepositDecoder::decodeFromLog) - .toList(); - final Optional> maybeDeposits = - depositsFromReceipts.isEmpty() ? Optional.empty() : Optional.of(depositsFromReceipts); + + final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); + Optional> maybeDeposits = Optional.empty(); + + if (depositsValidator instanceof DepositsValidator.AllowedDeposits) { + final List depositsFromReceipts = + transactionResults.getReceipts().stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .map(DepositDecoder::decodeFromLog) + .toList(); + maybeDeposits = Optional.of(depositsFromReceipts); + } + + throwIfStopped(); if (rewardCoinbase && !rewardBeneficiary( From ca121d381368b3f390ebd17d851cfda67cee2809 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 4 Apr 2023 01:38:52 +0800 Subject: [PATCH 05/36] Update test Signed-off-by: Navie Chan --- ...invalid_null_deposits_execute_payload.json} | 18 +++++++++--------- .../ethereum/mainnet/DepositsValidator.java | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{14_shanghai_execute_payload.json => 20_v6110_invalid_null_deposits_execute_payload.json} (75%) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json similarity index 75% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json index 9b7bb0b4286..aae972920e1 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json @@ -4,14 +4,14 @@ "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x7a6f2e03f2348dc75731e6e767c97a88da50430748a030874e27f7c3fac3d49d", + "stateRoot": "0x1a10dba514dc4faff7ec13edd9b5ef653c1cd14eb26608bfc2b37717730a55a4", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", "gasUsed": "0x0", - "timestamp": "0x10", + "timestamp": "0x20", "extraData": "0x", "baseFeePerGas": "0x7", "transactions": [], @@ -29,8 +29,9 @@ "amount": "0x2" } ], - "blockNumber": "0x2", - "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "deposits": null, + "blockNumber": "0x3", + "blockHash": "0x1475ca311179652e44b10b7e2d7b72f3708f3201f8d729880a83f3eb397910e8", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } ], @@ -39,10 +40,9 @@ "response": { "jsonrpc": "2.0", "id": 67, - "result": { - "status": "VALID", - "latestValidHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", - "validationError": null + "error": { + "code": -32602, + "message": "Invalid params" } }, "statusCode": 200 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index a3259fd1d4e..b0cc8f05808 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -80,7 +80,7 @@ class AllowedDeposits implements DepositsValidator { @Override public boolean validateDepositParameters(final Optional> deposits) { - return deposits != null; + return deposits.isPresent(); } @Override From faf5a831e7e79a8043e7c8a4b6d7e4d84e1ba5e3 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 4 Apr 2023 20:54:32 +0800 Subject: [PATCH 06/36] Update test Signed-off-by: Navie Chan --- .../test-cases/21_v6110_execute_payload.json | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json new file mode 100644 index 00000000000..d08bc81c4b1 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json @@ -0,0 +1,50 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "engine_newPayloadV2", + "params": [ + { + "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "timestamp": "0x20", + "extraData": "0x", + "baseFeePerGas": "0x7", + "transactions": [], + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x0", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x1" + }, + { + "index": "0x1", + "validatorIndex": "0x0", + "address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", + "amount": "0x2" + } + ], + "deposits": [], + "blockNumber": "0x3", + "blockHash": "0x8e1cd0eb8e0df1c3713dfee3c7594d2bd85db4421d40fd89c34375091cb66d5a", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + } + ], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": { + "status": "VALID", + "latestValidHash": "0x8e1cd0eb8e0df1c3713dfee3c7594d2bd85db4421d40fd89c34375091cb66d5a", + "validationError": null + } + }, + "statusCode": 200 +} \ No newline at end of file From 53b2ac3be6e1b2b800a207f1a3a36c6b48935088 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 4 Apr 2023 21:05:50 +0800 Subject: [PATCH 07/36] Spotless Apply Signed-off-by: Navie Chan --- .../besu/ethereum/blockcreation/AbstractBlockCreator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 3218f0ed193..99e82e66e44 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -197,7 +197,6 @@ protected BlockCreationResult createBlock( throwIfStopped(); - final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); Optional> maybeDeposits = Optional.empty(); From 941f6027b95ebfe486cde38decc68e9a6a8849a1 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Wed, 5 Apr 2023 00:06:39 +0800 Subject: [PATCH 08/36] Get deposit validator by block header Signed-off-by: Navie Chan --- .../engine/AbstractEngineNewPayload.java | 3 ++- .../engine/DepositsValidatorProvider.java | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index a0e85c60478..523ff5c77fc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -117,7 +117,8 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) final Optional> maybeDeposits = Optional.ofNullable(blockParam.getDeposits()) .map(ds -> ds.stream().map(DepositParameter::toDeposit).collect(toList())); - if (!getDepositsValidator(timestampSchedule, blockParam.getTimestamp()) + if (!getDepositsValidator( + timestampSchedule, blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateDepositParameters(maybeDeposits)) { return new JsonRpcErrorResponse(reqId, INVALID_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java index 5759c9dca34..eea57023682 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java @@ -15,17 +15,26 @@ 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.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule; -public class DepositsValidatorProvider { +import java.util.Optional; +public class DepositsValidatorProvider { static DepositsValidator getDepositsValidator( - final TimestampSchedule timestampSchedule, final long newPayloadTimestamp) { + final TimestampSchedule timestampSchedule, + final long blockTimestamp, + final long blockNumber) { - return timestampSchedule - .getByTimestamp(newPayloadTimestamp) + final BlockHeader blockHeader = + BlockHeaderBuilder.createDefault() + .timestamp(blockTimestamp) + .number(blockNumber) + .buildBlockHeader(); + return Optional.ofNullable(timestampSchedule.getByBlockHeader(blockHeader)) .map(ProtocolSpec::getDepositsValidator) .orElseGet(DepositsValidator.ProhibitedDeposits::new); } From 0c26667daf8c9ed6a62eb6910ad0240581755de5 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Wed, 5 Apr 2023 00:54:18 +0800 Subject: [PATCH 09/36] Fix up unit tests Signed-off-by: Navie Chan --- .../besu/ethereum/mainnet/DepositsValidatorTest.java | 4 ++-- .../besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java index b5bb7d43b97..76e23293ca1 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java @@ -246,14 +246,14 @@ public void validateAllowedDepositParams() { assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) .isTrue(); - final Optional> emptyDeposits = Optional.empty(); + final Optional> emptyDeposits = Optional.of(List.of()); assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(emptyDeposits)) .isTrue(); } @Test public void invalidateAllowedDepositParams() { - final Optional> deposits = null; + final Optional> deposits = Optional.empty(); assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) .isFalse(); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java index 1df20268177..8543321b470 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java @@ -45,9 +45,11 @@ class MainnetBlockBodyValidatorTest { private final BlockchainSetupUtil blockchainSetupUtil = BlockchainSetupUtil.forMainnet(); private final List withdrawals = List.of(new Withdrawal(UInt64.ONE, UInt64.ONE, Address.ZERO, GWei.ONE)); + @Mock private ProtocolSchedule protocolSchedule; @Mock private ProtocolSpec protocolSpec; @Mock private WithdrawalsValidator withdrawalsValidator; + @Mock private DepositsValidator depositsValidator; @Test void validatesWithdrawals() { @@ -67,8 +69,11 @@ void validatesWithdrawals() { when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); when(protocolSpec.getWithdrawalsValidator()).thenReturn(withdrawalsValidator); + when(protocolSpec.getDepositsValidator()).thenReturn(depositsValidator); when(withdrawalsValidator.validateWithdrawals(Optional.of(withdrawals))).thenReturn(true); when(withdrawalsValidator.validateWithdrawalsRoot(block)).thenReturn(true); + when(depositsValidator.validateDeposits(any(), any())).thenReturn(true); + when(depositsValidator.validateDepositsRoot(block)).thenReturn(true); assertThat( new MainnetBlockBodyValidator(protocolSchedule) From c15fa474864c192e3dadcc6a41554dfb061be9df Mon Sep 17 00:00:00 2001 From: navie Date: Thu, 6 Apr 2023 00:29:24 +0800 Subject: [PATCH 10/36] Recover deleted files Signed-off-by: navie --- .../11_shanghai_prepare_payload.json | 46 +++++++++++++++++ .../test-cases/12_shanghai_get_payload.json | 48 ++++++++++++++++++ .../14_shanghai_execute_payload.json | 49 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json new file mode 100644 index 00000000000..cf5117dfb9a --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/11_shanghai_prepare_payload.json @@ -0,0 +1,46 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "engine_forkchoiceUpdatedV2", + "params": [ + { + "headBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "safeBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "timestamp": "0x10", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x0", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x1" + }, + { + "index": "0x1", + "validatorIndex": "0x0", + "address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", + "amount": "0x2" + } + ] + } + ], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": { + "payloadStatus": { + "status": "VALID", + "latestValidHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "validationError": null + }, + "payloadId": "0x0065bd32d4f95410" + } + }, + "statusCode" : 200 +} \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json new file mode 100644 index 00000000000..7f405ef47bb --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json @@ -0,0 +1,48 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "engine_getPayloadV2", + "params": [ + "0x0065bd32d4f95410" + ], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": { + "executionPayload": { + "parentHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "stateRoot": "0x7a6f2e03f2348dc75731e6e767c97a88da50430748a030874e27f7c3fac3d49d", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "timestamp": "0x10", + "extraData": "0x", + "baseFeePerGas": "0x7", + "transactions": [], + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x0", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x1" + }, + { + "index": "0x1", + "validatorIndex": "0x0", + "address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", + "amount": "0x2" + } + ], + "blockNumber": "0x2", + "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "blockValue": "0x0" + } + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json new file mode 100644 index 00000000000..9b7bb0b4286 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/14_shanghai_execute_payload.json @@ -0,0 +1,49 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "engine_newPayloadV2", + "params": [ + { + "parentHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "stateRoot": "0x7a6f2e03f2348dc75731e6e767c97a88da50430748a030874e27f7c3fac3d49d", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "timestamp": "0x10", + "extraData": "0x", + "baseFeePerGas": "0x7", + "transactions": [], + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x0", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x1" + }, + { + "index": "0x1", + "validatorIndex": "0x0", + "address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", + "amount": "0x2" + } + ], + "blockNumber": "0x2", + "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + } + ], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": { + "status": "VALID", + "latestValidHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "validationError": null + } + }, + "statusCode": 200 +} \ No newline at end of file From 2c802931ab76152852189da999cb1c129d3105a3 Mon Sep 17 00:00:00 2001 From: navie Date: Thu, 6 Apr 2023 00:32:59 +0800 Subject: [PATCH 11/36] Fix test Signed-off-by: navie --- .../jsonrpc/engine/test-cases/12_shanghai_get_payload.json | 1 + 1 file changed, 1 insertion(+) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json index 7f405ef47bb..55881b39c52 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/12_shanghai_get_payload.json @@ -37,6 +37,7 @@ "amount": "0x2" } ], + "deposits": null, "blockNumber": "0x2", "blockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" From bb805c1172f296c38aa2f48b39f3744e65a69f78 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 11 Apr 2023 15:19:35 +0800 Subject: [PATCH 12/36] Rename according to feedback Signed-off-by: navie --- .../hyperledger/besu/datatypes/Address.java | 4 ++-- .../engine/AbstractEngineNewPayload.java | 2 +- .../methods/engine/EngineGetPayloadV2Test.java | 9 ++++++--- .../ethereum/mainnet/DepositsValidator.java | 8 ++++---- .../mainnet/DepositsValidatorTest.java | 18 +++++++++--------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java index cd4ee6aadf4..60474f3dbba 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java @@ -74,8 +74,8 @@ public class Address extends DelegatingBytes { public static final Address KZG_POINT_EVAL = Address.precompiled(0x14); /** The constant ZERO. */ public static final Address ZERO = Address.fromHexString("0x0"); - /** The deposit address. */ - public static final Address DEPOSIT_ADDRESS = + /** The deposit contract address. */ + public static final Address DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); /** diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index 523ff5c77fc..abea2204ce7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -119,7 +119,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) .map(ds -> ds.stream().map(DepositParameter::toDeposit).collect(toList())); if (!getDepositsValidator( timestampSchedule, blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateDepositParameters(maybeDeposits)) { + .validateDepositParameter(maybeDeposits)) { return new JsonRpcErrorResponse(reqId, INVALID_PARAMS); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java index f381b218cbb..481e6e6b76d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java @@ -67,14 +67,17 @@ public void shouldReturnBlockForKnownPayloadId() { .isEqualTo(mockHeader.getPrevRandao().map(Bytes32::toString).orElse("")); }); verify(engineCallListener, times(1)).executionEngineCalled(); + } + @Test + public void shouldReturnBlockForKnownPayloadIdPostV6110() { // should return deposits for a post-V6110 block when(mergeContext.retrieveBlockById(mockPid)) .thenReturn(Optional.of(mockBlockWithReceiptsAndDeposits)); - final var resp2 = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); - assertThat(resp2).isInstanceOf(JsonRpcSuccessResponse.class); - Optional.of(resp2) + final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); + assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class); + Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .ifPresent( r -> { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index b0cc8f05808..61e2bd3cb7b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -35,7 +35,7 @@ public interface DepositsValidator { - boolean validateDepositParameters(Optional> deposits); + boolean validateDepositParameter(Optional> deposits); boolean validateDeposits(Block block, List receipts); @@ -46,7 +46,7 @@ class ProhibitedDeposits implements DepositsValidator { private static final Logger LOG = LoggerFactory.getLogger(ProhibitedDeposits.class); @Override - public boolean validateDepositParameters(final Optional> deposits) { + public boolean validateDepositParameter(final Optional> deposits) { return deposits.isEmpty(); } @@ -79,7 +79,7 @@ class AllowedDeposits implements DepositsValidator { private static final Logger LOG = LoggerFactory.getLogger(AllowedDeposits.class); @Override - public boolean validateDepositParameters(final Optional> deposits) { + public boolean validateDepositParameter(final Optional> deposits) { return deposits.isPresent(); } @@ -95,7 +95,7 @@ public boolean validateDeposits(final Block block, final List> deposits = Optional.empty(); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameters(deposits)) + assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameter(deposits)) .isTrue(); } @Test public void invalidateProhibitedDepositParams() { final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameters(deposits)) + assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameter(deposits)) .isFalse(); } @Test public void validateAllowedDepositParams() { final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(deposits)) .isTrue(); final Optional> emptyDeposits = Optional.of(List.of()); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(emptyDeposits)) + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(emptyDeposits)) .isTrue(); } @Test public void invalidateAllowedDepositParams() { final Optional> deposits = Optional.empty(); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameters(deposits)) + assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(deposits)) .isFalse(); } } From e6adf321b478d78a7ef0e61f6de6f5f55d798ecc Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 11 Apr 2023 17:24:45 +0800 Subject: [PATCH 13/36] Introduce depositContractAddress to genesis file Signed-off-by: navie --- .../besu/config/GenesisConfigOptions.java | 9 +++ .../besu/config/JsonGenesisConfigOptions.java | 10 +++ .../besu/config/StubGenesisConfigOptions.java | 7 +++ .../besu/config/GenesisConfigOptionsTest.java | 26 ++++++++ .../valid_config_with_custom_forks.json | 1 + .../hyperledger/besu/datatypes/Address.java | 3 - .../engine/AbstractEngineNewPayloadTest.java | 9 ++- .../ethereum/mainnet/DepositsValidator.java | 7 ++- .../mainnet/MainnetProtocolSpecs.java | 8 ++- .../mainnet/DepositsValidatorTest.java | 63 +++++++++++++++---- 10 files changed, 125 insertions(+), 18 deletions(-) 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 fe92131c011..d9989c40195 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.config; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -525,4 +526,12 @@ default boolean isConsensusMigration() { * @return true, if you want the next block to use zero for the base fee. */ boolean isZeroBaseFee(); + + /** + * The deposit contract address that should be in the logger field in Receipt of Deposit + * transaction + * + * @return the deposit address + */ + Optional
getDepositContractAddress(); } 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 2f66ab343bd..0f4d5f632e9 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -17,6 +17,7 @@ import static java.util.Collections.emptyMap; import static java.util.Objects.isNull; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -48,6 +49,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { private static final String DISCOVERY_CONFIG_KEY = "discovery"; private static final String CHECKPOINT_CONFIG_KEY = "checkpoint"; private static final String ZERO_BASE_FEE_KEY = "zerobasefee"; + private static final String DEPOSIT_CONTRACT_ADDRESS_KEY = "depositcontractaddress"; private final ObjectNode configRoot; private final Map configOverrides = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); @@ -449,6 +451,12 @@ public boolean isZeroBaseFee() { return getOptionalBoolean(ZERO_BASE_FEE_KEY).orElse(false); } + @Override + public Optional
getDepositContractAddress() { + Optional inputAddress = JsonUtil.getString(configRoot, DEPOSIT_CONTRACT_ADDRESS_KEY); + return inputAddress.map(Address::fromHexString); + } + @Override public Map asMap() { final ImmutableMap.Builder builder = ImmutableMap.builder(); @@ -494,6 +502,8 @@ public Map asMap() { getEvmStackSize().ifPresent(l -> builder.put("evmstacksize", l)); getEcip1017EraRounds().ifPresent(l -> builder.put("ecip1017EraRounds", l)); + getDepositContractAddress().ifPresent(l -> builder.put("depositContractAddress", l)); + if (isClique()) { builder.put("clique", getCliqueConfigOptions().asMap()); } 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 d391e041009..6276395254f 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.config; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -393,6 +394,7 @@ public Map asMap() { getContractSizeLimit().ifPresent(l -> builder.put("contractSizeLimit", l)); getEvmStackSize().ifPresent(l -> builder.put("evmStackSize", l)); + getDepositContractAddress().ifPresent(l -> builder.put("depositContractAddress", l)); if (isClique()) { builder.put("clique", getCliqueConfigOptions().asMap()); } @@ -453,6 +455,11 @@ public List getForkBlockTimestamps() { return Collections.emptyList(); } + @Override + public Optional
getDepositContractAddress() { + return Optional.empty(); + } + /** * Homestead block stub genesis config options. * 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 a106e650657..a4aeb25a26d 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -19,6 +19,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import org.hyperledger.besu.datatypes.Address; + import java.math.BigInteger; import java.util.HashMap; import java.util.Map; @@ -329,6 +331,30 @@ public void asMapIncludesZeroBaseFee() { assertThat(config.asMap()).containsOnlyKeys("zeroBaseFee").containsValue(true); } + @Test + public void shouldGetDepositContractAddress() { + final GenesisConfigOptions config = + fromConfigOptions( + singletonMap("depositContractAddress", "0x00000000219ab540356cbb839cbe05303d7705fa")); + assertThat(config.getDepositContractAddress()) + .hasValue(Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa")); + } + + @Test + public void shouldNotHaveDepositContractAddressWhenEmpty() { + final GenesisConfigOptions config = fromConfigOptions(emptyMap()); + assertThat(config.getDepositContractAddress()).isEmpty(); + } + + @Test + public void asMapIncludesDepositContractAddress() { + final GenesisConfigOptions config = fromConfigOptions(Map.of("depositContractAddress", "0x0")); + + assertThat(config.asMap()) + .containsOnlyKeys("depositContractAddress") + .containsValue(Address.ZERO); + } + private GenesisConfigOptions fromConfigOptions(final Map configOptions) { final ObjectNode rootNode = JsonUtil.createEmptyObjectNode(); final ObjectNode options = JsonUtil.objectNodeFromMap(configOptions); diff --git a/config/src/test/resources/valid_config_with_custom_forks.json b/config/src/test/resources/valid_config_with_custom_forks.json index dd31babf8bc..b3853086c6f 100644 --- a/config/src/test/resources/valid_config_with_custom_forks.json +++ b/config/src/test/resources/valid_config_with_custom_forks.json @@ -6,6 +6,7 @@ "byzantiumBlock": 1035301, "londonBlock": 2222222, "zeroBaseFee": true, + "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa", "ibft2": { "blockperiodseconds": 2, "epochlength": 30000, diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java index 60474f3dbba..8862d9461e2 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java @@ -74,9 +74,6 @@ public class Address extends DelegatingBytes { public static final Address KZG_POINT_EVAL = Address.precompiled(0x14); /** The constant ZERO. */ public static final Address ZERO = Address.fromHexString("0x0"); - /** The deposit contract address. */ - public static final Address DEPOSIT_CONTRACT_ADDRESS = - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); /** * Instantiates a new Address. diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java index 9a8a94a624f..f8e8832d293 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java @@ -32,6 +32,7 @@ import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.BlockProcessingOutputs; @@ -106,6 +107,8 @@ public AbstractEngineNewPayloadTest(final MethodFactory methodFactory) { private static final Vertx vertx = Vertx.vertx(); private static final Hash mockHash = Hash.hash(Bytes32.fromHexStringLenient("0x1337deadbeef")); + private static final Address depositContractAddress = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); @Mock private ProtocolSpec protocolSpec; @Mock private TimestampSchedule timestampSchedule; @@ -514,7 +517,8 @@ public void shouldReturnValidIfDepositsIsNull_WhenDepositsProhibited() { @Test public void shouldReturnInvalidIfDepositsIsNull_WhenDepositsAllowed() { final List deposits = null; - when(protocolSpec.getDepositsValidator()).thenReturn(new DepositsValidator.AllowedDeposits()); + when(protocolSpec.getDepositsValidator()) + .thenReturn(new DepositsValidator.AllowedDeposits(depositContractAddress)); var resp = resp( @@ -532,7 +536,8 @@ public void shouldReturnInvalidIfDepositsIsNull_WhenDepositsAllowed() { public void shouldReturnValidIfDepositsIsNotNull_WhenDepositsAllowed() { final List depositsParam = List.of(DEPOSIT_PARAM_1); final List deposits = List.of(DEPOSIT_PARAM_1.toDeposit()); - when(protocolSpec.getDepositsValidator()).thenReturn(new DepositsValidator.AllowedDeposits()); + when(protocolSpec.getDepositsValidator()) + .thenReturn(new DepositsValidator.AllowedDeposits(depositContractAddress)); BlockHeader mockHeader = setupValidPayload( new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index 61e2bd3cb7b..f24a9d8e2a2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -77,6 +77,11 @@ public boolean validateDepositsRoot(final Block block) { class AllowedDeposits implements DepositsValidator { private static final Logger LOG = LoggerFactory.getLogger(AllowedDeposits.class); + private final Address depositContractAddress; + + public AllowedDeposits(final Address depositContractAddress) { + this.depositContractAddress = depositContractAddress; + } @Override public boolean validateDepositParameter(final Optional> deposits) { @@ -95,7 +100,7 @@ public boolean validateDeposits(final Block block, final List MainnetEVMs.experimentalEips( gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) - .depositsValidator(new DepositsValidator.AllowedDeposits()) + .depositsValidator(new DepositsValidator.AllowedDeposits(depositContractAddress)) .name("ExperimentalEips"); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java index dd36287b935..c77bb91544e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java @@ -45,6 +45,7 @@ public class DepositsValidatorTest { private static Deposit DEPOSIT_2; private static Log LOG_1; private static Log LOG_2; + private static Address DEPOSIT_CONTRACT_ADDRESS; @BeforeAll public static void setup() { @@ -88,6 +89,7 @@ public static void setup() { List.of( LogTopic.fromHexString( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); + DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); } @Test @@ -130,7 +132,9 @@ public void validateAllowedDeposits() { final TransactionReceipt receipt = new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt))) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDeposits(block, List.of(receipt))) .isTrue(); } @@ -147,7 +151,7 @@ public void validateAllowedDepositsSeparateReceipts() { new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits() + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) .validateDeposits(block, List.of(receipt1, receipt2))) .isTrue(); } @@ -159,7 +163,10 @@ public void validateAllowedDepositsRoot() { .setDeposits(Optional.of(Collections.emptyList())) .setDepositsRoot(Hash.EMPTY_TRIE_HASH); final Block block = blockDataGenerator.block(blockOptions); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositsRoot(block)).isTrue(); + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDepositsRoot(block)) + .isTrue(); } @Test @@ -171,7 +178,9 @@ public void invalidateAllowedDeposits() { final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); - assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDeposits(block, List.of(receipt1))) .isFalse(); } @@ -185,7 +194,9 @@ public void invalidateAllowedDepositsMissingLogInReceipt() { final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); - assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDeposits(block, List.of(receipt1))) .isFalse(); } @@ -198,7 +209,9 @@ public void invalidateAllowedDepositsExtraLogInReceipt() { final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDeposits(block, List.of(receipt1))) .isFalse(); } @@ -212,7 +225,26 @@ public void invalidateAllowedDepositsWrongOrder() { final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2, LOG_1), Optional.empty()); - assertThat(new DepositsValidator.AllowedDeposits().validateDeposits(block, List.of(receipt1))) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDeposits(block, List.of(receipt1))) + .isFalse(); + } + + @Test + public void invalidateAllowedDepositsMismatchContractAddress() { + + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + final Block block = blockDataGenerator.block(blockOptions); + + final TransactionReceipt receipt1 = + new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); + + assertThat( + new DepositsValidator.AllowedDeposits(Address.ZERO) + .validateDeposits(block, List.of(receipt1))) .isFalse(); } @@ -223,7 +255,10 @@ public void invalidateAllowedDepositsRoot() { .setDeposits(Optional.of(Collections.emptyList())) .setDepositsRoot(Hash.ZERO); // this is invalid it should be empty trie hash final Block block = blockDataGenerator.block(blockOptions); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositsRoot(block)).isFalse(); + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDepositsRoot(block)) + .isFalse(); } @Test @@ -243,18 +278,24 @@ public void invalidateProhibitedDepositParams() { @Test public void validateAllowedDepositParams() { final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(deposits)) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDepositParameter(deposits)) .isTrue(); final Optional> emptyDeposits = Optional.of(List.of()); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(emptyDeposits)) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDepositParameter(emptyDeposits)) .isTrue(); } @Test public void invalidateAllowedDepositParams() { final Optional> deposits = Optional.empty(); - assertThat(new DepositsValidator.AllowedDeposits().validateDepositParameter(deposits)) + assertThat( + new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) + .validateDepositParameter(deposits)) .isFalse(); } } From d3d18a89885337587a0f30babba738088e7e1383 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 11 Apr 2023 18:09:00 +0800 Subject: [PATCH 14/36] Update test to accommodate changes Signed-off-by: navie --- ...prepare_payload.json => 19_v6110_prepare_payload.json} | 8 ++++---- ...9_v6110_get_payload.json => 20_v6110_get_payload.json} | 6 +++--- ...> 21_v6110_invalid_null_deposits_execute_payload.json} | 2 +- ...execute_payload.json => 22_v6110_execute_payload.json} | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{18_v6110_prepare_payload.json => 19_v6110_prepare_payload.json} (76%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{19_v6110_get_payload.json => 20_v6110_get_payload.json} (89%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{20_v6110_invalid_null_deposits_execute_payload.json => 21_v6110_invalid_null_deposits_execute_payload.json} (95%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/{21_v6110_execute_payload.json => 22_v6110_execute_payload.json} (86%) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_prepare_payload.json similarity index 76% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_prepare_payload.json index ee80851dbe0..1e4faee33ec 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/18_v6110_prepare_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_prepare_payload.json @@ -4,8 +4,8 @@ "method": "engine_forkchoiceUpdatedV2", "params": [ { - "headBlockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", - "safeBlockHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "headBlockHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", + "safeBlockHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, { @@ -36,10 +36,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "latestValidHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", "validationError": null }, - "payloadId": "0x0065bd48ff13b2e0" + "payloadId": "0x0065bd4610115c06" } }, "statusCode" : 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_get_payload.json similarity index 89% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_get_payload.json index 4ef6a7c9ff3..84c236cd1e7 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/19_v6110_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_get_payload.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV2", "params": [ - "0x0065bd48ff13b2e0" + "0x0065bd4610115c06" ], "id": 67 }, @@ -12,7 +12,7 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -39,7 +39,7 @@ ], "deposits" : [], "blockNumber": "0x3", - "blockHash": "0x299b9dbc0670aa8b029ea11195e1d365308c456e120e62c5dc39507944be394b", + "blockHash": "0xf6c1bee3c5831a9fc068abd3ed3619fd82900622c6e8bb1dc39dee099b246b88", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, "blockValue": "0x0" diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_invalid_null_deposits_execute_payload.json similarity index 95% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_invalid_null_deposits_execute_payload.json index aae972920e1..ebdd0ad81c2 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/20_v6110_invalid_null_deposits_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_invalid_null_deposits_execute_payload.json @@ -4,7 +4,7 @@ "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "stateRoot": "0x1a10dba514dc4faff7ec13edd9b5ef653c1cd14eb26608bfc2b37717730a55a4", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/22_v6110_execute_payload.json similarity index 86% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/22_v6110_execute_payload.json index d08bc81c4b1..cb9701fb924 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/21_v6110_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/test-cases/22_v6110_execute_payload.json @@ -4,7 +4,7 @@ "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x5dec96e86ccd61362959cc73a0992b033fcde6f01d7467393363538c74c5260d", + "parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -31,7 +31,7 @@ ], "deposits": [], "blockNumber": "0x3", - "blockHash": "0x8e1cd0eb8e0df1c3713dfee3c7594d2bd85db4421d40fd89c34375091cb66d5a", + "blockHash": "0x9a083733e09cb4983933e7a7053ca470c3f583bb54e38d32c9ab396c8ededd6f", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } ], @@ -42,7 +42,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x8e1cd0eb8e0df1c3713dfee3c7594d2bd85db4421d40fd89c34375091cb66d5a", + "latestValidHash": "0x9a083733e09cb4983933e7a7053ca470c3f583bb54e38d32c9ab396c8ededd6f", "validationError": null } }, From 162f60cdd8a27ecbfeab1fb7acbb9254e1907457 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 11 Apr 2023 18:13:18 +0800 Subject: [PATCH 15/36] Fix test Signed-off-by: navie --- .../jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java index 481e6e6b76d..1018baa0884 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java @@ -90,7 +90,7 @@ public void shouldReturnBlockForKnownPayloadIdPostV6110() { assertThat(res.getExecutionPayload().getPrevRandao()) .isEqualTo(mockHeader.getPrevRandao().map(Bytes32::toString).orElse("")); }); - verify(engineCallListener, times(2)).executionEngineCalled(); + verify(engineCallListener, times(1)).executionEngineCalled(); } @Test From 6d567ccbc9572fbafd636fec5f3f821528f4b540 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Mon, 1 May 2023 02:18:20 +0800 Subject: [PATCH 16/36] Address comments Signed-off-by: Navie Chan --- config/src/main/resources/experimental.json | 3 ++- .../engine/EngineGetPayloadV2Test.java | 14 ----------- .../blockcreation/AbstractBlockCreator.java | 1 + .../besu/ethereum/core/DepositContract.java | 2 +- .../core/encoding/DepositDecoder.java | 5 +++- .../core/encoding/DepositDecoderTest.java | 23 ++++++++++++++----- .../mainnet/DepositsValidatorTest.java | 1 - 7 files changed, 25 insertions(+), 24 deletions(-) diff --git a/config/src/main/resources/experimental.json b/config/src/main/resources/experimental.json index f73b46d84ee..b715b755e7a 100644 --- a/config/src/main/resources/experimental.json +++ b/config/src/main/resources/experimental.json @@ -35,5 +35,6 @@ "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", "balance": "90000000000000000000000" } - } + }, + "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa" } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java index 1018baa0884..2250f63e718 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java @@ -104,20 +104,6 @@ public void shouldReturnExecutionPayloadWithoutWithdrawals_PreShanghaiBlock() { assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class); final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult(); assertThat(res.getExecutionPayload().getWithdrawals()).isNull(); - }); - verify(engineCallListener, times(1)).executionEngineCalled(); - } - - @Test - public void shouldReturnExecutionPayloadWithoutDeposits_PreShanghaiBlock() { - final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); - assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class); - Optional.of(resp) - .map(JsonRpcSuccessResponse.class::cast) - .ifPresent( - r -> { - assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class); - final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult(); assertThat(res.getExecutionPayload().getDeposits()).isNull(); }); verify(engineCallListener, times(1)).executionEngineCalled(); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 99e82e66e44..41b7eacc168 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -204,6 +204,7 @@ protected BlockCreationResult createBlock( final List depositsFromReceipts = transactionResults.getReceipts().stream() .flatMap(receipt -> receipt.getLogsList().stream()) + .filter(log -> true) // TODO: Figure out how to get the deposit contract address .map(DepositDecoder::decodeFromLog) .toList(); maybeDeposits = Optional.of(depositsFromReceipts); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java index 6537af928c6..4645e74a6c7 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java @@ -42,7 +42,7 @@ public class DepositContract extends Contract { new TypeReference() {}, new TypeReference() {})); - protected DepositContract( + private DepositContract( final String contractBinary, final String contractAddress, final Web3j web3j, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java index 341753c7780..4e12e4cbd55 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java @@ -28,6 +28,8 @@ import org.apache.tuweni.units.bigints.UInt64; import org.web3j.tx.Contract; +import java.nio.ByteOrder; + public class DepositDecoder { public static Deposit decode(final RLPInput rlpInput) { @@ -53,7 +55,7 @@ public static Deposit decodeFromLog(final Log log) { return new Deposit( BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)), Bytes32.wrap(Bytes.wrap(rawWithdrawalCredential)), - GWei.of(Bytes.wrap(rawAmount).reverse().toLong()), + GWei.of(Bytes.wrap(rawAmount).toLong(ByteOrder.LITTLE_ENDIAN)), // Amount is little endian as per Deposit Contract BLSSignature.wrap(Bytes.wrap(rawSignature)), UInt64.valueOf(Bytes.wrap(rawIndex).reverse().toLong())); } @@ -61,4 +63,5 @@ public static Deposit decodeFromLog(final Log log) { public static Deposit decodeOpaqueBytes(final Bytes input) { return decode(RLP.input(input)); } + } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java index 9514fbaaec1..e2467b43349 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java @@ -55,18 +55,29 @@ void shouldDecodeDeposit() { @Test void shouldDecodeDepositFromLog() { - Address address = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - List topics = + final Address address = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + final List topics = List.of( LogTopic.fromHexString( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")); - Bytes data = + final Bytes data = Bytes.fromHexString( "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"); - Log log = new Log(address, data, topics); - Deposit deposit = DepositDecoder.decodeFromLog(log); + final Log log = new Log(address, data, topics); + final Deposit deposit = DepositDecoder.decodeFromLog(log); - System.out.println(deposit); + final Deposit expectedDeposit = + new Deposit( + BLSPublicKey.fromHexString( + "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), + Bytes32.fromHexString( + "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), + GWei.of(32000000000L), + BLSSignature.fromHexString( + "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), + UInt64.ONE); + + assertThat(deposit).isEqualTo(expectedDeposit); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java index c77bb91544e..09bd5a110b7 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java @@ -49,7 +49,6 @@ public class DepositsValidatorTest { @BeforeAll public static void setup() { - System.out.println("setting"); DEPOSIT_1 = new Deposit( BLSPublicKey.fromHexString( From 1dbad0883d3a94304d06222912a2e5c8b2e2f37d Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 2 May 2023 12:28:51 +0800 Subject: [PATCH 17/36] Address pr comments Signed-off-by: Navie Chan --- config/src/main/resources/experimental.json | 6 +++--- .../org/hyperledger/besu/ethereum/core/DepositContract.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/src/main/resources/experimental.json b/config/src/main/resources/experimental.json index b715b755e7a..43eff251000 100644 --- a/config/src/main/resources/experimental.json +++ b/config/src/main/resources/experimental.json @@ -10,7 +10,8 @@ "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "number": 0, "totalDifficulty": "0x0" - } + }, + "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa" }, "nonce": "0x42", "timestamp": "0x0", @@ -35,6 +36,5 @@ "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", "balance": "90000000000000000000000" } - }, - "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa" + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java index 4645e74a6c7..9f36df7ca97 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositContract.java @@ -42,7 +42,7 @@ public class DepositContract extends Contract { new TypeReference() {}, new TypeReference() {})); - private DepositContract( + DepositContract( final String contractBinary, final String contractAddress, final Web3j web3j, From 695e6a048be2702f0deda1a96f04a059fac43308 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 2 May 2023 12:51:28 +0800 Subject: [PATCH 18/36] Updated DepositsValidatorProvider Signed-off-by: Navie Chan --- .../engine/AbstractEngineNewPayload.java | 2 +- .../engine/DepositsValidatorProvider.java | 23 +++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index f8c37434571..ba463759a69 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -118,7 +118,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) Optional.ofNullable(blockParam.getDeposits()) .map(ds -> ds.stream().map(DepositParameter::toDeposit).collect(toList())); if (!getDepositsValidator( - timestampSchedule, blockParam.getTimestamp(), blockParam.getBlockNumber()) + protocolSchedule, blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateDepositParameter(maybeDeposits)) { return new JsonRpcErrorResponse(reqId, INVALID_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java index eea57023682..26ee8f9a356 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java @@ -18,24 +18,37 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule; import java.util.Optional; public class DepositsValidatorProvider { + static DepositsValidator getDepositsValidator( - final TimestampSchedule timestampSchedule, - final long blockTimestamp, - final long blockNumber) { + final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { final BlockHeader blockHeader = BlockHeaderBuilder.createDefault() .timestamp(blockTimestamp) .number(blockNumber) .buildBlockHeader(); - return Optional.ofNullable(timestampSchedule.getByBlockHeader(blockHeader)) + return getDepositsValidator(protocolSchedule.getByBlockHeader(blockHeader)); + } + + static DepositsValidator getDepositsValidator( + final ProtocolSchedule protocolSchedule, + final BlockHeader parentBlockHeader, + final long timestampForNextBlock) { + + return getDepositsValidator( + protocolSchedule.getForNextBlockHeader(parentBlockHeader, timestampForNextBlock)); + } + + private static DepositsValidator getDepositsValidator(final ProtocolSpec protocolSchedule) { + return Optional.ofNullable(protocolSchedule) .map(ProtocolSpec::getDepositsValidator) .orElseGet(DepositsValidator.ProhibitedDeposits::new); } + } From fd8739b3884fd3cd5ad2b4eda76473149f773fde Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 2 May 2023 20:26:14 +0800 Subject: [PATCH 19/36] Spotless Apply Signed-off-by: Navie Chan --- .../methods/engine/DepositsValidatorProvider.java | 1 - .../besu/ethereum/core/encoding/DepositDecoder.java | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java index 26ee8f9a356..c9dd5c9a004 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java @@ -50,5 +50,4 @@ private static DepositsValidator getDepositsValidator(final ProtocolSpec protoco .map(ProtocolSpec::getDepositsValidator) .orElseGet(DepositsValidator.ProhibitedDeposits::new); } - } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java index 4e12e4cbd55..07738c28734 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java @@ -23,13 +23,13 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.evm.log.Log; +import java.nio.ByteOrder; + import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; import org.web3j.tx.Contract; -import java.nio.ByteOrder; - public class DepositDecoder { public static Deposit decode(final RLPInput rlpInput) { @@ -55,7 +55,10 @@ public static Deposit decodeFromLog(final Log log) { return new Deposit( BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)), Bytes32.wrap(Bytes.wrap(rawWithdrawalCredential)), - GWei.of(Bytes.wrap(rawAmount).toLong(ByteOrder.LITTLE_ENDIAN)), // Amount is little endian as per Deposit Contract + GWei.of( + Bytes.wrap(rawAmount) + .toLong( + ByteOrder.LITTLE_ENDIAN)), // Amount is little endian as per Deposit Contract BLSSignature.wrap(Bytes.wrap(rawSignature)), UInt64.valueOf(Bytes.wrap(rawIndex).reverse().toLong())); } @@ -63,5 +66,4 @@ public static Deposit decodeFromLog(final Log log) { public static Deposit decodeOpaqueBytes(final Bytes input) { return decode(RLP.input(input)); } - } From 0bf4be11b4aa5523ecb94eb90a6f316e07d35362 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 2 May 2023 20:36:30 +0800 Subject: [PATCH 20/36] Extract correct logs from receipts Signed-off-by: Navie Chan --- .../besu/ethereum/blockcreation/AbstractBlockCreator.java | 6 +++++- .../besu/ethereum/mainnet/DepositsValidator.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 41b7eacc168..39776b889ed 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -204,7 +204,11 @@ protected BlockCreationResult createBlock( final List depositsFromReceipts = transactionResults.getReceipts().stream() .flatMap(receipt -> receipt.getLogsList().stream()) - .filter(log -> true) // TODO: Figure out how to get the deposit contract address + .filter( + log -> + ((DepositsValidator.AllowedDeposits) depositsValidator) + .getDepositContractAddress() + .equals(log.getLogger())) .map(DepositDecoder::decodeFromLog) .toList(); maybeDeposits = Optional.of(depositsFromReceipts); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index f24a9d8e2a2..b171be2791a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -83,6 +83,10 @@ public AllowedDeposits(final Address depositContractAddress) { this.depositContractAddress = depositContractAddress; } + public Address getDepositContractAddress() { + return depositContractAddress; + } + @Override public boolean validateDepositParameter(final Optional> deposits) { return deposits.isPresent(); From 17d264b67f5e79fc5796c9d1742d9a6e63074397 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Wed, 3 May 2023 13:45:58 +0800 Subject: [PATCH 21/36] Add changelog Signed-off-by: Navie Chan --- CHANGELOG.md | 1 + .../besu/ethereum/core/encoding/DepositDecoderTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9138bbaa76b..393ed67b3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Breaking Changes ### Additions and Improvements +- Added In-Protocol Deposit prototype (EIP-6110) in the experimental eip. [#5005](https://github.com/hyperledger/besu/pull/5055) [#5295](https://github.com/hyperledger/besu/pull/5295) ### Bug Fixes - Fix eth_feeHistory response for the case in which blockCount is higher than highestBlock requested. [#5397](https://github.com/hyperledger/besu/pull/5397) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java index e2467b43349..5939611c5e9 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoderTest.java @@ -76,7 +76,7 @@ void shouldDecodeDepositFromLog() { GWei.of(32000000000L), BLSSignature.fromHexString( "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.ONE); + UInt64.valueOf(539967)); assertThat(deposit).isEqualTo(expectedDeposit); } From f79d2032ff9d38d276d0d3ab83824e774e9f1e7e Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 9 May 2023 01:10:36 +0800 Subject: [PATCH 22/36] Address PR comments Signed-off-by: Navie Chan --- .../src/test/resources/jsonrpc/engine/genesis.json | 2 +- .../besu/ethereum/core/encoding/DepositDecoder.java | 10 +++++----- .../besu/ethereum/mainnet/DepositsValidator.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json index ae26e56839b..2bfcecbc9a8 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/genesis.json @@ -13,7 +13,7 @@ "berlinBlock":0, "londonBlock":0, "shanghaiTime":10, - "experimentaleipstime":20, + "experimentalEipsTime":20, "clique": { "period": 5, "epoch": 30000 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java index 07738c28734..71661e241c5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java @@ -46,11 +46,11 @@ public static Deposit decode(final RLPInput rlpInput) { public static Deposit decodeFromLog(final Log log) { Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log); - byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue(); - byte[] rawWithdrawalCredential = (byte[]) eventValues.getNonIndexedValues().get(1).getValue(); - byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue(); - byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue(); - byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue(); + final byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue(); + final byte[] rawWithdrawalCredential = (byte[]) eventValues.getNonIndexedValues().get(1).getValue(); + final byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue(); + final byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue(); + final byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue(); return new Deposit( BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)), diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index b171be2791a..a359da3e23e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -55,7 +55,7 @@ public boolean validateDeposits(final Block block, final List> deposits = block.getBody().getDeposits(); final boolean isValid = deposits.isEmpty(); if (!isValid) { - LOG.warn("Deposits must be null when Deposits are prohibited but were: {}", deposits); + LOG.warn("Deposits must be empty when Deposits are prohibited but were: {}", deposits); } return isValid; } @@ -95,7 +95,7 @@ public boolean validateDepositParameter(final Optional> deposits) @Override public boolean validateDeposits(final Block block, final List receipts) { if (block.getBody().getDeposits().isEmpty()) { - LOG.warn("Deposits must not be null when Deposits are activated"); + LOG.warn("Deposits must not be empty when Deposits are activated"); return false; } From 807940f4d7feaad297441d3aca1ca5bb1210ee17 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 9 May 2023 01:17:18 +0800 Subject: [PATCH 23/36] Address PR comments Signed-off-by: Navie Chan --- .../engine/DepositsValidatorProvider.java | 9 - .../results/EngineGetPayloadResultV6110.java | 195 ------------------ 2 files changed, 204 deletions(-) delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV6110.java diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java index c9dd5c9a004..36c29bd26a1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java @@ -36,15 +36,6 @@ static DepositsValidator getDepositsValidator( return getDepositsValidator(protocolSchedule.getByBlockHeader(blockHeader)); } - static DepositsValidator getDepositsValidator( - final ProtocolSchedule protocolSchedule, - final BlockHeader parentBlockHeader, - final long timestampForNextBlock) { - - return getDepositsValidator( - protocolSchedule.getForNextBlockHeader(parentBlockHeader, timestampForNextBlock)); - } - private static DepositsValidator getDepositsValidator(final ProtocolSpec protocolSchedule) { return Optional.ofNullable(protocolSchedule) .map(ProtocolSpec::getDepositsValidator) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV6110.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV6110.java deleted file mode 100644 index 75d3e4bbe26..00000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV6110.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu - * - * 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.results; - -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; -import org.hyperledger.besu.ethereum.core.Withdrawal; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import org.apache.tuweni.bytes.Bytes32; - -@JsonPropertyOrder({ - "executionPayload", - "blockValue", -}) -public class EngineGetPayloadResultV6110 { - protected final PayloadResult executionPayload; - private final String blockValue; - - public EngineGetPayloadResultV6110( - final BlockHeader header, - final List transactions, - final Optional> withdrawals, - final Optional> deposits, - final String blockValue) { - this.executionPayload = new PayloadResult(header, transactions, withdrawals, deposits); - this.blockValue = blockValue; - } - - @JsonGetter(value = "executionPayload") - public PayloadResult getExecutionPayload() { - return executionPayload; - } - - @JsonGetter(value = "blockValue") - public String getBlockValue() { - return blockValue; - } - - public static class PayloadResult { - - protected final String blockHash; - private final String parentHash; - private final String feeRecipient; - private final String stateRoot; - private final String receiptsRoot; - private final String logsBloom; - private final String prevRandao; - private final String blockNumber; - private final String gasLimit; - private final String gasUsed; - private final String timestamp; - private final String extraData; - private final String baseFeePerGas; - protected final List transactions; - private final List withdrawals; - - private final List deposits; - - public PayloadResult( - final BlockHeader header, - final List transactions, - final Optional> withdrawals, - final Optional> deposits) { - this.blockNumber = Quantity.create(header.getNumber()); - this.blockHash = header.getHash().toString(); - this.parentHash = header.getParentHash().toString(); - this.logsBloom = header.getLogsBloom().toString(); - this.stateRoot = header.getStateRoot().toString(); - this.receiptsRoot = header.getReceiptsRoot().toString(); - this.extraData = header.getExtraData().toString(); - this.baseFeePerGas = header.getBaseFee().map(Quantity::create).orElse(null); - this.gasLimit = Quantity.create(header.getGasLimit()); - this.gasUsed = Quantity.create(header.getGasUsed()); - this.timestamp = Quantity.create(header.getTimestamp()); - this.transactions = transactions; - this.feeRecipient = header.getCoinbase().toString(); - this.prevRandao = header.getPrevRandao().map(Bytes32::toHexString).orElse(null); - this.withdrawals = - withdrawals - .map( - ws -> - ws.stream() - .map(WithdrawalParameter::fromWithdrawal) - .collect(Collectors.toList())) - .orElse(null); - this.deposits = - deposits - .map( - ws -> ws.stream().map(DepositParameter::fromDeposit).collect(Collectors.toList())) - .orElse(null); - } - - @JsonGetter(value = "blockNumber") - public String getNumber() { - return blockNumber; - } - - @JsonGetter(value = "blockHash") - public String getHash() { - return blockHash; - } - - @JsonGetter(value = "parentHash") - public String getParentHash() { - return parentHash; - } - - @JsonGetter(value = "logsBloom") - public String getLogsBloom() { - return logsBloom; - } - - @JsonGetter(value = "prevRandao") - public String getPrevRandao() { - return prevRandao; - } - - @JsonGetter(value = "stateRoot") - public String getStateRoot() { - return stateRoot; - } - - @JsonGetter(value = "receiptsRoot") - public String getReceiptRoot() { - return receiptsRoot; - } - - @JsonGetter(value = "extraData") - public String getExtraData() { - return extraData; - } - - @JsonGetter(value = "baseFeePerGas") - public String getBaseFeePerGas() { - return baseFeePerGas; - } - - @JsonGetter(value = "gasLimit") - public String getGasLimit() { - return gasLimit; - } - - @JsonGetter(value = "gasUsed") - public String getGasUsed() { - return gasUsed; - } - - @JsonGetter(value = "timestamp") - public String getTimestamp() { - return timestamp; - } - - @JsonGetter(value = "transactions") - public List getTransactions() { - return transactions; - } - - @JsonGetter(value = "withdrawals") - public List getWithdrawals() { - return withdrawals; - } - - @JsonGetter(value = "deposits") - public List getDeposits() { - return deposits; - } - - @JsonGetter(value = "feeRecipient") - @JsonInclude(JsonInclude.Include.NON_NULL) - public String getFeeRecipient() { - return feeRecipient; - } - } -} From d5ec15fed9af133f3c8133ea0025d9c6b5a2d9d1 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 9 May 2023 01:30:22 +0800 Subject: [PATCH 24/36] Address PR comments Signed-off-by: Navie Chan --- .../jsonrpc/internal/parameters/DepositParameter.java | 4 ++-- .../besu/ethereum/mainnet/DepositsValidator.java | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameter.java index acfc4fee81a..c13bc0435fc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameter.java @@ -40,8 +40,8 @@ public class DepositParameter { @JsonCreator public DepositParameter( - @JsonProperty("pubKey") final String pubKey, - @JsonProperty("withdrawal_credentials") final String withdrawalCredentials, + @JsonProperty("pubkey") final String pubKey, + @JsonProperty("withdrawalCredentials") final String withdrawalCredentials, @JsonProperty("amount") final String amount, @JsonProperty("signature") final String signature, @JsonProperty("index") final String index) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index a359da3e23e..6d445b89b66 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -111,7 +111,13 @@ public boolean validateDeposits(final Block block, final List Date: Tue, 9 May 2023 02:30:09 +0800 Subject: [PATCH 25/36] Spotless Apply Signed-off-by: Navie Chan --- .../besu/ethereum/core/encoding/DepositDecoder.java | 3 ++- .../hyperledger/besu/ethereum/mainnet/DepositsValidator.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java index 71661e241c5..cb8410d3d28 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositDecoder.java @@ -47,7 +47,8 @@ public static Deposit decode(final RLPInput rlpInput) { public static Deposit decodeFromLog(final Log log) { Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log); final byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue(); - final byte[] rawWithdrawalCredential = (byte[]) eventValues.getNonIndexedValues().get(1).getValue(); + final byte[] rawWithdrawalCredential = + (byte[]) eventValues.getNonIndexedValues().get(1).getValue(); final byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue(); final byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue(); final byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index 6d445b89b66..9974e465571 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -114,7 +114,8 @@ public boolean validateDeposits(final Block block, final List Date: Wed, 10 May 2023 17:21:42 +0800 Subject: [PATCH 26/36] Detail log on failing deposit validation Signed-off-by: Navie Chan --- .../hyperledger/besu/ethereum/mainnet/DepositsValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index 9974e465571..cb8f88b2256 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -115,7 +115,8 @@ public boolean validateDeposits(final Block block, final List Date: Thu, 11 May 2023 17:51:48 +0800 Subject: [PATCH 27/36] Pass depositContractAddress to block creator and coordinator Signed-off-by: Navie Chan --- .../controller/MergeBesuControllerBuilder.java | 8 +++++++- .../blockcreation/CliqueBlockCreator.java | 3 ++- .../bft/blockcreation/BftBlockCreator.java | 3 ++- .../merge/blockcreation/MergeBlockCreator.java | 6 ++++-- .../merge/blockcreation/MergeCoordinator.java | 6 ++++-- .../blockcreation/MergeCoordinatorTest.java | 18 ++++++++++++------ .../merge/blockcreation/MergeReorgTest.java | 4 +++- .../blockcreation/AbstractBlockCreator.java | 12 +++++++++--- .../blockcreation/PoWBlockCreator.java | 3 ++- .../AbstractBlockCreatorTest.java | 3 ++- .../ethereum/mainnet/DepositsValidator.java | 12 ++++++------ .../bonsai/AbstractIsolationTests.java | 3 ++- 12 files changed, 55 insertions(+), 26 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java index 7760efb6811..3ff13a472f2 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.consensus.merge.PostMergeContext; import org.hyperledger.besu.consensus.merge.TransitionBestPeerComparator; import org.hyperledger.besu.consensus.merge.blockcreation.MergeCoordinator; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; @@ -162,6 +163,10 @@ protected MiningCoordinator createTransitionMiningCoordinator( final ExecutorService blockBuilderExecutor = MonitoredExecutors.newSingleThreadExecutor("PoS-Block-Builder", metricsSystem); + final GenesisConfigOptions genesisConfigOptions = configOptionsSupplier.get(); + final Optional
depositContractAddress = + genesisConfigOptions.getDepositContractAddress(); + return new MergeCoordinator( protocolContext, protocolSchedule, @@ -171,7 +176,8 @@ protected MiningCoordinator createTransitionMiningCoordinator( }, transactionPool.getPendingTransactions(), miningParameters, - backwardSyncContext); + backwardSyncContext, + depositContractAddress); } @Override diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java index 861b7aad061..97bc962e6b7 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java @@ -83,7 +83,8 @@ public CliqueBlockCreator( protocolSchedule, minTransactionGasPrice, minBlockOccupancyRatio, - parentHeader); + parentHeader, + Optional.empty()); this.nodeKey = nodeKey; this.epochManager = epochManager; } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java index d83d92743ce..b1b374b69ff 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java @@ -76,7 +76,8 @@ public BftBlockCreator( protocolSchedule, minTransactionGasPrice, minBlockOccupancyRatio, - parentHeader); + parentHeader, + Optional.empty()); this.bftExtraDataCodec = bftExtraDataCodec; } diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java index fcfb639d975..56259ccc0e1 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java @@ -61,7 +61,8 @@ public MergeBlockCreator( final Wei minTransactionGasPrice, final Address miningBeneficiary, final Double minBlockOccupancyRatio, - final BlockHeader parentHeader) { + final BlockHeader parentHeader, + final Optional
depositContractAddress) { super( miningBeneficiary, __ -> miningBeneficiary, @@ -72,7 +73,8 @@ public MergeBlockCreator( protocolSchedule, minTransactionGasPrice, minBlockOccupancyRatio, - parentHeader); + parentHeader, + depositContractAddress); } /** diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index 03548c893d5..ada72dcc608 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -111,7 +111,8 @@ public MergeCoordinator( final ProposalBuilderExecutor blockBuilderExecutor, final PendingTransactions pendingTransactions, final MiningParameters miningParams, - final BackwardSyncContext backwardSyncContext) { + final BackwardSyncContext backwardSyncContext, + final Optional
depositContractAddress) { this.protocolContext = protocolContext; this.protocolSchedule = protocolSchedule; this.blockBuilderExecutor = blockBuilderExecutor; @@ -137,7 +138,8 @@ public MergeCoordinator( this.miningParameters.getMinTransactionGasPrice(), address.or(miningParameters::getCoinbase).orElse(Address.ZERO), this.miningParameters.getMinBlockOccupancyRatio(), - parentHeader); + parentHeader, + depositContractAddress); this.backwardSyncContext.subscribeBadChainListener(this); } diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java index 932b8130760..34a3be18e4d 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java @@ -205,7 +205,8 @@ public void setUp() { proposalBuilderExecutor, transactions, miningParameters, - backwardSyncContext); + backwardSyncContext, + Optional.empty()); } @Test @@ -255,7 +256,8 @@ public void exceptionDuringBuildingBlockShouldNotBeInvalid() this.miningParameters.getMinTransactionGasPrice(), address.or(miningParameters::getCoinbase).orElse(Address.ZERO), this.miningParameters.getMinBlockOccupancyRatio(), - parentHeader)); + parentHeader, + Optional.empty())); doCallRealMethod() .doCallRealMethod() @@ -656,7 +658,8 @@ public void shouldUseExtraDataFromMiningParameters() { proposalBuilderExecutor, transactions, miningParameters, - backwardSyncContext); + backwardSyncContext, + Optional.empty()); final PayloadIdentifier payloadId = this.coordinator.preparePayload( @@ -939,7 +942,8 @@ public void assertNonGenesisTerminalBlockSatisfiesDescendsFromTerminal() { CompletableFuture::runAsync, transactions, new MiningParameters.Builder().coinbase(coinbase).build(), - mock(BackwardSyncContext.class)); + mock(BackwardSyncContext.class), + Optional.empty()); var blockZero = mockHeaderBuilder.number(0L).difficulty(Difficulty.of(1336L)).buildHeader(); var blockOne = @@ -1000,7 +1004,8 @@ public void assertMergeAtGenesisSatisifiesTerminalPoW() { CompletableFuture::runAsync, transactions, new MiningParameters.Builder().coinbase(coinbase).build(), - mock(BackwardSyncContext.class)); + mock(BackwardSyncContext.class), + Optional.empty()); var blockZero = mockHeaderBuilder.number(0L).buildHeader(); var blockOne = mockHeaderBuilder.number(1L).parentHash(blockZero.getHash()).buildHeader(); @@ -1147,7 +1152,8 @@ MergeCoordinator terminalAncestorMock(final long chainDepth, final boolean hasTe CompletableFuture::runAsync, transactions, new MiningParameters.Builder().coinbase(coinbase).build(), - mock(BackwardSyncContext.class))); + mock(BackwardSyncContext.class), + Optional.empty())); return mockCoordinator; } diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java index de75bffd145..6d26651a9e0 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.junit.Before; @@ -90,7 +91,8 @@ public void setUp() { CompletableFuture::runAsync, mockPendingTransactions, new MiningParameters.Builder().coinbase(coinbase).build(), - mock(BackwardSyncContext.class)); + mock(BackwardSyncContext.class), + Optional.empty()); mergeContext.setIsPostMerge(genesisState.getBlock().getHeader().getDifficulty()); blockchain.observeBlockAdded( blockAddedEvent -> diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 39776b889ed..745e22350e3 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -84,6 +84,10 @@ public interface ExtraDataCalculator { private final Wei minTransactionGasPrice; private final Double minBlockOccupancyRatio; protected final BlockHeader parentHeader; + private static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + + private final Optional
depositContractAddress; private final AtomicBoolean isCancelled = new AtomicBoolean(false); @@ -97,7 +101,8 @@ protected AbstractBlockCreator( final ProtocolSchedule protocolSchedule, final Wei minTransactionGasPrice, final Double minBlockOccupancyRatio, - final BlockHeader parentHeader) { + final BlockHeader parentHeader, + final Optional
depositContractAddress) { this.coinbase = coinbase; this.miningBeneficiaryCalculator = miningBeneficiaryCalculator; this.targetGasLimitSupplier = targetGasLimitSupplier; @@ -108,6 +113,7 @@ protected AbstractBlockCreator( this.minTransactionGasPrice = minTransactionGasPrice; this.minBlockOccupancyRatio = minBlockOccupancyRatio; this.parentHeader = parentHeader; + this.depositContractAddress = depositContractAddress; blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); } @@ -206,8 +212,8 @@ protected BlockCreationResult createBlock( .flatMap(receipt -> receipt.getLogsList().stream()) .filter( log -> - ((DepositsValidator.AllowedDeposits) depositsValidator) - .getDepositContractAddress() + depositContractAddress + .orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS) .equals(log.getLogger())) .map(DepositDecoder::decodeFromLog) .toList(); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java index 5a421e8988b..90f529256ef 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java @@ -60,7 +60,8 @@ public PoWBlockCreator( protocolSchedule, minTransactionGasPrice, minBlockOccupancyRatio, - parentHeader); + parentHeader, + Optional.empty()); this.nonceSolver = nonceSolver; } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java index 30cafa78897..d0c3c6761b8 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java @@ -196,7 +196,8 @@ protected TestBlockCreator( protocolSchedule, minTransactionGasPrice, minBlockOccupancyRatio, - parentHeader); + parentHeader, + Optional.empty()); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java index cb8f88b2256..befa2231083 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java @@ -83,10 +83,6 @@ public AllowedDeposits(final Address depositContractAddress) { this.depositContractAddress = depositContractAddress; } - public Address getDepositContractAddress() { - return depositContractAddress; - } - @Override public boolean validateDepositParameter(final Optional> deposits) { return deposits.isPresent(); @@ -115,8 +111,12 @@ public boolean validateDeposits(final Block block, final List Date: Sun, 14 May 2023 22:42:35 +0800 Subject: [PATCH 28/36] Update javadoc Signed-off-by: Navie Chan --- .../besu/consensus/merge/blockcreation/MergeCoordinator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index ada72dcc608..b1f38e10ead 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -104,6 +104,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene * @param pendingTransactions the pending transactions * @param miningParams the mining params * @param backwardSyncContext the backward sync context + * @param depositContractAddress the address of the deposit contract */ public MergeCoordinator( final ProtocolContext protocolContext, From 52e422b994caf9bf0b64ce0d186e7d17f65f10dc Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 16 May 2023 10:56:11 +0800 Subject: [PATCH 29/36] Address comments Signed-off-by: Navie Chan --- .../besu/ethereum/blockcreation/AbstractBlockCreator.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 745e22350e3..048b108cabc 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -84,9 +84,6 @@ public interface ExtraDataCalculator { private final Wei minTransactionGasPrice; private final Double minBlockOccupancyRatio; protected final BlockHeader parentHeader; - private static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - private final Optional
depositContractAddress; private final AtomicBoolean isCancelled = new AtomicBoolean(false); @@ -206,14 +203,14 @@ protected BlockCreationResult createBlock( final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); Optional> maybeDeposits = Optional.empty(); - if (depositsValidator instanceof DepositsValidator.AllowedDeposits) { + if (depositContractAddress.isPresent()) { final List depositsFromReceipts = transactionResults.getReceipts().stream() .flatMap(receipt -> receipt.getLogsList().stream()) .filter( log -> depositContractAddress - .orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS) + .get() .equals(log.getLogger())) .map(DepositDecoder::decodeFromLog) .toList(); From 713cc5d896d66881572c62859cce329209c24a72 Mon Sep 17 00:00:00 2001 From: Navie Chan Date: Tue, 16 May 2023 11:29:21 +0800 Subject: [PATCH 30/36] Address comments Signed-off-by: Navie Chan --- .../besu/ethereum/blockcreation/AbstractBlockCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 048b108cabc..d1c21173bd6 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -203,7 +203,7 @@ protected BlockCreationResult createBlock( final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); Optional> maybeDeposits = Optional.empty(); - if (depositContractAddress.isPresent()) { + if (depositsValidator instanceof DepositsValidator.AllowedDeposits && depositContractAddress.isPresent()) { final List depositsFromReceipts = transactionResults.getReceipts().stream() .flatMap(receipt -> receipt.getLogsList().stream()) From eced98732eaf54570a0a14a16a52eee8555ff037 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 26 May 2023 17:32:51 +1000 Subject: [PATCH 31/36] Fix spotless Signed-off-by: Simon Dudley --- .../ethereum/blockcreation/AbstractBlockCreator.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index d1c21173bd6..eab6825b1f5 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -203,15 +203,12 @@ protected BlockCreationResult createBlock( final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); Optional> maybeDeposits = Optional.empty(); - if (depositsValidator instanceof DepositsValidator.AllowedDeposits && depositContractAddress.isPresent()) { + if (depositsValidator instanceof DepositsValidator.AllowedDeposits + && depositContractAddress.isPresent()) { final List depositsFromReceipts = transactionResults.getReceipts().stream() .flatMap(receipt -> receipt.getLogsList().stream()) - .filter( - log -> - depositContractAddress - .get() - .equals(log.getLogger())) + .filter(log -> depositContractAddress.get().equals(log.getLogger())) .map(DepositDecoder::decodeFromLog) .toList(); maybeDeposits = Optional.of(depositsFromReceipts); From e4efdff2486975567cb7b3c5f0c1246bef13e650 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 13 Jun 2023 22:34:42 +0800 Subject: [PATCH 32/36] Fix acceptance tests Signed-off-by: navie --- .../test/resources/jsonrpc/engine/eip6110/genesis.json | 3 ++- .../eip6110/test-cases/06_eip6110_get_payload.json | 8 ++++---- .../eip6110/test-cases/08_eip6110_execute_payload.json | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/genesis.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/genesis.json index 94982df74b3..b6a16b71a40 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/genesis.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/genesis.json @@ -18,7 +18,8 @@ "clique": { "period": 5, "epoch": 30000 - } + }, + "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa" }, "nonce":"0x42", "timestamp":"0x0", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/06_eip6110_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/06_eip6110_get_payload.json index d2861277388..89b7cf65b2e 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/06_eip6110_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/06_eip6110_get_payload.json @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", + "parentHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", + "stateRoot": "0x21395692fae33414143728c9ffc0aed8dcc76eb6731dd0f5a3239977478ca969", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -38,8 +38,8 @@ } ], "deposits" : [], - "blockNumber": "0x3", - "blockHash": "0xf6c1bee3c5831a9fc068abd3ed3619fd82900622c6e8bb1dc39dee099b246b88", + "blockNumber": "0x2", + "blockHash": "0x58ea3e01b03ac17c68ed3e3d724a021408273fac8a86f42cb30a26be8e93fbe9", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, "blockValue": "0x0" diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/08_eip6110_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/08_eip6110_execute_payload.json index cb9701fb924..6fe5f5a5640 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/08_eip6110_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/08_eip6110_execute_payload.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705", + "parentHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x0212f870b77bf90e46d6d7f3cab2d0b7b8c8599d452736d572048789fffda8de", + "stateRoot": "0x21395692fae33414143728c9ffc0aed8dcc76eb6731dd0f5a3239977478ca969", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -30,8 +30,8 @@ } ], "deposits": [], - "blockNumber": "0x3", - "blockHash": "0x9a083733e09cb4983933e7a7053ca470c3f583bb54e38d32c9ab396c8ededd6f", + "blockNumber": "0x2", + "blockHash": "0xdfdf57a09e352c38bb2873c5fd7d0d199481c6e13661c4a004d116417377b2e5", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } ], @@ -42,7 +42,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x9a083733e09cb4983933e7a7053ca470c3f583bb54e38d32c9ab396c8ededd6f", + "latestValidHash": "0xdfdf57a09e352c38bb2873c5fd7d0d199481c6e13661c4a004d116417377b2e5", "validationError": null } }, From fa691819f2aa487d2e82526fbbe8d6f2cbcc3ce1 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 16 Jun 2023 12:36:43 +1000 Subject: [PATCH 33/36] Fix unit tests by setting genesis file in the setup code Remove unnecessary Spy annotations that were causing issues with the test setup code. Tidy up NPE Signed-off-by: Simon Dudley --- .../besu/controller/BesuControllerBuilder.java | 2 +- .../TransitionControllerBuilderTest.java | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java index 656d39b01e0..aed7e9cb8bb 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -124,7 +124,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides () -> Optional.ofNullable(genesisConfig) .map(conf -> conf.getConfigOptions(genesisConfigOverrides)) - .orElseGet(genesisConfig::getConfigOptions); + .orElseThrow(); /** The Sync config. */ protected SynchronizerConfiguration syncConfig; diff --git a/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java index be1c9382b21..9fc337095f2 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.consensus.clique.BlockHeaderValidationRulesetFactory; import org.hyperledger.besu.consensus.clique.CliqueContext; import org.hyperledger.besu.consensus.common.EpochManager; @@ -53,7 +54,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; /** @@ -73,10 +73,10 @@ public class TransitionControllerBuilderTest { @Mock PostMergeContext mergeContext; StorageProvider storageProvider = new InMemoryKeyValueStorageProvider(); - @Spy CliqueBesuControllerBuilder cliqueBuilder = new CliqueBesuControllerBuilder(); - @Spy BesuControllerBuilder powBuilder = new MainnetBesuControllerBuilder(); - @Spy MergeBesuControllerBuilder postMergeBuilder = new MergeBesuControllerBuilder(); - @Spy MiningParameters miningParameters = new MiningParameters.Builder().build(); + CliqueBesuControllerBuilder cliqueBuilder = new CliqueBesuControllerBuilder(); + BesuControllerBuilder powBuilder = new MainnetBesuControllerBuilder(); + MergeBesuControllerBuilder postMergeBuilder = new MergeBesuControllerBuilder(); + MiningParameters miningParameters; TransitionProtocolSchedule transitionProtocolSchedule; @@ -88,6 +88,9 @@ public void setup() { preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext)); transitionProtocolSchedule.setProtocolContext(protocolContext); cliqueBuilder.nodeKey(NodeKeyUtils.generate()); + cliqueBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); + powBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); + postMergeBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); postMergeBuilder.storageProvider(storageProvider); when(protocolContext.getBlockchain()).thenReturn(mockBlockchain); when(transitionProtocolSchedule.getPostMergeSchedule()).thenReturn(postMergeProtocolSchedule); @@ -96,6 +99,7 @@ public void setup() { .thenReturn(mock(CliqueContext.class)); when(protocolContext.getConsensusContext(PostMergeContext.class)).thenReturn(mergeContext); when(protocolContext.getConsensusContext(MergeContext.class)).thenReturn(mergeContext); + miningParameters = new MiningParameters.Builder().miningEnabled(false).build(); } @Test @@ -114,7 +118,7 @@ public void assertPoWIsNotMiningPreMerge() { @Test public void assertPowMiningPreMerge() { - when(miningParameters.isMiningEnabled()).thenReturn(Boolean.TRUE); + miningParameters = new MiningParameters.Builder().miningEnabled(true).build(); var transCoordinator = buildTransitionCoordinator(powBuilder, postMergeBuilder); assertThat(transCoordinator.isMiningBeforeMerge()).isTrue(); } @@ -239,6 +243,7 @@ void assertDetachedRulesForPostMergeBlocks(final BlockHeaderValidator validator) TransitionCoordinator buildTransitionCoordinator( final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) { var builder = new TransitionBesuControllerBuilder(preMerge, postMerge); + builder.genesisConfigFile(GenesisConfigFile.mainnet()); builder.storageProvider(storageProvider); builder.metricsSystem(new NoOpMetricsSystem()); var coordinator = From 2380e32574994de13b83e29877c5fa709b556e4d Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 16 Jun 2023 16:08:27 +1000 Subject: [PATCH 34/36] Fix mock in another test, unintended consequence of last commit Signed-off-by: Simon Dudley --- .../controller/ConsensusScheduleBesuControllerBuilderTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java index 1ee211be808..4e1d87f4a68 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -103,7 +104,7 @@ public void mustCreateCombinedProtocolScheduleUsingProtocolSchedulesOrderedByBlo final StubGenesisConfigOptions genesisConfigOptions = new StubGenesisConfigOptions(); genesisConfigOptions.chainId(BigInteger.TEN); - when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); + when(genesisConfigFile.getConfigOptions(anyMap())).thenReturn(genesisConfigOptions); final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder = new ConsensusScheduleBesuControllerBuilder( From 8804b984c2951889a4ec4fc43a84acc933f071ef Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 16 Jun 2023 17:58:22 +1000 Subject: [PATCH 35/36] Add units for AbstractBlockCreator Extract findDepositsFromReceipts for testability Signed-off-by: Simon Dudley --- .../blockcreation/AbstractBlockCreator.java | 24 ++- .../AbstractBlockCreatorTest.java | 143 +++++++++++++++++- .../mainnet/MainnetProtocolSpecs.java | 2 +- 3 files changed, 154 insertions(+), 15 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 6ef4ba4cbc3..a9c0e566add 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -58,6 +58,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -205,16 +206,9 @@ protected BlockCreationResult createBlock( final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); Optional> maybeDeposits = Optional.empty(); - if (depositsValidator instanceof DepositsValidator.AllowedDeposits && depositContractAddress.isPresent()) { - final List depositsFromReceipts = - transactionResults.getReceipts().stream() - .flatMap(receipt -> receipt.getLogsList().stream()) - .filter(log -> depositContractAddress.get().equals(log.getLogger())) - .map(DepositDecoder::decodeFromLog) - .toList(); - maybeDeposits = Optional.of(depositsFromReceipts); + maybeDeposits = findDepositsFromReceipts(transactionResults); } throwIfStopped(); @@ -277,6 +271,20 @@ protected BlockCreationResult createBlock( } } + @VisibleForTesting + Optional> findDepositsFromReceipts( + final TransactionSelectionResults transactionResults) { + Optional> maybeDeposits; + final List depositsFromReceipts = + transactionResults.getReceipts().stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .filter(log -> depositContractAddress.get().equals(log.getLogger())) + .map(DepositDecoder::decodeFromLog) + .toList(); + maybeDeposits = Optional.of(depositsFromReceipts); + return maybeDeposits; + } + private DataGas computeExcessDataGas( TransactionSelectionResults transactionResults, ProtocolSpec newProtocolSpec) { diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java index d0c3c6761b8..fa77f7fe2c9 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java @@ -14,37 +14,49 @@ */ package org.hyperledger.besu.ethereum.blockcreation; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.BLSPublicKey; +import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.BlockCreator.BlockCreationResult; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.BlockDataGenerator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; +import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.SealableBlockHeader; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter; import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; +import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.evm.log.Log; +import org.hyperledger.besu.evm.log.LogTopic; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; @@ -55,6 +67,7 @@ import java.util.function.Supplier; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -63,8 +76,122 @@ @ExtendWith(MockitoExtension.class) abstract class AbstractBlockCreatorTest { + private static final Optional
EMPTY_DEPOSIT_CONTRACT_ADDRESS = Optional.empty(); @Mock private WithdrawalsProcessor withdrawalsProcessor; + @Test + void findDepositsFromReceipts() { + final AbstractBlockCreator blockCreator = + blockCreatorWithAllowedDeposits(Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); + final BlockTransactionSelector.TransactionSelectionResults transactionResults = + mock(BlockTransactionSelector.TransactionSelectionResults.class); + BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); + TransactionReceipt receiptWithoutDeposit1 = blockDataGenerator.receipt(); + TransactionReceipt receiptWithoutDeposit2 = blockDataGenerator.receipt(); + final Log depositLog = + new Log( + DEFAULT_DEPOSIT_CONTRACT_ADDRESS, + Bytes.fromHexString( + "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"), + List.of( + LogTopic.fromHexString( + "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); + final TransactionReceipt receiptWithDeposit = blockDataGenerator.receipt(List.of(depositLog)); + when(transactionResults.getReceipts()) + .thenReturn(List.of(receiptWithoutDeposit1, receiptWithDeposit, receiptWithoutDeposit2)); + + Deposit expectedDeposit = + new Deposit( + BLSPublicKey.fromHexString( + "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), + Bytes32.fromHexString( + "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), + GWei.of(32000000000L), + BLSSignature.fromHexString( + "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), + UInt64.valueOf(539967)); + final List expectedDeposits = List.of(expectedDeposit); + + final Optional> depositsFromReceipts = + blockCreator.findDepositsFromReceipts(transactionResults); + + assertThat(depositsFromReceipts).hasValue(expectedDeposits); + } + + @Test + void withAllowedDepositsAndContractAddress_DepositsAreParsed() { + final AbstractBlockCreator blockCreator = + blockCreatorWithAllowedDeposits(Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); + + final BlockCreationResult blockCreationResult = + blockCreator.createBlock( + Optional.empty(), + Optional.empty(), + Optional.of(emptyList()), + Optional.empty(), + 1L, + false); + + List deposits = emptyList(); + final Hash depositsRoot = BodyValidation.depositsRoot(deposits); + assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).hasValue(depositsRoot); + assertThat(blockCreationResult.getBlock().getBody().getDeposits()).hasValue(deposits); + } + + @Test + void withAllowedDepositsAndNoContractAddress_DepositsAreNotParsed() { + final AbstractBlockCreator blockCreator = blockCreatorWithAllowedDeposits(Optional.empty()); + + final BlockCreationResult blockCreationResult = + blockCreator.createBlock( + Optional.empty(), + Optional.empty(), + Optional.of(emptyList()), + Optional.empty(), + 1L, + false); + + assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).isEmpty(); + assertThat(blockCreationResult.getBlock().getBody().getDeposits()).isEmpty(); + } + + @Test + void withProhibitedDeposits_DepositsAreNotParsed() { + final AbstractBlockCreator blockCreator = blockCreatorWithProhibitedDeposits(); + + final BlockCreationResult blockCreationResult = + blockCreator.createBlock( + Optional.empty(), + Optional.empty(), + Optional.of(emptyList()), + Optional.empty(), + 1L, + false); + + assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).isEmpty(); + assertThat(blockCreationResult.getBlock().getBody().getDeposits()).isEmpty(); + } + + private AbstractBlockCreator blockCreatorWithAllowedDeposits( + final Optional
depositContractAddress) { + final ProtocolSpecAdapters protocolSpecAdapters = + ProtocolSpecAdapters.create( + 0, + specBuilder -> + specBuilder.depositsValidator( + new DepositsValidator.AllowedDeposits(depositContractAddress.orElse(null)))); + return createBlockCreator(protocolSpecAdapters, depositContractAddress); + } + + private AbstractBlockCreator blockCreatorWithProhibitedDeposits() { + final ProtocolSpecAdapters protocolSpecAdapters = + ProtocolSpecAdapters.create( + 0, + specBuilder -> + specBuilder.depositsValidator(new DepositsValidator.ProhibitedDeposits())); + return createBlockCreator(protocolSpecAdapters, Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); + } + @Test void withProcessorAndEmptyWithdrawals_NoWithdrawalsAreProcessed() { final AbstractBlockCreator blockCreator = blockCreatorWithWithdrawalsProcessor(); @@ -130,14 +257,16 @@ private AbstractBlockCreator blockCreatorWithWithdrawalsProcessor() { final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.withdrawalsProcessor(withdrawalsProcessor)); - return createBlockCreator(protocolSpecAdapters); + return createBlockCreator(protocolSpecAdapters, EMPTY_DEPOSIT_CONTRACT_ADDRESS); } private AbstractBlockCreator blockCreatorWithoutWithdrawalsProcessor() { - return createBlockCreator(new ProtocolSpecAdapters(Map.of())); + return createBlockCreator(new ProtocolSpecAdapters(Map.of()), EMPTY_DEPOSIT_CONTRACT_ADDRESS); } - private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) { + private AbstractBlockCreator createBlockCreator( + final ProtocolSpecAdapters protocolSpecAdapters, + final Optional
depositContractAddress) { final GenesisConfigOptions genesisConfigOptions = GenesisConfigFile.DEFAULT.getConfigOptions(); final ExecutionContextTestFixture executionContextTestFixture = ExecutionContextTestFixture.builder() @@ -170,7 +299,8 @@ private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters proto executionContextTestFixture.getProtocolSchedule(), Wei.of(1L), 0d, - blockchain.getChainHeadHeader()); + blockchain.getChainHeadHeader(), + depositContractAddress); } static class TestBlockCreator extends AbstractBlockCreator { @@ -185,7 +315,8 @@ protected TestBlockCreator( final ProtocolSchedule protocolSchedule, final Wei minTransactionGasPrice, final Double minBlockOccupancyRatio, - final BlockHeader parentHeader) { + final BlockHeader parentHeader, + final Optional
depositContractAddress) { super( coinbase, miningBeneficiaryCalculator, @@ -197,7 +328,7 @@ protected TestBlockCreator( minTransactionGasPrice, minBlockOccupancyRatio, parentHeader, - Optional.empty()); + depositContractAddress); } @Override 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 c3ba471ec50..889b82eaf3b 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 @@ -98,7 +98,7 @@ public abstract class MainnetProtocolSpecs { private static final Wei CONSTANTINOPLE_BLOCK_REWARD = Wei.fromEth(2); - private static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = + public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); private MainnetProtocolSpecs() {} From b790ff19a2cbc0731ed75f1e70cd529367478652 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 16 Jun 2023 18:04:58 +1000 Subject: [PATCH 36/36] Inline variables and tidy up Signed-off-by: Simon Dudley --- .../blockcreation/AbstractBlockCreator.java | 19 +++++++------------ .../AbstractBlockCreatorTest.java | 4 ++-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index a9c0e566add..5f4af0bf49d 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -208,7 +208,7 @@ protected BlockCreationResult createBlock( Optional> maybeDeposits = Optional.empty(); if (depositsValidator instanceof DepositsValidator.AllowedDeposits && depositContractAddress.isPresent()) { - maybeDeposits = findDepositsFromReceipts(transactionResults); + maybeDeposits = Optional.of(findDepositsFromReceipts(transactionResults)); } throwIfStopped(); @@ -272,17 +272,12 @@ protected BlockCreationResult createBlock( } @VisibleForTesting - Optional> findDepositsFromReceipts( - final TransactionSelectionResults transactionResults) { - Optional> maybeDeposits; - final List depositsFromReceipts = - transactionResults.getReceipts().stream() - .flatMap(receipt -> receipt.getLogsList().stream()) - .filter(log -> depositContractAddress.get().equals(log.getLogger())) - .map(DepositDecoder::decodeFromLog) - .toList(); - maybeDeposits = Optional.of(depositsFromReceipts); - return maybeDeposits; + List findDepositsFromReceipts(final TransactionSelectionResults transactionResults) { + return transactionResults.getReceipts().stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .filter(log -> depositContractAddress.get().equals(log.getLogger())) + .map(DepositDecoder::decodeFromLog) + .toList(); } private DataGas computeExcessDataGas( diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java index fa77f7fe2c9..6a832cf011c 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java @@ -112,10 +112,10 @@ void findDepositsFromReceipts() { UInt64.valueOf(539967)); final List expectedDeposits = List.of(expectedDeposit); - final Optional> depositsFromReceipts = + final List depositsFromReceipts = blockCreator.findDepositsFromReceipts(transactionResults); - assertThat(depositsFromReceipts).hasValue(expectedDeposits); + assertThat(depositsFromReceipts).isEqualTo(expectedDeposits); } @Test