diff --git a/src/parsec/util.cpp b/src/parsec/util.cpp index 4ac830fa7..5efb2e64c 100644 --- a/src/parsec/util.cpp +++ b/src/parsec/util.cpp @@ -9,8 +9,8 @@ #include namespace cbdc::parsec { - auto split(const std::string& s, const std::string& delim) - -> std::vector { + auto split(const std::string& s, + const std::string& delim) -> std::vector { size_t pos_start{}; size_t pos_end{}; std::vector ret; @@ -192,6 +192,42 @@ namespace cbdc::parsec { return cfg; } + auto read_shard_info(int argc, char** argv) -> std::optional { + auto opts = parse_args(argc, argv); + if(!opts.has_value()) { + return std::nullopt; + } + + auto cfg = config{}; + + auto shard_endpoints = read_cluster_endpoints(opts.value(), "shard"); + if(!shard_endpoints.has_value()) { + return std::nullopt; + } + cfg.m_shard_endpoints = shard_endpoints.value(); + + return cfg; + } + + auto read_ticket_machine_info(int argc, + char** argv) -> std::optional { + auto opts = parse_args(argc, argv); + if(!opts.has_value()) { + return std::nullopt; + } + + auto cfg = config{}; + + auto ticket_machine_endpoints + = read_endpoints(opts.value(), "ticket_machine"); + if(!ticket_machine_endpoints.has_value()) { + return std::nullopt; + } + cfg.m_ticket_machine_endpoints = ticket_machine_endpoints.value(); + + return cfg; + } + auto put_row(const std::shared_ptr& broker, broker::key_type key, broker::value_type value, diff --git a/src/parsec/util.hpp b/src/parsec/util.hpp index 201b4e30c..7e6455300 100644 --- a/src/parsec/util.hpp +++ b/src/parsec/util.hpp @@ -60,6 +60,18 @@ namespace cbdc::parsec { /// while parsing the arguments. auto read_config(int argc, char** argv) -> std::optional; + /// Read configuration parameters releated to connecting to shards + /// \param argc number of program arguments + /// \param argv program arguments + /// \return shard related config params + auto read_shard_info(int argc, char** argv) -> std::optional; + + /// Read configuration parameters related to connecting to ticket machine + /// \param argc number of program arguments + /// \param argv program arguments + /// \return ticket machine related config params + auto read_ticket_machine_info(int argc, char** argv) -> std::optional; + /// Asynchronously inserts the given row into the cluster. /// \param broker broker to use for inserting the row. /// \param key key at which to insert value. diff --git a/tools/bench/parsec/lua/CMakeLists.txt b/tools/bench/parsec/lua/CMakeLists.txt index f7cf37121..bb6ffec92 100644 --- a/tools/bench/parsec/lua/CMakeLists.txt +++ b/tools/bench/parsec/lua/CMakeLists.txt @@ -1,5 +1,6 @@ add_executable(lua_bench lua_bench.cpp wallet.cpp) +add_executable(emplace_contract emplace_lua_contract.cpp) target_link_libraries(lua_bench broker directory runtime_locking_shard @@ -14,3 +15,18 @@ target_link_libraries(lua_bench broker secp256k1 ${LUA_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + +target_link_libraries(emplace_contract broker + directory + runtime_locking_shard + ticket_machine + parsec + agent + rpc + network + common + serialization + crypto + secp256k1 + ${LUA_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT}) diff --git a/tools/bench/parsec/lua/contract_to_bytecode.lua b/tools/bench/parsec/lua/contract_to_bytecode.lua new file mode 100644 index 000000000..cac4c7802 --- /dev/null +++ b/tools/bench/parsec/lua/contract_to_bytecode.lua @@ -0,0 +1,13 @@ +function gen_bytecode(func) + c = string.dump(func, true) + tot = "" + for i = 1, string.len(c) do + hex = string.format("%x", string.byte(c, i)) + if string.len(hex) < 2 then + hex = "0" .. hex + end + tot = tot .. hex + end + + return tot +end diff --git a/tools/bench/parsec/lua/emplace_lua_contract.cpp b/tools/bench/parsec/lua/emplace_lua_contract.cpp new file mode 100644 index 000000000..a4a2a2f9c --- /dev/null +++ b/tools/bench/parsec/lua/emplace_lua_contract.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2021 MIT Digital Currency Initiative, +// Federal Reserve Bank of Boston +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/sha256.h" +#include "parsec/agent/client.hpp" +#include "parsec/broker/impl.hpp" +#include "parsec/directory/impl.hpp" +#include "parsec/runtime_locking_shard/client.hpp" +#include "parsec/ticket_machine/client.hpp" +#include "parsec/util.hpp" +#include "wallet.hpp" + +#include +#include +#include +#include + +auto main(int argc, char** argv) -> int { + auto log = std::make_shared( + cbdc::logging::log_level::trace); + + if(argc < 2) { + log->error("Not enough arguments"); + return 1; + } + auto shard_cfg = cbdc::parsec::read_shard_info(argc - 3, argv); + if(!shard_cfg.has_value()) { + log->error("Error parsing shard options"); + return 1; + } + + auto ticket_machine_cfg + = cbdc::parsec::read_ticket_machine_info(argc - 3, argv); + if(!ticket_machine_cfg.has_value()) { + log->error("Error parsing ticket machine options"); + return 1; + } + + log->trace("Connecting to shards"); + + auto shards = std::vector< + std::shared_ptr>(); + + for(const auto& shard_ep : shard_cfg->m_shard_endpoints) { + auto client = std::make_shared< + cbdc::parsec::runtime_locking_shard::rpc::client>( + std::vector{shard_ep}); + if(!client->init()) { + log->error("Error connecting to shard"); + return 1; + } + shards.emplace_back(client); + } + + log->trace("Connected to shards"); + + log->trace("Connecting to ticket machine"); + auto ticketer + = std::make_shared( + std::vector{ + ticket_machine_cfg->m_ticket_machine_endpoints}); + if(!ticketer->init()) { + log->error("Error connecting to ticket machine"); + return 1; + } + log->trace("Connected to ticket machine"); + + auto directory + = std::make_shared(shards.size()); + auto broker = std::make_shared( + std::numeric_limits::max(), + shards, + ticketer, + directory, + log); + + auto args = cbdc::config::get_args(argc, argv); + auto compile_file = args[args.size() - 3]; + auto contract_file = args[args.size() - 2]; + auto func_name = args[args.size() - 1]; + + auto contract = cbdc::buffer(); + lua_State* L = luaL_newstate(); + luaL_openlibs(L); + luaL_dofile(L, compile_file.c_str()); + luaL_dofile(L, contract_file.c_str()); + + lua_getglobal(L, "gen_bytecode"); + lua_getglobal(L, func_name.c_str()); + + if(lua_pcall(L, 1, 1, 0) != 0) { + log->error("Contract bytecode generation failed, with error:", + lua_tostring(L, -1)); + return 1; + } + + contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); + log->trace(contract.to_hex()); + auto pay_contract_key = cbdc::buffer(); + pay_contract_key.append("con", 3); + + auto prom = std::promise(); + auto fut = prom.get_future(); + log->info("Inserting pay contract"); + auto ret = cbdc::parsec::put_row( + broker, + pay_contract_key, + contract, + [&](bool res) { + if(!res) { + log->error("failed to instert pay contract"); + } else { + log->info("Inserted pay contract"); + } + prom.set_value(); + }); + fut.get(); + log->trace(ret); + return 0; +}