mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Added user input max ledger seq offset limit config (#256)
- Added new config for max input ledger offset inside contract section. - Updated implementation of getting and updating patch config inside node and c contracts. - Skip inputs if max ledger offset exceeds, when handling user inputs and nup messages.
This commit is contained in:
@@ -154,9 +154,10 @@ struct hp_config
|
||||
struct hp_unl_collection unl;
|
||||
char *bin_path;
|
||||
char *bin_args;
|
||||
u_int16_t roundtime;
|
||||
uint32_t roundtime;
|
||||
char *consensus;
|
||||
char *npl;
|
||||
uint16_t max_input_ledger_offset;
|
||||
struct hp_appbill_config appbill;
|
||||
struct hp_round_limits_config round_limits;
|
||||
};
|
||||
@@ -505,6 +506,9 @@ int hp_update_config(const struct hp_config *config)
|
||||
|
||||
if (config->roundtime <= 0)
|
||||
__HP_UPDATE_CONFIG_ERROR("Round time must be higher than 0.");
|
||||
|
||||
if (config->max_input_ledger_offset < 0)
|
||||
__HP_UPDATE_CONFIG_ERROR("Invalid max input ledger offset.");
|
||||
|
||||
if (!config->consensus || strlen(config->consensus) == 0 || (strcmp(config->consensus, "public") != 0 && strcmp(config->consensus, "private") != 0))
|
||||
__HP_UPDATE_CONFIG_ERROR("Invalid consensus flag. Valid values: public|private");
|
||||
@@ -643,14 +647,17 @@ int __hp_write_to_patch_file(const int fd, const struct hp_config *config)
|
||||
// Top-level field values.
|
||||
|
||||
const char *json_string = " \"bin_path\": \"%s\",\n \"bin_args\": \"%s\",\n \"roundtime\": %s,\n"
|
||||
" \"consensus\": \"%s\",\n \"npl\": \"%s\",\n";
|
||||
" \"consensus\": \"%s\",\n \"npl\": \"%s\",\n \"max_input_ledger_offset\": %s,\n";
|
||||
|
||||
char roundtime_str[16];
|
||||
sprintf(roundtime_str, "%d", config->roundtime);
|
||||
|
||||
const size_t json_string_len = 95 + strlen(config->bin_path) + strlen(config->bin_args) + strlen(roundtime_str) + strlen(config->consensus) + strlen(config->npl);
|
||||
char max_input_ledger_offset_str[16];
|
||||
sprintf(max_input_ledger_offset_str, "%d", config->max_input_ledger_offset);
|
||||
|
||||
const size_t json_string_len = 128 + strlen(config->bin_path) + strlen(config->bin_args) + strlen(roundtime_str) + strlen(config->consensus) + strlen(config->npl) + strlen(max_input_ledger_offset_str);
|
||||
char json_buf[json_string_len];
|
||||
sprintf(json_buf, json_string, config->bin_path, config->bin_args, roundtime_str, config->consensus, config->npl);
|
||||
sprintf(json_buf, json_string, config->bin_path, config->bin_args, roundtime_str, config->consensus, config->npl, max_input_ledger_offset_str);
|
||||
iov_vec[2].iov_base = json_buf;
|
||||
iov_vec[2].iov_len = json_string_len;
|
||||
|
||||
@@ -746,6 +753,11 @@ void __hp_populate_patch_from_json_object(struct hp_config *config, const struct
|
||||
const struct json_number_s *value = (struct json_number_s *)elem->value->payload;
|
||||
config->roundtime = strtol(value->number, NULL, 0);
|
||||
}
|
||||
else if (strcmp(k->string, "max_input_ledger_offset") == 0)
|
||||
{
|
||||
const struct json_number_s *value = (struct json_number_s *)elem->value->payload;
|
||||
config->max_input_ledger_offset = strtoul(value->number, NULL, 0);
|
||||
}
|
||||
else if (strcmp(k->string, "consensus") == 0)
|
||||
{
|
||||
__HP_ASSIGN_CHAR_PTR(config->consensus, elem);
|
||||
|
||||
@@ -149,6 +149,8 @@ class PatchConfig {
|
||||
if (config.round_limits.user_input_bytes < 0 || config.round_limits.user_output_bytes < 0 || config.round_limits.npl_output_bytes < 0 ||
|
||||
config.round_limits.proc_cpu_seconds < 0 || config.round_limits.proc_mem_bytes < 0 || config.round_limits.proc_ofd_count < 0)
|
||||
throw "Invalid round limits.";
|
||||
if (config.max_input_ledger_offset < 0)
|
||||
throw "Invalid max input ledger offset";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ namespace conf
|
||||
cfg.contract.roundtime = 1000;
|
||||
cfg.contract.is_consensus_public = false;
|
||||
cfg.contract.is_npl_public = false;
|
||||
cfg.contract.max_input_ledger_offset = 10;
|
||||
|
||||
cfg.mesh.port = 22860;
|
||||
cfg.mesh.msg_forwarding = true;
|
||||
@@ -516,12 +517,12 @@ namespace conf
|
||||
// We always save the startup role to config. Not the current role which might get changed dynamically during syncing.
|
||||
node_config.insert_or_assign("role", cfg.node.role == ROLE::OBSERVER ? ROLE_OBSERVER : ROLE_VALIDATOR);
|
||||
node_config.insert_or_assign("history", cfg.node.history == HISTORY::FULL ? HISTORY_FULL : HISTORY_CUSTOM);
|
||||
|
||||
|
||||
jsoncons::ojson history_config;
|
||||
history_config.insert_or_assign("max_primary_shards", cfg.node.history_config.max_primary_shards);
|
||||
history_config.insert_or_assign("max_blob_shards", cfg.node.history_config.max_blob_shards);
|
||||
node_config.insert_or_assign("history_config", history_config);
|
||||
|
||||
|
||||
d.insert_or_assign("node", node_config);
|
||||
}
|
||||
|
||||
@@ -905,6 +906,7 @@ namespace conf
|
||||
jdoc.insert_or_assign("roundtime", contract.roundtime.load());
|
||||
jdoc.insert_or_assign("consensus", contract.is_consensus_public ? PUBLIC : PRIVATE);
|
||||
jdoc.insert_or_assign("npl", contract.is_npl_public ? PUBLIC : PRIVATE);
|
||||
jdoc.insert_or_assign("max_input_ledger_offset", contract.max_input_ledger_offset);
|
||||
|
||||
jsoncons::ojson appbill;
|
||||
appbill.insert_or_assign("mode", contract.appbill.mode);
|
||||
@@ -995,6 +997,7 @@ namespace conf
|
||||
return -1;
|
||||
}
|
||||
contract.is_npl_public = jdoc["npl"] == PUBLIC;
|
||||
contract.max_input_ledger_offset = jdoc["max_input_ledger_offset"].as<uint16_t>();
|
||||
|
||||
jpath = "contract.appbill";
|
||||
contract.appbill.mode = jdoc["appbill"]["mode"].as<std::string>();
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace conf
|
||||
struct history_configuration
|
||||
{
|
||||
uint64_t max_primary_shards; // Maximum number of shards for primary shards.
|
||||
uint64_t max_blob_shards; // Maximum number of shards for blob shards.
|
||||
uint64_t max_blob_shards; // Maximum number of shards for blob shards.
|
||||
};
|
||||
|
||||
// Log severity levels used in Hot Pocket.
|
||||
@@ -122,6 +122,7 @@ namespace conf
|
||||
std::atomic<uint32_t> roundtime = 0; // Consensus round time in ms
|
||||
bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well.
|
||||
bool is_npl_public = false; // If true, npl messages are broadcasted to non-unl nodes as well.
|
||||
uint16_t max_input_ledger_offset; // Maximum ledger sequence number offset that can be specified in the input.
|
||||
appbill_config appbill;
|
||||
round_limits_config round_limits;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace msg::usrmsg
|
||||
constexpr const char *REASON_BAD_SIG = "bad_sig";
|
||||
constexpr const char *REASON_APPBILL_BALANCE_EXCEEDED = "appbill_balance_exceeded";
|
||||
constexpr const char *REASON_MAX_LEDGER_EXPIRED = "max_ledger_expired";
|
||||
constexpr const char *REASON_MAX_LEDGER_OFFSET_EXCEEDED = "max_ledger_offset_exceeded";
|
||||
constexpr const char *REASON_NONCE_EXPIRED = "nonce_expired";
|
||||
constexpr const char *REASON_ALREADY_SUBMITTED = "already_submitted";
|
||||
constexpr const char *REASON_NONCE_OVERFLOW = "nonce_overflow";
|
||||
|
||||
@@ -176,6 +176,14 @@ namespace usr
|
||||
uint64_t max_lcl_seq_no;
|
||||
if (parser.extract_input_container(input_data, nonce, max_lcl_seq_no, input_container) != -1)
|
||||
{
|
||||
const p2p::sequence_hash lcl_id = ledger::ctx.get_lcl_id();
|
||||
// Ignore the input if the max ledger seq number specified is beyond the max offeset.
|
||||
if (conf::cfg.contract.max_input_ledger_offset != 0 && max_lcl_seq_no > lcl_id.seq_no + conf::cfg.contract.max_input_ledger_offset)
|
||||
{
|
||||
send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_MAX_LEDGER_OFFSET_EXCEEDED, sig);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check for max nonce size.
|
||||
if (nonce.size() > MAX_INPUT_NONCE_SIZE)
|
||||
{
|
||||
@@ -384,6 +392,13 @@ namespace usr
|
||||
const char *validate_user_input_submission(const std::string &user_pubkey, const usr::extracted_user_input &extracted_input,
|
||||
const uint64_t lcl_seq_no, size_t &total_input_size, std::string &hash, util::buffer_view &input)
|
||||
{
|
||||
// Ignore the input if the max ledger seq number specified is beyond the max offeset.
|
||||
if (conf::cfg.contract.max_input_ledger_offset != 0 && extracted_input.max_lcl_seq_no > lcl_seq_no + conf::cfg.contract.max_input_ledger_offset)
|
||||
{
|
||||
LOG_DEBUG << "User input bad max ledger seq beyond the max offset.";
|
||||
return msg::usrmsg::REASON_MAX_LEDGER_OFFSET_EXCEEDED;
|
||||
}
|
||||
|
||||
// Ignore the input if our ledger has passed the input TTL.
|
||||
if (extracted_input.max_lcl_seq_no <= lcl_seq_no)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user