mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Optimized string passing with string_view.
This commit is contained in:
@@ -143,7 +143,7 @@ int load_config()
|
||||
ifs.close();
|
||||
|
||||
// Check whether the contract version is specified.
|
||||
std::string cfgversion = d["version"].GetString();
|
||||
std::string_view cfgversion = util::getsv(d["version"]);
|
||||
if (cfgversion.empty())
|
||||
{
|
||||
std::cerr << "Contract config version missing.\n";
|
||||
@@ -151,7 +151,7 @@ int load_config()
|
||||
}
|
||||
|
||||
// Check whether this contract complies with the min version requirement.
|
||||
int verresult = util::version_compare(cfgversion, std::string(util::MIN_CONTRACT_VERSION));
|
||||
int verresult = util::version_compare(std::string(cfgversion), std::string(util::MIN_CONTRACT_VERSION));
|
||||
if (verresult == -1)
|
||||
{
|
||||
std::cerr << "Contract version too old. Minimum "
|
||||
|
||||
@@ -45,7 +45,7 @@ void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string
|
||||
* @param seckey Secret key bytes.
|
||||
* @return Signature bytes.
|
||||
*/
|
||||
std::string sign(const std::string &msg, const std::string &seckey)
|
||||
std::string sign(std::string_view msg, std::string_view seckey)
|
||||
{
|
||||
//Generate the signature using libsodium.
|
||||
|
||||
@@ -68,7 +68,7 @@ std::string sign(const std::string &msg, const std::string &seckey)
|
||||
* @param seckeyb64 Base64 secret key string.
|
||||
* @return Base64 signature string.
|
||||
*/
|
||||
std::string sign_b64(const std::string &msg, const std::string &seckeyb64)
|
||||
std::string sign_b64(std::string_view msg, std::string_view seckeyb64)
|
||||
{
|
||||
//Decode b64 string and generate the signature using libsodium.
|
||||
|
||||
@@ -96,7 +96,7 @@ std::string sign_b64(const std::string &msg, const std::string &seckeyb64)
|
||||
* @param pubkey Public key bytes.
|
||||
* @return 0 for successful verification. -1 for failure.
|
||||
*/
|
||||
int verify(const std::string &msg, const std::string &sig, const std::string &pubkey)
|
||||
int verify(std::string_view msg, std::string_view sig, std::string_view pubkey)
|
||||
{
|
||||
return crypto_sign_verify_detached(
|
||||
reinterpret_cast<const unsigned char *>(sig.data()),
|
||||
@@ -113,7 +113,7 @@ int verify(const std::string &msg, const std::string &sig, const std::string &pu
|
||||
* @param pubkeyb64 Base64 secret key.
|
||||
* @return 0 for successful verification. -1 for failure.
|
||||
*/
|
||||
int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64)
|
||||
int verify_b64(std::string_view msg, std::string_view sigb64, std::string_view pubkeyb64)
|
||||
{
|
||||
//Decode b64 string and verify the signature using libsodium.
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@ int init();
|
||||
|
||||
void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string &keytype);
|
||||
|
||||
std::string sign(const std::string &msg, const std::string &seckey);
|
||||
std::string sign(std::string_view msg, std::string_view seckey);
|
||||
|
||||
std::string sign_b64(const std::string &msg, const std::string &seckeyb64);
|
||||
std::string sign_b64(std::string_view msg, std::string_view seckeyb64);
|
||||
|
||||
int verify(const std::string &msg, const std::string &sig, const std::string &pubkey);
|
||||
int verify(std::string_view msg, std::string_view sig, std::string_view pubkey);
|
||||
|
||||
int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64);
|
||||
int verify_b64(std::string_view msg, std::string_view sigb64, std::string_view pubkeyb64);
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ socket_session::socket_session(websocket::stream<beast::tcp_stream> &websocket,
|
||||
}
|
||||
|
||||
//port and address will be used to identify from which client the message recieved in the handler
|
||||
void socket_session::server_run(const std::uint16_t port, const std::string &address)
|
||||
void socket_session::server_run(const std::uint16_t port, std::string_view address)
|
||||
{
|
||||
port_ = port;
|
||||
address_ = address;
|
||||
@@ -31,15 +31,11 @@ void socket_session::server_run(const std::uint16_t port, const std::string &add
|
||||
}
|
||||
|
||||
//port and address will be used to identify from which server the message recieved in the handler
|
||||
void socket_session::client_run(const std::uint16_t port, const std::string &address, error ec)
|
||||
void socket_session::client_run(const std::uint16_t port, std::string_view address, error ec)
|
||||
{
|
||||
port_ = port;
|
||||
address_ = address;
|
||||
|
||||
// Create a unique id for the session combining ip and port.
|
||||
uniqueid_ = address + ":";
|
||||
uniqueid_.append(std::to_string(port));
|
||||
|
||||
if (ec)
|
||||
return fail(ec, "handshake");
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ public:
|
||||
// Setting and reading flags to this is completely managed by user-code.
|
||||
std::bitset<8> flags_;
|
||||
|
||||
void server_run(const std::uint16_t port, const std::string &address);
|
||||
void client_run(const std::uint16_t port, const std::string &address, error ec);
|
||||
void server_run(const std::uint16_t port, std::string_view address);
|
||||
void client_run(const std::uint16_t port, std::string_view address, error ec);
|
||||
|
||||
// Used to send message through an active websocket connection.
|
||||
void send(std::shared_ptr<std::string const> const &ss);
|
||||
|
||||
@@ -58,7 +58,7 @@ void user_session_handler::on_message(sock::socket_session *session, const std::
|
||||
if (itr != usr::pending_challenges.end())
|
||||
{
|
||||
std::string userpubkey;
|
||||
const std::string &original_challenge = itr->second;
|
||||
std::string_view original_challenge = itr->second;
|
||||
if (usr::verify_user_challenge_response(userpubkey, message, original_challenge) == 0)
|
||||
{
|
||||
// Challenge verification successful.
|
||||
|
||||
@@ -23,13 +23,13 @@ namespace usr
|
||||
* Global user list. (Exposed to other sub systems)
|
||||
* Map key: User socket session id (<ip:port>)
|
||||
*/
|
||||
std::map<std::string, util::contract_user> users;
|
||||
std::map<std::string, util::contract_user, std::less<>> users;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
* Map key: User socket session id (<ip:port>)
|
||||
*/
|
||||
std::map<std::string, std::string> pending_challenges;
|
||||
std::map<std::string, std::string, std::less<>> pending_challenges;
|
||||
|
||||
/**
|
||||
* User session handler instance. This instance's methods will be fired for any user socket activity.
|
||||
@@ -127,7 +127,7 @@ void create_user_challenge(std::string &msg, std::string &challengeb64)
|
||||
* @param original_challenge The original base64 challenge string issued to the user.
|
||||
* @return 0 if challenge response is verified. -1 if challenge not met or an error occurs.
|
||||
*/
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge)
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, std::string_view response, std::string_view original_challenge)
|
||||
{
|
||||
// We load response raw bytes into json document.
|
||||
rapidjson::Document d;
|
||||
@@ -167,10 +167,10 @@ int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::
|
||||
}
|
||||
|
||||
// Verify the challenge signature. We do this last due to signature verification cost.
|
||||
std::string sigb64 = d[CHALLENGE_RESP_SIG].GetString();
|
||||
extracted_pubkeyb64 = d[CHALLENGE_RESP_PUBKEY].GetString();
|
||||
|
||||
if (crypto::verify_b64(original_challenge, sigb64, extracted_pubkeyb64) != 0)
|
||||
if (crypto::verify_b64(
|
||||
original_challenge,
|
||||
util::getsv(d[CHALLENGE_RESP_SIG]),
|
||||
util::getsv(d[CHALLENGE_RESP_PUBKEY])) != 0)
|
||||
{
|
||||
std::cerr << "User challenge response signature verification failed.\n";
|
||||
return -1;
|
||||
@@ -187,7 +187,7 @@ int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::
|
||||
* @param pubkeyb64 User's base64 public key.
|
||||
* @return 0 on successful additions. -1 on failure.
|
||||
*/
|
||||
int add_user(const std::string &sessionid, const std::string &pubkeyb64)
|
||||
int add_user(std::string_view sessionid, std::string_view pubkeyb64)
|
||||
{
|
||||
if (users.count(sessionid) == 1)
|
||||
{
|
||||
@@ -228,7 +228,7 @@ int add_user(const std::string &sessionid, const std::string &pubkeyb64)
|
||||
*
|
||||
* @return 0 on successful removals. -1 on failure.
|
||||
*/
|
||||
int remove_user(const std::string &sessionid)
|
||||
int remove_user(std::string_view sessionid)
|
||||
{
|
||||
auto itr = users.find(sessionid);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _HP_USR_H_
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
#include "../util.hpp"
|
||||
|
||||
@@ -15,27 +15,22 @@ namespace usr
|
||||
/**
|
||||
* Global authenticated (challenge-verified) user list.
|
||||
*/
|
||||
extern std::map<std::string, util::contract_user> users;
|
||||
extern std::map<std::string, util::contract_user, std::less<>> users;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
*/
|
||||
extern std::map<std::string, std::string> pending_challenges;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
*/
|
||||
extern std::map<std::string, std::string> pending_challenges;
|
||||
extern std::map<std::string, std::string, std::less<>> pending_challenges;
|
||||
|
||||
int init();
|
||||
|
||||
void create_user_challenge(std::string &msg, std::string &challengeb64);
|
||||
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge);
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, std::string_view response, std::string_view original_challenge);
|
||||
|
||||
int add_user(const std::string &sessionid, const std::string &pubkeyb64);
|
||||
int add_user(std::string_view sessionid, std::string_view pubkeyb64);
|
||||
|
||||
int remove_user(const std::string &sessionid);
|
||||
int remove_user(std::string_view sessionid);
|
||||
|
||||
int read_contract_user_outputs();
|
||||
|
||||
|
||||
18
src/util.cpp
18
src/util.cpp
@@ -1,6 +1,7 @@
|
||||
#include <string>
|
||||
#include <sodium.h>
|
||||
#include <sstream>
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
namespace util
|
||||
{
|
||||
@@ -41,7 +42,7 @@ int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t
|
||||
* @param decodedbuf_len Decoded buffer size.
|
||||
* @param base64_str Base64 string to decode.
|
||||
*/
|
||||
int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, const std::string &base64_str)
|
||||
int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, std::string_view base64_str)
|
||||
{
|
||||
const char *b64_end;
|
||||
size_t bin_len;
|
||||
@@ -63,6 +64,11 @@ int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, const std::s
|
||||
* v1 == v2 -> returns 0
|
||||
* v1 > v2 -> returns +1
|
||||
* Error -> returns -2
|
||||
*
|
||||
* Remark on string_view: In other places of the code-base we utilize string_view
|
||||
* to pass immutable string references around. However in this function we keep the 'const string&'
|
||||
* syntax because istringstream doesn't support string_view. It's not worth optmising
|
||||
* this code as it's not being used in high-scale processing.
|
||||
*/
|
||||
int version_compare(const std::string &x, const std::string &y)
|
||||
{
|
||||
@@ -88,4 +94,14 @@ int version_compare(const std::string &x, const std::string &y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a std::string_view pointing to the rapidjson Value which is assumed
|
||||
* to be a string. We use this function because rapidjson does not have build-in string_view
|
||||
* support. Passing a non-string 'v' is not supported.
|
||||
*/
|
||||
std::string_view getsv(const rapidjson::Value &v)
|
||||
{
|
||||
return std::string_view(v.GetString(), v.GetStringLength());
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
11
src/util.hpp
11
src/util.hpp
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
/**
|
||||
* Contains helper functions and data structures used by multiple other subsystems.
|
||||
@@ -42,7 +43,7 @@ struct contract_user
|
||||
int outpipe[2]; // Pipe to receive output produced by the contract
|
||||
std::string outbuffer; // Holds the contract output to be processed by consensus rounds
|
||||
|
||||
contract_user(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
contract_user(std::string_view _pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
{
|
||||
pubkeyb64 = _pubkeyb64;
|
||||
inpipe[0] = _inpipe[0];
|
||||
@@ -61,7 +62,7 @@ struct peer_node
|
||||
int inpipe[2]; // NPL pipe from HP to SC
|
||||
int outpipe[2]; // NPL pipe from SC to HP
|
||||
|
||||
peer_node(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
peer_node(std::string_view _pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
{
|
||||
pubkeyb64 = _pubkeyb64;
|
||||
inpipe[0] = _inpipe[0];
|
||||
@@ -73,9 +74,11 @@ struct peer_node
|
||||
|
||||
int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t bin_len);
|
||||
|
||||
int base64_decode(unsigned char *decoded, size_t decoded_len, const std::string &base64_str);
|
||||
int base64_decode(unsigned char *decoded, size_t decoded_len, std::string_view base64_str);
|
||||
|
||||
int version_compare(const std::string &v1, const std::string &v2);
|
||||
int version_compare(const std::string &x, const std::string &y);
|
||||
|
||||
std::string_view getsv(const rapidjson::Value &v);
|
||||
|
||||
} // namespace util
|
||||
|
||||
|
||||
Reference in New Issue
Block a user