mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Separated lcl string usage to sequence no and hash. (#251)
This commit is contained in:
@@ -20,8 +20,8 @@ const char *__HP_PATCH_FILE_PATH = "../patch.cfg";
|
||||
|
||||
// Public constants.
|
||||
#define HP_NPL_MSG_MAX_SIZE __HP_SEQPKT_MAX_SIZE
|
||||
#define HP_KEY_SIZE 66 // Hex pubkey size. (64 char key + 2 chars for key type prfix)
|
||||
#define HP_HASH_SIZE 64
|
||||
#define HP_KEY_SIZE 66 // Hex pubkey size. (64 char key + 2 chars for key type prfix)
|
||||
#define HP_HASH_SIZE 64 // Hex hash size.
|
||||
const char *HP_POST_EXEC_SCRIPT_NAME = "post_exec.sh";
|
||||
|
||||
#define __HP_ASSIGN_STRING(dest, elem) \
|
||||
@@ -165,8 +165,9 @@ struct hp_contract_context
|
||||
{
|
||||
bool readonly;
|
||||
uint64_t timestamp;
|
||||
char pubkey[HP_KEY_SIZE + 1]; // +1 for null char.S
|
||||
char lcl[HP_HASH_SIZE + 22]; // uint64(20 chars) + "-" + hash + nullchar
|
||||
char pubkey[HP_KEY_SIZE + 1]; // +1 for null char.
|
||||
uint64_t lcl_seq_no; // lcl sequence no.
|
||||
char lcl_hash[HP_HASH_SIZE + 1]; // +1 for null char.
|
||||
struct hp_users_collection users;
|
||||
struct hp_unl_collection unl;
|
||||
};
|
||||
@@ -829,9 +830,13 @@ void __hp_parse_args_json(const struct json_object_s *object)
|
||||
{
|
||||
__HP_ASSIGN_BOOL(cctx->readonly, elem);
|
||||
}
|
||||
else if (strcmp(k->string, "lcl") == 0)
|
||||
else if (strcmp(k->string, "lcl_seq_no") == 0)
|
||||
{
|
||||
__HP_ASSIGN_STRING(cctx->lcl, elem);
|
||||
__HP_ASSIGN_UINT64(cctx->lcl_seq_no, elem);
|
||||
}
|
||||
else if (strcmp(k->string, "lcl_hash") == 0)
|
||||
{
|
||||
__HP_ASSIGN_STRING(cctx->lcl_hash, elem);
|
||||
}
|
||||
else if (strcmp(k->string, "user_in_fd") == 0)
|
||||
{
|
||||
|
||||
@@ -498,8 +498,8 @@
|
||||
else if (m.type == "stat_response") {
|
||||
statResponseResolvers.forEach(resolver => {
|
||||
resolver({
|
||||
lcl: m.lcl,
|
||||
lclSeqNo: m.lcl_seqno
|
||||
lclSeqNo: m.lcl_seq_no,
|
||||
lcl_hash: m.lcl_hash
|
||||
});
|
||||
})
|
||||
statResponseResolvers = [];
|
||||
@@ -759,7 +759,7 @@
|
||||
const inpContainer = {
|
||||
input: this.serializeInput(input),
|
||||
nonce: nonce,
|
||||
max_lcl_seqno: maxLclSeqNo
|
||||
max_lcl_seq_no: maxLclSeqNo
|
||||
}
|
||||
|
||||
const serlializedInpContainer = this.serializeObject(inpContainer);
|
||||
|
||||
@@ -80,7 +80,8 @@ class ContractContext {
|
||||
this.timestamp = hpargs.timestamp;
|
||||
this.users = users;
|
||||
this.unl = unl; // Not available in readonly mode.
|
||||
this.lcl = hpargs.lcl; // Not available in readonly mode.
|
||||
this.lcl_seq_no = hpargs.lcl_seq_no; // Not available in readonly mode.
|
||||
this.lcl_hash = hpargs.lcl_hash; // Not available in readonly mode.
|
||||
this.#patchConfig = new PatchConfig();
|
||||
}
|
||||
|
||||
|
||||
@@ -528,7 +528,7 @@ namespace consensus
|
||||
// No reject reason means we should go ahead and subject the input to consensus.
|
||||
ctx.candidate_user_inputs.try_emplace(
|
||||
hash,
|
||||
candidate_user_input(pubkey, stored_input, extracted_input.max_lcl_seqno));
|
||||
candidate_user_input(pubkey, stored_input, extracted_input.max_lcl_seq_no));
|
||||
}
|
||||
|
||||
responses[pubkey].push_back(usr::input_status_response{extracted_input.protocol, extracted_input.sig, reject_reason});
|
||||
@@ -856,7 +856,7 @@ namespace consensus
|
||||
auto itr = ctx.candidate_user_inputs.begin();
|
||||
while (itr != ctx.candidate_user_inputs.end())
|
||||
{
|
||||
if (itr->second.maxledgerseqno <= new_lcl_id.seq_no)
|
||||
if (itr->second.max_ledger_seq_no <= new_lcl_id.seq_no)
|
||||
ctx.candidate_user_inputs.erase(itr++);
|
||||
else
|
||||
++itr;
|
||||
@@ -878,7 +878,9 @@ namespace consensus
|
||||
sc::contract_execution_args &args = ctx.contract_ctx->args;
|
||||
args.readonly = false;
|
||||
args.time = cons_prop.time;
|
||||
args.lcl = ledger::get_lcl_string(new_lcl_id);
|
||||
|
||||
// lcl to be passed to the contract.
|
||||
args.lcl_id = new_lcl_id;
|
||||
|
||||
// This is currently used for npl message checks.
|
||||
args.lasl_primary_shard_id = new_last_primary_shard_id;
|
||||
@@ -924,7 +926,7 @@ namespace consensus
|
||||
* @param cons_prop The proposal that achieved consensus.
|
||||
* @param lcl_id Lcl sequnce no hash info.
|
||||
*/
|
||||
int dispatch_user_outputs(const p2p::proposal &cons_prop, const p2p::sequence_hash lcl_id)
|
||||
int dispatch_user_outputs(const p2p::proposal &cons_prop, const p2p::sequence_hash &lcl_id)
|
||||
{
|
||||
if (cons_prop.output_hash == ctx.user_outputs_hashtree.root_hash())
|
||||
{
|
||||
@@ -951,7 +953,7 @@ namespace consensus
|
||||
for (const sc::contract_output &output : user_output.outputs)
|
||||
outputs.emplace_back(output.message);
|
||||
|
||||
parser.create_contract_output_container(msg, outputs, collapsed_hash_root, ctx.user_outputs_unl_sig, lcl_id.seq_no, ledger::get_lcl_string(lcl_id));
|
||||
parser.create_contract_output_container(msg, outputs, collapsed_hash_root, ctx.user_outputs_unl_sig, lcl_id.seq_no, lcl_id.hash.to_string_view());
|
||||
|
||||
user.session.send(msg);
|
||||
}
|
||||
@@ -1002,7 +1004,7 @@ namespace consensus
|
||||
// Populate the input content into the bufmap.
|
||||
// It's VERY important that we preserve the proposal input hash order when feeding to the contract as well.
|
||||
candidate_user_input &cand_input = itr->second;
|
||||
sc::contract_iobufs &contract_user = bufmap[cand_input.userpubkey];
|
||||
sc::contract_iobufs &contract_user = bufmap[cand_input.user_pubkey];
|
||||
contract_user.inputs.push_back(cand_input.input);
|
||||
|
||||
// Remove the input from the candidate set because we no longer need it.
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace consensus
|
||||
*/
|
||||
struct candidate_user_input
|
||||
{
|
||||
const std::string userpubkey;
|
||||
const uint64_t maxledgerseqno = 0;
|
||||
const std::string user_pubkey;
|
||||
const uint64_t max_ledger_seq_no = 0;
|
||||
const util::buffer_view input;
|
||||
|
||||
candidate_user_input(const std::string userpubkey, const util::buffer_view input, const uint64_t maxledgerseqno)
|
||||
: userpubkey(std::move(userpubkey)), input(input), maxledgerseqno(maxledgerseqno)
|
||||
candidate_user_input(const std::string user_pubkey, const util::buffer_view input, const uint64_t max_ledger_seq_no)
|
||||
: user_pubkey(std::move(user_pubkey)), input(input), max_ledger_seq_no(max_ledger_seq_no)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -55,7 +55,7 @@ namespace consensus
|
||||
std::set<std::string> candidate_users;
|
||||
|
||||
// Map of candidate user inputs with input hash as map key. Inputs will stay here until they
|
||||
// achieve consensus or expire (due to maxledgerseqno). Input hash is globally unique among inputs
|
||||
// achieve consensus or expire (due to max_ledger_seq_no). Input hash is globally unique among inputs
|
||||
// from all users. We will use this map to feed inputs into the contract once consensus is achieved.
|
||||
std::map<std::string, candidate_user_input> candidate_user_inputs;
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace consensus
|
||||
|
||||
int update_ledger_and_execute_contract(const p2p::proposal &cons_prop, util::h32 &new_state_hash, const util::h32 &patch_hash, p2p::sequence_hash &new_lcl_id);
|
||||
|
||||
int dispatch_user_outputs(const p2p::proposal &cons_prop, const p2p::sequence_hash lcl_id);
|
||||
int dispatch_user_outputs(const p2p::proposal &cons_prop, const p2p::sequence_hash &lcl_id);
|
||||
|
||||
int feed_user_inputs_to_contract_bufmap(sc::contract_bufmap_t &bufmap, const p2p::proposal &cons_prop);
|
||||
|
||||
|
||||
@@ -352,10 +352,10 @@ namespace ledger
|
||||
std::string input;
|
||||
if (usr::input_store.read_buf(user_input.input, input) != -1)
|
||||
{
|
||||
const auto itr = blob.inputs.find(user_input.userpubkey);
|
||||
const auto itr = blob.inputs.find(user_input.user_pubkey);
|
||||
if (itr == blob.inputs.end())
|
||||
blob.inputs.emplace(user_input.userpubkey, std::vector<std::string>());
|
||||
blob.inputs[user_input.userpubkey].push_back(input);
|
||||
blob.inputs.emplace(user_input.user_pubkey, std::vector<std::string>());
|
||||
blob.inputs[user_input.user_pubkey].push_back(input);
|
||||
}
|
||||
}
|
||||
for (const auto &[hash, user_output] : generated_user_outputs)
|
||||
@@ -498,14 +498,5 @@ namespace ledger
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns lcl in (seq_no-lcl_hash_hex) format.
|
||||
* @param lcl_id Lcl id to be converted.
|
||||
* @return Returns constructed string.
|
||||
*/
|
||||
const std::string get_lcl_string(const p2p::sequence_hash &lcl_id)
|
||||
{
|
||||
return std::to_string(lcl_id.seq_no) + "-" + util::to_hex(lcl_id.hash.to_string_view());
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
@@ -92,8 +92,6 @@ namespace ledger
|
||||
|
||||
int get_last_shard_info(std::string_view session_name, p2p::sequence_hash &last_shard_id, std::string_view shard_parent_dir);
|
||||
|
||||
const std::string get_lcl_string(const p2p::sequence_hash &lcl_id);
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,20 +12,20 @@ namespace msg::usrmsg::bson
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "stat_response",
|
||||
* "lcl": "<lcl id>",
|
||||
* "lcl_seqno": <integer>
|
||||
* "lcl_seq_no": <lcl sequence no>,
|
||||
* "lcl_hash": <binary lcl hash>
|
||||
* }
|
||||
*/
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl)
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash)
|
||||
{
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
encoder.key(msg::usrmsg::FLD_TYPE);
|
||||
encoder.string_value(msg::usrmsg::MSGTYPE_STAT_RESPONSE);
|
||||
encoder.key(msg::usrmsg::FLD_LCL);
|
||||
encoder.string_value(lcl);
|
||||
encoder.key(msg::usrmsg::FLD_LCL_SEQ);
|
||||
encoder.int64_value(lcl_seq_no);
|
||||
encoder.key(msg::usrmsg::FLD_LCL_HASH);
|
||||
encoder.byte_string_value(lcl_hash);
|
||||
encoder.end_object();
|
||||
encoder.flush();
|
||||
}
|
||||
@@ -88,8 +88,8 @@ namespace msg::usrmsg::bson
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "contract_output",
|
||||
* "lcl": "<lcl id>"
|
||||
* "lcl_seqno": <integer>,
|
||||
* "lcl_seq_no": <integer>,
|
||||
* "lcl_hash": <binary lcl hash>
|
||||
* "outputs": [<binary output 1>, <binary output 2>, ...], // The output order is the hash order.
|
||||
* "hashes": [<binary merkle hash tree>], // Always includes user's output hash [output hash = hash(pubkey+all outputs for the user)]
|
||||
* "unl_sig": [["<pubkey>", "<sig>"], ...] // Binary UNL pubkeys and signatures of root hash.
|
||||
@@ -98,16 +98,16 @@ namespace msg::usrmsg::bson
|
||||
*/
|
||||
void create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl)
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash)
|
||||
{
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
encoder.key(msg::usrmsg::FLD_TYPE);
|
||||
encoder.string_value(msg::usrmsg::MSGTYPE_CONTRACT_OUTPUT);
|
||||
encoder.key(msg::usrmsg::FLD_LCL);
|
||||
encoder.string_value(lcl);
|
||||
encoder.key(msg::usrmsg::FLD_LCL_SEQ);
|
||||
encoder.int64_value(lcl_seq_no);
|
||||
encoder.key(msg::usrmsg::FLD_LCL_HASH);
|
||||
encoder.byte_string_value(lcl_hash);
|
||||
|
||||
encoder.key(msg::usrmsg::FLD_OUTPUTS);
|
||||
encoder.begin_array();
|
||||
@@ -261,16 +261,16 @@ namespace msg::usrmsg::bson
|
||||
* Extract the individual components of a given input container bson.
|
||||
* @param input The extracted input.
|
||||
* @param nonce The extracted nonce.
|
||||
* @param max_lcl_seqno The extracted max ledger sequence no.
|
||||
* @param max_lcl_seq_no The extracted max ledger sequence no.
|
||||
* @param contentjson The bson input container message.
|
||||
* {
|
||||
* "input": <binary buffer>,
|
||||
* "nonce": "<random string with optional sorted order>",
|
||||
* "max_lcl_seqno": <integer>
|
||||
* "max_lcl_seq_no": <integer>
|
||||
* }
|
||||
* @return 0 on succesful extraction. -1 on failure.
|
||||
*/
|
||||
int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_lcl_seqno, std::string_view contentbson)
|
||||
int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_lcl_seq_no, std::string_view contentbson)
|
||||
{
|
||||
jsoncons::ojson d;
|
||||
try
|
||||
@@ -299,7 +299,7 @@ namespace msg::usrmsg::bson
|
||||
input = std::string_view(reinterpret_cast<const char *>(bsv.data()), bsv.size());
|
||||
|
||||
nonce = d[msg::usrmsg::FLD_NONCE].as<std::string>();
|
||||
max_lcl_seqno = d[msg::usrmsg::FLD_MAX_LCL_SEQ].as<uint64_t>();
|
||||
max_lcl_seq_no = d[msg::usrmsg::FLD_MAX_LCL_SEQ].as<uint64_t>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
namespace msg::usrmsg::bson
|
||||
{
|
||||
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl);
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash);
|
||||
|
||||
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason,
|
||||
std::string_view input_sig);
|
||||
@@ -16,7 +16,7 @@ namespace msg::usrmsg::bson
|
||||
|
||||
void create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl);
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash);
|
||||
|
||||
void create_unl_list_container(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list);
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace msg::usrmsg::bson
|
||||
const jsoncons::ojson &d);
|
||||
|
||||
int extract_input_container(std::string &input, std::string &nonce,
|
||||
uint64_t &max_lcl_seqno, std::string_view contentbson);
|
||||
uint64_t &max_lcl_seq_no, std::string_view contentbson);
|
||||
|
||||
void populate_output_hash_array(jsoncons::bson::bson_bytes_encoder &encoder, const util::merkle_hash_node &node);
|
||||
|
||||
|
||||
@@ -130,11 +130,11 @@ namespace msg::usrmsg::json
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "stat_response",
|
||||
* "lcl": "<lcl id>",
|
||||
* "lcl_seqno": <integer>
|
||||
* "lcl_seq_no": <lcl sequence no>,
|
||||
* "lcl_hash": "<lcl hash hex>"
|
||||
* }
|
||||
*/
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl)
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash)
|
||||
{
|
||||
msg.reserve(256);
|
||||
msg += "{\"";
|
||||
@@ -142,14 +142,14 @@ namespace msg::usrmsg::json
|
||||
msg += SEP_COLON;
|
||||
msg += msg::usrmsg::MSGTYPE_STAT_RESPONSE;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_LCL;
|
||||
msg += SEP_COLON;
|
||||
msg += lcl;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_LCL_SEQ;
|
||||
msg += SEP_COLON_NOQUOTE;
|
||||
msg += std::to_string(lcl_seq_no);
|
||||
msg += "}";
|
||||
msg += SEP_COMMA_NOQUOTE;
|
||||
msg += msg::usrmsg::FLD_LCL_HASH;
|
||||
msg += SEP_COLON;
|
||||
msg += util::to_hex(lcl_hash);
|
||||
msg += "\"}";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,8 +235,8 @@ namespace msg::usrmsg::json
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "contract_output",
|
||||
* "lcl": "<lcl id>"
|
||||
* "lcl_seqno": <integer>,
|
||||
* "lcl_seq_no": <integer>,
|
||||
* "lcl_hash": "<lcl hash hex>",
|
||||
* "outputs": ["<output string 1>", "<output string 2>", ...], // The output order is the hash order.
|
||||
* "hashes": [<hex merkle hash tree>], // Always includes user's output hash [output hash = hash(pubkey+all outputs for the user)]
|
||||
* "unl_sig": [["<pubkey hex>", "<sig hex>"], ...] // UNL pubkeys and signatures of root hash.
|
||||
@@ -245,7 +245,7 @@ namespace msg::usrmsg::json
|
||||
*/
|
||||
void create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl)
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash)
|
||||
{
|
||||
msg.reserve(1024);
|
||||
msg += "{\"";
|
||||
@@ -253,14 +253,14 @@ namespace msg::usrmsg::json
|
||||
msg += SEP_COLON;
|
||||
msg += msg::usrmsg::MSGTYPE_CONTRACT_OUTPUT;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_LCL;
|
||||
msg += SEP_COLON;
|
||||
msg += lcl;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_LCL_SEQ;
|
||||
msg += SEP_COLON_NOQUOTE;
|
||||
msg += std::to_string(lcl_seq_no);
|
||||
msg += SEP_COMMA_NOQUOTE;
|
||||
msg += msg::usrmsg::FLD_LCL_HASH;
|
||||
msg += SEP_COLON;
|
||||
msg += util::to_hex(lcl_hash);
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_OUTPUTS;
|
||||
msg += "\":[";
|
||||
|
||||
@@ -568,16 +568,16 @@ namespace msg::usrmsg::json
|
||||
* Extract the individual components of a given input container json.
|
||||
* @param input The extracted input.
|
||||
* @param nonce The extracted nonce.
|
||||
* @param max_lcl_seqno The extracted max ledger sequence no.
|
||||
* @param max_lcl_seq_no The extracted max ledger sequence no.
|
||||
* @param contentjson The json string containing the input container message.
|
||||
* {
|
||||
* "input": "<any string>",
|
||||
* "nonce": "<random string with optional sorted order>",
|
||||
* "max_lcl_seqno": <integer>
|
||||
* "max_lcl_seq_no": <integer>
|
||||
* }
|
||||
* @return 0 on succesful extraction. -1 on failure.
|
||||
*/
|
||||
int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_lcl_seqno, std::string_view contentjson)
|
||||
int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_lcl_seq_no, std::string_view contentjson)
|
||||
{
|
||||
jsoncons::json d;
|
||||
try
|
||||
@@ -604,7 +604,7 @@ namespace msg::usrmsg::json
|
||||
|
||||
input = d[msg::usrmsg::FLD_INPUT].as<std::string>();
|
||||
nonce = d[msg::usrmsg::FLD_NONCE].as<std::string>();
|
||||
max_lcl_seqno = d[msg::usrmsg::FLD_MAX_LCL_SEQ].as<uint64_t>();
|
||||
max_lcl_seq_no = d[msg::usrmsg::FLD_MAX_LCL_SEQ].as<uint64_t>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace msg::usrmsg::json
|
||||
|
||||
void create_server_challenge_response(std::vector<uint8_t> &msg, const std::string &original_challenge);
|
||||
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl);
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash);
|
||||
|
||||
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason,
|
||||
std::string_view input_sig);
|
||||
@@ -20,7 +20,7 @@ namespace msg::usrmsg::json
|
||||
|
||||
void create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl);
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash);
|
||||
|
||||
void create_unl_list_container(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace msg::usrmsg::json
|
||||
const jsoncons::json &d);
|
||||
|
||||
int extract_input_container(std::string &input, std::string &nonce,
|
||||
uint64_t &max_lcl_seqno, std::string_view contentjson);
|
||||
uint64_t &max_lcl_seq_no, std::string_view contentjson);
|
||||
|
||||
bool is_json_string(std::string_view content);
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ namespace msg::usrmsg
|
||||
constexpr const char *FLD_INPUT = "input";
|
||||
constexpr const char *FLD_INPUT_CONTAINER = "input_container";
|
||||
constexpr const char *FLD_INPUT_SIG = "input_sig";
|
||||
constexpr const char *FLD_MAX_LCL_SEQ = "max_lcl_seqno";
|
||||
constexpr const char *FLD_MAX_LCL_SEQ = "max_lcl_seq_no";
|
||||
constexpr const char *FLD_CONTENT = "content";
|
||||
constexpr const char *FLD_OUTPUTS = "outputs";
|
||||
constexpr const char *FLD_HASHES = "hashes";
|
||||
constexpr const char *FLD_UNL_SIG = "unl_sig";
|
||||
constexpr const char *FLD_NONCE = "nonce";
|
||||
constexpr const char *FLD_LCL = "lcl";
|
||||
constexpr const char *FLD_LCL_SEQ = "lcl_seqno";
|
||||
constexpr const char *FLD_LCL_HASH = "lcl_hash";
|
||||
constexpr const char *FLD_LCL_SEQ = "lcl_seq_no";
|
||||
constexpr const char *FLD_STATUS = "status";
|
||||
constexpr const char *FLD_REASON = "reason";
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace msg::usrmsg
|
||||
{
|
||||
}
|
||||
|
||||
void usrmsg_parser::create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl) const
|
||||
void usrmsg_parser::create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash) const
|
||||
{
|
||||
if (protocol == util::PROTOCOL::JSON)
|
||||
jusrmsg::create_status_response(msg, lcl_seq_no, lcl);
|
||||
jusrmsg::create_status_response(msg, lcl_seq_no, lcl_hash);
|
||||
else
|
||||
busrmsg::create_status_response(msg, lcl_seq_no, lcl);
|
||||
busrmsg::create_status_response(msg, lcl_seq_no, lcl_hash);
|
||||
}
|
||||
|
||||
void usrmsg_parser::create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status,
|
||||
@@ -40,12 +40,12 @@ namespace msg::usrmsg
|
||||
|
||||
void usrmsg_parser::create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl) const
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash) const
|
||||
{
|
||||
if (protocol == util::PROTOCOL::JSON)
|
||||
jusrmsg::create_contract_output_container(msg, outputs, hash_root, unl_sig, lcl_seq_no, lcl);
|
||||
jusrmsg::create_contract_output_container(msg, outputs, hash_root, unl_sig, lcl_seq_no, lcl_hash);
|
||||
else
|
||||
busrmsg::create_contract_output_container(msg, outputs, hash_root, unl_sig, lcl_seq_no, lcl);
|
||||
busrmsg::create_contract_output_container(msg, outputs, hash_root, unl_sig, lcl_seq_no, lcl_hash);
|
||||
}
|
||||
|
||||
void usrmsg_parser::create_unl_list_container(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list) const
|
||||
@@ -89,12 +89,12 @@ namespace msg::usrmsg
|
||||
}
|
||||
|
||||
int usrmsg_parser::extract_input_container(std::string &input, std::string &nonce,
|
||||
uint64_t &max_lcl_seqno, std::string_view encoded_content) const
|
||||
uint64_t &max_lcl_seq_no, std::string_view encoded_content) const
|
||||
{
|
||||
if (protocol == util::PROTOCOL::JSON)
|
||||
return jusrmsg::extract_input_container(input, nonce, max_lcl_seqno, encoded_content);
|
||||
return jusrmsg::extract_input_container(input, nonce, max_lcl_seq_no, encoded_content);
|
||||
else
|
||||
return busrmsg::extract_input_container(input, nonce, max_lcl_seqno, encoded_content);
|
||||
return busrmsg::extract_input_container(input, nonce, max_lcl_seq_no, encoded_content);
|
||||
}
|
||||
|
||||
} // namespace msg::usrmsg
|
||||
@@ -19,7 +19,7 @@ namespace msg::usrmsg
|
||||
public:
|
||||
usrmsg_parser(const util::PROTOCOL protocol);
|
||||
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl) const;
|
||||
void create_status_response(std::vector<uint8_t> &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash) const;
|
||||
|
||||
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status,
|
||||
std::string_view reason, std::string_view input_sig) const;
|
||||
@@ -28,7 +28,7 @@ namespace msg::usrmsg
|
||||
|
||||
void create_contract_output_container(std::vector<uint8_t> &msg, const ::std::vector<std::string_view> &outputs,
|
||||
const util::merkle_hash_node &hash_root, const std::vector<std::pair<std::string, std::string>> &unl_sig,
|
||||
const uint64_t lcl_seq_no, std::string_view lcl) const;
|
||||
const uint64_t lcl_seq_no, std::string_view lcl_hash) const;
|
||||
|
||||
void create_unl_list_container(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list) const;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace msg::usrmsg
|
||||
int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig) const;
|
||||
|
||||
int extract_input_container(std::string &input, std::string &nonce,
|
||||
uint64_t &max_lcl_seqno, std::string_view encoded_content) const;
|
||||
uint64_t &max_lcl_seq_no, std::string_view encoded_content) const;
|
||||
};
|
||||
|
||||
} // namespace msg::usrmsg
|
||||
|
||||
@@ -37,6 +37,11 @@ namespace p2p
|
||||
{
|
||||
return seq_no < seq_hash.seq_no || hash < seq_hash.hash;
|
||||
}
|
||||
|
||||
const std::string to_string()
|
||||
{
|
||||
return std::to_string(seq_no) + "-" + util::to_hex(hash.to_string_view());
|
||||
}
|
||||
};
|
||||
// This is a helper method for sequence_hash structure which enables printing it straight away.
|
||||
std::ostream &operator<<(std::ostream &output, const sequence_hash &seq_hash);
|
||||
|
||||
@@ -308,7 +308,8 @@ namespace sc
|
||||
* "pubkey": "<this node's hex public key>",
|
||||
* "timestamp": <this node's timestamp (unix milliseconds)>,
|
||||
* "readonly": <true|false>,
|
||||
* "lcl": "<this node's last closed ledger seq no. and hash in hex>", (eg: 169-a1d82eb4c9ed005ec2c4f4f82b6f0c2fd7543d66b1a0f6b8e58ae670b3e2bcfb)
|
||||
* "lcl_seq_no": "<lcl sequence no>",
|
||||
* "lcl_hex": "<lcl hash hex>",
|
||||
* "control_fd": fd,
|
||||
* "npl_fd":fd,
|
||||
* "user_in_fd":fd, // User inputs fd.
|
||||
@@ -331,7 +332,8 @@ namespace sc
|
||||
|
||||
if (!ctx.args.readonly)
|
||||
{
|
||||
os << ",\"lcl\":\"" << ctx.args.lcl
|
||||
os << ",\"lcl_seq_no\":" << ctx.args.lcl_id.seq_no
|
||||
<< ",\"lcl_hash\":\"" << util::to_hex(ctx.args.lcl_id.hash.to_string_view())
|
||||
<< "\",\"npl_fd\":" << ctx.npl_fds.scfd;
|
||||
}
|
||||
|
||||
@@ -475,9 +477,10 @@ namespace sc
|
||||
LOG_INFO << "Running post-exec script...";
|
||||
|
||||
const std::string log_redirect = conf::cfg.contract.log_output ? (" >>" + ctx.stdout_file + " 2>>" + ctx.stderr_file + " ") : "";
|
||||
const std::string script_args = " " + std::to_string(ctx.args.lcl_id.seq_no) + " " + util::to_hex(ctx.args.lcl_id.hash.to_string_view());
|
||||
|
||||
// We set current working dir and pass lcl as command line arg to the script.
|
||||
const std::string command = "(cd " + ctx.working_dir + " && ./" + POST_EXEC_SCRIPT + " " + ctx.args.lcl + log_redirect + ")";
|
||||
// We set current working dir and pass command line arg to the script.
|
||||
const std::string command = "(cd " + ctx.working_dir + " && ./" + POST_EXEC_SCRIPT + " " + script_args + log_redirect + ")";
|
||||
|
||||
const int ret = system(command.c_str());
|
||||
if (ret == -1)
|
||||
@@ -819,7 +822,7 @@ namespace sc
|
||||
// to mark the start of each execution.
|
||||
if (!ctx.args.readonly)
|
||||
{
|
||||
const std::string header = "Execution lcl " + ctx.args.lcl + "\n";
|
||||
const std::string header = "Execution lcl " + ctx.args.lcl_id.to_string() + "\n";
|
||||
if (write(outfd, header.data(), header.size()) == -1 ||
|
||||
write(errfd, header.data(), header.size()) == -1)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace sc
|
||||
uint64_t time = 0;
|
||||
|
||||
// Current HotPocket lcl (seq no. and ledger hash hex)
|
||||
std::string lcl;
|
||||
p2p::sequence_hash lcl_id;
|
||||
|
||||
// Current HotPocket primary shard id (struct of seq no. and ledger hash)
|
||||
p2p::sequence_hash lasl_primary_shard_id;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace usr
|
||||
* 1 if nonce has expired.
|
||||
* 2 if message with same nonce/sig has already been submitted.
|
||||
*/
|
||||
int input_nonce_map::check(const std::string &pubkey, const std::string &nonce, const std::string &sig, const uint64_t &max_lcl_seqno, const bool no_add)
|
||||
int input_nonce_map::check(const std::string &pubkey, const std::string &nonce, const std::string &sig, const uint64_t &max_lcl_seq_no, const bool no_add)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
@@ -25,20 +25,20 @@ namespace usr
|
||||
{
|
||||
result = 0;
|
||||
if (!no_add)
|
||||
nonce_map.emplace(pubkey, std::tuple<std::string, std::string, uint64_t>(nonce, sig, max_lcl_seqno));
|
||||
nonce_map.emplace(pubkey, std::tuple<std::string, std::string, uint64_t>(nonce, sig, max_lcl_seq_no));
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string &existing_nonce = std::get<0>(itr->second);
|
||||
const uint64_t expire_lcl_seqno = std::get<2>(itr->second);
|
||||
const uint64_t expire_lcl_seq_no = std::get<2>(itr->second);
|
||||
|
||||
// Check if previous nonce has already expired or it is less than new nonce.
|
||||
if (expire_lcl_seqno <= ledger::ctx.get_lcl_id().seq_no || existing_nonce < nonce)
|
||||
if (expire_lcl_seq_no <= ledger::ctx.get_lcl_id().seq_no || existing_nonce < nonce)
|
||||
{
|
||||
if (!no_add)
|
||||
{
|
||||
std::get<0>(itr->second) = nonce;
|
||||
std::get<2>(itr->second) = max_lcl_seqno;
|
||||
std::get<2>(itr->second) = max_lcl_seq_no;
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace usr
|
||||
void cleanup();
|
||||
|
||||
public:
|
||||
int check(const std::string &pubkey, const std::string &nonce, const std::string &sig, const uint64_t &max_lcl_seqno, const bool no_add = false);
|
||||
int check(const std::string &pubkey, const std::string &nonce, const std::string &sig, const uint64_t &max_lcl_seq_no, const bool no_add = false);
|
||||
};
|
||||
|
||||
} // namespace usr
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace usr
|
||||
{
|
||||
std::string input;
|
||||
std::string nonce;
|
||||
uint64_t max_lcl_seqno;
|
||||
uint64_t max_lcl_seq_no;
|
||||
std::string sig;
|
||||
util::PROTOCOL protocol; // The message protocol used by the user.
|
||||
|
||||
|
||||
@@ -173,8 +173,8 @@ namespace usr
|
||||
|
||||
std::string input_data;
|
||||
std::string nonce;
|
||||
uint64_t max_lcl_seqno;
|
||||
if (parser.extract_input_container(input_data, nonce, max_lcl_seqno, input_container) != -1)
|
||||
uint64_t max_lcl_seq_no;
|
||||
if (parser.extract_input_container(input_data, nonce, max_lcl_seq_no, input_container) != -1)
|
||||
{
|
||||
// Check for max nonce size.
|
||||
if (nonce.size() > MAX_INPUT_NONCE_SIZE)
|
||||
@@ -191,7 +191,7 @@ namespace usr
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int nonce_status = nonce_map.check(user.pubkey, nonce, sig, max_lcl_seqno, true);
|
||||
const int nonce_status = nonce_map.check(user.pubkey, nonce, sig, max_lcl_seq_no, true);
|
||||
if (nonce_status == 0)
|
||||
{
|
||||
//Add to the submitted input list.
|
||||
@@ -228,7 +228,7 @@ namespace usr
|
||||
{
|
||||
std::vector<uint8_t> msg;
|
||||
const p2p::sequence_hash lcl_id = ledger::ctx.get_lcl_id();
|
||||
parser.create_status_response(msg, lcl_id.seq_no, ledger::get_lcl_string(lcl_id));
|
||||
parser.create_status_response(msg, lcl_id.seq_no, lcl_id.hash.to_string_view());
|
||||
user.session.send(msg);
|
||||
return 0;
|
||||
}
|
||||
@@ -365,7 +365,7 @@ namespace usr
|
||||
|
||||
// Extract information from input container.
|
||||
msg::usrmsg::usrmsg_parser parser(submitted.protocol);
|
||||
if (parser.extract_input_container(extracted.input, extracted.nonce, extracted.max_lcl_seqno, submitted.input_container) == -1)
|
||||
if (parser.extract_input_container(extracted.input, extracted.nonce, extracted.max_lcl_seq_no, submitted.input_container) == -1)
|
||||
{
|
||||
LOG_DEBUG << "User input bad input container format.";
|
||||
return msg::usrmsg::REASON_BAD_MSG_FORMAT;
|
||||
@@ -385,7 +385,7 @@ namespace usr
|
||||
const uint64_t lcl_seq_no, size_t &total_input_size, std::string &hash, util::buffer_view &input)
|
||||
{
|
||||
// Ignore the input if our ledger has passed the input TTL.
|
||||
if (extracted_input.max_lcl_seqno <= lcl_seq_no)
|
||||
if (extracted_input.max_lcl_seq_no <= lcl_seq_no)
|
||||
{
|
||||
LOG_DEBUG << "User input bad max ledger seq expired.";
|
||||
return msg::usrmsg::REASON_MAX_LEDGER_EXPIRED;
|
||||
@@ -400,7 +400,7 @@ namespace usr
|
||||
return msg::usrmsg::REASON_ROUND_INPUTS_OVERFLOW;
|
||||
}
|
||||
|
||||
const int nonce_status = nonce_map.check(user_pubkey, extracted_input.nonce, extracted_input.sig, extracted_input.max_lcl_seqno);
|
||||
const int nonce_status = nonce_map.check(user_pubkey, extracted_input.nonce, extracted_input.sig, extracted_input.max_lcl_seq_no);
|
||||
if (nonce_status > 0)
|
||||
{
|
||||
LOG_DEBUG << (nonce_status == 1 ? "User input nonce expired." : "User input with same nonce/sig already submitted.");
|
||||
|
||||
Reference in New Issue
Block a user