use of org.hyperledger.besu.ethereum.privacy.PrivateTransactionWithMetadata in project besu by hyperledger.
the class PrivateTransactionDataFixture method generateAddToGroupReceiveResponse.
public static ReceiveResponse generateAddToGroupReceiveResponse(final PrivateTransaction privateTransaction, final Transaction markerTransaction) {
final List<PrivateTransactionWithMetadata> privateTransactionWithMetadataList = generateAddBlobResponse(privateTransaction, markerTransaction);
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
rlpOutput.startList();
privateTransactionWithMetadataList.stream().forEach(privateTransactionWithMetadata -> privateTransactionWithMetadata.writeTo(rlpOutput));
rlpOutput.endList();
return new ReceiveResponse(rlpOutput.encoded().toBase64String().getBytes(UTF_8), privateTransaction.getPrivacyGroupId().orElse(Bytes.EMPTY).toBase64String(), null);
}
use of org.hyperledger.besu.ethereum.privacy.PrivateTransactionWithMetadata in project besu by hyperledger.
the class PrivacyBlockProcessor method maybeRehydrate.
void maybeRehydrate(final Blockchain blockchain, final BlockHeader blockHeader, final List<Transaction> transactions) {
transactions.stream().filter(this::onchainAddToGroupPrivateMarkerTransactions).forEach(pmt -> {
final Bytes32 privateTransactionsLookupId = Bytes32.wrap(pmt.getPayload().slice(32, 32));
try {
final ReceiveResponse receiveResponse = enclave.receive(privateTransactionsLookupId.toBase64String());
final List<PrivateTransactionWithMetadata> privateTransactionWithMetadataList = PrivateTransactionWithMetadata.readListFromPayload(Bytes.wrap(Base64.getDecoder().decode(receiveResponse.getPayload())));
final Bytes32 privacyGroupId = Bytes32.wrap(privateTransactionWithMetadataList.get(0).getPrivateTransaction().getPrivacyGroupId().get());
final List<PrivateTransactionWithMetadata> actualListToRehydrate = transactionsInGroupThatNeedToBeApplied(blockHeader, privateTransactionWithMetadataList, privacyGroupId);
if (actualListToRehydrate.size() > 0) {
LOG.debug("Rehydrating privacy group {}, number of transactions to be rehydrated is {} out of a total number of {} transactions.", privacyGroupId.toString(), actualListToRehydrate.size(), privateTransactionWithMetadataList.size());
final PrivateStateRehydration privateStateRehydration = new PrivateStateRehydration(privateStateStorage, blockchain, protocolSchedule, publicWorldStateArchive, privateWorldStateArchive, privateStateRootResolver, privateStateGenesisAllocator);
privateStateRehydration.rehydrate(actualListToRehydrate);
privateStateStorage.updater().putAddDataKey(privacyGroupId, privateTransactionsLookupId).commit();
}
} catch (final EnclaveClientException e) {
// we were not being added because we have not found the add blob
}
});
}
use of org.hyperledger.besu.ethereum.privacy.PrivateTransactionWithMetadata in project besu by hyperledger.
the class PrivacyBlockProcessor method transactionsInGroupThatNeedToBeApplied.
private List<PrivateTransactionWithMetadata> transactionsInGroupThatNeedToBeApplied(final BlockHeader blockHeader, final List<PrivateTransactionWithMetadata> privateTransactionWithMetadataList, final Bytes32 privacyGroupId) {
// if we are the member adding another member we do not have to rehydrate
// if we have been removed from the group at some point we only need to rehydrate from where we
// were removed
// if we are a new member we need to rehydrate the complete state
List<PrivateTransactionWithMetadata> actualList = privateTransactionWithMetadataList;
final Optional<PrivacyGroupHeadBlockMap> maybePrivacyGroupHeadBlockMap = privateStateStorage.getPrivacyGroupHeadBlockMap(blockHeader.getParentHash());
if (maybePrivacyGroupHeadBlockMap.isPresent()) {
final PrivacyGroupHeadBlockMap privacyGroupHeadBlockMap = maybePrivacyGroupHeadBlockMap.get();
final Hash lastBlockWithTx = privacyGroupHeadBlockMap.get(privacyGroupId);
if (lastBlockWithTx != null) {
// we are or have been a member of the privacy group
final PrivateBlockMetadata nodeLatestBlockMetadata = privateStateStorage.getPrivateBlockMetadata(lastBlockWithTx, privacyGroupId).orElseThrow();
final List<PrivateTransactionMetadata> nodeLatestPrivateTxMetadataList = nodeLatestBlockMetadata.getPrivateTransactionMetadataList();
final Hash nodeLatestStateRoot = nodeLatestPrivateTxMetadataList.get(nodeLatestPrivateTxMetadataList.size() - 1).getStateRoot();
final Hash latestStateRootFromRehydrationList = privateTransactionWithMetadataList.get(privateTransactionWithMetadataList.size() - 1).getPrivateTransactionMetadata().getStateRoot();
if (nodeLatestStateRoot.equals(latestStateRootFromRehydrationList)) {
// we are already on the latest state root, which means that we are the member adding a
// new member
actualList = Collections.emptyList();
} else {
// we are being added, but do not have to rehydrate all private transactions
final Hash nodeLatestPrivateMarkerTransactionHash = nodeLatestPrivateTxMetadataList.get(nodeLatestPrivateTxMetadataList.size() - 1).getPrivateMarkerTransactionHash();
for (int i = 0; i < privateTransactionWithMetadataList.size(); i++) {
if (!privateTransactionWithMetadataList.get(i).getPrivateTransactionMetadata().getPrivateMarkerTransactionHash().equals(nodeLatestPrivateMarkerTransactionHash)) {
continue;
}
if (privateTransactionWithMetadataList.size() - 1 == i) {
// nothing needs to be re-hydrated
actualList = Collections.emptyList();
} else {
actualList = privateTransactionWithMetadataList.subList(i + 1, privateTransactionWithMetadataList.size());
}
break;
}
}
}
}
return actualList;
}
Aggregations