Search in sources :

Example 11 with TransactionManager

use of com.quorum.tessera.transaction.TransactionManager in project tessera by ConsenSys.

the class Main method main.

public static void main(final String... args) throws Exception {
    Security.addProvider(new BouncyCastleProvider());
    LOGGER.debug("args [{}]", String.join(",", args));
    try {
        PicoCliDelegate picoCliDelegate = new PicoCliDelegate();
        LOGGER.debug("Execute PicoCliDelegate with args [{}]", String.join(",", args));
        final CliResult cliResult = picoCliDelegate.execute(args);
        LOGGER.debug("Executed PicoCliDelegate with args [{}].", String.join(",", args));
        if (cliResult.isSuppressStartup()) {
            System.exit(0);
        }
        if (cliResult.getStatus() != 0) {
            System.exit(cliResult.getStatus());
        }
        final Config config = cliResult.getConfig().orElseThrow(() -> new NoSuchElementException("No config found. Tessera will not run."));
        // Start legacy spring profile stuff
        final String springProfileWarning = "Warn: Spring profiles will not be supported in future. To start in recover mode use 'tessera recover'";
        if (System.getProperties().containsKey("spring.profiles.active")) {
            System.out.println(springProfileWarning);
            config.setRecoveryMode(System.getProperty("spring.profiles.active").contains("enable-sync-poller"));
        } else if (System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) {
            System.out.println(springProfileWarning);
            config.setRecoveryMode(System.getenv("SPRING_PROFILES_ACTIVE").contains("enable-sync-poller"));
        }
        // end spring profile stuff
        LOGGER.debug("Storing config {}", config);
        ConfigFactory.create().store(config);
        LOGGER.debug("Stored config {}", config);
        LOGGER.debug("Creating enclave");
        final Enclave enclave = Enclave.create();
        LOGGER.debug("Created enclave {}", enclave);
        LOGGER.debug("Creating RuntimeContext");
        final RuntimeContext runtimeContext = RuntimeContext.getInstance();
        LOGGER.debug("Created RuntimeContext {}", runtimeContext);
        LOGGER.debug("Creating Discovery");
        Discovery discovery = Discovery.create();
        discovery.onCreate();
        LOGGER.debug("Created Discovery {}", discovery);
        if (runtimeContext.isMultiplePrivateStates()) {
            LOGGER.debug("Creating ResidentGroupHandler");
            ResidentGroupHandler residentGroupHandler = ResidentGroupHandler.create();
            residentGroupHandler.onCreate(config);
            LOGGER.debug("Created ResidentGroupHandler {}", residentGroupHandler);
        }
        LOGGER.debug("Creating EncodedPayloadManager");
        EncodedPayloadManager.create();
        LOGGER.debug("Created EncodedPayloadManager");
        LOGGER.debug("Creating BatchResendManager");
        BatchResendManager.create();
        LOGGER.debug("Created BatchResendManager");
        LOGGER.debug("Creating txn manager");
        TransactionManager transactionManager = TransactionManager.create();
        LOGGER.debug("Created txn manager");
        LOGGER.debug("Validating if transaction table exists");
        if (!transactionManager.upcheck()) {
            throw new RuntimeException("The database has not been setup correctly. Please ensure transaction tables " + "are present and correct");
        }
        LOGGER.debug("Creating ScheduledServiceFactory");
        ScheduledServiceFactory scheduledServiceFactory = ScheduledServiceFactory.fromConfig(config);
        scheduledServiceFactory.build();
        LOGGER.debug("Created ScheduledServiceFactory");
        LOGGER.debug("Creating Launcher");
        final List<TesseraServer> tesseraServers = Launcher.create(runtimeContext.isRecoveryMode()).launchServer(config);
        LOGGER.debug("Created Launcher");
        if (config.getOutputServerURIPath() != null) {
            ServerURIFileWriter.writeURIFile(config.getOutputServerURIPath(), tesseraServers);
        }
    } catch (final ConstraintViolationException ex) {
        for (final ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            System.err.println("ERROR: Config validation issue: " + violation.getPropertyPath() + " " + violation.getMessage());
        }
        System.exit(1);
    } catch (final ConfigException ex) {
        LOGGER.debug("", ex);
        final Throwable cause = ExceptionUtils.getRootCause(ex);
        if (JsonException.class.isInstance(cause)) {
            System.err.println("ERROR: Invalid json, cause is " + cause.getMessage());
        } else {
            System.err.println("ERROR: Configuration exception, cause is " + Objects.toString(cause));
        }
        System.exit(3);
    } catch (final CliException ex) {
        LOGGER.debug("", ex);
        System.err.println("ERROR: CLI exception, cause is " + ex.getMessage());
        System.exit(4);
    } catch (final ServiceConfigurationError ex) {
        LOGGER.debug("", ex);
        Optional<Throwable> e = Optional.of(ex);
        e.map(Throwable::getMessage).ifPresent(System.err::println);
        // get root cause
        while (e.map(Throwable::getCause).isPresent()) {
            e = e.map(Throwable::getCause);
        }
        e.map(Throwable::toString).ifPresent(System.err::println);
        System.exit(5);
    } catch (final Throwable ex) {
        LOGGER.debug(null, ex);
        if (Arrays.asList(args).contains("--debug")) {
            ex.printStackTrace();
        } else {
            if (Optional.ofNullable(ex.getMessage()).isPresent()) {
                System.err.println("ERROR: Cause is " + ex.getMessage());
            } else {
                System.err.println("ERROR: In class " + ex.getClass().getSimpleName());
            }
        }
        System.exit(2);
    }
}
Also used : JsonException(jakarta.json.JsonException) Config(com.quorum.tessera.config.Config) ResidentGroupHandler(com.quorum.tessera.privacygroup.ResidentGroupHandler) Discovery(com.quorum.tessera.discovery.Discovery) ConfigException(com.quorum.tessera.config.ConfigException) TesseraServer(com.quorum.tessera.server.TesseraServer) PicoCliDelegate(com.quorum.tessera.config.cli.PicoCliDelegate) CliException(com.quorum.tessera.cli.CliException) CliResult(com.quorum.tessera.cli.CliResult) Enclave(com.quorum.tessera.enclave.Enclave) TransactionManager(com.quorum.tessera.transaction.TransactionManager) ConstraintViolation(jakarta.validation.ConstraintViolation) ConstraintViolationException(jakarta.validation.ConstraintViolationException) RuntimeContext(com.quorum.tessera.context.RuntimeContext) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider)

Example 12 with TransactionManager

use of com.quorum.tessera.transaction.TransactionManager in project tessera by ConsenSys.

the class RawTransactionResourceTest method defaultConstrcutor.

@Test
public void defaultConstrcutor() {
    RawTransactionResource resource;
    try (var mockedStaticTM = mockStatic(TransactionManager.class)) {
        TransactionManager transactionManager = mock(TransactionManager.class);
        mockedStaticTM.when(TransactionManager::create).thenReturn(transactionManager);
        resource = new RawTransactionResource();
        mockedStaticTM.verify(TransactionManager::create);
        mockedStaticTM.verifyNoMoreInteractions();
        verifyNoInteractions(transactionManager);
    }
    assertThat(resource).isNotNull();
}
Also used : TransactionManager(com.quorum.tessera.transaction.TransactionManager) Test(org.junit.Test)

Example 13 with TransactionManager

use of com.quorum.tessera.transaction.TransactionManager in project tessera by ConsenSys.

the class BesuTransactionResource method send.

@Hidden
@POST
@Path("send")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response send(@NotNull @Valid @PrivacyValid final SendRequest sendRequest) {
    final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
    final Optional<PrivacyGroup.Id> optionalPrivacyGroup = Optional.ofNullable(sendRequest.getPrivacyGroupId()).map(PrivacyGroup.Id::fromBase64String);
    final List<PublicKey> recipientList = optionalPrivacyGroup.map(privacyGroupManager::retrievePrivacyGroup).map(PrivacyGroup::getMembers).orElse(Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList()));
    final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(base64Decoder::decode).map(MessageHash::new).collect(Collectors.toSet());
    final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
    final PrivacyMode privacyMode = PrivacyMode.fromFlag(sendRequest.getPrivacyFlag());
    final com.quorum.tessera.transaction.SendRequest.Builder requestBuilder = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(privacyMode).withAffectedContractTransactions(affectedTransactions);
    optionalPrivacyGroup.ifPresentOrElse(requestBuilder::withPrivacyGroupId, () -> {
        PrivacyGroup legacyGroup = privacyGroupManager.createLegacyPrivacyGroup(sender, recipientList);
        requestBuilder.withPrivacyGroupId(legacyGroup.getId());
    });
    final com.quorum.tessera.transaction.SendResponse response = transactionManager.send(requestBuilder.build());
    final String encodedKey = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).get();
    final SendResponse sendResponse = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).map(messageHash -> new SendResponse(messageHash, null, null)).get();
    final URI location = UriBuilder.fromPath("transaction").path(URLEncoder.encode(encodedKey, StandardCharsets.UTF_8)).build();
    return Response.status(Response.Status.OK).type(APPLICATION_JSON).location(location).entity(sendResponse).build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) LoggerFactory(org.slf4j.LoggerFactory) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) PrivacyValid(com.quorum.tessera.api.constraint.PrivacyValid) Path(jakarta.ws.rs.Path) 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) Produces(jakarta.ws.rs.Produces) URI(java.net.URI) MessageHash(com.quorum.tessera.data.MessageHash) Schema(io.swagger.v3.oas.annotations.media.Schema) Consumes(jakarta.ws.rs.Consumes) Logger(org.slf4j.Logger) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) Hidden(io.swagger.v3.oas.annotations.Hidden) POST(jakarta.ws.rs.POST) com.quorum.tessera.api(com.quorum.tessera.api) Predicate(java.util.function.Predicate) TransactionManager(com.quorum.tessera.transaction.TransactionManager) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) URLEncoder(java.net.URLEncoder) Stream(java.util.stream.Stream) UriBuilder(jakarta.ws.rs.core.UriBuilder) Tag(io.swagger.v3.oas.annotations.tags.Tag) APPLICATION_JSON(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) MessageHash(com.quorum.tessera.data.MessageHash) URI(java.net.URI) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) Path(jakarta.ws.rs.Path) POST(jakarta.ws.rs.POST) Consumes(jakarta.ws.rs.Consumes) Produces(jakarta.ws.rs.Produces) Hidden(io.swagger.v3.oas.annotations.Hidden)

Example 14 with TransactionManager

use of com.quorum.tessera.transaction.TransactionManager in project tessera by ConsenSys.

the class TransactionResource3 method send.

// path /send is overloaded (application/json and application/vnd.tessera-2.1+json); swagger
// annotations cannot
// handle situations like this so this operation documents both
@Operation(summary = "/send", operationId = "encryptStoreAndSendJson", description = "encrypts a payload, stores result in database, and publishes result to recipients", requestBody = @RequestBody(content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendRequest.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = SendRequest.class)) }))
@ApiResponse(responseCode = "201", description = "encrypted payload hash", content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendResponse.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = SendResponse.class)) })
@ApiResponse(responseCode = "200", description = "hash returned when running in orion mode", content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendResponse.class)))
@POST
@Path("send")
@Consumes({ MIME_TYPE_JSON_2_1, MIME_TYPE_JSON_3 })
@Produces({ MIME_TYPE_JSON_2_1, MIME_TYPE_JSON_3 })
public Response send(@NotNull @Valid @PrivacyValid final SendRequest sendRequest) {
    final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
    final Optional<PrivacyGroup.Id> privacyGroupId = Optional.ofNullable(sendRequest.getPrivacyGroupId()).map(PrivacyGroup.Id::fromBase64String);
    final List<PublicKey> recipientList = privacyGroupId.map(privacyGroupManager::retrievePrivacyGroup).map(PrivacyGroup::getMembers).orElse(Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList()));
    final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(base64Decoder::decode).map(MessageHash::new).collect(Collectors.toSet());
    final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
    final PrivacyMode privacyMode = PrivacyMode.fromFlag(sendRequest.getPrivacyFlag());
    final com.quorum.tessera.transaction.SendRequest.Builder requestBuilder = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(privacyMode).withAffectedContractTransactions(affectedTransactions);
    privacyGroupId.ifPresent(requestBuilder::withPrivacyGroupId);
    final com.quorum.tessera.transaction.SendResponse response = transactionManager.send(requestBuilder.build());
    final String encodedKey = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).get();
    final String[] managedParties = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getManagedParties).orElse(Collections.emptySet()).stream().map(PublicKey::encodeToBase64).toArray(String[]::new);
    final SendResponse sendResponse = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).map(messageHash -> new SendResponse(messageHash, managedParties, sender.encodeToBase64())).get();
    final URI location = UriBuilder.fromPath("transaction").path(URLEncoder.encode(encodedKey, StandardCharsets.UTF_8)).build();
    return Response.created(location).entity(sendResponse).build();
}
Also used : SendSignedRequest(com.quorum.tessera.api.SendSignedRequest) MIME_TYPE_JSON_3(com.quorum.tessera.version.PrivacyGroupVersion.MIME_TYPE_JSON_3) PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) SendResponse(com.quorum.tessera.api.SendResponse) LoggerFactory(org.slf4j.LoggerFactory) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) PrivacyValid(com.quorum.tessera.api.constraint.PrivacyValid) Content(io.swagger.v3.oas.annotations.media.Content) Operation(io.swagger.v3.oas.annotations.Operation) Response(jakarta.ws.rs.core.Response) ReceiveResponse(com.quorum.tessera.api.ReceiveResponse) RequestBody(io.swagger.v3.oas.annotations.parameters.RequestBody) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse) MIME_TYPE_JSON_2_1(com.quorum.tessera.version.MultiTenancyVersion.MIME_TYPE_JSON_2_1) URI(java.net.URI) MessageHash(com.quorum.tessera.data.MessageHash) Schema(io.swagger.v3.oas.annotations.media.Schema) Pattern(jakarta.validation.constraints.Pattern) Logger(org.slf4j.Logger) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) ExampleObject(io.swagger.v3.oas.annotations.media.ExampleObject) Predicate(java.util.function.Predicate) TransactionManager(com.quorum.tessera.transaction.TransactionManager) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) jakarta.ws.rs(jakarta.ws.rs) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) ValidBase64(com.quorum.tessera.config.constraints.ValidBase64) Parameter(io.swagger.v3.oas.annotations.Parameter) ArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema) URLEncoder(java.net.URLEncoder) SendRequest(com.quorum.tessera.api.SendRequest) Stream(java.util.stream.Stream) MediaType(jakarta.ws.rs.core.MediaType) UriBuilder(jakarta.ws.rs.core.UriBuilder) Tag(io.swagger.v3.oas.annotations.tags.Tag) SendRequest(com.quorum.tessera.api.SendRequest) MessageHash(com.quorum.tessera.data.MessageHash) URI(java.net.URI) PublicKey(com.quorum.tessera.encryption.PublicKey) SendResponse(com.quorum.tessera.api.SendResponse) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) Operation(io.swagger.v3.oas.annotations.Operation) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse)

Example 15 with TransactionManager

use of com.quorum.tessera.transaction.TransactionManager in project tessera by ConsenSys.

the class P2PRestApp method getSingletons.

@Override
public Set<Object> getSingletons() {
    RuntimeContext runtimeContext = RuntimeContext.getInstance();
    List<URI> peers = runtimeContext.getPeers();
    LOGGER.debug("Found configured peers {}", peers);
    peers.stream().map(NodeUri::create).map(NodeUri::asURI).peek(u -> LOGGER.debug("Adding {} to party store", u)).forEach(partyStore::store);
    final PartyInfoResource partyInfoResource = new PartyInfoResource(discovery, partyInfoParser, runtimeContext.getP2pClient(), enclave, runtimeContext.isRemoteKeyValidation());
    final IPWhitelistFilter iPWhitelistFilter = new IPWhitelistFilter();
    final TransactionResource transactionResource = new TransactionResource(transactionManager, batchResendManager, legacyResendManager);
    final UpCheckResource upCheckResource = new UpCheckResource();
    final PrivacyGroupResource privacyGroupResource = new PrivacyGroupResource(privacyGroupManager);
    if (runtimeContext.isRecoveryMode()) {
        final RecoveryResource recoveryResource = new RecoveryResource(transactionManager, batchResendManager);
        return Set.of(partyInfoResource, iPWhitelistFilter, recoveryResource, upCheckResource);
    }
    return Set.of(partyInfoResource, iPWhitelistFilter, transactionResource, privacyGroupResource, upCheckResource);
}
Also used : PartyInfoParser(com.quorum.tessera.p2p.partyinfo.PartyInfoParser) AppType(com.quorum.tessera.config.AppType) Logger(org.slf4j.Logger) TransactionManager(com.quorum.tessera.transaction.TransactionManager) LoggerFactory(org.slf4j.LoggerFactory) BatchResendManager(com.quorum.tessera.recovery.workflow.BatchResendManager) Set(java.util.Set) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) NodeUri(com.quorum.tessera.discovery.NodeUri) PartyStore(com.quorum.tessera.p2p.partyinfo.PartyStore) Objects(java.util.Objects) Discovery(com.quorum.tessera.discovery.Discovery) ApplicationPath(jakarta.ws.rs.ApplicationPath) List(java.util.List) Stream(java.util.stream.Stream) UpCheckResource(com.quorum.tessera.api.common.UpCheckResource) GlobalFilter(com.quorum.tessera.api.filter.GlobalFilter) RuntimeContext(com.quorum.tessera.context.RuntimeContext) Enclave(com.quorum.tessera.enclave.Enclave) URI(java.net.URI) LegacyResendManager(com.quorum.tessera.recovery.workflow.LegacyResendManager) Collectors.toSet(java.util.stream.Collectors.toSet) IPWhitelistFilter(com.quorum.tessera.api.filter.IPWhitelistFilter) TesseraRestApplication(com.quorum.tessera.app.TesseraRestApplication) UpCheckResource(com.quorum.tessera.api.common.UpCheckResource) IPWhitelistFilter(com.quorum.tessera.api.filter.IPWhitelistFilter) NodeUri(com.quorum.tessera.discovery.NodeUri) RuntimeContext(com.quorum.tessera.context.RuntimeContext) URI(java.net.URI)

Aggregations

TransactionManager (com.quorum.tessera.transaction.TransactionManager)16 Logger (org.slf4j.Logger)9 LoggerFactory (org.slf4j.LoggerFactory)9 MessageHash (com.quorum.tessera.data.MessageHash)8 PrivacyMode (com.quorum.tessera.enclave.PrivacyMode)8 PublicKey (com.quorum.tessera.encryption.PublicKey)8 PrivacyGroupManager (com.quorum.tessera.privacygroup.PrivacyGroupManager)8 Response (jakarta.ws.rs.core.Response)8 java.util (java.util)8 Stream (java.util.stream.Stream)8 Operation (io.swagger.v3.oas.annotations.Operation)7 Content (io.swagger.v3.oas.annotations.media.Content)7 Schema (io.swagger.v3.oas.annotations.media.Schema)7 ApiResponse (io.swagger.v3.oas.annotations.responses.ApiResponse)7 Tag (io.swagger.v3.oas.annotations.tags.Tag)7 Valid (jakarta.validation.Valid)7 NotNull (jakarta.validation.constraints.NotNull)7 Collectors (java.util.stream.Collectors)7 URI (java.net.URI)6 PrivacyValid (com.quorum.tessera.api.constraint.PrivacyValid)5