diff --git a/CMakeLists.txt b/CMakeLists.txt index 125bcde0..2e31633c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,8 +75,8 @@ add_dependencies(hpcore ) add_custom_command(TARGET hpcore POST_BUILD - # COMMAND strip ./build/hpcore - # COMMAND strip ./build/appbill + COMMAND strip ./build/hpcore + COMMAND strip ./build/appbill COMMAND cp ./test/bin/websocketd ./test/bin/websocat ./test/bin/hpfs ./build/ ) diff --git a/examples/echo_contract/contract.js b/examples/echo_contract/contract.js index 65c2dfea..c15cb925 100644 --- a/examples/echo_contract/contract.js +++ b/examples/echo_contract/contract.js @@ -13,9 +13,9 @@ fs.appendFileSync("exects.txt", "ts:" + hpargs.ts + "\n"); Object.keys(hpargs.usrfd).forEach(function (key, index) { let userfds = hpargs.usrfd[key]; - let userinput = fs.readFileSync(userfds[0], 'utf8'); - if (userinput.length > 0) { + if (userfds[0] != -1) { + let userinput = fs.readFileSync(userfds[0], 'utf8'); // Append user input to a state file. fs.appendFileSync("userinputs.txt", userinput + "\n"); fs.writeSync(userfds[1], "Echoing: " + userinput); diff --git a/examples/file_contract/contract.js b/examples/file_contract/contract.js index 3c212817..0e4d7e7e 100644 --- a/examples/file_contract/contract.js +++ b/examples/file_contract/contract.js @@ -13,9 +13,11 @@ fs.appendFileSync("exects.txt", "ts:" + hpargs.ts + "\n"); Object.keys(hpargs.usrfd).forEach(function (key, index) { let userfds = hpargs.usrfd[key]; - let fileContent = fs.readFileSync(userfds[0]); - if (fileContent.length > 0) { + if (userfds[0] != -1) { + + let fileContent = fs.readFileSync(userfds[0]); + // Save the content into a new file. var fileName = new Date().getTime().toString(); fs.writeFileSync(fileName, fileContent); diff --git a/examples/hpclient/file-client.js b/examples/hpclient/file-client.js index 7bf12c64..0d85a9ee 100644 --- a/examples/hpclient/file-client.js +++ b/examples/hpclient/file-client.js @@ -51,12 +51,9 @@ function main() { function create_input_container(inp) { - let hexInp = inp.toString('hex'); - console.log("hex " + hexInp.length); - let inp_container = { nonce: (new Date()).getTime().toString(), - input: hexInp, + input: inp.toString('hex'), max_ledger_seqno: 9999999 } let inp_container_bytes = JSON.stringify(inp_container); diff --git a/src/comm/comm_server.cpp b/src/comm/comm_server.cpp index 5cf35a9d..b01e99ab 100644 --- a/src/comm/comm_server.cpp +++ b/src/comm/comm_server.cpp @@ -22,7 +22,8 @@ namespace comm watchdog_thread = std::thread( &comm_server::connection_watchdog, this, accept_fd, session_type, is_binary, std::ref(metric_thresholds), req_known_remotes, max_msg_size); - return start_websocketd_process(port, domain_socket_name, is_binary, use_size_header); + return start_websocketd_process(port, domain_socket_name, is_binary, + use_size_header, max_msg_size); } return -1; @@ -255,7 +256,9 @@ namespace comm } } - int comm_server::start_websocketd_process(const uint16_t port, const char *domain_socket_name, const bool is_binary, const bool use_size_header) + int comm_server::start_websocketd_process( + const uint16_t port, const char *domain_socket_name, + const bool is_binary, const bool use_size_header, const uint64_t max_msg_size) { // setup pipe for firewall int firewall_pipe[2]; // parent to child pipe @@ -299,10 +302,10 @@ namespace comm dup2(firewall_pipe[0], 0); } - // Override stdout in the child's file table with /dev/null - // int null_fd = open("/dev/null", O_WRONLY); - // if (null_fd) - // dup2(null_fd, 1); + std::string max_frame = std::string("--maxframe=") + .append(use_size_header + ? "4294967296" // 4GB + : std::to_string(max_msg_size)); // Fill process args. char *execv_args[] = { @@ -316,6 +319,7 @@ namespace comm conf::ctx.tls_key_file.data(), (char *)(is_binary ? "--binary=true" : "--binary=false"), (char *)(use_size_header ? "--sizeheader=true" : "--sizeheader=false"), + max_frame.data(), (char *)"--loglevel=error", (char *)"nc", // netcat (OpenBSD) is used for domain socket redirection. (char *)"-U", // Use UNIX domain socket diff --git a/src/comm/comm_server.hpp b/src/comm/comm_server.hpp index 53500d82..b9008a03 100644 --- a/src/comm/comm_server.hpp +++ b/src/comm/comm_server.hpp @@ -8,42 +8,44 @@ namespace comm { -class comm_server -{ - pid_t websocketd_pid = 0; - int firewall_out = -1; // at some point we may want to listen for firewall_in but at the moment unimplemented - std::thread watchdog_thread; - bool should_stop_listening = false; + class comm_server + { + pid_t websocketd_pid = 0; + int firewall_out = -1; // at some point we may want to listen for firewall_in but at the moment unimplemented + std::thread watchdog_thread; + bool should_stop_listening = false; - int open_domain_socket(const char *domain_socket_name); + int open_domain_socket(const char *domain_socket_name); - void connection_watchdog( - const int accept_fd, const SESSION_TYPE session_type, const bool is_binary, - const uint64_t (&metric_thresholds)[4], const std::set &eq_known_remotes, const uint64_t max_msg_size); + void connection_watchdog( + const int accept_fd, const SESSION_TYPE session_type, const bool is_binary, + const uint64_t (&metric_thresholds)[4], const std::set &eq_known_remotes, const uint64_t max_msg_size); - int start_websocketd_process(const uint16_t port, const char *domain_socket_name, const bool is_binary, const bool use_size_header); + int start_websocketd_process( + const uint16_t port, const char *domain_socket_name, + const bool is_binary, const bool use_size_header, const uint64_t max_msg_size); - int poll_fds(pollfd *pollfds, const int accept_fd, const std::unordered_map &sessions); + int poll_fds(pollfd *pollfds, const int accept_fd, const std::unordered_map &sessions); - void check_for_new_connection( - std::unordered_map &sessions, const int accept_fd, - const SESSION_TYPE session_type, const bool is_binary, const uint64_t (&metric_thresholds)[4]); + void check_for_new_connection( + std::unordered_map &sessions, const int accept_fd, + const SESSION_TYPE session_type, const bool is_binary, const uint64_t (&metric_thresholds)[4]); - void maintain_known_connections( - std::unordered_map &sessions, std::unordered_map &outbound_clients, - const std::set &req_known_remotes, const SESSION_TYPE session_type, const bool is_binary, - const uint64_t max_msg_size, const uint64_t (&metric_thresholds)[4]); + void maintain_known_connections( + std::unordered_map &sessions, std::unordered_map &outbound_clients, + const std::set &req_known_remotes, const SESSION_TYPE session_type, const bool is_binary, + const uint64_t max_msg_size, const uint64_t (&metric_thresholds)[4]); - std::string get_cgi_ip(const int fd); + std::string get_cgi_ip(const int fd); -public: - // Start accepting incoming connections - int start( - const uint16_t port, const char *domain_socket_name, const SESSION_TYPE session_type, const bool is_binary, const bool use_size_header, - const uint64_t (&metric_thresholds)[4], const std::set &req_known_remotes, const uint64_t max_msg_size); - void stop(); - void firewall_ban(std::string_view ip, const bool unban); -}; + public: + // Start accepting incoming connections + int start( + const uint16_t port, const char *domain_socket_name, const SESSION_TYPE session_type, const bool is_binary, const bool use_size_header, + const uint64_t (&metric_thresholds)[4], const std::set &req_known_remotes, const uint64_t max_msg_size); + void stop(); + void firewall_ban(std::string_view ip, const bool unban); + }; } // namespace comm diff --git a/src/fbschema/p2pmsg_helpers.cpp b/src/fbschema/p2pmsg_helpers.cpp index 765fd1a8..e08f8cbc 100644 --- a/src/fbschema/p2pmsg_helpers.cpp +++ b/src/fbschema/p2pmsg_helpers.cpp @@ -12,9 +12,13 @@ namespace fbschema::p2pmsg { -constexpr size_t PEERCHALLENGE_LEN = 16; + // Length of a peer connection challange. + constexpr size_t PEERCHALLENGE_LEN = 16; -/** + // Max size of messages which are subjected to time (too old) check. + constexpr size_t MAX_SIZE_FOR_TIME_CHECK = 10 * 1024 * 1024; // 10 MB + + /** * This section contains Flatbuffer message reading/writing helpers. * These helpers are mainly used by peer_session_handler. * @@ -29,9 +33,9 @@ constexpr size_t PEERCHALLENGE_LEN = 16; * received data and then interprit the 'Content' portion of it separately to read the actual content. */ -//---Message validation helpers---/ + //---Message validation helpers---/ -/** + /** * Verifies Conatiner message structure and outputs faltbuffer Container pointer to access the given buffer. * * @param container_ref A pointer reference to assign the pointer to the Container object. @@ -39,82 +43,85 @@ constexpr size_t PEERCHALLENGE_LEN = 16; * via the container pointer. * @return 0 on successful verification. -1 for failure. */ -int validate_and_extract_container(const Container **container_ref, std::string_view container_buf) -{ - //Accessing message buffer - const uint8_t *container_buf_ptr = reinterpret_cast(container_buf.data()); - const size_t container_buf_size = container_buf.length(); - - //Defining Flatbuffer verifier (default max depth = 64, max_tables = 1000000,) - flatbuffers::Verifier container_verifier(container_buf_ptr, container_buf_size); - - //Verify container message using flatbuffer verifier - if (!VerifyContainerBuffer(container_verifier)) + int validate_and_extract_container(const Container **container_ref, std::string_view container_buf) { - LOG_DBG << "Flatbuffer verify: Bad peer message container."; - return -1; + //Accessing message buffer + const uint8_t *container_buf_ptr = reinterpret_cast(container_buf.data()); + const size_t container_buf_size = container_buf.length(); + + //Defining Flatbuffer verifier (default max depth = 64, max_tables = 1000000,) + flatbuffers::Verifier container_verifier(container_buf_ptr, container_buf_size); + + //Verify container message using flatbuffer verifier + if (!VerifyContainerBuffer(container_verifier)) + { + LOG_DBG << "Flatbuffer verify: Bad peer message container."; + return -1; + } + + //Get message container + const Container *container = GetContainer(container_buf_ptr); + + //check protocol version of message whether it is greater than minimum supported protocol version. + const uint16_t version = container->version(); + if (version < util::MIN_PEERMSG_VERSION) + { + LOG_DBG << "Peer message is from unsupported protocol version (" << version << ")."; + return -1; + } + + //check message timestamp (ignore this for large messages). + if (container_buf_size <= MAX_SIZE_FOR_TIME_CHECK) + { + const int64_t time_now = util::get_epoch_milliseconds(); + if (container->timestamp() < (time_now - conf::cfg.roundtime * 4)) + { + LOG_DBG << "Peer message is too old."; + return -1; + } + } + + //Assign container and content out params. + *container_ref = container; + return 0; } - //Get message container - const Container *container = GetContainer(container_buf_ptr); - - //check protocol version of message whether it is greater than minimum supported protocol version. - const uint16_t version = container->version(); - if (version < util::MIN_PEERMSG_VERSION) - { - LOG_DBG << "Peer message is from unsupported protocol version (" << version << ")."; - return -1; - } - - //check message timestamp. - const int64_t time_now = util::get_epoch_milliseconds(); - if (container->timestamp() < (time_now - conf::cfg.roundtime * 4)) - { - LOG_DBG << "Peer message is too old."; - return -1; - } - - //Assign container and content out params. - *container_ref = container; - return 0; -} - -/** + /** * Validates the container message signing keys to see if the message is from a trusted source (UNL). * @return 0 on successful verification. -1 for failure. */ -int validate_container_trust(const Container *container) -{ - std::string_view msg_pubkey = flatbuff_bytes_to_sv(container->pubkey()); - std::string_view msg_sig = flatbuff_bytes_to_sv(container->signature()); - - if (msg_pubkey.empty() || msg_sig.empty()) + int validate_container_trust(const Container *container) { - LOG_DBG << "Peer message key pair incomplete. Trust verification failed."; - return -1; + std::string_view msg_pubkey = flatbuff_bytes_to_sv(container->pubkey()); + std::string_view msg_sig = flatbuff_bytes_to_sv(container->signature()); + + if (msg_pubkey.empty() || msg_sig.empty()) + { + LOG_DBG << "Peer message key pair incomplete. Trust verification failed."; + return -1; + } + + //validate if the message is not from a node of current node's unl list. + if (!conf::cfg.unl.count(std::string(msg_pubkey))) + { + LOG_DBG << "Peer message pubkey verification failed. Not in UNL."; + return -1; + } + + //verify message signature. + //this is performed towards end since this is bit expensive + std::string_view msg_content = flatbuff_bytes_to_sv(container->content()); + + if (crypto::verify(msg_content, msg_sig, msg_pubkey) != 0) + { + LOG_DBG << "Peer message signature verification failed."; + return -1; + } + + return 0; } - //validate if the message is not from a node of current node's unl list. - if (!conf::cfg.unl.count(std::string(msg_pubkey))) - { - LOG_DBG << "Peer message pubkey verification failed. Not in UNL."; - return -1; - } - - //verify message signature. - //this is performed towards end since this is bit expensive - std::string_view msg_content = flatbuff_bytes_to_sv(container->content()); - - if (crypto::verify(msg_content, msg_sig, msg_pubkey) != 0) - { - LOG_DBG << "Peer message signature verification failed."; - return -1; - } - - return 0; -} - -/** + /** * Verifies the Content message structure and outputs faltbuffer Content pointer to access the given buffer. * * @param content_ref A pointer reference to assign the pointer to the Content object. @@ -123,353 +130,353 @@ int validate_container_trust(const Container *container) * @param content_size Data buffer size. * @return 0 on successful verification. -1 for failure. */ -int validate_and_extract_content(const Content **content_ref, const uint8_t *content_ptr, const flatbuffers::uoffset_t content_size) -{ - //Defining Flatbuffer verifier for message content verification. - //Since content is also serialised by using Flatbuffer we can verify it using Flatbuffer. - flatbuffers::Verifier content_verifier(content_ptr, content_size); - - //verify content message using flatbuffer verifier. - if (!VerifyContainerBuffer(content_verifier)) + int validate_and_extract_content(const Content **content_ref, const uint8_t *content_ptr, const flatbuffers::uoffset_t content_size) { - LOG_DBG << "Flatbuffer verify: Bad content."; - return -1; + //Defining Flatbuffer verifier for message content verification. + //Since content is also serialised by using Flatbuffer we can verify it using Flatbuffer. + flatbuffers::Verifier content_verifier(content_ptr, content_size); + + //verify content message using flatbuffer verifier. + if (!VerifyContainerBuffer(content_verifier)) + { + LOG_DBG << "Flatbuffer verify: Bad content."; + return -1; + } + + *content_ref = GetContent(content_ptr); + return 0; } - *content_ref = GetContent(content_ptr); - return 0; -} + //---Message reading helpers---/ -//---Message reading helpers---/ - -/** + /** * Returns challenge from the peer challenge message. * @param The Flatbuffer peer challenge message received from the peer. * @return binary challenge. */ -const std::string_view get_peer_challenge_from_msg(const Peer_Challenge_Message &msg) -{ - return flatbuff_bytes_to_sv(msg.challenge()); -} + const std::string_view get_peer_challenge_from_msg(const Peer_Challenge_Message &msg) + { + return flatbuff_bytes_to_sv(msg.challenge()); + } -/** + /** * Creates a peer challenge response struct from the given peer challenge response message. * @param The Flatbuffer peer challenge response message received from the peer. * @return A peer challenge response struct representing the message. */ -const p2p::peer_challenge_response create_peer_challenge_response_from_msg(const Peer_Challenge_Response_Message &msg, const flatbuffers::Vector *pubkey) -{ - p2p::peer_challenge_response pchalresp; + const p2p::peer_challenge_response create_peer_challenge_response_from_msg(const Peer_Challenge_Response_Message &msg, const flatbuffers::Vector *pubkey) + { + p2p::peer_challenge_response pchalresp; - pchalresp.challenge = flatbuff_bytes_to_sv(msg.challenge()); - pchalresp.signature = flatbuff_bytes_to_sv(msg.sig()); - pchalresp.pubkey = flatbuff_bytes_to_sv(pubkey); + pchalresp.challenge = flatbuff_bytes_to_sv(msg.challenge()); + pchalresp.signature = flatbuff_bytes_to_sv(msg.sig()); + pchalresp.pubkey = flatbuff_bytes_to_sv(pubkey); - return pchalresp; -} + return pchalresp; + } -/** + /** * Creates a non-unl proposal stuct from the given non-unl proposal message. * @param The Flatbuffer non-unl poporal received from the peer. * @return A non-unl proposal struct representing the message. */ -const p2p::nonunl_proposal create_nonunl_proposal_from_msg(const NonUnl_Proposal_Message &msg, const uint64_t timestamp) -{ - p2p::nonunl_proposal nup; + const p2p::nonunl_proposal create_nonunl_proposal_from_msg(const NonUnl_Proposal_Message &msg, const uint64_t timestamp) + { + p2p::nonunl_proposal nup; - if (msg.usermessages()) - nup.user_messages = flatbuf_usermsgsmap_to_usermsgsmap(msg.usermessages()); + if (msg.usermessages()) + nup.user_messages = flatbuf_usermsgsmap_to_usermsgsmap(msg.usermessages()); - return nup; -} + return nup; + } -/** + /** * Creates a history response stuct from the given histrory response message. * @param msg Flatbuffer History response message received from the peer. * @return A History response struct representing the message. */ -const p2p::history_response create_history_response_from_msg(const History_Response_Message &msg) -{ - p2p::history_response hr; + const p2p::history_response create_history_response_from_msg(const History_Response_Message &msg) + { + p2p::history_response hr; - if (msg.hist_ledgers()) - hr.hist_ledgers = flatbuf_historyledgermap_to_historyledgermap(msg.hist_ledgers()); + if (msg.hist_ledgers()) + hr.hist_ledgers = flatbuf_historyledgermap_to_historyledgermap(msg.hist_ledgers()); - if (msg.error()) - hr.error = (p2p::LEDGER_RESPONSE_ERROR)msg.error(); + if (msg.error()) + hr.error = (p2p::LEDGER_RESPONSE_ERROR)msg.error(); - return hr; -} + return hr; + } -/** + /** * Creates a proposal stuct from the given proposal message. * @param The Flatbuffer poposal received from the peer. * @return A proposal struct representing the message. */ -const p2p::proposal create_proposal_from_msg(const Proposal_Message &msg, const flatbuffers::Vector *pubkey, const uint64_t timestamp, const flatbuffers::Vector *lcl) -{ - p2p::proposal p; + const p2p::proposal create_proposal_from_msg(const Proposal_Message &msg, const flatbuffers::Vector *pubkey, const uint64_t timestamp, const flatbuffers::Vector *lcl) + { + p2p::proposal p; - p.pubkey = flatbuff_bytes_to_sv(pubkey); - p.timestamp = timestamp; - p.time = msg.time(); - p.stage = msg.stage(); - p.lcl = flatbuff_bytes_to_sv(lcl); - p.curr_state_hash = flatbuff_bytes_to_sv(msg.curr_state_hash()); + p.pubkey = flatbuff_bytes_to_sv(pubkey); + p.timestamp = timestamp; + p.time = msg.time(); + p.stage = msg.stage(); + p.lcl = flatbuff_bytes_to_sv(lcl); + p.curr_state_hash = flatbuff_bytes_to_sv(msg.curr_state_hash()); - if (msg.users()) - p.users = flatbuf_bytearrayvector_to_stringlist(msg.users()); + if (msg.users()) + p.users = flatbuf_bytearrayvector_to_stringlist(msg.users()); - if (msg.hash_inputs()) - p.hash_inputs = flatbuf_bytearrayvector_to_stringlist(msg.hash_inputs()); + if (msg.hash_inputs()) + p.hash_inputs = flatbuf_bytearrayvector_to_stringlist(msg.hash_inputs()); - if (msg.hash_outputs()) - p.hash_outputs = flatbuf_bytearrayvector_to_stringlist(msg.hash_outputs()); + if (msg.hash_outputs()) + p.hash_outputs = flatbuf_bytearrayvector_to_stringlist(msg.hash_outputs()); - return p; -} + return p; + } -/** + /** * Creates a history request struct from the given history request message. * @param msg Flatbuffer History request message received from the peer. * @return A History request struct representing the message. */ -const p2p::history_request create_history_request_from_msg(const History_Request_Message &msg) -{ - p2p::history_request hr; + const p2p::history_request create_history_request_from_msg(const History_Request_Message &msg) + { + p2p::history_request hr; - if (msg.minimum_lcl()) - hr.minimum_lcl = flatbuff_bytes_to_sv(msg.minimum_lcl()); + if (msg.minimum_lcl()) + hr.minimum_lcl = flatbuff_bytes_to_sv(msg.minimum_lcl()); - if (msg.required_lcl()) - hr.required_lcl = flatbuff_bytes_to_sv(msg.required_lcl()); + if (msg.required_lcl()) + hr.required_lcl = flatbuff_bytes_to_sv(msg.required_lcl()); - return hr; -} + return hr; + } -/** + /** * Creates a state request struct from the given state request message. * @param msg Flatbuffer State request message received from the peer. * @return A State request struct representing the message. */ -const p2p::state_request create_state_request_from_msg(const State_Request_Message &msg) -{ - p2p::state_request sr; + const p2p::state_request create_state_request_from_msg(const State_Request_Message &msg) + { + p2p::state_request sr; - sr.block_id = msg.block_id(); - sr.is_file = msg.is_file(); - sr.parent_path = flatbuff_str_to_sv(msg.parent_path()); - sr.expected_hash = flatbuff_bytes_to_hash(msg.expected_hash()); + sr.block_id = msg.block_id(); + sr.is_file = msg.is_file(); + sr.parent_path = flatbuff_str_to_sv(msg.parent_path()); + sr.expected_hash = flatbuff_bytes_to_hash(msg.expected_hash()); - return sr; -} + return sr; + } -/** + /** * Creates a block response struct from the given block response message. * @param msg Flatbuffer block response message received from the peer. * @return A Block response struct representing the message. */ -const p2p::block_response create_block_response_from_msg(const Block_Response &msg) -{ - p2p::block_response br; + const p2p::block_response create_block_response_from_msg(const Block_Response &msg) + { + p2p::block_response br; - br.path = flatbuff_str_to_sv(msg.path()); - br.block_id = msg.block_id(); - br.data = flatbuff_bytes_to_sv(msg.data()); - return br; -} + br.path = flatbuff_str_to_sv(msg.path()); + br.block_id = msg.block_id(); + br.data = flatbuff_bytes_to_sv(msg.data()); + return br; + } -//---Message creation helpers---// + //---Message creation helpers---// -/** + /** * Create peer challenge message from the given challenge. * @param container_builder Flatbuffer builder for the container message. * @param challenge Challenge message needed to convert to flatbuffer message. */ -void create_msg_from_peer_challenge(flatbuffers::FlatBufferBuilder &container_builder, std::string &challenge) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_peer_challenge(flatbuffers::FlatBufferBuilder &container_builder, std::string &challenge) + { + flatbuffers::FlatBufferBuilder builder(1024); - // We calculate the peer challenge to be a random string. - // Use libsodium to generate the random challenge bytes. - challenge.resize(PEERCHALLENGE_LEN); - randombytes_buf(challenge.data(), PEERCHALLENGE_LEN); + // We calculate the peer challenge to be a random string. + // Use libsodium to generate the random challenge bytes. + challenge.resize(PEERCHALLENGE_LEN); + randombytes_buf(challenge.data(), PEERCHALLENGE_LEN); - const flatbuffers::Offset peer_challenge_msg = - CreatePeer_Challenge_Message( - builder, - sv_to_flatbuff_bytes(builder, challenge)); + const flatbuffers::Offset peer_challenge_msg = + CreatePeer_Challenge_Message( + builder, + sv_to_flatbuff_bytes(builder, challenge)); - const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Message, peer_challenge_msg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Message, peer_challenge_msg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message - create_containermsg_from_content(container_builder, builder, nullptr, false); -} + // Now that we have built the content message + create_containermsg_from_content(container_builder, builder, nullptr, false); + } -/** + /** * Create peer challenge response message from the given challenge. * @param container_builder Flatbuffer builder for the container message. * @param challenge Message which need to be signed and placed in the container message. */ -void create_peer_challenge_response_from_challenge(flatbuffers::FlatBufferBuilder &container_builder, const std::string &challenge) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_peer_challenge_response_from_challenge(flatbuffers::FlatBufferBuilder &container_builder, const std::string &challenge) + { + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset challenge_resp_msg = - CreatePeer_Challenge_Response_Message( - builder, - sv_to_flatbuff_bytes(builder, challenge), - sv_to_flatbuff_bytes(builder, crypto::sign(challenge, conf::cfg.seckey))); + const flatbuffers::Offset challenge_resp_msg = + CreatePeer_Challenge_Response_Message( + builder, + sv_to_flatbuff_bytes(builder, challenge), + sv_to_flatbuff_bytes(builder, crypto::sign(challenge, conf::cfg.seckey))); - const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Response_Message, challenge_resp_msg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Response_Message, challenge_resp_msg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, nullptr, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, nullptr, true); + } -void create_msg_from_nonunl_proposal(flatbuffers::FlatBufferBuilder &container_builder, const p2p::nonunl_proposal &nup) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_nonunl_proposal(flatbuffers::FlatBufferBuilder &container_builder, const p2p::nonunl_proposal &nup) + { + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset nupmsg = - CreateNonUnl_Proposal_Message( - builder, - usermsgsmap_to_flatbuf_usermsgsmap(builder, nup.user_messages)); + const flatbuffers::Offset nupmsg = + CreateNonUnl_Proposal_Message( + builder, + usermsgsmap_to_flatbuf_usermsgsmap(builder, nup.user_messages)); - const flatbuffers::Offset message = CreateContent(builder, Message_NonUnl_Proposal_Message, nupmsg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + const flatbuffers::Offset message = CreateContent(builder, Message_NonUnl_Proposal_Message, nupmsg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, nullptr, false); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, nullptr, false); + } -/** + /** * Create proposal peer message from the given proposal struct. * @param container_builder Flatbuffer builder for the container message. * @param p The proposal struct to be placed in the container message. */ -void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder, const p2p::proposal &p) -{ - // todo:get a average propsal message size and allocate content builder based on that. - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder, const p2p::proposal &p) + { + // todo:get a average propsal message size and allocate content builder based on that. + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset proposal = - CreateProposal_Message( - builder, - p.stage, - p.time, - stringlist_to_flatbuf_bytearrayvector(builder, p.users), - stringlist_to_flatbuf_bytearrayvector(builder, p.hash_inputs), - stringlist_to_flatbuf_bytearrayvector(builder, p.hash_outputs), - sv_to_flatbuff_bytes(builder, p.curr_state_hash.to_string_view())); + const flatbuffers::Offset proposal = + CreateProposal_Message( + builder, + p.stage, + p.time, + stringlist_to_flatbuf_bytearrayvector(builder, p.users), + stringlist_to_flatbuf_bytearrayvector(builder, p.hash_inputs), + stringlist_to_flatbuf_bytearrayvector(builder, p.hash_outputs), + sv_to_flatbuff_bytes(builder, p.curr_state_hash.to_string_view())); - const flatbuffers::Offset message = CreateContent(builder, Message_Proposal_Message, proposal.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + const flatbuffers::Offset message = CreateContent(builder, Message_Proposal_Message, proposal.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, p.lcl, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, p.lcl, true); + } -/** + /** * Ctreat npl message from the given npl output srtuct. * @param container_builder Flatbuffer builder for the container message. * @param n The npl struct to be placed in the container message. * @param lcl Lcl value to be passed in the container message. */ -void create_msg_from_npl_output(flatbuffers::FlatBufferBuilder &container_builder, const p2p::npl_message &n, std::string_view lcl) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_npl_output(flatbuffers::FlatBufferBuilder &container_builder, const p2p::npl_message &n, std::string_view lcl) + { + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset npl = - CreateNpl_Message( - builder, - sv_to_flatbuff_bytes(builder, n.data)); + const flatbuffers::Offset npl = + CreateNpl_Message( + builder, + sv_to_flatbuff_bytes(builder, n.data)); - const flatbuffers::Offset message = CreateContent(builder, Message_Npl_Message, npl.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + const flatbuffers::Offset message = CreateContent(builder, Message_Npl_Message, npl.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } -/** + /** * Create history request message from the given history request struct. * @param container_builder Flatbuffer builder for the container message. * @param hr The History request struct to be placed in the container message. */ -void create_msg_from_history_request(flatbuffers::FlatBufferBuilder &container_builder, const p2p::history_request &hr) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_history_request(flatbuffers::FlatBufferBuilder &container_builder, const p2p::history_request &hr) + { + flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset hrmsg = - CreateHistory_Request_Message( - builder, - sv_to_flatbuff_bytes(builder, hr.minimum_lcl), - sv_to_flatbuff_bytes(builder, hr.required_lcl)); + flatbuffers::Offset hrmsg = + CreateHistory_Request_Message( + builder, + sv_to_flatbuff_bytes(builder, hr.minimum_lcl), + sv_to_flatbuff_bytes(builder, hr.required_lcl)); - flatbuffers::Offset message = CreateContent(builder, Message_History_Request_Message, hrmsg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + flatbuffers::Offset message = CreateContent(builder, Message_History_Request_Message, hrmsg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, nullptr, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, nullptr, true); + } -/** + /** * Create history response message from the given history response struct. * @param container_builder Flatbuffer builder for the container message. * @param hr The History response struct to be placed in the container message. */ -void create_msg_from_history_response(flatbuffers::FlatBufferBuilder &container_builder, const p2p::history_response &hr) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_history_response(flatbuffers::FlatBufferBuilder &container_builder, const p2p::history_response &hr) + { + flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset hrmsg = - CreateHistory_Response_Message( - builder, - historyledgermap_to_flatbuf_historyledgermap(builder, hr.hist_ledgers), - (Ledger_Response_Error)hr.error); + flatbuffers::Offset hrmsg = + CreateHistory_Response_Message( + builder, + historyledgermap_to_flatbuf_historyledgermap(builder, hr.hist_ledgers), + (Ledger_Response_Error)hr.error); - flatbuffers::Offset message = CreateContent(builder, Message_History_Response_Message, hrmsg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + flatbuffers::Offset message = CreateContent(builder, Message_History_Response_Message, hrmsg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, nullptr, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, nullptr, true); + } -/** + /** * Create state request message from the given state request struct. * @param container_builder Flatbuffer builder for the container message. * @param sr The state request struct to be placed in the container message. */ -void create_msg_from_state_request(flatbuffers::FlatBufferBuilder &container_builder, const p2p::state_request &hr, std::string_view lcl) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_state_request(flatbuffers::FlatBufferBuilder &container_builder, const p2p::state_request &hr, std::string_view lcl) + { + flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset srmsg = - CreateState_Request_Message( - builder, - sv_to_flatbuff_str(builder, hr.parent_path), - hr.is_file, - hr.block_id, - hash_to_flatbuff_bytes(builder, hr.expected_hash)); + flatbuffers::Offset srmsg = + CreateState_Request_Message( + builder, + sv_to_flatbuff_str(builder, hr.parent_path), + hr.is_file, + hr.block_id, + hash_to_flatbuff_bytes(builder, hr.expected_hash)); - flatbuffers::Offset message = CreateContent(builder, Message_State_Request_Message, srmsg.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + flatbuffers::Offset message = CreateContent(builder, Message_State_Request_Message, srmsg.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } -/** + /** * Create content response message from the given content response. * @param container_builder Flatbuffer builder for the container message. * @param path The path of the directory. @@ -477,277 +484,277 @@ void create_msg_from_state_request(flatbuffers::FlatBufferBuilder &container_bui * @param expected_hash The exptected hash of the requested path. * @param lcl Lcl to be include in the container msg. */ -void create_msg_from_fsentry_response(flatbuffers::FlatBufferBuilder &container_builder, const std::string_view path, std::unordered_map &fs_entries, hpfs::h32 expected_hash, std::string_view lcl) -{ - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_fsentry_response(flatbuffers::FlatBufferBuilder &container_builder, const std::string_view path, std::unordered_map &fs_entries, hpfs::h32 expected_hash, std::string_view lcl) + { + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset resp = - CreateFs_Entry_Response( - builder, - sv_to_flatbuff_str(builder, path), - statefshashentry_to_flatbuff_statefshashentry(builder, fs_entries)); + const flatbuffers::Offset resp = + CreateFs_Entry_Response( + builder, + sv_to_flatbuff_str(builder, path), + statefshashentry_to_flatbuff_statefshashentry(builder, fs_entries)); - const flatbuffers::Offset st_resp = CreateState_Response_Message( - builder, State_Response_Fs_Entry_Response, - resp.Union(), - hash_to_flatbuff_bytes(builder, expected_hash)); + const flatbuffers::Offset st_resp = CreateState_Response_Message( + builder, State_Response_Fs_Entry_Response, + resp.Union(), + hash_to_flatbuff_bytes(builder, expected_hash)); - flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } -/** + /** * Create content response message from the given content response. * @param container_builder Flatbuffer builder for the container message. * @param path The path of the directory. * @param hashmap Hashmap of the file * @param lcl Lcl to be include in the container msg. */ -void create_msg_from_filehashmap_response(flatbuffers::FlatBufferBuilder &container_builder, std::string_view path, std::vector &hashmap, std::size_t file_length, hpfs::h32 expected_hash, std::string_view lcl) -{ - // todo:get a average propsal message size and allocate content builder based on that. - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_filehashmap_response(flatbuffers::FlatBufferBuilder &container_builder, std::string_view path, std::vector &hashmap, std::size_t file_length, hpfs::h32 expected_hash, std::string_view lcl) + { + // todo:get a average propsal message size and allocate content builder based on that. + flatbuffers::FlatBufferBuilder builder(1024); - std::string_view hashmap_sv(reinterpret_cast(hashmap.data()), hashmap.size()); + std::string_view hashmap_sv(reinterpret_cast(hashmap.data()), hashmap.size()); - const flatbuffers::Offset resp = - CreateFile_HashMap_Response( + const flatbuffers::Offset resp = + CreateFile_HashMap_Response( + builder, + sv_to_flatbuff_str(builder, path), + file_length, + sv_to_flatbuff_bytes(builder, hashmap_sv)); + + const flatbuffers::Offset st_resp = CreateState_Response_Message( builder, - sv_to_flatbuff_str(builder, path), - file_length, - sv_to_flatbuff_bytes(builder, hashmap_sv)); + State_Response_File_HashMap_Response, + resp.Union(), + hash_to_flatbuff_bytes(builder, expected_hash)); - const flatbuffers::Offset st_resp = CreateState_Response_Message( - builder, - State_Response_File_HashMap_Response, - resp.Union(), - hash_to_flatbuff_bytes(builder, expected_hash)); + flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} - -/** + /** * Create content response message from the given content response. * @param container_builder Flatbuffer builder for the container message. * @param block_resp Block response struct to place in the message * @param lcl Lcl to be include in the container message. */ -void create_msg_from_block_response(flatbuffers::FlatBufferBuilder &container_builder, p2p::block_response &block_resp, std::string_view lcl) -{ - // todo:get a average propsal message size and allocate content builder based on that. - flatbuffers::FlatBufferBuilder builder(1024); + void create_msg_from_block_response(flatbuffers::FlatBufferBuilder &container_builder, p2p::block_response &block_resp, std::string_view lcl) + { + // todo:get a average propsal message size and allocate content builder based on that. + flatbuffers::FlatBufferBuilder builder(1024); - const flatbuffers::Offset resp = - CreateBlock_Response( + const flatbuffers::Offset resp = + CreateBlock_Response( + builder, + sv_to_flatbuff_str(builder, block_resp.path), + block_resp.block_id, + sv_to_flatbuff_bytes(builder, block_resp.data)); + + const flatbuffers::Offset st_resp = CreateState_Response_Message( builder, - sv_to_flatbuff_str(builder, block_resp.path), - block_resp.block_id, - sv_to_flatbuff_bytes(builder, block_resp.data)); + State_Response_Block_Response, + resp.Union(), + hash_to_flatbuff_bytes(builder, block_resp.hash)); - const flatbuffers::Offset st_resp = CreateState_Response_Message( - builder, - State_Response_Block_Response, - resp.Union(), - hash_to_flatbuff_bytes(builder, block_resp.hash)); + flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} + void create_msg_from_state_error_response(flatbuffers::FlatBufferBuilder &container_builder, std::string_view lcl) + { + // todo:get a average propsal message size and allocate content builder based on that. + flatbuffers::FlatBufferBuilder builder(1024); -void create_msg_from_state_error_response(flatbuffers::FlatBufferBuilder &container_builder, std::string_view lcl) -{ - // todo:get a average propsal message size and allocate content builder based on that. - flatbuffers::FlatBufferBuilder builder(1024); + const flatbuffers::Offset st_resp = CreateState_Response_Message(builder, State_Response_NONE, 0, true); - const flatbuffers::Offset st_resp = CreateState_Response_Message(builder, State_Response_NONE, 0, true); + flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); + builder.Finish(message); // Finished building message content to get serialised content. - flatbuffers::Offset message = CreateContent(builder, Message_State_Response_Message, st_resp.Union()); - builder.Finish(message); // Finished building message content to get serialised content. + // Now that we have built the content message, + // we need to sign it and place it inside a container message. + create_containermsg_from_content(container_builder, builder, lcl, true); + } - // Now that we have built the content message, - // we need to sign it and place it inside a container message. - create_containermsg_from_content(container_builder, builder, lcl, true); -} - -/** + /** * Creates a Flatbuffer container message from the given Content message. * @param container_builder The Flatbuffer builder to which the final container message should be written to. * @param content_builder The Flatbuffer builder containing the content message that should be placed * inside the container message. * @param sign Whether to sign the message content. */ -void create_containermsg_from_content( - flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder, std::string_view lcl, const bool sign) -{ - const uint8_t *content_buf = content_builder.GetBufferPointer(); - const flatbuffers::uoffset_t content_size = content_builder.GetSize(); - - // Create container message content from serialised content from previous step. - const flatbuffers::Offset> content = container_builder.CreateVector(content_buf, content_size); - - flatbuffers::Offset> pubkey_offset = 0; - flatbuffers::Offset> sig_offset = 0; - - flatbuffers::Offset> lcl_offset = 0; - - if (sign) + void create_containermsg_from_content( + flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder, std::string_view lcl, const bool sign) { - // Sign message content with this node's private key. - std::string_view content_to_sign(reinterpret_cast(content_buf), content_size); + const uint8_t *content_buf = content_builder.GetBufferPointer(); + const flatbuffers::uoffset_t content_size = content_builder.GetSize(); - sig_offset = sv_to_flatbuff_bytes(container_builder, crypto::sign(content_to_sign, conf::cfg.seckey)); - pubkey_offset = sv_to_flatbuff_bytes(container_builder, conf::cfg.pubkey); - } + // Create container message content from serialised content from previous step. + const flatbuffers::Offset> content = container_builder.CreateVector(content_buf, content_size); - if (!lcl.empty()) - lcl_offset = sv_to_flatbuff_bytes(container_builder, lcl); + flatbuffers::Offset> pubkey_offset = 0; + flatbuffers::Offset> sig_offset = 0; - const flatbuffers::Offset container_message = CreateContainer( - container_builder, - util::PEERMSG_VERSION, - util::get_epoch_milliseconds(), - pubkey_offset, - lcl_offset, - sig_offset, - content); + flatbuffers::Offset> lcl_offset = 0; - // Finish building message container to get serialised message. - container_builder.Finish(container_message); -} - -//---Conversion helpers from flatbuffers data types to std data types---// - -const std::unordered_map> -flatbuf_usermsgsmap_to_usermsgsmap(const flatbuffers::Vector> *fbvec) -{ - std::unordered_map> map; - map.reserve(fbvec->size()); - for (const UserSubmittedMessageGroup *group : *fbvec) - { - std::list msglist; - - for (const auto msg : *group->messages()) + if (sign) { - msglist.push_back(usr::user_submitted_message( - flatbuff_bytes_to_sv(msg->content()), - flatbuff_bytes_to_sv(msg->signature()))); + // Sign message content with this node's private key. + std::string_view content_to_sign(reinterpret_cast(content_buf), content_size); + + sig_offset = sv_to_flatbuff_bytes(container_builder, crypto::sign(content_to_sign, conf::cfg.seckey)); + pubkey_offset = sv_to_flatbuff_bytes(container_builder, conf::cfg.pubkey); } - map.emplace(flatbuff_bytes_to_sv(group->pubkey()), std::move(msglist)); + if (!lcl.empty()) + lcl_offset = sv_to_flatbuff_bytes(container_builder, lcl); + + const flatbuffers::Offset container_message = CreateContainer( + container_builder, + util::PEERMSG_VERSION, + util::get_epoch_milliseconds(), + pubkey_offset, + lcl_offset, + sig_offset, + content); + + // Finish building message container to get serialised message. + container_builder.Finish(container_message); } - return map; -} -//---Conversion helpers from std data types to flatbuffers data types---// -//---These are used in constructing Flatbuffer messages using builders---// + //---Conversion helpers from flatbuffers data types to std data types---// -const flatbuffers::Offset>> -usermsgsmap_to_flatbuf_usermsgsmap(flatbuffers::FlatBufferBuilder &builder, const std::unordered_map> &map) -{ - std::vector> fbvec; - fbvec.reserve(map.size()); - for (const auto &[pubkey, msglist] : map) + const std::unordered_map> + flatbuf_usermsgsmap_to_usermsgsmap(const flatbuffers::Vector> *fbvec) { - std::vector> fbmsgsvec; - for (const usr::user_submitted_message &msg : msglist) + std::unordered_map> map; + map.reserve(fbvec->size()); + for (const UserSubmittedMessageGroup *group : *fbvec) { - fbmsgsvec.push_back(CreateUserSubmittedMessage( + std::list msglist; + + for (const auto msg : *group->messages()) + { + msglist.push_back(usr::user_submitted_message( + flatbuff_bytes_to_sv(msg->content()), + flatbuff_bytes_to_sv(msg->signature()))); + } + + map.emplace(flatbuff_bytes_to_sv(group->pubkey()), std::move(msglist)); + } + return map; + } + + //---Conversion helpers from std data types to flatbuffers data types---// + //---These are used in constructing Flatbuffer messages using builders---// + + const flatbuffers::Offset>> + usermsgsmap_to_flatbuf_usermsgsmap(flatbuffers::FlatBufferBuilder &builder, const std::unordered_map> &map) + { + std::vector> fbvec; + fbvec.reserve(map.size()); + for (const auto &[pubkey, msglist] : map) + { + std::vector> fbmsgsvec; + for (const usr::user_submitted_message &msg : msglist) + { + fbmsgsvec.push_back(CreateUserSubmittedMessage( + builder, + sv_to_flatbuff_bytes(builder, msg.content), + sv_to_flatbuff_bytes(builder, msg.sig))); + } + + fbvec.push_back(CreateUserSubmittedMessageGroup( builder, - sv_to_flatbuff_bytes(builder, msg.content), - sv_to_flatbuff_bytes(builder, msg.sig))); + sv_to_flatbuff_bytes(builder, pubkey), + builder.CreateVector(fbmsgsvec))); } - - fbvec.push_back(CreateUserSubmittedMessageGroup( - builder, - sv_to_flatbuff_bytes(builder, pubkey), - builder.CreateVector(fbmsgsvec))); + return builder.CreateVector(fbvec); } - return builder.CreateVector(fbvec); -} -const std::map -flatbuf_historyledgermap_to_historyledgermap(const flatbuffers::Vector> *fbvec) -{ - std::map map; - - for (const HistoryLedgerPair *pair : *fbvec) + const std::map + flatbuf_historyledgermap_to_historyledgermap(const flatbuffers::Vector> *fbvec) { - std::list msglist; + std::map map; - p2p::history_ledger ledger; + for (const HistoryLedgerPair *pair : *fbvec) + { + std::list msglist; - ledger.lcl = flatbuff_bytes_to_sv(pair->ledger()->lcl()); - auto raw = pair->ledger()->raw_ledger(); - ledger.raw_ledger = std::vector(raw->begin(), raw->end()); + p2p::history_ledger ledger; - map.emplace(pair->seq_no(), std::move(ledger)); + ledger.lcl = flatbuff_bytes_to_sv(pair->ledger()->lcl()); + auto raw = pair->ledger()->raw_ledger(); + ledger.raw_ledger = std::vector(raw->begin(), raw->end()); + + map.emplace(pair->seq_no(), std::move(ledger)); + } + return map; } - return map; -} -const flatbuffers::Offset>> -historyledgermap_to_flatbuf_historyledgermap(flatbuffers::FlatBufferBuilder &builder, const std::map &map) -{ - std::vector> fbvec; - fbvec.reserve(map.size()); - for (auto const &[seq_no, ledger] : map) + const flatbuffers::Offset>> + historyledgermap_to_flatbuf_historyledgermap(flatbuffers::FlatBufferBuilder &builder, const std::map &map) { - flatbuffers::Offset history_ledger = CreateHistoryLedger( - builder, - sv_to_flatbuff_bytes(builder, ledger.state), - sv_to_flatbuff_bytes(builder, ledger.lcl), - builder.CreateVector(ledger.raw_ledger)); + std::vector> fbvec; + fbvec.reserve(map.size()); + for (auto const &[seq_no, ledger] : map) + { + flatbuffers::Offset history_ledger = CreateHistoryLedger( + builder, + sv_to_flatbuff_bytes(builder, ledger.state), + sv_to_flatbuff_bytes(builder, ledger.lcl), + builder.CreateVector(ledger.raw_ledger)); - fbvec.push_back(CreateHistoryLedgerPair( - builder, - seq_no, - history_ledger)); + fbvec.push_back(CreateHistoryLedgerPair( + builder, + seq_no, + history_ledger)); + } + return builder.CreateVector(fbvec); } - return builder.CreateVector(fbvec); -} -void flatbuf_statefshashentry_to_statefshashentry(std::unordered_map &fs_entries, const flatbuffers::Vector> *fhashes) -{ - - for (const State_FS_Hash_Entry *f_hash : *fhashes) + void flatbuf_statefshashentry_to_statefshashentry(std::unordered_map &fs_entries, const flatbuffers::Vector> *fhashes) { - p2p::state_fs_hash_entry h; - h.is_file = f_hash->is_file(); - h.hash = flatbuff_bytes_to_hash(f_hash->hash()); - fs_entries.emplace(flatbuff_str_to_sv(f_hash->path()), std::move(h)); + for (const State_FS_Hash_Entry *f_hash : *fhashes) + { + p2p::state_fs_hash_entry h; + + h.is_file = f_hash->is_file(); + h.hash = flatbuff_bytes_to_hash(f_hash->hash()); + fs_entries.emplace(flatbuff_str_to_sv(f_hash->path()), std::move(h)); + } } -} -flatbuffers::Offset>> -statefshashentry_to_flatbuff_statefshashentry(flatbuffers::FlatBufferBuilder &builder, std::unordered_map &fs_entries) -{ - std::vector> fbvec; - fbvec.reserve(fs_entries.size()); - for (auto const &[path, fs_entry] : fs_entries) + flatbuffers::Offset>> + statefshashentry_to_flatbuff_statefshashentry(flatbuffers::FlatBufferBuilder &builder, std::unordered_map &fs_entries) { - flatbuffers::Offset state_fs_entry = CreateState_FS_Hash_Entry( - builder, - sv_to_flatbuff_str(builder, path), - fs_entry.is_file, - hash_to_flatbuff_bytes(builder, fs_entry.hash)); + std::vector> fbvec; + fbvec.reserve(fs_entries.size()); + for (auto const &[path, fs_entry] : fs_entries) + { + flatbuffers::Offset state_fs_entry = CreateState_FS_Hash_Entry( + builder, + sv_to_flatbuff_str(builder, path), + fs_entry.is_file, + hash_to_flatbuff_bytes(builder, fs_entry.hash)); - fbvec.push_back(state_fs_entry); + fbvec.push_back(state_fs_entry); + } + return builder.CreateVector(fbvec); } - return builder.CreateVector(fbvec); -} } // namespace fbschema::p2pmsg \ No newline at end of file diff --git a/src/proc.cpp b/src/proc.cpp index ba897e56..e6f4b93c 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -9,6 +9,7 @@ namespace proc { + constexpr size_t OUTPUT_READ_BUF_SIZE = 64 * 1024; //64KB // Enum used to differenciate pipe fds maintained for SC I/O pipes. enum FDTYPE @@ -38,7 +39,10 @@ namespace proc // Holds the hpfs rw process id (if currently executing). pid_t hpfs_pid; - const char *FINDMNT_COMMAND = "findmnt --noheadings "; + // Thread to collect contract outputs while contract is running. + std::thread output_fetcher_thread; + + bool should_deinit = false; /** * Executes the contract process and passes the specified arguments. @@ -46,18 +50,16 @@ namespace proc */ int exec_contract(const contract_exec_args &args, hpfs::h32 &state_hash) { - // Setup io pipes and feed all inputs to them. - create_iopipes_for_fdmap(userfds, args.userbufs); - create_iopipes(nplfds); - create_iopipes(hpscfds); - - if (feed_inputs(args) != 0) - return -1; - // Start the hpfs rw session before starting the contract process. if (start_hpfs_rw_session() != 0) return -1; + // Setup io pipes and feed all inputs to them. + create_iopipes_for_fdmap(userfds, args.userbufs); + create_iopipes(nplfds, !args.nplbuff.inputs.empty()); + create_iopipes(hpscfds, !args.hpscbufs.inputs.empty()); + + int ret = 0; const pid_t pid = fork(); if (pid > 0) { @@ -67,23 +69,29 @@ namespace proc // Close all fds unused by HP process. close_unused_fds(true); + // Start the contract output collection thread. + output_fetcher_thread = std::thread(fetch_outputs, std::ref(args)); + + // Write the inputs into the contract process. + if (feed_inputs(args) != 0) + goto failure; + // Wait for child process (contract process) to complete execution. const int presult = await_process_execution(contract_pid); + contract_pid = 0; LOG_DBG << "Contract process ended."; - contract_pid = 0; + // Wait for the output collection thread to gracefully stop. + output_fetcher_thread.join(); + if (presult != 0) { LOG_ERR << "Contract process exited with non-normal status code: " << presult; - return -1; + goto failure; } if (stop_hpfs_rw_session(state_hash) != 0) - return -1; - - // After contract execution, collect contract outputs. - if (fetch_outputs(args) != 0) - return -1; + goto failure; } else if (pid == 0) { @@ -123,10 +131,19 @@ namespace proc else { LOG_ERR << "fork() failed when starting contract process."; - return -1; + goto failure; } - return 0; + goto success; + failure: + ret = -1; + + success: + cleanup_fdmap(userfds); + cleanup_vectorfds(hpscfds); + cleanup_vectorfds(nplfds); + + return ret; } /** @@ -261,7 +278,6 @@ namespace proc // Write any verified (consensus-reached) user inputs to user pipes. if (write_contract_fdmap_inputs(userfds, args.userbufs) != 0) { - cleanup_fdmap(userfds); LOG_ERR << "Failed to write user inputs to contract."; return -1; } @@ -271,19 +287,30 @@ namespace proc int fetch_outputs(const contract_exec_args &args) { - if (read_contract_hp_npl_outputs(args) != 0) + while (true) { - return -1; + if (should_deinit) + break; + + const int hpsc_npl_res = read_contract_hp_npl_outputs(args); + if (hpsc_npl_res == -1) + return -1; + + const int user_res = read_contract_fdmap_outputs(userfds, args.userbufs); + if (user_res == -1) + { + LOG_ERR << "Error reading user outputs from the contract."; + return -1; + } + + // If no bytes were read after contract finished execution, exit the read loop. + if (hpsc_npl_res == 0 && user_res == 0 && contract_pid == 0) + break; + + util::sleep(20); } - if (read_contract_fdmap_outputs(userfds, args.userbufs) != 0) - { - LOG_ERR << "Error reading User output from the contract."; - return -1; - } - - nplfds.clear(); - userfds.clear(); + LOG_DBG << "Contract outputs collected.\n"; return 0; } @@ -311,27 +338,25 @@ namespace proc * Read all HP output messages produced by the contract process and store them in * the buffer for later processing. * - * @return 0 on success. -1 on failure. + * @return 0 if no bytes were read. 1 if bytes were read. -1 on failure. */ int read_contract_hp_npl_outputs(const contract_exec_args &args) { - // Clear the input buffers because we are sure the contract has finished reading from - // that mapped memory portion. - args.hpscbufs.inputs.clear(); - - if (read_iopipe(hpscfds, args.hpscbufs.output) != 0) // hpscbufs.second is the output buffer. + const int hpsc_res = read_iopipe(hpscfds, args.hpscbufs.output); + if (hpsc_res == -1) { LOG_ERR << "Error reading HP output from the contract."; return -1; } - if (read_iopipe(nplfds, args.nplbuff.output) != 0) // hpscbufs.second is the output buffer. + const int npl_res = read_iopipe(nplfds, args.nplbuff.output); + if (npl_res == -1) { LOG_ERR << "Error reading NPL output from the contract."; return -1; } - return 0; + return (hpsc_res == 0 && npl_res == 0) ? 0 : 1; } /** @@ -372,7 +397,7 @@ namespace proc for (auto &[pubkey, buflist] : bufmap) { std::vector fds = std::vector(); - if (create_iopipes(fds) != 0) + if (create_iopipes(fds, !buflist.inputs.empty()) != 0) return -1; fdmap.emplace(pubkey, std::move(fds)); @@ -408,24 +433,25 @@ namespace proc * * @param fdmap A map which has public key and a vector as fd list for that public key. * @param bufmap A map which has a public key and input/output buffer pair for that public key. - * @return 0 on success. -1 on failure. + * @return 0 if no bytes were read. 1 if bytes were read. -1 on failure. */ int read_contract_fdmap_outputs(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap) { + bool bytes_read = false; for (auto &[pubkey, bufpair] : bufmap) { - // Clear the input buffer because we are sure the contract has finished reading from - // the inputs' mapped memory portion. - bufpair.inputs.clear(); - // Get fds for the pubkey. std::vector &fds = fdmap[pubkey]; - if (read_iopipe(fds, bufpair.output) != 0) // bufpair.second is the output buffer. + const int res = read_iopipe(fds, bufpair.output); + if (res == -1) return -1; + + if (res > 0) + bytes_read = true; } - return 0; + return bytes_read ? 1 : 0; } /** @@ -435,33 +461,32 @@ namespace proc void cleanup_fdmap(contract_fdmap_t &fdmap) { for (auto &[pubkey, fds] : fdmap) - { - for (int i = 0; i < 4; i++) - { - if (fds[i] > 0) - close(fds[i]); - fds[i] = 0; - } - } + cleanup_vectorfds(fds); + + fdmap.clear(); } /** * Common function to create a pair of pipes (Hp->SC, SC->HP). * @param fds Vector to populate fd list. * @param inputbuffer Buffer to write into the HP write fd. + * @param create_inpipe Whether to create the input pipe from HP to SC. */ - int create_iopipes(std::vector &fds) + int create_iopipes(std::vector &fds, const bool create_inpipe) { - int inpipe[2]; - if (pipe(inpipe) != 0) + int inpipe[2] = {-1, -1}; + if (create_inpipe && pipe(inpipe) != 0) return -1; - int outpipe[2]; + int outpipe[2] = {-1, -1}; if (pipe(outpipe) != 0) { - // Close the earlier created pipe. - close(inpipe[0]); - close(inpipe[1]); + if (create_inpipe) + { + // Close the earlier created pipe. + close(inpipe[0]); + close(inpipe[1]); + } return -1; } @@ -485,11 +510,14 @@ namespace proc // Write the inputs (if any) into the contract and close the writefd. const int writefd = fds[FDTYPE::HPWRITE]; - bool vmsplice_error = false; + if (writefd == -1) + return 0; + + bool write_error = false; if (!inputs.empty()) { - // Prepare the input memory segments to map with vmsplice. + // Prepare the input memory segments to write with wrtiev. size_t i = 0; iovec memsegs[inputs.size()]; for (std::string &input : inputs) @@ -499,21 +527,17 @@ namespace proc i++; } - // We use vmsplice to map (zero-copy) the inputs into the fd. - if (vmsplice(writefd, memsegs, inputs.size(), 0) == -1) - vmsplice_error = true; + if (writev(writefd, memsegs, inputs.size()) == -1) + write_error = true; - // It's important that we DO NOT clear the input buffer string until the contract - // process has actually read from the fd. Because the OS is just mapping our - // input buffer memory portion into the fd, if we clear it now, the contract process - // will get invaid bytes when reading the fd. + inputs.clear(); } // Close the writefd since we no longer need it. close(writefd); - fds[FDTYPE::HPWRITE] = 0; + fds[FDTYPE::HPWRITE] = -1; - return vmsplice_error ? -1 : 0; + return write_error ? -1 : 0; } /** @@ -529,7 +553,10 @@ namespace proc * Length of the message is calculated without including public key length */ const int writefd = fds[FDTYPE::HPWRITE]; - bool vmsplice_error = false; + if (writefd == -1) + return 0; + + bool write_error = false; if (!inputs.empty()) { int8_t total_memsegs = inputs.size() * 3; @@ -579,56 +606,60 @@ namespace proc i++; } - if (vmsplice(writefd, memsegs, total_memsegs, 0) == -1) - vmsplice_error = true; + if (writev(writefd, memsegs, total_memsegs) == -1) + write_error = true; + + inputs.clear(); } - // It's important that we DO NOT clear the input buffer string until the contract - // process has actually read from the fd. Because the OS is just mapping our - // input buffer memory portion into the fd, if we clear it now, the contract process - // will get invaid bytes when reading the fd. // Close the writefd since we no longer need it. close(writefd); - fds[FDTYPE::HPWRITE] = 0; + fds[FDTYPE::HPWRITE] = -1; - return vmsplice_error ? -1 : 0; + return write_error ? -1 : 0; } /** - * Common function to read and close SC output from the pipe and populate the output list. + * Common function to read buffered output from the pipe and populate the output list. * @param fds Vector representing the pipes fd list. * @param output The buffer to place the read output. + * @return -1 on error. Otherwise no. of bytes read. */ int read_iopipe(std::vector &fds, std::string &output) { - // Read any data that have been written by the contract process + // Read any available data that have been written by the contract process // from the output pipe and store in the output buffer. // Outputs will be read by the consensus process later when it wishes so. const int readfd = fds[FDTYPE::HPREAD]; - int bytes_available = 0; - ioctl(readfd, FIONREAD, &bytes_available); - bool vmsplice_error = false; + if (readfd == -1) + return 0; - if (bytes_available > 0) + bool read_error = false; + size_t available_bytes = 0; + if (ioctl(readfd, FIONREAD, &available_bytes) != -1) { - output.resize(bytes_available); + if (available_bytes == 0) + return 0; - // Populate the user output buffer with new data from the pipe. - // We use vmsplice to map (zero-copy) the output from the fd into output bbuffer. - iovec memsegs[1]; - memsegs[0].iov_base = output.data(); - memsegs[0].iov_len = bytes_available; + const size_t current_size = output.size(); + output.resize(current_size + available_bytes); + const int res = read(readfd, output.data() + current_size, available_bytes); - if (vmsplice(readfd, memsegs, 1, 0) == -1) - vmsplice_error = true; + if (res >= 0) + { + if (res == 0) // EOF + { + close(readfd); + fds[FDTYPE::HPREAD] = -1; + } + return res; + } } - // Close readfd fd on HP process side because we are done with contract process I/O. close(readfd); - fds[FDTYPE::HPREAD] = 0; - - return vmsplice_error ? -1 : 0; + fds[FDTYPE::HPREAD] = -1; + return -1; } void close_unused_fds(const bool is_hp) @@ -649,35 +680,54 @@ namespace proc */ void close_unused_vectorfds(const bool is_hp, std::vector &fds) { - if (is_hp) - { - // Close unused fds in Hot Pocket process. - close(fds[FDTYPE::SCREAD]); - fds[FDTYPE::SCREAD] = 0; - close(fds[FDTYPE::SCWRITE]); - fds[FDTYPE::SCWRITE] = 0; - } - else - { - // Close unused fds in smart contract process. - close(fds[FDTYPE::HPREAD]); - fds[FDTYPE::HPREAD] = 0; + const int fdtypes_to_close[2] = { + is_hp ? FDTYPE::SCREAD : FDTYPE::HPREAD, + is_hp ? FDTYPE::SCWRITE : FDTYPE::HPWRITE, + }; - // HPWRITE fd has aleady been closed by HP process after writing - // inputs (before the fork). + for (const int fdtype : fdtypes_to_close) + { + const int fd = fds[fdtype]; + if (fd != -1) + { + close(fd); + fds[fdtype] = -1; + } } } + /** + * Closes all fds in a vector fd set. + */ + void cleanup_vectorfds(std::vector &fds) + { + for (int i = 0; i < fds.size(); i++) + { + if (fds[i] != -1) + { + close(fds[i]); + fds[i] = -1; + } + } + + fds.clear(); + } + /** * Cleanup any running processes. */ void deinit() { + should_deinit = true; + if (contract_pid > 0) util::kill_process(contract_pid, true); if (hpfs_pid > 0) util::kill_process(hpfs_pid, true); + + if (output_fetcher_thread.joinable()) + output_fetcher_thread.join(); } } // namespace proc diff --git a/src/proc.hpp b/src/proc.hpp index 66c34fb4..b45b04e5 100644 --- a/src/proc.hpp +++ b/src/proc.hpp @@ -12,106 +12,107 @@ namespace proc { -/** + /** * Represents list of inputs to the contract and the accumulated contract output for those inputs. */ -struct contract_iobuf_pair -{ - // List of inputs to be fed into the contract. - std::list inputs; + struct contract_iobuf_pair + { + // List of inputs to be fed into the contract. + std::list inputs; - // Output emitted by contract after execution. - // (Because we are reading output at the end, there's no way to - // get a "list" of outputs. So it's always a one contiguous output.) - std::string output; -}; + // Output emitted by contract after execution. + // (Because we are reading output at the end, there's no way to + // get a "list" of outputs. So it's always a one contiguous output.) + std::string output; + }; -// Common typedef for a map of pubkey->fdlist. -// This is used to keep track of fdlist quadruplet with a public key (eg. user, npl). -typedef std::unordered_map> contract_fdmap_t; + // Common typedef for a map of pubkey->fdlist. + // This is used to keep track of fdlist quadruplet with a public key (eg. user, npl). + typedef std::unordered_map> contract_fdmap_t; -// Common typedef for a map of pubkey->I/O list pair (input list and output list). -// This is used to keep track of input/output buffers for a given public key (eg. user, npl) -typedef std::unordered_map contract_bufmap_t; + // Common typedef for a map of pubkey->I/O list pair (input list and output list). + // This is used to keep track of input/output buffers for a given public key (eg. user, npl) + typedef std::unordered_map contract_bufmap_t; -/** + /** * Holds information that should be passed into the contract process. */ -struct contract_exec_args -{ - // Map of user I/O buffers (map key: user binary public key). - // The value is a pair holding consensus-verified inputs and contract-generated outputs. - contract_bufmap_t &userbufs; - - // Pair of NPL<->SC byte array message buffers. - // Input buffers for NPL->SC messages, Output buffers for SC->NPL messages. - contract_iobuf_pair &nplbuff; - - // Pair of HP<->SC JSON message buffers (mainly used for control messages). - // Input buffers for HP->SC messages, Output buffers for SC->HP messages. - contract_iobuf_pair &hpscbufs; - - // Current HotPocket timestamp. - const int64_t timestamp; - - contract_exec_args( - int64_t timestamp, - contract_bufmap_t &userbufs, - contract_iobuf_pair &nplbuff, - contract_iobuf_pair &hpscbufs) : - userbufs(userbufs), - nplbuff(nplbuff), - hpscbufs(hpscbufs), - timestamp(timestamp) + struct contract_exec_args { - } -}; + // Map of user I/O buffers (map key: user binary public key). + // The value is a pair holding consensus-verified inputs and contract-generated outputs. + contract_bufmap_t &userbufs; -int exec_contract(const contract_exec_args &args, hpfs::h32 &state_hash); + // Pair of NPL<->SC byte array message buffers. + // Input buffers for NPL->SC messages, Output buffers for SC->NPL messages. + contract_iobuf_pair &nplbuff; -void deinit(); + // Pair of HP<->SC JSON message buffers (mainly used for control messages). + // Input buffers for HP->SC messages, Output buffers for SC->HP messages. + contract_iobuf_pair &hpscbufs; -//------Internal-use functions for this namespace. + // Current HotPocket timestamp. + const int64_t timestamp; -int await_process_execution(pid_t pid); + contract_exec_args( + int64_t timestamp, + contract_bufmap_t &userbufs, + contract_iobuf_pair &nplbuff, + contract_iobuf_pair &hpscbufs) : userbufs(userbufs), + nplbuff(nplbuff), + hpscbufs(hpscbufs), + timestamp(timestamp) + { + } + }; -int start_hpfs_rw_session(); + int exec_contract(const contract_exec_args &args, hpfs::h32 &state_hash); -int stop_hpfs_rw_session(hpfs::h32 &state_hash); + void deinit(); -int write_contract_args(const contract_exec_args &args); + //------Internal-use functions for this namespace. -int feed_inputs(const contract_exec_args &args); + int await_process_execution(pid_t pid); -int fetch_outputs(const contract_exec_args &args); + int start_hpfs_rw_session(); -int write_contract_hp_npl_inputs(const contract_exec_args &args); + int stop_hpfs_rw_session(hpfs::h32 &state_hash); -int read_contract_hp_npl_outputs(const contract_exec_args &args); + int write_contract_args(const contract_exec_args &args); -// Common helper functions + int feed_inputs(const contract_exec_args &args); -void fdmap_json_to_stream(const contract_fdmap_t &fdmap, std::ostringstream &os); + int fetch_outputs(const contract_exec_args &args); -int create_iopipes_for_fdmap(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); + int write_contract_hp_npl_inputs(const contract_exec_args &args); -int write_contract_fdmap_inputs(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); + int read_contract_hp_npl_outputs(const contract_exec_args &args); -int read_contract_fdmap_outputs(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); + // Common helper functions -void cleanup_fdmap(contract_fdmap_t &fdmap); + void fdmap_json_to_stream(const contract_fdmap_t &fdmap, std::ostringstream &os); -int create_iopipes(std::vector &fds); + int create_iopipes_for_fdmap(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); -int write_iopipe(std::vector &fds, std::list &inputs); + int write_contract_fdmap_inputs(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); -int write_npl_iopipe(std::vector &fds, std::list &inputs); + int read_contract_fdmap_outputs(contract_fdmap_t &fdmap, contract_bufmap_t &bufmap); -int read_iopipe(std::vector &fds, std::string &output); + void cleanup_fdmap(contract_fdmap_t &fdmap); -void close_unused_fds(const bool is_hp); + int create_iopipes(std::vector &fds, const bool create_inpipe); -void close_unused_vectorfds(const bool is_hp, std::vector &fds); + int write_iopipe(std::vector &fds, std::list &inputs); + + int write_npl_iopipe(std::vector &fds, std::list &inputs); + + int read_iopipe(std::vector &fds, std::string &output); + + void close_unused_fds(const bool is_hp); + + void close_unused_vectorfds(const bool is_hp, std::vector &fds); + + void cleanup_vectorfds(std::vector &fds); } // namespace proc diff --git a/test/local-cluster/cluster-create.sh b/test/local-cluster/cluster-create.sh index 706ab5b3..4ac5d43a 100755 --- a/test/local-cluster/cluster-create.sh +++ b/test/local-cluster/cluster-create.sh @@ -115,16 +115,16 @@ done for (( i=1; i<=$ncount; i++ )) do - mkdir -p ./node$i/statehist/0/data/ > /dev/null 2>&1 + mkdir -p ./node$i/state/seed > /dev/null 2>&1 - # Load credit balance for user for testing purposes. - pushd ./node$i/statehist/0/data/ > /dev/null 2>&1 + # Load credit balance for user for appbill testing purposes. + pushd ./node$i/state/seed/ > /dev/null 2>&1 >appbill.table - ../../../../../bin/appbill --credit "705bf26354ee4c63c0e5d5d883c07cefc3196d049bd3825f827eb3bc23ead035" 10000 + ../../../../bin/appbill --credit "705bf26354ee4c63c0e5d5d883c07cefc3196d049bd3825f827eb3bc23ead035" 10000 popd > /dev/null 2>&1 # Copy any more initial state files for testing. - #cp ~/my_big_file ~/hpcore/hpcluster/node$i/statehist/0/data/ + #cp ~/my_big_file ~/hpcore/hpcluster/node$i/state/seed/ done diff --git a/test/vm-cluster/cluster.sh b/test/vm-cluster/cluster.sh index eddb129d..8c799358 100755 --- a/test/vm-cluster/cluster.sh +++ b/test/vm-cluster/cluster.sh @@ -42,7 +42,7 @@ fi if [ $mode = "check" ]; then let nodeid=$2-1 vmip=${vmips[$nodeid]} - sshpass -f vmpass.txt ssh geveo@$vmip 'echo hpcore pid:$(pidof hpcore) hpfs pid:$(pidof hpfs) websocketd pid:$(pidof websocketd)' + sshpass -f vmpass.txt ssh geveo@$vmip 'echo hpcore pid:$(pidof hpcore) hpfs pid:$(pidof hpfs) websocketd pid:$(pidof websocketd) websocat pid:$(pidof websocat)' exit 0 fi @@ -59,6 +59,7 @@ if [ $mode = "kill" ]; then sshpass -f vmpass.txt ssh geveo@$vmip 'sudo kill $(pidof hpcore) > /dev/null 2>&1' sshpass -f vmpass.txt ssh geveo@$vmip 'sudo kill $(pidof hpfs) > /dev/null 2>&1' sshpass -f vmpass.txt ssh geveo@$vmip 'sudo kill $(pidof websocketd) > /dev/null 2>&1' + sshpass -f vmpass.txt ssh geveo@$vmip 'sudo kill $(pidof websocat) > /dev/null 2>&1' exit 0 fi diff --git a/test/vm-cluster/vmcreate.sh b/test/vm-cluster/vmcreate.sh index a9c84d18..c609ea56 100755 --- a/test/vm-cluster/vmcreate.sh +++ b/test/vm-cluster/vmcreate.sh @@ -10,9 +10,9 @@ name=$1 loc=$2 -vmsize=Standard_B1ls +vmsize=Standard_B1s vmpass=$(cat vmpass.txt) -resgroup=My-ResGroup +resgroup=HotPocket-ResGroup az vm create --name $name --resource-group $resgroup --size $vmsize --admin-username geveo --admin-password $vmpass --image UbuntuLTS --location $loc --generate-ssh-keys az vm open-port --resource-group $resgroup --name $name --port 22860 --priority 900 && \