Npl outputs round limit. (#242)

This commit is contained in:
Ravin Perera
2021-02-15 14:50:03 +05:30
committed by GitHub
parent 0de7983504
commit 0937ca0bbe
6 changed files with 35 additions and 14 deletions

View File

@@ -137,6 +137,7 @@ struct hp_round_limits_config
{
size_t user_input_bytes;
size_t user_output_bytes;
size_t npl_output_bytes;
};
struct hp_config
@@ -504,7 +505,7 @@ int hp_update_config(const struct hp_config *config)
if (!config->npl || strlen(config->npl) == 0 || (strcmp(config->npl, "public") != 0 && strcmp(config->npl, "private")) != 0)
__HP_UPDATE_CONFIG_ERROR("Invalid npl flag. Valid values: public|private");
if (config->round_limits.user_input_bytes < 0 || config->round_limits.user_output_bytes < 0)
if (config->round_limits.user_input_bytes < 0 || config->round_limits.user_output_bytes < 0 || config->round_limits.npl_output_bytes < 0)
__HP_UPDATE_CONFIG_ERROR("Invalid round limits.");
const int fd = open(PATCH_FILE_PATH, O_RDWR);
@@ -655,17 +656,18 @@ int __hp_write_to_patch_file(const int fd, const struct hp_config *config)
// Round limits field valies.
const char *round_limits_json = " \"round_limits\": {\n \"user_input_bytes\": %s,\n \"user_output_bytes\": %s\n }\n}";
const char *round_limits_json = " \"round_limits\": {\n \"user_input_bytes\": %s,\n \"user_output_bytes\": %s,\n \"npl_output_bytes\": %s\n }\n}";
char user_input_bytes_str[20], user_output_bytes_str[20];
char user_input_bytes_str[20], user_output_bytes_str[20], npl_output_bytes_str[20];
sprintf(user_input_bytes_str, "%" PRIu64, config->round_limits.user_input_bytes);
sprintf(user_output_bytes_str, "%" PRIu64, config->round_limits.user_output_bytes);
sprintf(npl_output_bytes_str, "%" PRIu64, config->round_limits.npl_output_bytes);
const size_t round_limits_json_len = 89 + strlen(user_input_bytes_str) + strlen(user_output_bytes_str);
const size_t round_limits_json_len = 119 + strlen(user_input_bytes_str) + strlen(user_output_bytes_str) + strlen(npl_output_bytes_str);
char round_limits_buf[round_limits_json_len];
sprintf(round_limits_buf, round_limits_json, user_input_bytes_str, user_output_bytes_str);
sprintf(round_limits_buf, round_limits_json, user_input_bytes_str, user_output_bytes_str, npl_output_bytes_str);
iov_vec[4].iov_base = round_limits_buf;
iov_vec[4].iov_len = round_limits_json_len;
iov_vec[4].iov_len = strlen(round_limits_buf);
if (ftruncate(fd, 0) == -1 || // Clear any previous content in the file.
pwritev(fd, iov_vec, 5, 0) == -1) // Start writing from begining.
@@ -763,6 +765,10 @@ void __hp_populate_patch_from_json_object(struct hp_config *config, const struct
{
__HP_ASSIGN_UINT64(config->round_limits.user_output_bytes, sub_ele);
}
else if (strcmp(sub_ele->name->string, "npl_output_bytes") == 0)
{
__HP_ASSIGN_UINT64(config->round_limits.npl_output_bytes, sub_ele);
}
sub_ele = sub_ele->next;
} while (sub_ele);
}

View File

@@ -144,7 +144,7 @@ class PatchConfig {
throw "Invalid consensus flag configured in patch file. Valid values: public|private";
if (config.npl != "public" && config.npl != "private")
throw "Invalid npl flag configured in patch file. Valid values: public|private";
if (config.round_limits.user_input_bytes < 0 || config.round_limits.user_output_bytes < 0)
if (config.round_limits.user_input_bytes < 0 || config.round_limits.user_output_bytes < 0 || config.round_limits.npl_output_bytes < 0)
throw "Invalid round limits.";
}
}

View File

@@ -854,6 +854,7 @@ namespace conf
jsoncons::ojson round_limits;
round_limits.insert_or_assign("user_input_bytes", contract.round_limits.user_input_bytes);
round_limits.insert_or_assign("user_output_bytes", contract.round_limits.user_output_bytes);
round_limits.insert_or_assign("npl_output_bytes", contract.round_limits.npl_output_bytes);
jdoc.insert_or_assign("round_limits", round_limits);
}
@@ -945,6 +946,7 @@ namespace conf
contract.round_limits.user_input_bytes = jdoc["round_limits"]["user_input_bytes"].as<size_t>();
contract.round_limits.user_output_bytes = jdoc["round_limits"]["user_output_bytes"].as<size_t>();
contract.round_limits.npl_output_bytes = jdoc["round_limits"]["npl_output_bytes"].as<size_t>();
}
catch (const std::exception &e)
{

View File

@@ -89,6 +89,7 @@ namespace conf
{
size_t user_input_bytes = 0; // Max contract input bytes per user per round.
size_t user_output_bytes = 0; // Max contract output bytes per user per round.
size_t npl_output_bytes = 0; // Max npl output bytes per round.
};
struct contract_config

View File

@@ -3,12 +3,12 @@
#include "../consensus.hpp"
#include "../hplog.hpp"
#include "../ledger.hpp"
#include "sc.hpp"
#include "../msg/fbuf/p2pmsg_helpers.hpp"
#include "../msg/controlmsg_common.hpp"
#include "../msg/controlmsg_parser.hpp"
#include "../unl.hpp"
#include "contract_serve.hpp"
#include "sc.hpp"
namespace sc
{
@@ -351,7 +351,7 @@ namespace sc
// Atempt to read messages from contract (regardless of contract terminated or not).
const int control_read_res = read_control_outputs(ctx, out_fds[control_fd_idx]);
const int npl_read_res = ctx.args.readonly ? 0 : read_npl_outputs(ctx, out_fds[npl_fd_idx]);
const int npl_read_res = ctx.args.readonly ? 0 : read_npl_outputs(ctx, &out_fds[npl_fd_idx]);
const int user_read_res = read_contract_fdmap_outputs(ctx.user_fds, out_fds, ctx.args.userbufs);
if (ctx.termination_signaled || ctx.contract_pid == 0)
@@ -500,10 +500,10 @@ namespace sc
* @param ctx contract execution context.
* @return 0 if no bytes were read. 1 if bytes were read.
*/
int read_npl_outputs(execution_context &ctx, const pollfd pfd)
int read_npl_outputs(execution_context &ctx, pollfd *pfd)
{
std::string output;
const int res = read_iosocket(false, pfd, output);
const int res = read_iosocket(false, *pfd, output);
if (res == -1)
{
@@ -511,8 +511,18 @@ namespace sc
}
else if (res > 0)
{
// Broadcast npl messages once contract npl output is collected.
broadcast_npl_output(output);
ctx.total_npl_output_size += output.size();
if (conf::cfg.contract.round_limits.npl_output_bytes > 0 &&
ctx.total_npl_output_size > conf::cfg.contract.round_limits.npl_output_bytes)
{
close(pfd->fd);
pfd->fd = -1;
}
else
{
// Broadcast npl messages once contract npl output is collected.
broadcast_npl_output(output);
}
}
return (res > 0) ? 1 : 0;

View File

@@ -119,6 +119,8 @@ namespace sc
// Thread to collect contract inputs and outputs and feed npl messages while contract is running.
std::thread contract_monitor_thread;
size_t total_npl_output_size = 0;
// Indicates that the contract has sent termination control message.
bool termination_signaled = false;
@@ -157,7 +159,7 @@ namespace sc
int read_control_outputs(execution_context &ctx, const pollfd pfd);
int read_npl_outputs(execution_context &ctx, const pollfd pfd);
int read_npl_outputs(execution_context &ctx, pollfd *pfd);
void broadcast_npl_output(std::string_view output);