Using PMT index on private logs tx index (fixes #756) (#758)

Signed-off-by: Lucas Saldanha <lucas.saldanha@consensys.net>
pull/768/head
Lucas Saldanha 5 years ago committed by GitHub
parent 6f05bdccfc
commit 0c5703fad7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
  2. 20
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueries.java
  3. 26
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueriesTest.java

@ -480,6 +480,10 @@ public class BlockchainQueries {
txs.get(txIndex), header.getNumber(), blockHeaderHash, txIndex);
}
public Optional<TransactionLocation> transactionLocationByHash(final Hash transactionHash) {
return blockchain.getTransactionLocation(transactionHash);
}
/**
* Returns the transaction receipt associated with the given transaction hash.
*

@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.api.query;
import org.hyperledger.besu.ethereum.chain.TransactionLocation;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
@ -67,15 +68,19 @@ public class PrivacyQueries {
final List<PrivateTransactionMetadata> privateTransactionMetadataList =
privateWorldStateReader.getPrivateTransactionMetadataList(privacyGroupId, blockHash);
final List<PrivateTransactionReceipt> privateTransactionReceiptList =
final List<Hash> pmtHashList =
privateTransactionMetadataList.stream()
.map(PrivateTransactionMetadata::getPrivacyMarkerTransactionHash)
.collect(Collectors.toList());
final List<PrivateTransactionReceipt> privateTransactionReceiptList =
pmtHashList.stream()
.map(
pmtHash -> privateWorldStateReader.getPrivateTransactionReceipt(blockHash, pmtHash))
.flatMap(Optional::stream)
.collect(Collectors.toList());
final long number = blockHeader.get().getNumber();
final long blockNumber = blockHeader.get().getNumber();
final boolean removed = !blockchainQueries.blockIsOnCanonicalChain(blockHash);
return IntStream.range(0, privateTransactionReceiptList.size())
@ -83,13 +88,20 @@ public class PrivacyQueries {
i ->
LogWithMetadata.generate(
privateTransactionReceiptList.get(i),
number,
blockNumber,
blockHash,
privateTransactionMetadataList.get(i).getPrivacyMarkerTransactionHash(),
i,
findPMTIndex(pmtHashList.get(i)),
removed))
.flatMap(Collection::stream)
.filter(query::matches)
.collect(Collectors.toList());
}
private int findPMTIndex(final Hash pmtHash) {
return blockchainQueries
.transactionLocationByHash(pmtHash)
.map(TransactionLocation::getTransactionIndex)
.orElseThrow(() -> new IllegalStateException("Can't find PMT index with hash " + pmtHash));
}
}

@ -22,6 +22,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.chain.TransactionLocation;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@ -82,8 +83,8 @@ public class PrivacyQueriesTest {
@Test
public void matchingLogsReturnEmptyListForNonExistingTransactions() {
final Hash blockHash = Hash.hash(Bytes32.random());
final BlockHeader blockHeader = new BlockHeaderTestFixture().buildHeader();
final Hash blockHash = blockHeader.getHash();
final LogsQuery query = new LogsQuery.Builder().build();
when(blockchainQueries.getBlockHeaderByHash(blockHash)).thenReturn(Optional.of(blockHeader));
@ -98,8 +99,8 @@ public class PrivacyQueriesTest {
@Test
public void matchingLogsReturnsEmptyListWhenQueryDoesNotMatch() {
final Hash blockHash = Hash.hash(Bytes32.random());
final BlockHeader blockHeader = new BlockHeaderTestFixture().buildHeader();
final Hash blockHash = blockHeader.getHash();
final LogTopic nonMatchingTopic = LogTopic.of(Bytes32.random());
final LogsQuery query =
new LogsQuery.Builder().topics(List.of(List.of(nonMatchingTopic))).build();
@ -111,7 +112,7 @@ public class PrivacyQueriesTest {
when(blockchainQueries.blockIsOnCanonicalChain(blockHash)).thenReturn(true);
when(privateWorldStateReader.getPrivateTransactionMetadataList(PRIVACY_GROUP_ID, blockHash))
.thenReturn(transactionMetadataList);
mockBlockchainWithPMTs(blockHeader, transactionMetadataList);
mockReceiptsWithLogsAndTopics(blockHash, transactionMetadataList, null);
final List<LogWithMetadata> logs =
@ -122,8 +123,8 @@ public class PrivacyQueriesTest {
@Test
public void matchingLogsReturnsAllLogsThatMatchQuery() {
final Hash blockHash = Hash.hash(Bytes32.random());
final BlockHeader blockHeader = new BlockHeaderTestFixture().buildHeader();
final Hash blockHash = blockHeader.getHash();
final LogTopic matchingTopic = LogTopic.of(Bytes32.random());
final LogsQuery query = new LogsQuery.Builder().topics(List.of(List.of(matchingTopic))).build();
@ -134,7 +135,7 @@ public class PrivacyQueriesTest {
when(blockchainQueries.blockIsOnCanonicalChain(blockHash)).thenReturn(true);
when(privateWorldStateReader.getPrivateTransactionMetadataList(PRIVACY_GROUP_ID, blockHash))
.thenReturn(transactionMetadataList);
mockBlockchainWithPMTs(blockHeader, transactionMetadataList);
mockReceiptsWithLogsAndTopics(blockHash, transactionMetadataList, matchingTopic);
final List<LogWithMetadata> logs =
@ -180,7 +181,7 @@ public class PrivacyQueriesTest {
when(privateWorldStateReader.getPrivateTransactionMetadataList(
PRIVACY_GROUP_ID, blockHash))
.thenReturn(transactionMetadataList);
mockBlockchainWithPMTs(blockHeader, transactionMetadataList);
mockReceiptsWithLogsAndTopics(blockHash, transactionMetadataList, matchingTopic);
});
@ -214,4 +215,17 @@ public class PrivacyQueriesTest {
.thenReturn(Optional.of(receipt));
});
}
private void mockBlockchainWithPMTs(
final BlockHeader blockHeader,
final List<PrivateTransactionMetadata> transactionMetadataList) {
for (int i = 0; i < transactionMetadataList.size(); i++) {
final PrivateTransactionMetadata privateTransactionMetadata = transactionMetadataList.get(i);
final Hash pmtHash = privateTransactionMetadata.getPrivacyMarkerTransactionHash();
final TransactionLocation pmtLocation = new TransactionLocation(blockHeader.getHash(), i);
when(blockchainQueries.transactionLocationByHash(pmtHash))
.thenReturn(Optional.of(pmtLocation));
}
}
}

Loading…
Cancel
Save