Search in sources :

Example 1 with PrivacyViolationException

use of com.quorum.tessera.transaction.exception.PrivacyViolationException in project tessera by ConsenSys.

the class PrivacyViolationExceptionMapperTest method handleException.

@Test
public void handleException() {
    final String message = ".. all outta gum";
    final PrivacyViolationException exception = new PrivacyViolationException(message);
    final Response result = mapper.toResponse(exception);
    assertThat(result.getStatus()).isEqualTo(403);
    assertThat(result.getEntity()).isEqualTo(message);
}
Also used : Response(jakarta.ws.rs.core.Response) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) Test(org.junit.Test)

Example 2 with PrivacyViolationException

use of com.quorum.tessera.transaction.exception.PrivacyViolationException in project tessera by ConsenSys.

the class PrivacyGroupManagerImpl method deletePrivacyGroup.

@Override
public PrivacyGroup deletePrivacyGroup(PublicKey from, PrivacyGroup.Id privacyGroupId) {
    final PrivacyGroup retrieved = retrievePrivacyGroup(privacyGroupId);
    if (!retrieved.getMembers().contains(from)) {
        throw new PrivacyViolationException("Sender of request does not belong to this privacy group");
    }
    final PrivacyGroup updated = PrivacyGroup.Builder.create().from(retrieved).withState(PrivacyGroup.State.DELETED).build();
    final byte[] updatedData = privacyGroupUtil.encode(updated);
    final byte[] lookupId = privacyGroupUtil.generateLookupId(updated.getMembers());
    final PrivacyGroupEntity updatedEt = new PrivacyGroupEntity(updated.getId().getBytes(), lookupId, updatedData);
    final Set<PublicKey> localKeys = enclave.getPublicKeys();
    final List<PublicKey> forwardingMembers = updated.getMembers().stream().filter(Predicate.not(localKeys::contains)).collect(Collectors.toList());
    privacyGroupDAO.update(updatedEt, () -> {
        publisher.publishPrivacyGroup(updatedData, forwardingMembers);
        return null;
    });
    return updated;
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) PrivacyGroupEntity(com.quorum.tessera.data.PrivacyGroupEntity) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup)

Example 3 with PrivacyViolationException

use of com.quorum.tessera.transaction.exception.PrivacyViolationException in project tessera by ConsenSys.

the class ResidentGroupHandlerImpl method onCreate.

@Override
public void onCreate(Config config) {
    final Set<PublicKey> managedKeys = privacyGroupManager.getManagedKeys();
    final List<PrivacyGroup> configuredResidentGroups = Stream.ofNullable(config.getResidentGroups()).flatMap(Collection::stream).map(convertToPrivacyGroup).collect(Collectors.toUnmodifiableList());
    configuredResidentGroups.stream().map(PrivacyGroup::getMembers).flatMap(List::stream).filter(Predicate.not(managedKeys::contains)).findFirst().ifPresent(key -> {
        throw new PrivacyViolationException("Key " + key + " configured in resident groups must be locally managed");
    });
    final List<PrivacyGroup> existing = privacyGroupManager.findPrivacyGroupByType(PrivacyGroup.Type.RESIDENT);
    final List<PrivacyGroup> allResidentGroups = new ArrayList<>(configuredResidentGroups);
    allResidentGroups.addAll(existing);
    final List<PrivacyGroup> merged = allResidentGroups.stream().collect(Collectors.collectingAndThen(Collectors.toMap(PrivacyGroup::getId, Function.identity(), (left, right) -> {
        final List<PublicKey> mergedMembers = Stream.concat(left.getMembers().stream(), right.getMembers().stream()).distinct().collect(Collectors.toUnmodifiableList());
        return PrivacyGroup.Builder.create().from(left).withMembers(mergedMembers).build();
    }), m -> new ArrayList<>(m.values())));
    try {
        merged.stream().flatMap(p -> p.getMembers().stream().distinct().map(m -> Map.entry(m, p.getId()))).distinct().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    } catch (IllegalStateException ex) {
        throw new PrivacyViolationException("Key cannot belong to more than one resident group." + "Cause: " + ex.getMessage());
    }
    final Set<PublicKey> mergedResidentKeys = merged.stream().map(PrivacyGroup::getMembers).flatMap(List::stream).collect(Collectors.toUnmodifiableSet());
    managedKeys.stream().filter(Predicate.not(mergedResidentKeys::contains)).findAny().ifPresent(key -> {
        throw new PrivacyViolationException(key + " must belong to a resident group");
    });
    final List<PrivacyGroup.Id> configuredGroupId = configuredResidentGroups.stream().map(PrivacyGroup::getId).collect(Collectors.toList());
    merged.stream().filter(pg -> configuredGroupId.contains(pg.getId())).collect(Collectors.toList()).forEach(toPersist -> privacyGroupManager.saveResidentGroup(toPersist.getName(), toPersist.getDescription(), toPersist.getMembers()));
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) ResidentGroup(com.quorum.tessera.config.ResidentGroup) Stream(java.util.stream.Stream) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) Predicate(java.util.function.Predicate) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) Config(com.quorum.tessera.config.Config) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) ResidentGroupHandler(com.quorum.tessera.privacygroup.ResidentGroupHandler) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup)

Example 4 with PrivacyViolationException

use of com.quorum.tessera.transaction.exception.PrivacyViolationException 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;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) PersistenceException(jakarta.persistence.PersistenceException) StagingTransaction(com.quorum.tessera.data.staging.StagingTransaction) Collectors.toList(java.util.stream.Collectors.toList) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload)

Example 5 with PrivacyViolationException

use of com.quorum.tessera.transaction.exception.PrivacyViolationException in project tessera by ConsenSys.

the class PrivacyHelperImpl method validatePayload.

@Override
public boolean validatePayload(TxHash txHash, EncodedPayload payload, List<AffectedTransaction> affectedTransactions) {
    final PrivacyMode privacyMode = payload.getPrivacyMode();
    if (privacyMode != PrivacyMode.STANDARD_PRIVATE) {
        checkIfEnhancedPrivacyIsEnabled();
    }
    boolean privacyMetadataMismatched = affectedTransactions.stream().anyMatch(a -> {
        if (a.getPayload().getPrivacyMode() != privacyMode) {
            LOGGER.info("ACOTH {} has PrivacyMode={} for TX {} with PrivacyMode={}. Ignoring transaction.", a.getHash(), a.getPayload().getPrivacyMode(), txHash, privacyMode.name());
            return true;
        }
        if (!payload.getMandatoryRecipients().containsAll(a.getPayload().getMandatoryRecipients())) {
            LOGGER.info("ACOTH {} has mandatory recipients mismatched. Ignoring transaction.", a.getHash());
            return true;
        }
        return false;
    });
    if (privacyMetadataMismatched)
        return false;
    if (PrivacyMode.PRIVATE_STATE_VALIDATION == privacyMode) {
        if (affectedTransactions.size() != payload.getAffectedContractTransactions().size()) {
            LOGGER.info("Not all ACOTHs were found. Ignoring transaction.");
            return false;
        }
        final PublicKey senderKey = payload.getSenderKey();
        if (affectedTransactions.stream().anyMatch(a -> {
            final List<PublicKey> recipients = a.getPayload().getRecipientKeys();
            if (!recipients.contains(senderKey)) {
                LOGGER.info("Sender key {} for TX {} is not a recipient for ACOTH {}", senderKey.encodeToBase64(), txHash, a.getHash().encodeToBase64());
                return true;
            }
            return false;
        })) {
            return false;
        }
        validateRecipients(payload.getRecipientKeys(), affectedTransactions).findFirst().ifPresent(affectedTransaction -> {
            throw new PrivacyViolationException("Recipients mismatched for Affected Txn " + affectedTransaction.getHash().encodeToBase64());
        });
    }
    return true;
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException)

Aggregations

PrivacyViolationException (com.quorum.tessera.transaction.exception.PrivacyViolationException)6 PublicKey (com.quorum.tessera.encryption.PublicKey)4 PrivacyGroup (com.quorum.tessera.enclave.PrivacyGroup)3 PrivacyGroupEntity (com.quorum.tessera.data.PrivacyGroupEntity)2 Config (com.quorum.tessera.config.Config)1 ResidentGroup (com.quorum.tessera.config.ResidentGroup)1 StagingTransaction (com.quorum.tessera.data.staging.StagingTransaction)1 EncodedPayload (com.quorum.tessera.enclave.EncodedPayload)1 PrivacyGroupManager (com.quorum.tessera.privacygroup.PrivacyGroupManager)1 ResidentGroupHandler (com.quorum.tessera.privacygroup.ResidentGroupHandler)1 PersistenceException (jakarta.persistence.PersistenceException)1 Response (jakarta.ws.rs.core.Response)1 java.util (java.util)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Function (java.util.function.Function)1 Predicate (java.util.function.Predicate)1 Collectors (java.util.stream.Collectors)1 Collectors.toList (java.util.stream.Collectors.toList)1 Stream (java.util.stream.Stream)1 Test (org.junit.Test)1