OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
twophase_client.cpp
Go to the documentation of this file.
1// Copyright (c) 2021 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "twophase_client.hpp"
7
9
10namespace cbdc {
12 const cbdc::config::options& opts,
13 const std::shared_ptr<logging::log>& logger,
14 const std::string& wallet_file,
15 const std::string& client_file)
16 : client(opts, logger, wallet_file, client_file),
17 m_coordinator_client(opts.m_coordinator_endpoints[0]),
18 m_shard_status_client(opts.m_locking_shard_readonly_endpoints,
19 opts.m_shard_ranges,
20 m_client_timeout),
21 m_logger(logger),
22 m_opts(opts) {}
23
25 if(!m_coordinator_client.init()) {
26 m_logger->warn("Failed to initialize coordinator client");
27 }
28
29 if(!m_shard_status_client.init()) {
30 m_logger->warn("Failed to initialize shard status client");
31 }
32
33 return true;
34 }
35
36 auto twophase_client::sync() -> bool {
37 auto success = true;
38
39 auto txids = std::set<hash_t>();
40 for(const auto& [tx_id, tx] : pending_txs()) {
41 txids.insert(tx_id);
42 }
43 for(const auto& [tx_id, inp] : pending_inputs()) {
44 txids.insert(tx_id);
45 }
46
47 for(const auto& tx_id : txids) {
48 m_logger->debug("Requesting status of", to_string(tx_id));
49 auto res = m_shard_status_client.check_tx_id(tx_id);
50 if(!res.has_value()) {
51 m_logger->error("Timeout waiting for shard response");
52 success = false;
53 } else {
54 if(res.value()) {
55 m_logger->info(to_string(tx_id), "confirmed");
56 confirm_transaction(tx_id);
57 } else {
58 m_logger->info(to_string(tx_id), "not found");
59 }
60 }
61 }
62
63 return success;
64 }
65
67 -> std::optional<bool> {
68 return m_shard_status_client.check_tx_id(tx_id);
69 }
70
72 -> std::optional<bool> {
73 return m_shard_status_client.check_unspent(uhs_id);
74 }
75
77 -> bool {
78 auto ctx = transaction::compact_tx(mint_tx);
79 for(size_t i = 0; i < m_opts.m_attestation_threshold; i++) {
80 auto att
81 = ctx.sign(m_secp.get(), m_opts.m_sentinel_private_keys[i]);
82 ctx.m_attestations.insert(att);
83 }
84 auto done = std::promise<void>();
85 auto done_fut = done.get_future();
86 auto res = m_coordinator_client.execute_transaction(
87 ctx,
88 [&, tx_id = ctx.m_id](std::optional<bool> success) {
89 if(!success.has_value()) {
90 m_logger->error(
91 "Coordinator error processing transaction");
92 return;
93 }
94 if(!success.value()) {
95 m_logger->error("Coordinator rejected transaction");
96 return;
97 }
98 confirm_transaction(tx_id);
99 m_logger->info("Confirmed mint TX");
100 done.set_value();
101 });
102 if(!res) {
103 m_logger->error("Failed to send transaction to coordinator");
104 return false;
105 }
106 constexpr auto timeout = std::chrono::seconds(5);
107 auto maybe_timeout = done_fut.wait_for(timeout);
108 if(maybe_timeout == std::future_status::timeout) {
109 m_logger->error("Timed out waiting for mint response");
110 return false;
111 }
112 return res;
113 }
114}
External client for sending new transactions to the system.
auto check_unspent(const hash_t &uhs_id) -> std::optional< bool >
Checks the shard network for the status of a specific UHS ID.
auto sync() -> bool override
Update the client with the latest state from the shard network.
auto send_mint_tx(const transaction::full_tx &mint_tx) -> bool override
Sends the given mint transaction directly to a coordinator cluster.
auto check_tx_id(const hash_t &tx_id) -> std::optional< bool >
Checks the shard network for the status of a specific transaction.
auto init_derived() -> bool override
Initializes the 2PC architecture client.
std::array< unsigned char, cbdc::hash_size > hash_t
SHA256 hash container.
auto to_string(const hash_t &val) -> std::string
Converts a hash to a hexadecimal string.
Project-wide configuration options.
Definition config.hpp:132
A condensed, hash-only transaction representation.
A complete transaction.