diff --git a/examples/js_client/browser-example.html b/examples/js_client/browser-example.html index 222f2969..a8b157b6 100644 --- a/examples/js_client/browser-example.html +++ b/examples/js_client/browser-example.html @@ -64,12 +64,15 @@ // This will get fired when contract sends an output. hpc.on(HotPocket.events.contractOutput, (r) => { - r.outputs.forEach(o => console.log("Contract output>> " + o)); + r.outputs.forEach(o => console.log(`Output (ledger:${r.ledgerSeqNo})>> ${o}`)); + + // Retrieve ledger info. + hpc.getLedgerBySeqNo(r.ledgerSeqNo, true, true).then(ledger => console.log(ledger)); }) // This will get fired when contract sends a read response. hpc.on(HotPocket.events.contractReadResponse, (response) => { - console.log("Contract read response>> " + response); + console.log("Read response>> " + response); }) // Establish HotPocket connection. diff --git a/examples/js_client/hp-client-lib.js b/examples/js_client/hp-client-lib.js index 0cb7d60b..a5d87f83 100644 --- a/examples/js_client/hp-client-lib.js +++ b/examples/js_client/hp-client-lib.js @@ -632,6 +632,7 @@ return { pubkey: msgHelper.deserializeValue(i.pubkey), hash: msgHelper.deserializeValue(i.hash), + nonce: i.nonce, blob: msgHelper.deserializeValue(i.blob) } }); @@ -805,12 +806,12 @@ throw "Max ledger seq no. or offset cannot be 0."; if (!isOffset && !maxLedger) throw "Max ledger seq. no not specified."; + if (nonce && (!Number.isInteger(nonce) || nonce < 0)) + throw "Input nonce must be a positive integer."; // Use time-based incrementing nonce if not specified. if (!nonce) - nonce = (new Date()).getTime().toString(); - else - nonce = nonce.toString(); + nonce = (new Date()).getTime(); // If max ledger is specified as offset, we need to get current ledger status and add the offset to it. if (isOffset) { diff --git a/examples/js_client/text-client.js b/examples/js_client/text-client.js index a69d6da3..78e65302 100644 --- a/examples/js_client/text-client.js +++ b/examples/js_client/text-client.js @@ -59,12 +59,12 @@ async function main() { // This will get fired when contract sends outputs. hpc.on(HotPocket.events.contractOutput, (r) => { - r.outputs.forEach(o => console.log("Contract output>> " + o)); + r.outputs.forEach(o => console.log(`Output (ledger:${r.ledgerSeqNo})>> ${o}`)); }) // This will get fired when contract sends a read response. hpc.on(HotPocket.events.contractReadResponse, (response) => { - console.log("Contract read response>> " + response); + console.log("Read response>> " + response); }) // Establish HotPocket connection. @@ -93,8 +93,13 @@ async function main() { rl.question('', (inp) => { if (inp.length > 0) { - if (inp.startsWith("read ")) + if (inp.startsWith("read ")) { hpc.sendContractReadRequest(inp.substr(5)); + } + else if (inp.startsWith("ledger ")) { + hpc.getLedgerBySeqNo(parseInt(inp.substr(7)), true, true) + .then(result => console.log(result)); + } else { hpc.submitContractInput(inp).then(input => { // console.log(input.hash); diff --git a/src/ledger/ledger.cpp b/src/ledger/ledger.cpp index 2249c0b2..5072cf51 100644 --- a/src/ledger/ledger.cpp +++ b/src/ledger/ledger.cpp @@ -323,7 +323,7 @@ namespace ledger // Insert sqlite record. std::string_view hash = util::get_string_suffix(cui.ordered_hash, BLAKE3_OUT_LEN); - std::string_view nonce = cui.ordered_hash.substr(0, cui.ordered_hash.size() - hash.size()); + const uint64_t nonce = util::uint64_from_bytes((uint8_t *)cui.ordered_hash.data()); if (sqlite::insert_user_input_record(inputs_stmt, lcl_id.seq_no, pubkey, hash, nonce, in_pos, buf.size()) == -1) RAW_DATA_RETURN(-1); diff --git a/src/ledger/ledger_common.hpp b/src/ledger/ledger_common.hpp index cffc1d3d..9a80e982 100644 --- a/src/ledger/ledger_common.hpp +++ b/src/ledger/ledger_common.hpp @@ -21,7 +21,7 @@ namespace ledger uint64_t ledger_seq_no; // Ledger seq no. std::string pubkey; // The user pubkey. std::string hash; // The hash of this input. - std::string nonce; // Nonce the user had submitted for this input. + uint64_t nonce; // Nonce the user had submitted for this input. off_t blob_offset; // Blob file offset of this input blob. size_t blob_size; // Length of the input. std::string blob; // THe actual input blob. diff --git a/src/ledger/ledger_query.cpp b/src/ledger/ledger_query.cpp index 022f0635..98565ff8 100644 --- a/src/ledger/ledger_query.cpp +++ b/src/ledger/ledger_query.cpp @@ -42,7 +42,7 @@ namespace ledger::query ledgers.push_back(std::move(ledger)); // Fill raw data if required. - if (seq_q.inputs || seq_q.outputs) + if (seq_q.seq_no > 0 && (seq_q.inputs || seq_q.outputs)) { for (ledger_record &ledger : ledgers) { diff --git a/src/ledger/sqlite.cpp b/src/ledger/sqlite.cpp index 651dd39c..702269cf 100644 --- a/src/ledger/sqlite.cpp +++ b/src/ledger/sqlite.cpp @@ -42,7 +42,6 @@ namespace ledger::sqlite #define PUBKEY_SIZE 33 #define BIND_H32_BLOB(idx, field) (field.size() == sizeof(util::h32) && sqlite3_bind_blob(stmt, idx, field.data(), sizeof(util::h32), SQLITE_STATIC) == SQLITE_OK) #define BIND_PUBKEY_BLOB(idx, field) (field.size() == PUBKEY_SIZE && sqlite3_bind_blob(stmt, idx, field.data(), PUBKEY_SIZE, SQLITE_STATIC) == SQLITE_OK) -#define BIND_BLOB(idx, field) (field.size() > 0 && sqlite3_bind_blob(stmt, idx, field.data(), field.size(), SQLITE_STATIC) == SQLITE_OK) #define GET_H32_BLOB(idx) std::string((char *)sqlite3_column_blob(stmt, idx), sizeof(util::h32)) #define GET_PUBKEY_BLOB(idx) std::string((char *)sqlite3_column_blob(stmt, idx), PUBKEY_SIZE) @@ -323,7 +322,7 @@ namespace ledger::sqlite table_column_info("ledger_seq_no", COLUMN_DATA_TYPE::INT), table_column_info("pubkey", COLUMN_DATA_TYPE::BLOB), table_column_info("hash", COLUMN_DATA_TYPE::BLOB), - table_column_info("nonce", COLUMN_DATA_TYPE::BLOB), + table_column_info("nonce", COLUMN_DATA_TYPE::INT), table_column_info("blob_offset", COLUMN_DATA_TYPE::INT), table_column_info("blob_size", COLUMN_DATA_TYPE::INT)}; @@ -455,7 +454,7 @@ namespace ledger::sqlite } int insert_user_input_record(sqlite3_stmt *stmt, const uint64_t ledger_seq_no, std::string_view pubkey, - std::string_view hash, std::string_view nonce, const uint64_t blob_offset, const uint64_t blob_size) + std::string_view hash, const uint64_t nonce, const uint64_t blob_offset, const uint64_t blob_size) { if (stmt == NULL) { @@ -467,7 +466,7 @@ namespace ledger::sqlite sqlite3_bind_int64(stmt, 1, ledger_seq_no) == SQLITE_OK && BIND_PUBKEY_BLOB(2, pubkey) && BIND_H32_BLOB(3, hash) && - BIND_BLOB(4, nonce) && + sqlite3_bind_int64(stmt, 4, nonce) == SQLITE_OK && sqlite3_bind_int64(stmt, 5, blob_offset) == SQLITE_OK && sqlite3_bind_int64(stmt, 6, blob_size) == SQLITE_OK && sqlite3_step(stmt) == SQLITE_DONE) @@ -617,7 +616,7 @@ namespace ledger::sqlite inp.ledger_seq_no = sqlite3_column_int64(stmt, 0); inp.pubkey = GET_PUBKEY_BLOB(1); inp.hash = GET_H32_BLOB(2); - // inp.nonce = GET_BLOB(3); + inp.nonce = sqlite3_column_int64(stmt, 3); inp.blob_offset = sqlite3_column_int64(stmt, 4); inp.blob_size = sqlite3_column_int64(stmt, 5); return inp; diff --git a/src/ledger/sqlite.hpp b/src/ledger/sqlite.hpp index aa269728..9f10fc1f 100644 --- a/src/ledger/sqlite.hpp +++ b/src/ledger/sqlite.hpp @@ -74,7 +74,7 @@ namespace ledger::sqlite int insert_user_record(sqlite3_stmt *stmt, const uint64_t ledger_seq_no, std::string_view pubkey); int insert_user_input_record(sqlite3_stmt *stmt, const uint64_t ledger_seq_no, std::string_view pubkey, - std::string_view hash, std::string_view nonce, const uint64_t blob_offset, const uint64_t blob_size); + std::string_view hash, const uint64_t nonce, const uint64_t blob_offset, const uint64_t blob_size); int insert_user_output_record(sqlite3_stmt *stmt, const uint64_t ledger_seq_no, std::string_view pubkey, std::string_view hash, const uint64_t blob_offset, const uint64_t output_count); diff --git a/src/msg/bson/usrmsg_bson.cpp b/src/msg/bson/usrmsg_bson.cpp index 5b29258a..7957113f 100644 --- a/src/msg/bson/usrmsg_bson.cpp +++ b/src/msg/bson/usrmsg_bson.cpp @@ -367,12 +367,12 @@ namespace msg::usrmsg::bson * @param contentjson The bson input container message. * { * "input": , - * "nonce": "", + * "nonce": , // Indicates input ordering. * "max_ledger_seq_no": * } * @return 0 on succesful extraction. -1 on failure. */ - int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_ledger_seq_no, std::string_view contentbson) + int extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view contentbson) { jsoncons::ojson d; try @@ -391,7 +391,7 @@ namespace msg::usrmsg::bson return -1; } - if (!d[msg::usrmsg::FLD_INPUT].is_byte_string_view() || !d[msg::usrmsg::FLD_NONCE].is_string() || !d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].is_uint64()) + if (!d[msg::usrmsg::FLD_INPUT].is_byte_string_view() || !d[msg::usrmsg::FLD_NONCE].is_uint64() || !d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].is_uint64()) { LOG_DEBUG << "User input container invalid field values."; return -1; @@ -400,7 +400,7 @@ namespace msg::usrmsg::bson const jsoncons::byte_string_view &bsv = d[msg::usrmsg::FLD_INPUT].as_byte_string_view(); input = std::string_view(reinterpret_cast(bsv.data()), bsv.size()); - nonce = d[msg::usrmsg::FLD_NONCE].as(); + nonce = d[msg::usrmsg::FLD_NONCE].as(); max_ledger_seq_no = d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].as(); return 0; } @@ -553,6 +553,8 @@ namespace msg::usrmsg::bson encoder.byte_string_value(inp.pubkey); encoder.key(msg::usrmsg::FLD_HASH); encoder.byte_string_value(inp.hash); + encoder.key(msg::usrmsg::FLD_NONCE); + encoder.uint64_value(inp.nonce); encoder.key(msg::usrmsg::FLD_BLOB); encoder.byte_string_value(inp.blob); diff --git a/src/msg/bson/usrmsg_bson.hpp b/src/msg/bson/usrmsg_bson.hpp index 99cbd15f..0b9dbef5 100644 --- a/src/msg/bson/usrmsg_bson.hpp +++ b/src/msg/bson/usrmsg_bson.hpp @@ -36,7 +36,7 @@ namespace msg::usrmsg::bson int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig, const jsoncons::ojson &d); - int extract_input_container(std::string &input, std::string &nonce, + int extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view contentbson); int extract_ledger_query(ledger::query::query_request &extracted_query, std::string &extracted_id, const jsoncons::ojson &d); diff --git a/src/msg/json/usrmsg_json.cpp b/src/msg/json/usrmsg_json.cpp index 2299ff23..1dde8796 100644 --- a/src/msg/json/usrmsg_json.cpp +++ b/src/msg/json/usrmsg_json.cpp @@ -715,12 +715,12 @@ namespace msg::usrmsg::json * @param contentjson The json string containing the input container message. * { * "input": "", - * "nonce": "", + * "nonce": , // Indicates input ordering. * "max_ledger_seq_no": * } * @return 0 on succesful extraction. -1 on failure. */ - int extract_input_container(std::string &input, std::string &nonce, uint64_t &max_ledger_seq_no, std::string_view contentjson) + int extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view contentjson) { jsoncons::json d; try @@ -739,14 +739,14 @@ namespace msg::usrmsg::json return -1; } - if (!d[msg::usrmsg::FLD_INPUT].is() || !d[msg::usrmsg::FLD_NONCE].is() || !d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].is()) + if (!d[msg::usrmsg::FLD_INPUT].is() || !d[msg::usrmsg::FLD_NONCE].is() || !d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].is()) { LOG_DEBUG << "User input container invalid field values."; return -1; } input = d[msg::usrmsg::FLD_INPUT].as(); - nonce = d[msg::usrmsg::FLD_NONCE].as(); + nonce = d[msg::usrmsg::FLD_NONCE].as(); max_ledger_seq_no = d[msg::usrmsg::FLD_MAX_LEDGER_SEQ_NO].as(); return 0; @@ -964,6 +964,10 @@ namespace msg::usrmsg::json msg += SEP_COLON; msg += util::to_hex(itr->hash); msg += SEP_COMMA; + msg += msg::usrmsg::FLD_NONCE; + msg += SEP_COLON_NOQUOTE; + msg += std::to_string(itr->nonce); + msg += SEP_COMMA_NOQUOTE; msg += msg::usrmsg::FLD_BLOB; msg += SEP_COLON; msg += util::to_hex(itr->blob); diff --git a/src/msg/json/usrmsg_json.hpp b/src/msg/json/usrmsg_json.hpp index 0f7a1752..68d64ad8 100644 --- a/src/msg/json/usrmsg_json.hpp +++ b/src/msg/json/usrmsg_json.hpp @@ -40,7 +40,7 @@ namespace msg::usrmsg::json int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig, const jsoncons::json &d); - int extract_input_container(std::string &input, std::string &nonce, + int extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view contentjson); int extract_ledger_query(ledger::query::query_request &extracted_query, std::string &extracted_id, const jsoncons::json &d); diff --git a/src/msg/usrmsg_common.hpp b/src/msg/usrmsg_common.hpp index e164a2e4..ed381bac 100644 --- a/src/msg/usrmsg_common.hpp +++ b/src/msg/usrmsg_common.hpp @@ -85,7 +85,6 @@ namespace msg::usrmsg 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"; constexpr const char *REASON_ROUND_INPUTS_OVERFLOW = "round_inputs_overflow"; constexpr const char *QUERY_FILTER_BY_SEQ_NO = "seq_no"; diff --git a/src/msg/usrmsg_parser.cpp b/src/msg/usrmsg_parser.cpp index 06348f5a..0ce4a945 100644 --- a/src/msg/usrmsg_parser.cpp +++ b/src/msg/usrmsg_parser.cpp @@ -97,7 +97,7 @@ namespace msg::usrmsg return busrmsg::extract_signed_input_container(extracted_input_container, extracted_sig, bdoc); } - int usrmsg_parser::extract_input_container(std::string &input, std::string &nonce, + int usrmsg_parser::extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view encoded_content) const { if (protocol == util::PROTOCOL::JSON) diff --git a/src/msg/usrmsg_parser.hpp b/src/msg/usrmsg_parser.hpp index 6bed01fa..2a767bf5 100644 --- a/src/msg/usrmsg_parser.hpp +++ b/src/msg/usrmsg_parser.hpp @@ -44,7 +44,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, + int extract_input_container(std::string &input, uint64_t &nonce, uint64_t &max_ledger_seq_no, std::string_view encoded_content) const; int extract_ledger_query(ledger::query::query_request &extracted_query, std::string &extracted_id) const; diff --git a/src/sc/sc.cpp b/src/sc/sc.cpp index a1c8422d..334bc361 100644 --- a/src/sc/sc.cpp +++ b/src/sc/sc.cpp @@ -257,7 +257,7 @@ namespace sc } else { - LOG_ERROR << "Contract process" << (ctx.args.readonly ? " (rdonly)" : "") << " ended prematurely. Exit code " << WEXITSTATUS(scstatus); + LOG_WARNING << "Contract process" << (ctx.args.readonly ? " (rdonly)" : "") << " ended prematurely. Exit code " << WEXITSTATUS(scstatus); return -1; } } diff --git a/src/usr/input_nonce_map.cpp b/src/usr/input_nonce_map.cpp index e0c011f6..85d39593 100644 --- a/src/usr/input_nonce_map.cpp +++ b/src/usr/input_nonce_map.cpp @@ -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_ledger_seq_no, const bool no_add) + int input_nonce_map::check(const std::string &pubkey, const uint64_t &nonce, const std::string &sig, const uint64_t &max_ledger_seq_no, const bool no_add) { int result = 0; @@ -25,11 +25,11 @@ namespace usr { result = 0; if (!no_add) - nonce_map.emplace(pubkey, std::tuple(nonce, sig, max_ledger_seq_no)); + nonce_map.emplace(pubkey, std::tuple(nonce, sig, max_ledger_seq_no)); } else { - const std::string &existing_nonce = std::get<0>(itr->second); + const uint64_t &existing_nonce = std::get<0>(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. diff --git a/src/usr/input_nonce_map.hpp b/src/usr/input_nonce_map.hpp index e396a306..d21c0c44 100644 --- a/src/usr/input_nonce_map.hpp +++ b/src/usr/input_nonce_map.hpp @@ -9,11 +9,12 @@ namespace usr { private: // Keeps short-lived nonces and signatures with their absolute expiration time. - std::unordered_map> nonce_map; + // Keyed by user binary pubkey. + std::unordered_map> nonce_map; void cleanup(); public: - int check(const std::string &pubkey, const std::string &nonce, const std::string &sig, const uint64_t &max_ledger_seq_no, const bool no_add = false); + int check(const std::string &pubkey, const uint64_t &nonce, const std::string &sig, const uint64_t &max_ledger_seq_no, const bool no_add = false); }; } // namespace usr diff --git a/src/usr/user_input.hpp b/src/usr/user_input.hpp index 71c3adf1..b3c7ca7f 100644 --- a/src/usr/user_input.hpp +++ b/src/usr/user_input.hpp @@ -20,7 +20,7 @@ namespace usr struct extracted_user_input { std::string input; - std::string nonce; + uint64_t nonce; uint64_t max_ledger_seq_no; std::string sig; diff --git a/src/usr/usr.cpp b/src/usr/usr.cpp index 00d64f62..0d3635bd 100644 --- a/src/usr/usr.cpp +++ b/src/usr/usr.cpp @@ -28,8 +28,6 @@ namespace usr uint64_t metric_thresholds[5]; bool init_success = false; - constexpr size_t MAX_INPUT_NONCE_SIZE = 128; - /** * Initializes the usr subsystem. Must be called once during application startup. * @return 0 for successful initialization. -1 for failure. @@ -172,7 +170,7 @@ namespace usr std::scoped_lock lock(ctx.users_mutex); std::string input_data; - std::string nonce; + uint64_t nonce; uint64_t max_ledger_seq_no; if (parser.extract_input_container(input_data, nonce, max_ledger_seq_no, input_container) != -1) { @@ -191,13 +189,6 @@ namespace usr return -1; } - // Check for max nonce size. - if (nonce.size() > MAX_INPUT_NONCE_SIZE) - { - send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_NONCE_OVERFLOW, crypto::get_hash(sig)); - return -1; - } - // Check whether the newly received input is going to cause overflow of round input limit. if (conf::cfg.contract.round_limits.user_input_bytes > 0 && (user.collected_input_size + input_data.size()) > conf::cfg.contract.round_limits.user_input_bytes) @@ -423,10 +414,9 @@ namespace usr // Ordered hash is used as the globally unqiue 'key' to represent this input for this consensus round. // It is prefixed with the nonce to support user-defined sort order and the input hash is appended // to make it unique among inputs from all users. - // Ordered hash = nonce + input hash - // Nonce length is not fixed. So last 32 bytes of ordered hash always contains the input hash. + // Ordered hash = nonce (8 bytes) + input hash (32 bytes) // In the ledger, we will store the nonce and input hash separately. - ordered_hash = extracted_input.nonce + crypto::get_hash(extracted_input.sig); + ordered_hash = util::uint64_to_string_bytes(extracted_input.nonce) + crypto::get_hash(extracted_input.sig); // 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_ledger_seq_no > lcl_seq_no + conf::cfg.contract.max_input_ledger_offset) diff --git a/src/util/util.cpp b/src/util/util.cpp index 11465de0..f6bb2a83 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -487,6 +487,17 @@ namespace util ((uint64_t)data[7]); } + /** + * Returns a string buffer containing uint64 bytes. + */ + const std::string uint64_to_string_bytes(const uint64_t x) + { + std::string s; + s.resize(sizeof(uint64_t)); + uint64_to_bytes((uint8_t *)s.data(), x); + return s; + } + /** * Returns the substring view from the end of the provided string view. */ diff --git a/src/util/util.hpp b/src/util/util.hpp index fcf46cef..57e7b60e 100644 --- a/src/util/util.hpp +++ b/src/util/util.hpp @@ -81,6 +81,8 @@ namespace util uint64_t uint64_from_bytes(const uint8_t *data); + const std::string uint64_to_string_bytes(const uint64_t x); + std::string_view get_string_suffix(std::string_view sv, const size_t suffix_len); } // namespace util diff --git a/test/local-cluster/Dockerfile b/test/local-cluster/Dockerfile index 313da7d4..03173f6d 100644 --- a/test/local-cluster/Dockerfile +++ b/test/local-cluster/Dockerfile @@ -18,4 +18,7 @@ COPY ./bin/hpcore . COPY ./bin/hpfs . COPY ./bin/hpws . -ENTRYPOINT ["/hp/hpcore"] \ No newline at end of file +ENTRYPOINT ["/hp/hpcore"] + +# Run with vagrind +# ENTRYPOINT ["valgrind", "/hp/hpcore"] \ No newline at end of file diff --git a/test/metrics/metrics.js b/test/metrics/metrics.js index 0ca77f2d..2f844dcf 100644 --- a/test/metrics/metrics.js +++ b/test/metrics/metrics.js @@ -109,8 +109,7 @@ function singleUserInputOutput(payloadKB, requestCount) { timer.start(); for (let i = 0; i < requestCount; i++) { - const nonce = i.toString().padStart(5); - const input = await hpc.submitContractInput(payload, nonce, 10); + const input = await hpc.submitContractInput(payload, i, 10); input.submissionStatus.then(s => { if (s.status != "accepted") console.log(s.reason);