9#include <unordered_map>
12 auto split(
const std::string& s,
const std::string& delim)
13 -> std::vector<std::string> {
16 std::vector<std::string> ret;
18 while((pos_end = s.find(delim, pos_start)) != std::string::npos) {
19 auto token = s.substr(pos_start, pos_end - pos_start);
20 pos_start = pos_end + delim.size();
21 ret.emplace_back(token);
24 ret.emplace_back(s.substr(pos_start));
29 -> std::optional<std::unordered_map<std::string, std::string>> {
30 auto opts = std::unordered_map<std::string, std::string>();
32 for(
size_t i = 1; i < args.size(); i++) {
33 const auto& arg = args[i];
34 auto arr =
split(arg,
"--");
35 if(arr.size() != 2 || !arr[0].empty() || arr[1].empty()) {
39 auto elems =
split(arr[1],
"=");
40 if(elems.size() != 2) {
44 opts.emplace(elems[0], elems[1]);
51 const std::string& component_name)
52 -> std::optional<std::vector<network::endpoint_t>> {
53 auto ret = std::vector<network::endpoint_t>();
55 auto count_key = component_name +
"_count";
56 auto it = opts.find(count_key);
57 if(it == opts.end()) {
60 auto count = std::stoull(it->second);
62 for(
size_t i = 0; i < count; i++) {
63 auto ep_key = component_name + std::to_string(i) +
"_endpoint";
64 it = opts.find(ep_key);
65 if(it == opts.end()) {
76 const std::unordered_map<std::string, std::string>& opts,
77 const std::string& component_name)
78 -> std::optional<std::vector<std::vector<network::endpoint_t>>> {
79 auto ret = std::vector<std::vector<network::endpoint_t>>();
81 auto count_key = component_name +
"_count";
82 auto it = opts.find(count_key);
83 if(it == opts.end()) {
86 auto count = std::stoull(it->second);
88 for(
size_t i = 0; i < count; i++) {
89 auto node_name = component_name + std::to_string(i);
91 if(!eps.has_value()) {
94 ret.emplace_back(eps.value());
100 auto read_config(
int argc,
char** argv) -> std::optional<config> {
103 if(!opts.has_value()) {
109 constexpr auto component_id_key =
"component_id";
110 auto it = opts->find(component_id_key);
111 if(it == opts->end()) {
117 constexpr auto loglevel_key =
"loglevel";
118 it = opts->find(loglevel_key);
119 if(it != opts->end()) {
121 if(maybe_loglevel.has_value()) {
122 cfg.m_loglevel = maybe_loglevel.value();
126 auto ticket_machine_endpoints
128 if(!ticket_machine_endpoints.has_value()) {
131 cfg.m_ticket_machine_endpoints = ticket_machine_endpoints.value();
133 constexpr auto node_id_key =
"node_id";
134 it = opts->find(node_id_key);
135 if(it != opts->end()) {
136 cfg.m_node_id = std::stoull(it->second);
140 if(!shard_endpoints.has_value()) {
143 cfg.m_shard_endpoints = shard_endpoints.value();
146 if(!agent_endpoints.has_value()) {
149 cfg.m_agent_endpoints = agent_endpoints.value();
151 constexpr auto loadgen_txtype_key =
"loadgen_txtype";
152 it = opts->find(loadgen_txtype_key);
153 if(it != opts->end()) {
154 const auto& val = it->second;
155 if(val ==
"transfer") {
157 }
else if(val ==
"erc20") {
164 cfg.m_contention_rate = 0.0;
165 constexpr auto contention_rate_key =
"contention_rate";
166 it = opts->find(contention_rate_key);
167 if(it != opts->end()) {
168 cfg.m_contention_rate = std::stod(it->second);
171 constexpr auto default_loadgen_accounts = 1000;
172 cfg.m_loadgen_accounts = default_loadgen_accounts;
173 constexpr auto loadgen_accounts_key =
"loadgen_accounts";
174 it = opts->find(loadgen_accounts_key);
175 if(it != opts->end()) {
176 cfg.m_loadgen_accounts = std::stoull(it->second);
179 constexpr auto runner_type_key =
"runner_type";
180 it = opts->find(runner_type_key);
181 if(it != opts->end()) {
182 const auto& val = it->second;
185 }
else if(val ==
"lua") {
195 auto put_row(
const std::shared_ptr<broker::interface>& broker,
198 const std::function<
void(
bool)>& result_callback) ->
bool {
199 auto begin_res = broker->begin([=](
auto begin_ret) {
200 if(!std::holds_alternative<
203 result_callback(
false);
208 = std::get<cbdc::parsec::ticket_machine::ticket_number_type>(
210 auto lock_res = broker->try_lock(
214 [=](
auto try_lock_res) {
215 if(!std::holds_alternative<cbdc::buffer>(try_lock_res)) {
216 result_callback(
false);
219 auto commit_res = broker->commit(
222 [=](
auto commit_ret) {
223 if(commit_ret.has_value()) {
224 result_callback(
false);
227 auto finish_res = broker->finish(
229 [=](
auto finish_ret) {
230 result_callback(!finish_ret.has_value());
233 result_callback(
false);
238 result_callback(
false);
243 result_callback(
false);
250 auto get_row(
const std::shared_ptr<broker::interface>& broker,
252 const std::function<
void(
256 std::promise<cbdc::parsec::broker::interface::try_lock_return_type>
258 auto res_future = res_promise.get_future();
260 auto finish_cb = [=](
auto finish_ret) {
261 if(finish_ret.has_value()) {
262 result_callback(finish_ret.value());
266 auto begin_cb = [&](
auto begin_ret) {
267 if(!std::holds_alternative<
270 res_promise.set_value(
272 ticket_number_assignment);
274 ticket_number_assignment);
279 = std::get<cbdc::parsec::ticket_machine::ticket_number_type>(
281 auto lock_res = broker->try_lock(
285 [&](
auto try_lock_res) {
286 if(!std::holds_alternative<cbdc::buffer>(try_lock_res)) {
287 res_promise.set_value(
291 error_code::shard_unreachable);
294 res_promise.set_value(try_lock_res);
295 result_callback(try_lock_res);
297 auto commit_cb = [=](
auto commit_ret) {
298 if(commit_ret.has_value()) {
299 if(std::holds_alternative<
301 error_code>(commit_ret.value())) {
305 commit_ret.value()));
310 shard_error>(commit_ret.value()));
314 = broker->finish(ticket_number, finish_cb);
317 error_code::finish_error);
322 auto commit_res = broker->commit(
329 error_code::commit_error);
341 [[maybe_unused]]
auto begin_success = broker->begin(begin_cb);
342 return res_future.get();
Buffer to store and retrieve byte data.
std::variant< value_type, error_code, runtime_locking_shard::shard_error > try_lock_return_type
Return type from a try lock operation.
error_code
Error codes returned by broker operations.
auto parse_ip_port(const std::string &in_str) -> network::endpoint_t
auto get_args(int argc, char **argv) -> std::vector< std::string >
Converts c-args from an executable's main function into a vector of strings.
@ trace
Fine-grained, fully verbose operating information.
auto parse_loglevel(const std::string &level) -> std::optional< log_level >
Parses a capitalized string into a log level.
std:: unordered_map< key_type, value_type, hashing::const_sip_hash< key_type > > state_update_type
Type for state updates to a shard. A map of keys and their new values.
@ read
Read lock. Multiple readers can hold a lock for the same key.
@ write
Write lock. Only one ticket can hold this lock at a time.
uint64_t ticket_number_type
Type alias for a ticket number.
@ evm
Ethereum-style transactions using EVM.
@ lua
Transaction semantics defined using Lua.
auto split(const std::string &s, const std::string &delim) -> std::vector< std::string >
auto put_row(const std::shared_ptr< broker::interface > &broker, broker::key_type key, broker::value_type value, const std::function< void(bool)> &result_callback) -> bool
Asynchronously inserts the given row into the cluster.
@ erc20
ERC20 token transfer.
@ transfer
Base token transfer.
auto read_endpoints(const std::unordered_map< std::string, std::string > &opts, const std::string &component_name) -> std::optional< std::vector< network::endpoint_t > >
auto parse_args(int argc, char **argv) -> std::optional< std::unordered_map< std::string, std::string > >
auto read_config(int argc, char **argv) -> std::optional< config >
Reads the configuration parameters from the program arguments.
auto get_row(const std::shared_ptr< broker::interface > &broker, broker::key_type key, const std::function< void(cbdc::parsec::broker::interface::try_lock_return_type)> &result_callback) -> cbdc::parsec::broker::interface::try_lock_return_type
Asynchronously get the value stored at key from the cluster.
auto read_cluster_endpoints(const std::unordered_map< std::string, std::string > &opts, const std::string &component_name) -> std::optional< std::vector< std::vector< network::endpoint_t > > >
Configuration parameters for a phase two system.
size_t m_component_id
ID of the component the instance should be.