use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.
the class ResendManagerImplTest method storePayloadAsSenderWhenTxIsPresentAndPsv.
@Test
public void storePayloadAsSenderWhenTxIsPresentAndPsv() {
final PublicKey senderKey = PublicKey.from("SENDER".getBytes());
final PublicKey recipientKey1 = PublicKey.from("RECIPIENT-KEY1".getBytes());
final RecipientBox recipientBox1 = RecipientBox.from("BOX1".getBytes());
final PublicKey recipientKey2 = PublicKey.from("RECIPIENT-KEY2".getBytes());
final RecipientBox recipientBox2 = RecipientBox.from("BOX2".getBytes());
final EncodedPayload encodedPayload = mock(EncodedPayload.class);
when(encodedPayload.getCipherText()).thenReturn("CIPHERTEXT".getBytes());
when(encodedPayload.getSenderKey()).thenReturn(senderKey);
when(encodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey2, senderKey));
when(encodedPayload.getRecipientBoxes()).thenReturn(List.of(recipientBox2));
when(encodedPayload.getPrivacyMode()).thenReturn(PrivacyMode.PRIVATE_STATE_VALIDATION);
final EncodedPayload existingEncodedPayload = mock(EncodedPayload.class);
when(existingEncodedPayload.getCipherText()).thenReturn("CIPHERTEXT".getBytes());
when(existingEncodedPayload.getSenderKey()).thenReturn(senderKey);
when(existingEncodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey1));
when(existingEncodedPayload.getRecipientBoxes()).thenReturn(List.of(recipientBox1));
final EncryptedTransaction et = new EncryptedTransaction(mock(MessageHash.class), existingEncodedPayload);
when(enclave.getPublicKeys()).thenReturn(singleton(senderKey));
when(encryptedTransactionDAO.retrieveByHash(any(MessageHash.class))).thenReturn(Optional.of(et));
resendManager.acceptOwnMessage(encodedPayload);
ArgumentCaptor<EncryptedTransaction> updatedTxCaptor = ArgumentCaptor.forClass(EncryptedTransaction.class);
verify(encryptedTransactionDAO).update(updatedTxCaptor.capture());
final EncodedPayload updated = updatedTxCaptor.getValue().getPayload();
// Check recipients are being added
assertThat(updated.getRecipientKeys()).containsExactlyInAnyOrder(recipientKey1, recipientKey2);
// Check boxes are being added
assertThat(updated.getRecipientBoxes()).hasSize(2);
verify(encryptedTransactionDAO).retrieveByHash(any(MessageHash.class));
verify(enclave).getPublicKeys();
verify(enclave, times(2)).unencryptTransaction(any(EncodedPayload.class), eq(senderKey));
}
use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.
the class PrivacyHelperTest method findAffectedContractTransactionsFromPayload.
@Test
public void findAffectedContractTransactionsFromPayload() {
final EncodedPayload payload = mock(EncodedPayload.class);
Map<TxHash, SecurityHash> affected = new HashMap<>();
affected.put(TxHash.from("Hash1".getBytes()), SecurityHash.from("secHash1".getBytes()));
affected.put(TxHash.from("Hash2".getBytes()), SecurityHash.from("secHash2".getBytes()));
EncryptedTransaction et1 = mock(EncryptedTransaction.class);
when(et1.getEncodedPayload()).thenReturn("payload1".getBytes());
when(et1.getHash()).thenReturn(new MessageHash("Hash1".getBytes()));
when(et1.getPayload()).thenReturn(mock(EncodedPayload.class));
when(payload.getAffectedContractTransactions()).thenReturn(affected);
when(encryptedTransactionDAO.findByHashes(any())).thenReturn(singletonList(et1));
List<AffectedTransaction> result = privacyHelper.findAffectedContractTransactionsFromPayload(payload);
assertThat(result).hasSize(1);
verify(encryptedTransactionDAO).findByHashes(any());
}
use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.
the class PrivacyHelperTest method findAffectedContractTransactionsFromSendRequestNotFound.
@Test
public void findAffectedContractTransactionsFromSendRequestNotFound() {
final MessageHash hash1 = mock(MessageHash.class);
final MessageHash hash2 = mock(MessageHash.class);
EncryptedTransaction et1 = mock(EncryptedTransaction.class);
when(et1.getEncodedPayload()).thenReturn("payload1".getBytes());
when(et1.getHash()).thenReturn(new MessageHash("hash1".getBytes()));
when(encryptedTransactionDAO.findByHashes(anyCollection())).thenReturn(List.of(et1));
assertThatExceptionOfType(PrivacyViolationException.class).isThrownBy(() -> {
privacyHelper.findAffectedContractTransactionsFromSendRequest(Set.of(hash1, hash2));
failBecauseExceptionWasNotThrown(Exception.class);
}).withMessageContaining("Unable to find affectedContractTransaction");
verify(encryptedTransactionDAO).findByHashes(any());
}
use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.
the class ResendManagerImpl method acceptOwnMessage.
public synchronized void acceptOwnMessage(final EncodedPayload payload) {
// check the payload can be decrypted to ensure it isn't rubbish being sent to us
final byte[] newDecrypted;
if (payload.getPrivacyMode() == PrivacyMode.PRIVATE_STATE_VALIDATION) {
// if it is PSV, then the enclave would be expected our own box to be available,
// but it isn't (since we are rebuilding)
// since we only want to decrypt the tx and not worry about all the other pieces,
// treat it just like a standard private tx, and remove the other recipients
final EncodedPayload tempPayload = EncodedPayload.Builder.from(payload).withPrivacyMode(PrivacyMode.STANDARD_PRIVATE).withExecHash(new byte[0]).withNewRecipientKeys(List.of(payload.getRecipientKeys().get(0))).withRecipientBoxes(List.of(payload.getRecipientBoxes().get(0).getData())).build();
newDecrypted = enclave.unencryptTransaction(tempPayload, payload.getSenderKey());
} else {
newDecrypted = enclave.unencryptTransaction(payload, payload.getSenderKey());
}
final MessageHash transactionHash = Optional.of(payload).map(EncodedPayload::getCipherText).map(payloadDigest::digest).map(MessageHash::new).get();
final PublicKey sender = payload.getSenderKey();
if (!enclave.getPublicKeys().contains(sender)) {
throw new IllegalArgumentException("Message " + transactionHash.toString() + " does not have one the nodes own keys as a sender");
}
// this is a tx which we created
final Optional<EncryptedTransaction> tx = this.encryptedTransactionDAO.retrieveByHash(transactionHash);
if (tx.isPresent()) {
// we just need to add the recipient
final EncodedPayload existing = tx.get().getPayload();
// this is the easiest way to tell if a recipient has already been included
for (RecipientBox existingBox : existing.getRecipientBoxes()) {
if (Objects.equals(existingBox, payload.getRecipientBoxes().get(0))) {
// recipient must already exist, so just act as though things went normally
return;
}
}
final EncodedPayload.Builder payloadBuilder = EncodedPayload.Builder.from(existing);
if (!existing.getRecipientKeys().contains(payload.getRecipientKeys().get(0))) {
// lets compare it against another message received before
final byte[] oldDecrypted = enclave.unencryptTransaction(existing, existing.getSenderKey());
final boolean same = Arrays.equals(newDecrypted, oldDecrypted) && Arrays.equals(payload.getCipherText(), existing.getCipherText());
if (!same) {
throw new IllegalArgumentException("Invalid payload provided");
}
// check recipients
if (!existing.getRecipientKeys().contains(payload.getRecipientKeys().get(0))) {
payloadBuilder.withRecipientKey(payload.getRecipientKeys().get(0)).withRecipientBox(payload.getRecipientBoxes().get(0).getData());
}
EncryptedTransaction encryptedTransaction = tx.get();
encryptedTransaction.setPayload(payloadBuilder.build());
this.encryptedTransactionDAO.update(encryptedTransaction);
}
} else {
final EncodedPayload.Builder payloadBuilder = EncodedPayload.Builder.from(payload);
final List<PublicKey> recipientKeys = new ArrayList<>(payload.getRecipientKeys());
// we need to recreate this
if (!recipientKeys.contains(sender)) {
recipientKeys.add(sender);
payloadBuilder.withRecipientKey(sender);
}
// add recipient boxes for all recipients (applicable for PSV transactions)
for (int i = payload.getRecipientBoxes().size(); i < recipientKeys.size(); i++) {
PublicKey recipient = recipientKeys.get(i);
byte[] newBox = enclave.createNewRecipientBox(payload, recipient);
payloadBuilder.withRecipientBox(newBox);
}
final EncryptedTransaction txToSave = new EncryptedTransaction(transactionHash, payloadBuilder.build());
this.encryptedTransactionDAO.save(txToSave);
}
}
use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.
the class BatchWorkflowFactoryImplTest method createBatchWorkflowFactoryImplAndExecuteWorkflow.
@Test
public void createBatchWorkflowFactoryImplAndExecuteWorkflow() {
BatchWorkflowFactoryImpl batchWorkflowFactory = new BatchWorkflowFactoryImpl(enclave, discovery, resendBatchPublisher);
BatchWorkflow batchWorkflow = batchWorkflowFactory.create(1L);
assertThat(batchWorkflow).isNotNull();
BatchWorkflowContext batchWorkflowContext = new BatchWorkflowContext();
PublicKey recipientKey = mock(PublicKey.class);
batchWorkflowContext.setRecipientKey(recipientKey);
PublicKey ownedKey = mock(PublicKey.class);
EncodedPayload encodedPayload = mock(EncodedPayload.class);
when(encodedPayload.getSenderKey()).thenReturn(ownedKey);
when(encodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey));
EncryptedTransaction encryptedTransaction = mock(EncryptedTransaction.class);
when(encryptedTransaction.getPayload()).thenReturn(encodedPayload);
batchWorkflowContext.setEncryptedTransaction(encryptedTransaction);
batchWorkflowContext.setEncodedPayload(encodedPayload);
batchWorkflowContext.setBatchSize(100);
when(mockPayloadBuilder.build()).thenReturn(encodedPayload);
when(enclave.status()).thenReturn(Service.Status.STARTED);
when(enclave.getPublicKeys()).thenReturn(Set.of(ownedKey));
NodeInfo nodeInfo = mock(NodeInfo.class);
when(nodeInfo.getRecipients()).thenReturn(Set.of(Recipient.of(recipientKey, "url")));
when(discovery.getCurrent()).thenReturn(nodeInfo);
assertThat(batchWorkflow.execute(batchWorkflowContext)).isTrue();
assertThat(batchWorkflow.getPublishedMessageCount()).isOne();
verify(enclave).status();
verify(enclave, times(2)).getPublicKeys();
mockStaticPayloadBuilder.verify(() -> EncodedPayload.Builder.forRecipient(any(), any()));
verify(mockPayloadBuilder).build();
verify(discovery).getCurrent();
verify(resendBatchPublisher).publishBatch(any(), any());
}
Aggregations