mirror of https://github.com/hyperledger/besu
Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>pull/7638/head
parent
c03bffbc93
commit
b2a45c201e
@ -0,0 +1,89 @@ |
||||
/* |
||||
* 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.mainnet; |
||||
|
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.core.Request; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt; |
||||
import org.hyperledger.besu.ethereum.core.Withdrawal; |
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** A utility class for body validation tasks. Implemented utilising BodyValidation */ |
||||
public class BodyValidator { |
||||
|
||||
/** |
||||
* Generates the transaction root for a list of transactions |
||||
* |
||||
* @param transactions the transactions |
||||
* @return the transaction root |
||||
*/ |
||||
public Hash transactionsRoot(final List<Transaction> transactions) { |
||||
return BodyValidation.transactionsRoot(transactions); |
||||
} |
||||
|
||||
/** |
||||
* Generates the withdrawals root for a list of withdrawals |
||||
* |
||||
* @param withdrawals the transactions |
||||
* @return the transaction root |
||||
*/ |
||||
public Hash withdrawalsRoot(final List<Withdrawal> withdrawals) { |
||||
return BodyValidation.withdrawalsRoot(withdrawals); |
||||
} |
||||
|
||||
/** |
||||
* Generates the requests root for a list of requests |
||||
* |
||||
* @param requests list of request |
||||
* @return the requests root |
||||
*/ |
||||
public Hash requestsRoot(final List<Request> requests) { |
||||
return BodyValidation.requestsRoot(requests); |
||||
} |
||||
|
||||
/** |
||||
* Generates the receipt root for a list of receipts |
||||
* |
||||
* @param receipts the receipts |
||||
* @return the receipt root |
||||
*/ |
||||
public Hash receiptsRoot(final List<TransactionReceipt> receipts) { |
||||
return BodyValidation.receiptsRoot(receipts); |
||||
} |
||||
|
||||
/** |
||||
* Generates the ommers hash for a list of ommer block headers |
||||
* |
||||
* @param ommers the ommer block headers |
||||
* @return the ommers hash |
||||
*/ |
||||
public Hash ommersHash(final List<BlockHeader> ommers) { |
||||
return BodyValidation.ommersHash(ommers); |
||||
} |
||||
|
||||
/** |
||||
* Generates the logs bloom filter for a list of transaction receipts |
||||
* |
||||
* @param receipts the transaction receipts |
||||
* @return the logs bloom filter |
||||
*/ |
||||
public LogsBloomFilter logsBloom(final List<TransactionReceipt> receipts) { |
||||
return BodyValidation.logsBloom(receipts); |
||||
} |
||||
} |
@ -0,0 +1,34 @@ |
||||
/* |
||||
* 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.eth.manager.peertask; |
||||
|
||||
import java.lang.reflect.Field; |
||||
|
||||
import org.junit.platform.commons.util.ReflectionUtils; |
||||
|
||||
public class PeerTaskFeatureToggleTestHelper { |
||||
|
||||
public static void setPeerTaskFeatureToggle(final boolean usePeerTaskSystem) |
||||
throws IllegalAccessException { |
||||
Field usePeerTaskSystemField = |
||||
ReflectionUtils.findFields( |
||||
PeerTaskFeatureToggle.class, |
||||
(f) -> f.getName().equals("USE_PEER_TASK_SYSTEM"), |
||||
ReflectionUtils.HierarchyTraversalMode.TOP_DOWN) |
||||
.getFirst(); |
||||
usePeerTaskSystemField.setAccessible(true); |
||||
usePeerTaskSystemField.set(null, usePeerTaskSystem); |
||||
} |
||||
} |
@ -0,0 +1,152 @@ |
||||
/* |
||||
* 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.eth.manager.peertask.task; |
||||
|
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt; |
||||
import org.hyperledger.besu.ethereum.eth.EthProtocol; |
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.InvalidPeerTaskResponseException; |
||||
import org.hyperledger.besu.ethereum.eth.messages.EthPV63; |
||||
import org.hyperledger.besu.ethereum.eth.messages.GetReceiptsMessage; |
||||
import org.hyperledger.besu.ethereum.eth.messages.ReceiptsMessage; |
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidator; |
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.mockito.Mockito; |
||||
|
||||
public class GetReceiptsFromPeerTaskTest { |
||||
|
||||
@Test |
||||
public void testGetSubProtocol() { |
||||
GetReceiptsFromPeerTask task = new GetReceiptsFromPeerTask(Collections.emptyList(), null); |
||||
Assertions.assertEquals(EthProtocol.NAME, task.getSubProtocol()); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetRequiredBlockNumber() { |
||||
GetReceiptsFromPeerTask task = |
||||
new GetReceiptsFromPeerTask( |
||||
List.of(mockBlockHeader(1), mockBlockHeader(2), mockBlockHeader(3)), null); |
||||
Assertions.assertEquals(3, task.getRequiredBlockNumber()); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetRequestMessage() { |
||||
GetReceiptsFromPeerTask task = |
||||
new GetReceiptsFromPeerTask( |
||||
List.of(mockBlockHeader(1), mockBlockHeader(2), mockBlockHeader(3)), null); |
||||
|
||||
MessageData messageData = task.getRequestMessage(); |
||||
GetReceiptsMessage getReceiptsMessage = GetReceiptsMessage.readFrom(messageData); |
||||
|
||||
Assertions.assertEquals(EthPV63.GET_RECEIPTS, getReceiptsMessage.getCode()); |
||||
Iterable<Hash> hashesInMessage = getReceiptsMessage.hashes(); |
||||
List<Hash> expectedHashes = |
||||
List.of( |
||||
Hash.fromHexString(StringUtils.repeat("00", 31) + "11"), |
||||
Hash.fromHexString(StringUtils.repeat("00", 31) + "21"), |
||||
Hash.fromHexString(StringUtils.repeat("00", 31) + "31")); |
||||
List<Hash> actualHashes = new ArrayList<>(); |
||||
hashesInMessage.forEach(actualHashes::add); |
||||
|
||||
Assertions.assertEquals(3, actualHashes.size()); |
||||
Assertions.assertEquals( |
||||
expectedHashes.stream().sorted().toList(), actualHashes.stream().sorted().toList()); |
||||
} |
||||
|
||||
@Test |
||||
public void testParseResponseWithNullResponseMessage() { |
||||
GetReceiptsFromPeerTask task = new GetReceiptsFromPeerTask(Collections.emptyList(), null); |
||||
Assertions.assertThrows(InvalidPeerTaskResponseException.class, () -> task.parseResponse(null)); |
||||
} |
||||
|
||||
@Test |
||||
public void testParseResponseForInvalidResponse() throws InvalidPeerTaskResponseException { |
||||
GetReceiptsFromPeerTask task = |
||||
new GetReceiptsFromPeerTask( |
||||
List.of(mockBlockHeader(1), mockBlockHeader(2), mockBlockHeader(3)), null); |
||||
ReceiptsMessage receiptsMessage = |
||||
ReceiptsMessage.create( |
||||
List.of( |
||||
List.of(new TransactionReceipt(1, 123, Collections.emptyList(), Optional.empty())), |
||||
List.of(new TransactionReceipt(1, 456, Collections.emptyList(), Optional.empty())), |
||||
List.of(new TransactionReceipt(1, 789, Collections.emptyList(), Optional.empty())), |
||||
List.of( |
||||
new TransactionReceipt(1, 101112, Collections.emptyList(), Optional.empty())))); |
||||
|
||||
Assertions.assertThrows( |
||||
InvalidPeerTaskResponseException.class, () -> task.parseResponse(receiptsMessage)); |
||||
} |
||||
|
||||
@Test |
||||
public void testParseResponse() throws InvalidPeerTaskResponseException { |
||||
BodyValidator bodyValidator = Mockito.mock(BodyValidator.class); |
||||
BlockHeader blockHeader1 = mockBlockHeader(1); |
||||
BlockHeader blockHeader2 = mockBlockHeader(2); |
||||
BlockHeader blockHeader3 = mockBlockHeader(3); |
||||
|
||||
GetReceiptsFromPeerTask task = |
||||
new GetReceiptsFromPeerTask( |
||||
List.of(blockHeader1, blockHeader2, blockHeader3), bodyValidator); |
||||
|
||||
TransactionReceipt receiptForBlock1 = |
||||
new TransactionReceipt(1, 123, Collections.emptyList(), Optional.empty()); |
||||
TransactionReceipt receiptForBlock2 = |
||||
new TransactionReceipt(1, 456, Collections.emptyList(), Optional.empty()); |
||||
TransactionReceipt receiptForBlock3 = |
||||
new TransactionReceipt(1, 789, Collections.emptyList(), Optional.empty()); |
||||
ReceiptsMessage receiptsMessage = |
||||
ReceiptsMessage.create( |
||||
List.of( |
||||
List.of(receiptForBlock1), List.of(receiptForBlock2), List.of(receiptForBlock3))); |
||||
|
||||
Mockito.when(bodyValidator.receiptsRoot(List.of(receiptForBlock1))) |
||||
.thenReturn(Hash.fromHexString(StringUtils.repeat("00", 31) + "12")); |
||||
Mockito.when(bodyValidator.receiptsRoot(List.of(receiptForBlock2))) |
||||
.thenReturn(Hash.fromHexString(StringUtils.repeat("00", 31) + "22")); |
||||
Mockito.when(bodyValidator.receiptsRoot(List.of(receiptForBlock3))) |
||||
.thenReturn(Hash.fromHexString(StringUtils.repeat("00", 31) + "32")); |
||||
|
||||
Map<BlockHeader, List<TransactionReceipt>> resultMap = task.parseResponse(receiptsMessage); |
||||
|
||||
Assertions.assertEquals(3, resultMap.size()); |
||||
Assertions.assertEquals(List.of(receiptForBlock1), resultMap.get(blockHeader1)); |
||||
Assertions.assertEquals(List.of(receiptForBlock2), resultMap.get(blockHeader2)); |
||||
Assertions.assertEquals(List.of(receiptForBlock3), resultMap.get(blockHeader3)); |
||||
} |
||||
|
||||
private BlockHeader mockBlockHeader(final long blockNumber) { |
||||
BlockHeader blockHeader = Mockito.mock(BlockHeader.class); |
||||
Mockito.when(blockHeader.getNumber()).thenReturn(blockNumber); |
||||
// second to last hex digit indicates the blockNumber, last hex digit indicates the usage of the
|
||||
// hash
|
||||
Mockito.when(blockHeader.getHash()) |
||||
.thenReturn(Hash.fromHexString(StringUtils.repeat("00", 31) + blockNumber + "1")); |
||||
Mockito.when(blockHeader.getReceiptsRoot()) |
||||
.thenReturn(Hash.fromHexString(StringUtils.repeat("00", 31) + blockNumber + "2")); |
||||
|
||||
return blockHeader; |
||||
} |
||||
} |
Loading…
Reference in new issue