use of com.quorum.tessera.data.staging.StagingTransaction in project tessera by ConsenSys.
the class StagingEntityDAOTest method createFixtures.
public Map<String, StagingTransaction> createFixtures() {
final EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
final String txnHash1 = Utils.createHashStr();
final StagingTransaction stTransaction1 = new StagingTransaction();
stTransaction1.setId(1L);
stTransaction1.setHash(txnHash1);
stTransaction1.setEncodedPayloadCodec(CODEC);
entityManager.persist(stTransaction1);
final String txnHash2 = Utils.createHashStr();
final StagingTransaction stTransaction2a = new StagingTransaction();
stTransaction2a.setId(21L);
stTransaction2a.setHash(txnHash2);
stTransaction2a.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction21a = new StagingAffectedTransaction();
stAffectedContractTransaction21a.setHash(txnHash1);
stAffectedContractTransaction21a.setSourceTransaction(stTransaction2a);
stTransaction2a.getAffectedContractTransactions().add(stAffectedContractTransaction21a);
entityManager.persist(stTransaction2a);
// Another version of transaction 2
final StagingTransaction stTransaction2b = new StagingTransaction();
stTransaction2b.setId(22L);
stTransaction2b.setHash(txnHash2);
stTransaction2b.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction21b = new StagingAffectedTransaction();
stAffectedContractTransaction21b.setHash(txnHash1);
stAffectedContractTransaction21b.setSourceTransaction(stTransaction2b);
stTransaction2b.getAffectedContractTransactions().add(stAffectedContractTransaction21b);
entityManager.persist(stTransaction2b);
final String txnHash4 = Utils.createHashStr();
// we are storing a transaction TXN4 which depends on another transaction TXN3 (which has not
// been received yet)
final String txnHash3 = Utils.createHashStr();
final StagingTransaction stTransaction4 = new StagingTransaction();
stTransaction4.setId(4L);
stTransaction4.setHash(txnHash4);
stTransaction4.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction43 = new StagingAffectedTransaction();
stAffectedContractTransaction43.setHash(txnHash3);
stAffectedContractTransaction43.setSourceTransaction(stTransaction4);
stTransaction4.getAffectedContractTransactions().add(stAffectedContractTransaction43);
entityManager.persist(stTransaction4);
final StagingTransaction stTransaction3 = new StagingTransaction();
stTransaction3.setHash(txnHash3);
stTransaction3.setId(3L);
stTransaction3.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction31 = new StagingAffectedTransaction();
stAffectedContractTransaction31.setHash(txnHash1);
stAffectedContractTransaction31.setSourceTransaction(stTransaction3);
stTransaction3.getAffectedContractTransactions().add(stAffectedContractTransaction31);
entityManager.persist(stTransaction3);
final String txnHash5 = Utils.createHashStr();
// TXN5 is a unresolvable transaction as it depends on TXN6 which is never received
final String txnHash6 = Utils.createHashStr();
final StagingTransaction stTransaction5 = new StagingTransaction();
stTransaction5.setHash(txnHash5);
stTransaction5.setId(5L);
stTransaction5.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction56 = new StagingAffectedTransaction();
stAffectedContractTransaction56.setHash(txnHash6);
stAffectedContractTransaction56.setSourceTransaction(stTransaction5);
stTransaction5.getAffectedContractTransactions().add(stAffectedContractTransaction56);
entityManager.persist(stTransaction5);
final String txnHash7 = Utils.createHashStr();
// TXN7 depends on TXN1 and TXN3
final StagingTransaction stTransaction7 = new StagingTransaction();
stTransaction7.setHash(txnHash7);
stTransaction7.setId(7L);
stTransaction7.setEncodedPayloadCodec(CODEC);
StagingAffectedTransaction stAffectedContractTransaction71 = new StagingAffectedTransaction();
stAffectedContractTransaction71.setHash(txnHash1);
stAffectedContractTransaction71.setSourceTransaction(stTransaction7);
stTransaction7.getAffectedContractTransactions().add(stAffectedContractTransaction71);
StagingAffectedTransaction stAffectedContractTransaction74 = new StagingAffectedTransaction();
stAffectedContractTransaction74.setHash(txnHash4);
stAffectedContractTransaction74.setSourceTransaction(stTransaction7);
stTransaction7.getAffectedContractTransactions().add(stAffectedContractTransaction74);
entityManager.persist(stTransaction7);
entityManager.getTransaction().commit();
Map<String, StagingTransaction> transactions = new HashMap<>();
transactions.put("TXN1", stTransaction1);
transactions.put("TXN2A", stTransaction2a);
transactions.put("TXN2B", stTransaction2b);
transactions.put("TXN3", stTransaction3);
transactions.put("TXN4", stTransaction4);
transactions.put("TXN5", stTransaction5);
transactions.put("TXN7", stTransaction7);
return transactions;
}
use of com.quorum.tessera.data.staging.StagingTransaction in project tessera by ConsenSys.
the class BatchResendManagerImplTest method testStoreResendBatchMultipleVersions.
@Test
public void testStoreResendBatchMultipleVersions() {
try (var payloadDigestMockedStatic = mockStatic(PayloadDigest.class);
var payloadEncoderMockedStatic = mockStatic(PayloadEncoder.class)) {
payloadDigestMockedStatic.when(PayloadDigest::create).thenReturn((PayloadDigest) cipherText -> cipherText);
payloadEncoderMockedStatic.when(() -> PayloadEncoder.create(any())).thenReturn(payloadEncoder);
final EncodedPayload encodedPayload = EncodedPayload.Builder.create().withSenderKey(publicKey).withCipherText("cipherText".getBytes()).withCipherTextNonce(new Nonce("nonce".getBytes())).withRecipientBoxes(singletonList("box".getBytes())).withRecipientNonce(new Nonce("recipientNonce".getBytes())).withRecipientKeys(singletonList(PublicKey.from("receiverKey".getBytes()))).withPrivacyMode(PrivacyMode.STANDARD_PRIVATE).withAffectedContractTransactions(emptyMap()).withExecHash(new byte[0]).build();
when(payloadEncoder.decode(any())).thenReturn(encodedPayload);
final byte[] raw = new PayloadEncoderImpl().encode(encodedPayload);
PushBatchRequest request = PushBatchRequest.from(List.of(raw), EncodedPayloadCodec.LEGACY);
StagingTransaction existing = new StagingTransaction();
when(stagingEntityDAO.retrieveByHash(any())).thenReturn(Optional.of(existing));
when(stagingEntityDAO.update(any(StagingTransaction.class))).thenReturn(new StagingTransaction());
manager.storeResendBatch(request);
verify(stagingEntityDAO).save(any(StagingTransaction.class));
verify(payloadEncoder).decode(any());
verify(payloadEncoder).encodedPayloadCodec();
payloadDigestMockedStatic.verify(PayloadDigest::create);
payloadDigestMockedStatic.verifyNoMoreInteractions();
}
}
use of com.quorum.tessera.data.staging.StagingTransaction in project tessera by ConsenSys.
the class RecoveryImplTest method testSyncPsvTransactionOnlySentOnce.
@Test
public void testSyncPsvTransactionOnlySentOnce() {
StagingTransaction version1 = mock(StagingTransaction.class);
StagingTransaction version2 = mock(StagingTransaction.class);
StagingTransaction anotherTx = mock(StagingTransaction.class);
when(version1.getHash()).thenReturn("TXN1");
when(version2.getHash()).thenReturn("TXN1");
when(anotherTx.getHash()).thenReturn("TXN2");
EncodedPayload encodedPayload = mock(EncodedPayload.class);
EncodedPayload encodedPayload2 = mock(EncodedPayload.class);
when(version1.getEncodedPayload()).thenReturn(encodedPayload);
when(version2.getEncodedPayload()).thenReturn(encodedPayload);
when(anotherTx.getEncodedPayload()).thenReturn(encodedPayload2);
when(version1.getPrivacyMode()).thenReturn(PrivacyMode.PRIVATE_STATE_VALIDATION);
when(version2.getPrivacyMode()).thenReturn(PrivacyMode.PRIVATE_STATE_VALIDATION);
when(anotherTx.getPrivacyMode()).thenReturn(PrivacyMode.STANDARD_PRIVATE);
when(stagingEntityDAO.retrieveTransactionBatchOrderByStageAndHash(anyInt(), anyInt())).thenReturn(List.of(version1, version2, anotherTx));
when(stagingEntityDAO.countAll()).thenReturn(3L);
when(transactionManager.storePayload(any())).thenThrow(PrivacyViolationException.class);
RecoveryResult result = recovery.sync();
assertThat(result).isEqualTo(RecoveryResult.FAILURE);
verify(stagingEntityDAO).retrieveTransactionBatchOrderByStageAndHash(anyInt(), anyInt());
verify(stagingEntityDAO, times(2)).countAll();
verify(transactionManager).storePayload(encodedPayload);
verify(transactionManager).storePayload(encodedPayload2);
}
use of com.quorum.tessera.data.staging.StagingTransaction in project tessera by ConsenSys.
the class RecoveryImpl method sync.
@Override
public RecoveryResult sync() {
final AtomicInteger payloadCount = new AtomicInteger(0);
final AtomicInteger syncFailureCount = new AtomicInteger(0);
final int maxResult = BATCH_SIZE;
for (int offset = 0; offset < stagingEntityDAO.countAll(); offset += maxResult) {
final List<StagingTransaction> transactions = stagingEntityDAO.retrieveTransactionBatchOrderByStageAndHash(offset, maxResult);
final Map<String, List<StagingTransaction>> grouped = transactions.stream().collect(Collectors.groupingBy(StagingTransaction::getHash, LinkedHashMap::new, toList()));
grouped.forEach((key, value) -> value.stream().filter(t -> {
payloadCount.incrementAndGet();
EncodedPayload encodedPayload = t.getEncodedPayload();
try {
transactionManager.storePayload(encodedPayload);
} catch (PrivacyViolationException | PersistenceException ex) {
LOGGER.error("An error occurred during batch resend sync stage.", ex);
syncFailureCount.incrementAndGet();
}
return PrivacyMode.PRIVATE_STATE_VALIDATION == t.getPrivacyMode();
}).findFirst());
}
if (syncFailureCount.get() > 0) {
LOGGER.warn("There have been issues during the synchronisation process. " + "Problematic transactions have been ignored.");
if (syncFailureCount.get() == payloadCount.get()) {
return RecoveryResult.FAILURE;
}
return RecoveryResult.PARTIAL_SUCCESS;
}
return RecoveryResult.SUCCESS;
}
use of com.quorum.tessera.data.staging.StagingTransaction in project tessera by ConsenSys.
the class RecoveryImplTest method testSyncPartialSuccess.
@Test
public void testSyncPartialSuccess() {
StagingTransaction version1 = mock(StagingTransaction.class);
StagingTransaction version2 = mock(StagingTransaction.class);
when(version1.getHash()).thenReturn("TXN1");
when(version2.getHash()).thenReturn("TXN1");
when(stagingEntityDAO.retrieveTransactionBatchOrderByStageAndHash(anyInt(), anyInt())).thenReturn(List.of(version1, version2));
when(stagingEntityDAO.countAll()).thenReturn(2L);
EncodedPayload encodedPayload = mock(EncodedPayload.class);
EncodedPayload encodedPayload2 = mock(EncodedPayload.class);
when(version1.getEncodedPayload()).thenReturn(encodedPayload);
when(version2.getEncodedPayload()).thenReturn(encodedPayload2);
when(transactionManager.storePayload(encodedPayload)).thenThrow(PrivacyViolationException.class);
RecoveryResult result = recovery.sync();
assertThat(result).isEqualTo(RecoveryResult.PARTIAL_SUCCESS);
verify(stagingEntityDAO).retrieveTransactionBatchOrderByStageAndHash(anyInt(), anyInt());
verify(stagingEntityDAO, times(2)).countAll();
verify(transactionManager).storePayload(encodedPayload);
verify(transactionManager).storePayload(encodedPayload2);
}
Aggregations