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);
}
}
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();
}
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();
}
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();
}
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);
}
Aggregations