Search in sources :

Example 1 with EncodedPayloadCodec

use of com.quorum.tessera.enclave.EncodedPayloadCodec in project tessera by ConsenSys.

the class ResendAllIT method transactionsAreReconstructedFromMultipleParties.

@Test
public void transactionsAreReconstructedFromMultipleParties() throws UnsupportedEncodingException, SQLException {
    // setup (sending in a tx)
    Response sendRawResponse = partyOne.getRestClient().target(partyOne.getQ2TUri()).path("/sendraw").request().header("c11n-from", partyOne.getPublicKey()).header("c11n-to", partyTwo.getPublicKey() + "," + partyThree.getPublicKey()).post(Entity.entity(transactionData, MediaType.APPLICATION_OCTET_STREAM));
    URI location = sendRawResponse.getLocation();
    String hash = sendRawResponse.readEntity(String.class);
    final String encodedHash = URLEncoder.encode(hash, UTF_8.toString());
    // delete it from the sender node
    final Response deleteReq = partyOne.getRestClient().target(location).request().delete();
    assertThat(deleteReq).isNotNull();
    assertThat(deleteReq.getStatus()).isEqualTo(204);
    // check it is deleted
    final Response deleteCheck = partyOne.getRestClient().target(partyOne.getQ2TUri()).path("transaction").path(encodedHash).request().get();
    assertThat(deleteCheck).isNotNull();
    assertThat(deleteCheck.getStatus()).isEqualTo(404);
    // request resend from recipients
    final ResendRequest req = new ResendRequest();
    req.setType(RESEND_ALL_VALUE);
    req.setPublicKey(partyOne.getPublicKey());
    final Response resendRequest = vanillaHttpOnlyClient.target(partyTwo.getP2PUri()).path(RESEND_PATH).request().buildPost(Entity.entity(req, MediaType.APPLICATION_JSON_TYPE)).invoke();
    assertThat(resendRequest).isNotNull();
    assertThat(resendRequest.getStatus()).isEqualTo(200);
    final Response resendRequestNode3 = vanillaHttpOnlyClient.target(partyThree.getP2PUri()).path(RESEND_PATH).request().buildPost(Entity.entity(req, MediaType.APPLICATION_JSON_TYPE)).invoke();
    assertThat(resendRequestNode3).isNotNull();
    assertThat(resendRequestNode3.getStatus()).isEqualTo(200);
    final String fetch = "SELECT ENCODED_PAYLOAD, PAYLOAD_CODEC FROM ENCRYPTED_TRANSACTION WHERE HASH = ?";
    final Connection databaseConnection = PartyHelper.create().findByPublicKey(partyOne.getPublicKey()).getDatabaseConnection();
    try (PreparedStatement statement = databaseConnection.prepareStatement(fetch)) {
        statement.setBytes(1, Base64.getDecoder().decode(hash));
        try (ResultSet rs = statement.executeQuery()) {
            assertThat(rs.next()).isTrue();
            final byte[] output = rs.getBytes(1);
            final EncodedPayloadCodec codec = EncodedPayloadCodec.valueOf(rs.getString(2));
            final PayloadEncoder encoderToUse = PayloadEncoder.create(codec);
            final EncodedPayload payload = encoderToUse.decode(output);
            assertThat(payload.getRecipientKeys()).hasSize(3);
            assertThat(payload.getSenderKey().encodeToBase64()).isEqualTo(partyOne.getPublicKey());
            assertThat(payload.getRecipientBoxes()).hasSize(3);
        }
    }
}
Also used : Response(jakarta.ws.rs.core.Response) PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) URI(java.net.URI) ResendRequest(com.quorum.tessera.p2p.resend.ResendRequest) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) Test(org.junit.Test)

Example 2 with EncodedPayloadCodec

use of com.quorum.tessera.enclave.EncodedPayloadCodec in project tessera by ConsenSys.

the class RestPayloadPublisher method publishPayload.

@Override
public void publishPayload(EncodedPayload payload, PublicKey recipientKey) {
    final NodeInfo remoteNodeInfo = discovery.getRemoteNodeInfo(recipientKey);
    final Set<String> supportedApiVersions = remoteNodeInfo.supportedApiVersions();
    final EncodedPayloadCodec preferredCodec = EncodedPayloadCodec.getPreferredCodec(supportedApiVersions);
    final PayloadEncoder payloadEncoder = PayloadEncoder.create(preferredCodec);
    if (PrivacyMode.STANDARD_PRIVATE != payload.getPrivacyMode() && !supportedApiVersions.contains(EnhancedPrivacyVersion.API_VERSION_2)) {
        throw new EnhancedPrivacyNotSupportedException("Transactions with enhanced privacy is not currently supported on recipient " + recipientKey.encodeToBase64());
    }
    if (PrivacyMode.MANDATORY_RECIPIENTS == payload.getPrivacyMode() && !supportedApiVersions.contains(MandatoryRecipientsVersion.API_VERSION_4)) {
        throw new MandatoryRecipientsNotSupportedException("Transactions with mandatory recipients are not currently supported on recipient " + recipientKey.encodeToBase64());
    }
    final String targetUrl = remoteNodeInfo.getUrl();
    LOGGER.info("Publishing message to {}", targetUrl);
    final byte[] encoded = payloadEncoder.encode(payload);
    try (Response response = client.target(targetUrl).path("/push").request().post(Entity.entity(encoded, MediaType.APPLICATION_OCTET_STREAM_TYPE))) {
        if (Response.Status.OK.getStatusCode() != response.getStatus() && Response.Status.CREATED.getStatusCode() != response.getStatus()) {
            throw new PublishPayloadException("Unable to push payload to recipient url " + targetUrl);
        }
        LOGGER.info("Published to {}", targetUrl);
    } catch (ProcessingException ex) {
        LOGGER.debug("", ex);
        throw new NodeOfflineException(URI.create(targetUrl));
    }
}
Also used : Response(jakarta.ws.rs.core.Response) PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) PublishPayloadException(com.quorum.tessera.transaction.publish.PublishPayloadException) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) MandatoryRecipientsNotSupportedException(com.quorum.tessera.transaction.exception.MandatoryRecipientsNotSupportedException) NodeOfflineException(com.quorum.tessera.transaction.publish.NodeOfflineException) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) EnhancedPrivacyNotSupportedException(com.quorum.tessera.transaction.exception.EnhancedPrivacyNotSupportedException) ProcessingException(jakarta.ws.rs.ProcessingException)

Example 3 with EncodedPayloadCodec

use of com.quorum.tessera.enclave.EncodedPayloadCodec in project tessera by ConsenSys.

the class EncryptedTransactionListener method onUpdate.

@PreUpdate
public void onUpdate(EncryptedTransaction encryptedTransaction) {
    LOGGER.debug("onUpdate {}", encryptedTransaction);
    final EncodedPayload encodedPayload = encryptedTransaction.getPayload();
    final EncodedPayloadCodec encodedPayloadCodec = encryptedTransaction.getEncodedPayloadCodec();
    final PayloadEncoder payloadEncoder = PayloadEncoder.create(encodedPayloadCodec);
    final byte[] encodedPayloadData = payloadEncoder.encode(encodedPayload);
    encryptedTransaction.setEncodedPayload(encodedPayloadData);
}
Also used : PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) PreUpdate(jakarta.persistence.PreUpdate)

Example 4 with EncodedPayloadCodec

use of com.quorum.tessera.enclave.EncodedPayloadCodec in project tessera by ConsenSys.

the class TransactionResource method push.

// path push is overloaded (RecoveryResource & TransactionResource); swagger cannot handle
// situations like this so this operation documents both
@Operation(summary = "/push", operationId = "pushPayload", description = "store encoded payload to the server's database")
@ApiResponse(responseCode = "201", description = "hash of encoded payload", content = @Content(mediaType = TEXT_PLAIN, schema = @Schema(description = "hash of encrypted payload", type = "string", format = "base64")))
@ApiResponse(responseCode = "403", description = "server is in recovery mode and encoded payload is not a Standard Private transaction")
@POST
@Path("push")
@Consumes(APPLICATION_OCTET_STREAM)
public Response push(@Schema(description = "encoded payload") final byte[] payload, @HeaderParam(Constants.API_VERSION_HEADER) @Parameter(description = "client's supported API versions", array = @ArraySchema(schema = @Schema(type = "string"))) final List<String> headers) {
    LOGGER.debug("Received push request");
    final Set<String> versions = Optional.ofNullable(headers).orElse(emptyList()).stream().filter(Objects::nonNull).flatMap(v -> Arrays.stream(v.split(","))).collect(Collectors.toSet());
    final EncodedPayloadCodec codec = EncodedPayloadCodec.getPreferredCodec(versions);
    final PayloadEncoder payloadEncoder = PayloadEncoder.create(codec);
    final MessageHash messageHash = transactionManager.storePayload(payloadEncoder.decode(payload));
    LOGGER.debug("Push request generated hash {}", messageHash);
    return Response.status(Response.Status.CREATED).entity(Objects.toString(messageHash)).build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) LoggerFactory(org.slf4j.LoggerFactory) BatchResendManager(com.quorum.tessera.recovery.workflow.BatchResendManager) Base64Codec(com.quorum.tessera.base64.Base64Codec) PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) Content(io.swagger.v3.oas.annotations.media.Content) Operation(io.swagger.v3.oas.annotations.Operation) Response(jakarta.ws.rs.core.Response) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse) MessageHash(com.quorum.tessera.data.MessageHash) ResendBatchRequest(com.quorum.tessera.p2p.recovery.ResendBatchRequest) LegacyResendManager(com.quorum.tessera.recovery.workflow.LegacyResendManager) Constants(com.quorum.tessera.shared.Constants) Schema(io.swagger.v3.oas.annotations.media.Schema) Logger(org.slf4j.Logger) Collections.emptyList(java.util.Collections.emptyList) TransactionManager(com.quorum.tessera.transaction.TransactionManager) jakarta.ws.rs(jakarta.ws.rs) Collectors(java.util.stream.Collectors) Parameter(io.swagger.v3.oas.annotations.Parameter) ArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema) MediaType(jakarta.ws.rs.core.MediaType) ResendBatchResponse(com.quorum.tessera.recovery.resend.ResendBatchResponse) Tag(io.swagger.v3.oas.annotations.tags.Tag) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) ResendRequest(com.quorum.tessera.p2p.resend.ResendRequest) PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) MessageHash(com.quorum.tessera.data.MessageHash) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) Operation(io.swagger.v3.oas.annotations.Operation) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse)

Example 5 with EncodedPayloadCodec

use of com.quorum.tessera.enclave.EncodedPayloadCodec in project tessera by ConsenSys.

the class StagingTransactionListener method onLoad.

@PostLoad
public void onLoad(StagingTransaction stagingTransaction) {
    LOGGER.debug("onLoad[{}]", stagingTransaction);
    final EncodedPayloadCodec encodedPayloadCodec = stagingTransaction.getEncodedPayloadCodec();
    final byte[] encodedPayloadData = stagingTransaction.getPayload();
    final PayloadEncoder payloadEncoder = PayloadEncoder.create(encodedPayloadCodec);
    final EncodedPayload encodedPayload = payloadEncoder.decode(encodedPayloadData);
    stagingTransaction.setEncodedPayload(encodedPayload);
}
Also used : PayloadEncoder(com.quorum.tessera.enclave.PayloadEncoder) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) EncodedPayloadCodec(com.quorum.tessera.enclave.EncodedPayloadCodec) PostLoad(jakarta.persistence.PostLoad)

Aggregations

EncodedPayloadCodec (com.quorum.tessera.enclave.EncodedPayloadCodec)9 PayloadEncoder (com.quorum.tessera.enclave.PayloadEncoder)9 EncodedPayload (com.quorum.tessera.enclave.EncodedPayload)7 Response (jakarta.ws.rs.core.Response)5 ResendRequest (com.quorum.tessera.p2p.resend.ResendRequest)3 MessageHash (com.quorum.tessera.data.MessageHash)2 BatchResendManager (com.quorum.tessera.recovery.workflow.BatchResendManager)2 Constants (com.quorum.tessera.shared.Constants)2 TransactionManager (com.quorum.tessera.transaction.TransactionManager)2 Operation (io.swagger.v3.oas.annotations.Operation)2 ApiResponse (io.swagger.v3.oas.annotations.responses.ApiResponse)2 Tag (io.swagger.v3.oas.annotations.tags.Tag)2 PostLoad (jakarta.persistence.PostLoad)2 Valid (jakarta.validation.Valid)2 NotNull (jakarta.validation.constraints.NotNull)2 URI (java.net.URI)2 Connection (java.sql.Connection)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 java.util (java.util)2