Implementation for message handling

This commit is contained in:
chalith
2023-10-31 13:35:37 +05:30
parent 23ee18e454
commit f84a02ce09
18 changed files with 265 additions and 169 deletions

View File

@@ -59,10 +59,10 @@ add_executable(hpcore
src/ledger/ledger_sync.cpp
src/ledger/ledger_serve.cpp
src/ledger/ledger.cpp
src/hpsh/hpsh.cpp
src/status.cpp
src/consensus.cpp
src/main.cpp
src/hpsh/hpsh.cpp
)
target_link_libraries(hpcore
killswitch
@@ -78,7 +78,7 @@ target_link_libraries(hpcore
add_custom_command(TARGET hpcore POST_BUILD
# COMMAND strip ./build/hpcore
COMMAND rm -f ./build/hpws ./build/hpfs ./build/hpsh && cp ./test/bin/hpws ./test/bin/hpfs ./test/bin/hpsh ./build/
COMMAND cp ./test/bin/hpws ./test/bin/hpfs ./test/bin/hpsh ./build/
)
target_precompile_headers(hpcore PUBLIC src/pchheader.hpp)

View File

@@ -123,6 +123,9 @@ async function main() {
else if (inp === "stat") {
hpc.getStatus().then(stat => console.log(stat));
}
else if (inp.startsWith("hpsh ")) {
hpc.submitHpshRequest(inp.substr(5)).then(reply => console.log(reply));
}
else {
if (inp.startsWith("upload ")) {

View File

@@ -84,5 +84,42 @@ const echoContract = async (ctx) => {
// await ctx.updateConfig(config);
}
const fallback = async (ctx) => {
console.log("This is fallback mode");
const hpconfig = await ctx.getConfig();
for (const u of ctx.unl.list()) {
const gap = Math.abs(u.activeOn - ctx.timestamp);
// If last active timestamp is before the twice of roundtime, This node must be active.
if (u.activeOn && gap > (hpconfig.consensus.roundtime * 4)) {
console.log("Updating patch config", u);
hpconfig.unl = hpconfig.unl.filter(e => e !== u.publicKey);
await ctx.updateConfig(hpconfig);
}
}
// NPL messages example.
// Start listening to incoming NPL messages before we send ours.
const promise = new Promise((resolve, reject) => {
let timeout = setTimeout(() => {
reject('NPL timeout.');
}, 4000);
let list = [];
ctx.unl.onMessage((node, msg) => {
console.log(`${node.publicKey} said ${msg} to me.`);
list.push(msg);
if (list.length == ctx.unl.list().length) {
clearTimeout(timeout);
resolve();
}
});
});
await ctx.unl.send("Hello");
await promise;
}
const hpc = new HotPocket.Contract();
hpc.init(echoContract);

View File

@@ -194,6 +194,8 @@ namespace conf
cfg.log.loggers.emplace("console");
cfg.log.loggers.emplace("file");
cfg.hpsh.enabled = false;
// Save the default settings into the config file.
if (write_config(cfg) != 0)
return -1;
@@ -512,6 +514,28 @@ namespace conf
}
}
// hpsh
{
jpath = "hpsh";
try
{
const jsoncons::ojson &hpsh = d["hpsh"];
cfg.hpsh.enabled = hpsh["enabled"].as<bool>();
if (cfg.hpsh.run_as.from_string(hpsh["run_as"].as<std::string>()) == -1)
{
std::cerr << "Invalid format for hpsh run as config (\"uid>0:gid>0\" expected).\n";
return -1;
}
}
catch (const std::exception &e)
{
print_missing_field_error(jpath, e);
return -1;
}
}
return 0;
}
@@ -624,6 +648,14 @@ namespace conf
d.insert_or_assign("log", log_config);
}
// hpsh configs
{
jsoncons::ojson hpsh_config;
hpsh_config.insert_or_assign("enabled", cfg.hpsh.enabled);
hpsh_config.insert_or_assign("run_as", cfg.hpsh.run_as.to_string());
d.insert_or_assign("hpsh", hpsh_config);
}
return write_json_file(ctx.config_file, d);
}

View File

@@ -208,6 +208,12 @@ namespace conf
std::vector<std::string> runtime_env_args; // Contract environment variables.
};
struct hpsh_config
{
bool enabled = false; // Whether or not to enable hpsh.
ugid run_as; // The user/groups id to execute the hpsh as.
};
struct user_config
{
uint16_t port = 0; // Listening port for public user connections
@@ -317,6 +323,7 @@ namespace conf
hpfs_config hpfs;
log_config log;
health_config health; // For debugging only. Not included in the config file.
hpsh_config hpsh;
};
// Global contract context struct exposed to the application.

View File

@@ -2,27 +2,27 @@
namespace hpsh
{
constexpr const char *HPSH_EXEC_PATH = "./executable/hpsh";
constexpr int MAX_BUFFER_LEN = 1024;
constexpr int POLL_TIMEOUT = 1000;
constexpr uint32_t POLL_TIMEOUT = 1000;
constexpr uint32_t READ_BUFFER_SIZE = 128 * 1024;
hpsh_context ctx;
int init()
{
std::cout << "Initializing hpsh process.." << std::endl;
// Do not initialize if disabled in config.
if (!conf::cfg.hpsh.enabled)
return 0;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, ctx.control_fds) == -1)
{
std::cerr << errno << "Error initializing socket pair." << std::endl;
LOG_ERROR << errno << ": Error initializing socket pair.";
return -1;
}
ctx.hpsh_pid = fork();
if (ctx.hpsh_pid == -1)
{
std::cerr << errno << "Error forking." << std::endl;
LOG_ERROR << errno << ": Error forking.";
close(ctx.control_fds[0]);
close(ctx.control_fds[1]);
return -1;
@@ -39,27 +39,41 @@ namespace hpsh
close(ctx.control_fds[1]);
std::cout << "Starting hpsh process... " << std::endl;
std::string fd_str;
fd_str.resize(10);
snprintf(fd_str.data(), sizeof(fd_str), "%d", ctx.control_fds[0]);
char *argv[] = {(char *)conf::ctx.hpsh_exe_path.data(), fd_str.data(), NULL};
// Just before we execv the hpsh binary, we set user execution user/group if specified in hp config.
// (Must set gid before setting uid)
if (!conf::cfg.hpsh.run_as.empty() && (setgid(conf::cfg.hpsh.run_as.gid) == -1 || setuid(conf::cfg.hpsh.run_as.uid) == -1))
{
std::cerr << errno << ": Hpsh process setgid/uid failed."
<< "\n";
exit(1);
}
char *argv[] = {(char *)HPSH_EXEC_PATH, (char *)("-s1"), fd_str.data(), NULL};
execv(argv[0], argv);
std::cerr << errno << "Error executing hpfs." << std::endl;
std::cerr << errno << ": Error executing hpsh."
<< "\n";
close(ctx.control_fds[0]);
exit(EXIT_FAILURE);
exit(1);
}
ctx.is_initialized = true;
LOG_INFO << "Hpsh handler started.";
return 0;
}
void deinit()
{
std::cout << "De-initializing hpsh process.." << std::endl;
// This is not initialized if disabled in config.
if (!conf::cfg.hpsh.enabled)
return;
ctx.is_shutting_down = true;
@@ -89,7 +103,7 @@ namespace hpsh
}
}
std::cout << "Stopped hpsh process.." << std::endl;
LOG_INFO << "Hpsh handler stopped.";
}
int check_hpsh_exited(const bool block)
@@ -103,7 +117,7 @@ namespace hpsh
}
if (wait_res == -1)
{
std::cerr << errno << ": hpsh process waitpid error. pid:" << ctx.hpsh_pid << std::endl;
LOG_ERROR << errno << ": Hpsh process waitpid error. pid:" << ctx.hpsh_pid;
ctx.hpsh_pid = 0;
return -1;
}
@@ -113,18 +127,18 @@ namespace hpsh
if (WIFEXITED(scstatus))
{
std::cerr << "Contract process ended normally." << std::endl;
LOG_DEBUG << "Hpsh process ended normally.";
return 1;
}
else
{
std::cerr << "Contract process ended prematurely. Exit code " << WEXITSTATUS(scstatus) << std::endl;
LOG_WARNING << "Hpsh process ended prematurely. Exit code " << WEXITSTATUS(scstatus);
return -1;
}
}
}
int execute(std::string_view pubkey, std::string_view message)
int execute(std::string_view id, std::string_view pubkey, std::string_view message)
{
if (ctx.is_shutting_down)
return -1;
@@ -132,7 +146,7 @@ namespace hpsh
int child_fds[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, child_fds) == -1)
{
std::cerr << errno << "Error initializing socket pair." << std::endl;
LOG_ERROR << errno << ": Error initializing socket pair.";
return -1;
}
@@ -161,7 +175,7 @@ namespace hpsh
if (sendmsg(ctx.control_fds[1], &msg, 0) < 0)
{
std::cerr << errno << "Error writing to control fd." << std::endl;
LOG_ERROR << errno << ": Error writing to control fd.";
close(child_fds[0]);
close(child_fds[1]);
return -1;
@@ -169,7 +183,7 @@ namespace hpsh
if (write(child_fds[1], message.data(), sizeof(message)) < 0)
{
std::cerr << errno << "Error writing to child fd." << std::endl;
LOG_ERROR << errno << ": Error writing to child fd.";
close(child_fds[0]);
close(child_fds[1]);
return -1;
@@ -177,7 +191,7 @@ namespace hpsh
{
std::scoped_lock lock(ctx.command_mutex);
ctx.commands.push_back(command_context{std::string(pubkey), {child_fds[0], child_fds[1]}, std::string(), false});
ctx.commands.push_back(command_context{std::string(id), std::string(pubkey), {child_fds[0], child_fds[1]}, std::string(), false});
}
return 0;
@@ -203,7 +217,7 @@ namespace hpsh
if (poll(&pfd, 1, POLL_TIMEOUT) == -1)
{
std::cerr << errno << "Error in poll" << std::endl;
LOG_ERROR << errno << ": Error in poll";
continue;
}
else if (pfd.revents & POLLIN)
@@ -219,7 +233,7 @@ namespace hpsh
if (errno == EPIPE || errno == ECONNRESET)
itr->read_completed = true;
else
std::cerr << errno << "Error reading from fd" << std::endl;
LOG_ERROR << errno << ": Error reading from fd";
}
}
else
@@ -230,10 +244,20 @@ namespace hpsh
// Send command back to user;
if (itr->read_completed)
{
std::cout << "Received full output for user " << itr->pubkey << std::endl;
std::cout << itr->response.data() << std::endl;
{
std::scoped_lock<std::mutex> lock(usr::ctx.users_mutex);
std::list<command_context> collected_commands;
// Find the user session by user pubkey.
const auto user_itr = usr::ctx.users.find(itr->pubkey);
if (user_itr != usr::ctx.users.end()) // match found
{
const usr::connected_user &user = user_itr->second;
msg::usrmsg::usrmsg_parser parser(user.protocol);
std::vector<uint8_t> msg;
parser.create_hpsh_response_container(msg, itr->id, itr->response);
user.session.send(msg);
}
}
{
std::scoped_lock<std::mutex> lock(ctx.command_mutex);
itr = ctx.commands.erase(itr);

View File

@@ -1,27 +1,15 @@
#ifndef _HP_HPSH_
#define _HP_HPSH_
#include <sys/socket.h>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <signal.h>
#include <unordered_map>
#include <list>
#include <thread>
#include <poll.h>
#include <wait.h>
#include <mutex>
#include "util.hpp"
#include "../pchheader.hpp"
#include "../conf.hpp"
#include "../usr/usr.hpp"
namespace hpsh
{
struct command_context
{
std::string id;
std::string pubkey;
int child_fds[2];
std::string response;
@@ -36,6 +24,7 @@ namespace hpsh
int hpsh_pid;
std::thread watcher_thread;
bool is_shutting_down;
bool is_initialized = false;
};
extern hpsh_context ctx;
@@ -46,7 +35,7 @@ namespace hpsh
int check_hpsh_exited(const bool block);
int execute(std::string_view pubkey, std::string_view message);
int execute(std::string_view id, std::string_view pubkey, std::string_view message);
void response_watcher();
}

View File

@@ -1,45 +0,0 @@
#include "util.hpp"
namespace util
{
constexpr mode_t DIR_PERMS = 0755;
/**
* Sleeps the current thread for specified no. of milliseconds.
*/
void sleep(const uint64_t milliseconds)
{
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}
// Applies signal mask to the calling thread.
void mask_signal()
{
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
}
/**
* Clears signal mask and signal handlers from the caller.
* Called by other processes forked from hpcore threads so they get detatched from
* the hpcore signal setup.
*/
void fork_detach()
{
// Restore signal handlers to defaults.
signal(SIGINT, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGABRT, SIG_DFL);
// Remove any signal masks applied by hpcore.
sigset_t mask;
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
// Set process group id (so the terminal doesn't send kill signals to forked children).
setpgrp();
}
} // namespace util

View File

@@ -1,30 +0,0 @@
#ifndef _HP_UTIL_UTIL_
#define _HP_UTIL_UTIL_
#include <sys/socket.h>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <cstdlib>
#include <sstream>
#include <signal.h>
#include <unordered_map>
#include <vector>
#include <thread>
#include <poll.h>
/**
* Contains helper functions and data structures used by multiple other subsystems.
*/
namespace util
{
void sleep(const uint64_t milliseconds);
void mask_signal();
void fork_detach();
} // namespace util
#endif

View File

@@ -161,6 +161,31 @@ namespace msg::usrmsg::bson
encoder.flush();
}
/**
* Constructs a hpsh response message.
* @param msg Buffer to construct the generated bson message into.
* Message format:
* {
* "type": "hpsh_response",
* "reply_for": "<corresponding request id>",
* "content": <contract output>
* }
* @param content The contract binary output content to be put in the message.
*/
void create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content)
{
jsoncons::bson::bson_bytes_encoder encoder(msg);
encoder.begin_object();
encoder.key(msg::usrmsg::FLD_TYPE);
encoder.string_value(msg::usrmsg::MSGTYPE_HPSH_RESPONSE);
encoder.key(msg::usrmsg::FLD_REPLY_FOR);
encoder.string_value(reply_for);
encoder.key(msg::usrmsg::FLD_CONTENT);
encoder.byte_string_value(content);
encoder.end_object();
encoder.flush();
}
/**
* Constructs a contract read response message.
* @param msg Buffer to construct the generated bson message into.
@@ -196,7 +221,7 @@ namespace msg::usrmsg::bson
* "ledger_hash": <binary lcl hash>,
* "outputs": [<binary output 1>, <binary output 2>, ...], // The output order is the hash generation order.
* "output_hash": <binary hash of user's outputs>, [output hash = hash(pubkey+all outputs for the user)]
* "hash_tree": [<binary merkle hash tree for this round>], // Collapsed merkle tree with user's hash element marked as null.
* "hash_tree": [<binary merkle hash tree for this round>], // Collapsed merkle tree with user's hash element marked as null.
* "unl_sig": [["<pubkey>", "<sig>"], ...] // Binary UNL pubkeys and signatures of root hash.
* }
* @param hash This user's combined output hash. [output hash = hash(pubkey+all outputs for the user)]
@@ -466,7 +491,7 @@ namespace msg::usrmsg::bson
/**
* Extracts a contract read request message sent by user.
*
*
* @param extracted_content The content to be passed to the contract, extracted from the message.
* @param d The bson document holding the read request message.
* Accepted signed input container format:
@@ -497,30 +522,30 @@ namespace msg::usrmsg::bson
return 0;
}
/**
* Extracts a contract shell input message sent by user.
*
* @param extracted_content The content to be passed to the contract, extracted from the message.
* @param d The bson document holding the shell input message.
/**
* Extracts a hpsh input message sent by user.
*
* @param extracted_content The content to be passed to the hpsh, extracted from the message.
* @param d The bson document holding the hpsh input message.
* Accepted signed input container format:
* {
* "type": "contract_shell_input",
* "type": "hpsh_request",
* "id": "<any string>",
* "content": <binary buffer>
* }
* @return 0 on successful extraction. -1 for failure.
*/
int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d)
int extract_hpsh_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d)
{
if (!d.contains(msg::usrmsg::FLD_ID) || !d[msg::usrmsg::FLD_ID].is<std::string>())
{
LOG_DEBUG << "Shell input 'id' field missing or invalid.";
LOG_DEBUG << "Hpsh input 'id' field missing or invalid.";
return -1;
}
if (!d.contains(msg::usrmsg::FLD_CONTENT) || !d[msg::usrmsg::FLD_CONTENT].is_byte_string_view())
{
LOG_DEBUG << "Shell input 'content' field missing or invalid.";
LOG_DEBUG << "Hpsh input 'content' field missing or invalid.";
return -1;
}
@@ -532,9 +557,9 @@ namespace msg::usrmsg::bson
/**
* Extracts a signed input container message sent by user.
*
*
* @param extracted_input_container The input container extracted from the message.
* @param extracted_sig The binary signature extracted from the message.
* @param extracted_sig The binary signature extracted from the message.
* @param d The bson document holding the input container.
* Accepted signed input container format:
* {

View File

@@ -17,6 +17,8 @@ namespace msg::usrmsg::bson
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason,
std::string_view input_hash, const uint64_t ledger_seq_no, const util::h32 &ledger_hash);
void create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content);
void create_contract_read_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content);
void create_contract_output_container(std::vector<uint8_t> &msg, std::string_view hash, const ::std::vector<std::string> &outputs,
@@ -43,7 +45,7 @@ namespace msg::usrmsg::bson
int extract_read_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d);
int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d);
int extract_hpsh_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d);
int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig,
const jsoncons::ojson &d);

View File

@@ -34,7 +34,7 @@ namespace msg::usrmsg::json
* Constructs user challenge message json and the challenge string required for
* initial user challenge handshake. This gets called when a user establishes
* a web socket connection to HP.
*
*
* @param msg Buffer to construct the generated json message string into.
* Message format:
* {
@@ -84,7 +84,7 @@ namespace msg::usrmsg::json
/**
* Constructs server challenge response message json. This gets sent when we receive
* a challenge from the user.
*
*
* @param msg Buffer to construct the generated json message string into.
* Message format:
* {
@@ -325,6 +325,52 @@ namespace msg::usrmsg::json
msg += "\"}";
}
/**
* Constructs a hpsh response message.
* @param msg Buffer to construct the generated json message string into.
* Message format:
* {
* "type": "hpsh_response",
* "reply_for": "<corresponding request id>",
* "content": "<response string>"
* }
* @param content The contract binary output content to be put in the message.
*/
void create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content)
{
msg.reserve(content.size() + 256);
msg += "{\"";
msg += msg::usrmsg::FLD_TYPE;
msg += SEP_COLON;
msg += msg::usrmsg::MSGTYPE_HPSH_RESPONSE;
msg += SEP_COMMA;
msg += msg::usrmsg::FLD_REPLY_FOR;
msg += SEP_COLON;
msg += reply_for;
msg += SEP_COMMA;
msg += msg::usrmsg::FLD_CONTENT;
msg += SEP_COLON_NOQUOTE;
if (is_json_string(content))
{
// Process the final string using jsoncons.
jsoncons::json jstring = content;
jsoncons::json_options options;
options.escape_all_non_ascii(true);
std::string escaped_content;
jstring.dump(escaped_content);
msg += escaped_content;
}
else
{
msg += content;
}
msg += "}";
}
/**
* Constructs a contract read response message.
* @param msg Buffer to construct the generated json message string into.
@@ -381,7 +427,7 @@ namespace msg::usrmsg::json
* "ledger_hash": "<lcl hash hex>",
* "outputs": ["<output string 1>", "<output string 2>", ...], // The output order is the hash generation order.
* "output_hash": "<hex hash of user's outputs>", [output hash = hash(pubkey+all outputs for the user)]
* "hash_tree": [<hex merkle hash tree>], // Collapsed merkle tree with user's hash element marked as null.
* "hash_tree": [<hex merkle hash tree>], // Collapsed merkle tree with user's hash element marked as null.
* "unl_sig": [["<pubkey hex>", "<sig hex>"], ...] // UNL pubkeys and signatures of root hash.
* }
* @param hash This user's combined output hash. [output hash = hash(pubkey+all outputs for the user)]
@@ -566,12 +612,12 @@ namespace msg::usrmsg::json
* {
* "type": "health_event",
* "event": "proposal" | "connectivity",
*
*
* // proposal
* "comm_latency": {min:0, max:0, avg:0},
* "read_latency": {min:0, max:0, avg:0}
* "batch_size": 0
*
*
* // connectivity
* "peer_count": 0,
* "weakly_connected": true | false
@@ -697,7 +743,7 @@ namespace msg::usrmsg::json
/**
* Verifies the user handshake response with the original challenge issued to the user
* and the user public key contained in the response.
*
*
* @param extracted_pubkeyhex The hex public key extracted from the response.
* @param extracted_protocol The protocol code extracted from the response.
* @param extracted_server_challenge Any server challenge issued by user.
@@ -842,7 +888,7 @@ namespace msg::usrmsg::json
/**
* Extracts a contract read request message sent by user.
*
*
* @param extracted_content The content to be passed to the contract, extracted from the message.
* @param d The json document holding the read request message.
* Accepted signed input container format:
@@ -872,30 +918,30 @@ namespace msg::usrmsg::json
return 0;
}
/**
* Extracts a contract shell input message sent by user.
*
* @param extracted_content The content to be passed to the contract, extracted from the message.
* @param d The json document holding the shell input message.
/**
* Extracts a hpsh input message sent by user.
*
* @param extracted_content The content to be passed to the, extracted from the message.
* @param d The json document holding the hpsh input message.
* Accepted signed input container format:
* {
* "type": "contract_shell_input",
* "type": "hpsh_request",
* "id": "<any string>",
* "content": "<any string>"
* }
* @return 0 on successful extraction. -1 for failure.
*/
int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d)
int extract_hpsh_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d)
{
if (!d.contains(msg::usrmsg::FLD_ID) || !d[msg::usrmsg::FLD_ID].is<std::string>())
{
LOG_DEBUG << "Shell input 'id' field missing or invalid.";
LOG_DEBUG << "Hpsh input 'id' field missing or invalid.";
return -1;
}
if (!d.contains(msg::usrmsg::FLD_CONTENT) || !d[msg::usrmsg::FLD_CONTENT].is<std::string>())
{
LOG_DEBUG << "Shell input 'content' field missing or invalid.";
LOG_DEBUG << "Hpsh input 'content' field missing or invalid.";
return -1;
}
@@ -906,9 +952,9 @@ namespace msg::usrmsg::json
/**
* Extracts a signed input container message sent by user.
*
*
* @param extracted_input_container The input container extracted from the message.
* @param extracted_sig The binary signature extracted from the message.
* @param extracted_sig The binary signature extracted from the message.
* @param d The json document holding the input container.
* Accepted signed input container format:
* {

View File

@@ -21,6 +21,8 @@ namespace msg::usrmsg::json
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason,
std::string_view input_hash, const uint64_t ledger_seq_no, const util::h32 &ledger_hash);
void create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content);
void create_contract_read_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content);
void create_contract_output_container(std::vector<uint8_t> &msg, std::string_view hash, const ::std::vector<std::string> &outputs,
@@ -47,7 +49,7 @@ namespace msg::usrmsg::json
int extract_read_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d);
int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d);
int extract_hpsh_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d);
int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig,
const jsoncons::json &d);

View File

@@ -80,8 +80,8 @@ namespace msg::usrmsg
constexpr const char *MSGTYPE_SERVER_CHALLENGE_RESPONSE = "server_challenge_response";
constexpr const char *MSGTYPE_CONTRACT_READ_REQUEST = "contract_read_request";
constexpr const char *MSGTYPE_CONTRACT_READ_RESPONSE = "contract_read_response";
constexpr const char *MSGTYPE_CONTRACT_SHELL_INPUT = "contract_shell_input";
constexpr const char *MSGTYPE_CONTRACT_SHELL_OUTPUT = "contract_shell_output";
constexpr const char *MSGTYPE_HPSH_REQUEST = "hpsh_request";
constexpr const char *MSGTYPE_HPSH_RESPONSE = "hpsh_response";
constexpr const char *MSGTYPE_CONTRACT_INPUT = "contract_input";
constexpr const char *MSGTYPE_CONTRACT_INPUT_STATUS = "contract_input_status";
constexpr const char *MSGTYPE_CONTRACT_OUTPUT = "contract_output";

View File

@@ -38,6 +38,14 @@ namespace msg::usrmsg
busrmsg::create_contract_input_status(msg, status, reason, input_hash, ledger_seq_no, ledger_hash);
}
void usrmsg_parser::create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content) const
{
if (protocol == util::PROTOCOL::JSON)
jusrmsg::create_hpsh_response_container(msg, reply_for, content);
else
busrmsg::create_hpsh_response_container(msg, reply_for, content);
}
void usrmsg_parser::create_contract_read_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content) const
{
if (protocol == util::PROTOCOL::JSON)
@@ -121,12 +129,12 @@ namespace msg::usrmsg
return busrmsg::extract_read_request(extracted_id, extracted_content, bdoc);
}
int usrmsg_parser::extract_shell_input(std::string &extracted_id, std::string &extracted_content) const
int usrmsg_parser::extract_hpsh_request(std::string &extracted_id, std::string &extracted_content) const
{
if (protocol == util::PROTOCOL::JSON)
return jusrmsg::extract_shell_input(extracted_id, extracted_content, jdoc);
return jusrmsg::extract_hpsh_request(extracted_id, extracted_content, jdoc);
else
return busrmsg::extract_shell_input(extracted_id, extracted_content, bdoc);
return busrmsg::extract_hpsh_request(extracted_id, extracted_content, bdoc);
}
int usrmsg_parser::extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig) const

View File

@@ -26,6 +26,8 @@ namespace msg::usrmsg
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason,
std::string_view input_hash, const uint64_t ledger_seq_no, const util::h32 &ledger_hash) const;
void create_hpsh_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content) const;
void create_contract_read_response_container(std::vector<uint8_t> &msg, std::string_view reply_for, std::string_view content) const;
void create_contract_output_container(std::vector<uint8_t> &msg, std::string_view hash, const ::std::vector<std::string> &outputs,
@@ -49,7 +51,7 @@ namespace msg::usrmsg
int extract_read_request(std::string &extracted_id, std::string &extracted_content) const;
int extract_shell_input(std::string &extracted_id, std::string &extracted_content) const;
int extract_hpsh_request(std::string &extracted_id, std::string &extracted_content) const;
int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig) const;

View File

@@ -273,19 +273,13 @@ namespace usr
user.session.send(resp);
return 0;
}
else if (msg_type == msg::usrmsg::MSGTYPE_CONTRACT_SHELL_INPUT)
else if (msg_type == msg::usrmsg::MSGTYPE_HPSH_REQUEST)
{
std::string id, content;
if (parser.extract_shell_input(id, content) != -1)
if (hpsh::ctx.is_initialized && parser.extract_hpsh_request(id, content) != -1)
{
LOG_INFO << "shell input received:" << content;
// std::string response = hpsh::serve(content.c_str());
if (hpsh::execute(std::string("user_").append(std::to_string(1)), content.c_str()) == -1)
{
std::cout << "\nError sending message:" << content.c_str() << std::endl;
}
// LOG_INFO << "response: " << response;
if (hpsh::execute(id, user.pubkey, content.c_str()) == -1)
return -1;
return 0;
}

Binary file not shown.