mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Npl outputs round limit. (#242)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user