Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method for emplacing lua contracts from CLI #269

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions src/parsec/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include <unordered_map>

namespace cbdc::parsec {
auto split(const std::string& s, const std::string& delim)
-> std::vector<std::string> {
auto split(const std::string& s,
const std::string& delim) -> std::vector<std::string> {
size_t pos_start{};
size_t pos_end{};
std::vector<std::string> ret;
Expand Down Expand Up @@ -192,6 +192,42 @@ namespace cbdc::parsec {
return cfg;
}

auto read_shard_info(int argc, char** argv) -> std::optional<config> {
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<config> {
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::interface>& broker,
broker::key_type key,
broker::value_type value,
Expand Down
12 changes: 12 additions & 0 deletions src/parsec/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ namespace cbdc::parsec {
/// while parsing the arguments.
auto read_config(int argc, char** argv) -> std::optional<config>;

/// 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<config>;

/// 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<config>;

/// 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.
Expand Down
16 changes: 16 additions & 0 deletions tools/bench/parsec/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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})
13 changes: 13 additions & 0 deletions tools/bench/parsec/lua/contract_to_bytecode.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function gen_bytecode(func)
c = string.dump(func, true)
tot = ""
for i = 1, string.len(c) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since strings are immutable, string concatenation in a for loop is generally discouraged due to inefficiency (it requires the creation of an entirely new string for each iteration).

It looks like Lua has a "string buffer" equivalent by using tables https://www.lua.org/pil/11.6.html and then just returning table.concat (PIL, pp. 110 and E 5.8 on pp. 41)

also it looks like you can just use the length operator # (PIL, pp. 24) rather than using a method call for the length

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
122 changes: 122 additions & 0 deletions tools/bench/parsec/lua/emplace_lua_contract.cpp
Original file line number Diff line number Diff line change
@@ -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 <future>
#include <lua.hpp>
#include <random>
#include <thread>

auto main(int argc, char** argv) -> int {
auto log = std::make_shared<cbdc::logging::log>(
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<cbdc::parsec::runtime_locking_shard::interface>>();

for(const auto& shard_ep : shard_cfg->m_shard_endpoints) {
auto client = std::make_shared<
cbdc::parsec::runtime_locking_shard::rpc::client>(
std::vector<cbdc::network::endpoint_t>{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<cbdc::parsec::ticket_machine::rpc::client>(
std::vector<cbdc::network::endpoint_t>{
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<cbdc::parsec::directory::impl>(shards.size());
auto broker = std::make_shared<cbdc::parsec::broker::impl>(
std::numeric_limits<size_t>::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<void>();
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;
}
Loading