Compilation time improvements. (#52)

* Precompiled header for all common library headers (with cmake 3.16rc3).
* Divided cmake build into shared libraries.
* Added gold linker support.
* Separated websockets lambda expressions to an independent file.
This commit is contained in:
Ravin Perera
2019-11-02 14:46:21 +05:30
committed by GitHub
parent 7b78387cef
commit cb364cc420
49 changed files with 476 additions and 377 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
**/**
!build/hpcore

6
.gitignore vendored
View File

@@ -3,9 +3,9 @@
*.swo
.*.sw?
.DS_Store
build/**
release/**
.vscode/**
build
hpsupport.dir
.vscode
**/Makefile
**/CMakeCache.txt
**/cmake_install.cmake

View File

@@ -1,42 +1,33 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.16)
project(HPCore)
# Check for gold linker for faster linking time.
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version OUTPUT_VARIABLE stdout ERROR_QUIET)
if("${stdout}" MATCHES "GNU gold")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
else()
message(WARNING "GNU gold linker isn't available, using the default system linker.")
endif()
add_definitions("-std=c++17")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build)
# Using buildtype MinSizeRel for smaller build outputs.
set(CMAKE_BUILD_TYPE "MinSizeRel" FORCE)
add_executable(hpcore
link_directories(/usr/local/lib)
add_library(hpsupport
src/util.cpp
src/crypto.cpp
src/conf.cpp
src/hplog.cpp
src/fbschema/common_helpers.cpp
src/fbschema/p2pmsg_helpers.cpp
src/fbschema/ledger_helpers.cpp
src/jsonschema/usrmsg_helpers.cpp
src/sock/socket_client.cpp
src/sock/socket_server.cpp
src/sock/socket_session.cpp
src/sock/socket_monitor.cpp
src/p2p/peer_session_handler.cpp
src/p2p/p2p.cpp
src/usr/user_session_handler.cpp
src/usr/usr.cpp
src/proc.cpp
src/cons/cons.cpp
src/cons/ledger_handler.cpp
src/main.cpp
)
add_custom_target(docker
COMMAND strip ./build/hpcore
COMMAND docker build -t hpcore:latest .
)
set_target_properties(docker PROPERTIES EXCLUDE_FROM_ALL TRUE)
add_dependencies(docker hpcore)
target_link_libraries(hpcore
target_link_libraries(hpsupport
libsodium.a
libboost_system.a
libboost_thread.a
@@ -46,4 +37,69 @@ target_link_libraries(hpcore
pthread
crypto
ssl
)
)
add_library(hpsock
src/sock/socket_client.cpp
src/sock/socket_server.cpp
src/sock/socket_message.cpp
src/sock/socket_monitor.cpp
src/sock/socket_session.cpp
src/sock/socket_session_lambda.cpp
)
target_link_libraries(hpsock hpsupport)
add_library(hpschema
src/fbschema/common_helpers.cpp
src/fbschema/p2pmsg_helpers.cpp
src/fbschema/ledger_helpers.cpp
src/jsonschema/usrmsg_helpers.cpp
)
target_link_libraries(hpschema hpsupport)
add_library(hpp2p
src/p2p/peer_session_handler.cpp
src/p2p/p2p.cpp
)
target_link_libraries(hpp2p hpsupport hpsock hpschema)
add_library(hpusr
src/usr/user_session_handler.cpp
src/usr/usr.cpp
)
target_link_libraries(hpusr hpsupport hpsock hpschema)
add_library(hpcons
src/cons/cons.cpp
src/cons/ledger_handler.cpp
)
target_link_libraries(hpcons hpsupport hpp2p hpusr)
add_executable(hpcore
src/main.cpp
)
target_link_libraries(hpcore
hpsupport
hpschema
hpsock
hpp2p
hpusr
hpcons
)
target_precompile_headers(hpsupport PUBLIC src/pchheader.hpp)
target_precompile_headers(hpcore REUSE_FROM hpsupport)
target_precompile_headers(hpsock REUSE_FROM hpsupport)
target_precompile_headers(hpschema REUSE_FROM hpsupport)
target_precompile_headers(hpp2p REUSE_FROM hpsupport)
target_precompile_headers(hpusr REUSE_FROM hpsupport)
target_precompile_headers(hpcons REUSE_FROM hpsupport)
# Create docker image from hpcore build output with 'make docker'
# Requires docker to be runnable without 'sudo'
add_custom_target(docker
COMMAND strip ./build/hpcore
COMMAND docker build -t hpcore:latest .
)
set_target_properties(docker PROPERTIES EXCLUDE_FROM_ALL TRUE)
add_dependencies(docker hpcore)

View File

@@ -15,6 +15,12 @@ A C++ version of hotpocket designed for production envrionments, original protot
## Steps to setup Hot Pocket
#### Install CMAKE 3.16
1. Download and extract [cmake-3.16.0-rc3-Linux-x86_64.tar.gz](https://github.com/Kitware/CMake/releases/download/v3.16.0-rc3/cmake-3.16.0-rc3-Linux-x86_64.tar.gz)
2. Navigate into the extracted directory in a terminal.
3. Run `sudo cp -r bin/* /usr/local/bin/`
4. Run `sudo cp -r share/* /usr/local/share/`
#### Install Libsodium
Instructions are based on [this](https://libsodium.gitbook.io/doc/installation).
@@ -68,9 +74,6 @@ When you make a change to `message.fbc` defnition file, you need to run this:
This will update your library cache and avoid potential issues when running your compiled C++ program which links to newly installed libraries.
#### Install CMAKE
If you use apt, run `sudo apt install cmake` or follow [this](https://cmake.org/install/).
#### Build and run Hot Pocket
1. Navigate to hotpocket repo root.
1. Run `cmake .` (You only have to do this once)

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Generate contract sub-directories within this script directory for the given no. of cluster nodes.
# Usage (to generate 8-node cluster): ./cluster.sh 8
# Usage (to generate 8-node cluster): ./cluster-create.sh 8
# Validate the node count arg.
if [ -n "$1" ] && [ "$1" -eq "$1" ] 2>/dev/null; then

View File

@@ -1,15 +1,4 @@
#include <cstdio>
#include <iostream>
#include <fstream>
#include <unordered_set>
#include <sodium.h>
#include <rapidjson/document.h>
#include <rapidjson/schema.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/prettywriter.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "pchheader.hpp"
#include "conf.hpp"
#include "crypto.hpp"
#include "util.hpp"

View File

@@ -1,10 +1,7 @@
#ifndef _HP_CONF_H_
#define _HP_CONF_H_
#ifndef _HP_CONF_
#define _HP_CONF_
#include <rapidjson/document.h>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include "pchheader.hpp"
/**
* Manages the central contract config and context structs.

View File

@@ -1,8 +1,5 @@
#include <math.h>
#include <thread>
#include <flatbuffers/flatbuffers.h>
#include <boost/filesystem.hpp>
#include <fstream>
#include "../pchheader.hpp"
#include "../conf.hpp"
#include "../usr/usr.hpp"
#include "../p2p/p2p.hpp"

View File

@@ -1,10 +1,7 @@
#ifndef _HP_CONS_H_
#define _HP_CONS_H_
#ifndef _HP_CONS_
#define _HP_CONS_
#include <vector>
#include <unordered_map>
#include <list>
#include <ctime>
#include "../pchheader.hpp"
#include "../proc.hpp"
#include "../p2p/p2p.hpp"

View File

@@ -1,8 +1,5 @@
#include <flatbuffers/flatbuffers.h>
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include "../pchheader.hpp"
#include "../conf.hpp"
#include "../crypto.hpp"
#include "../p2p/p2p.hpp"

View File

@@ -1,5 +1,5 @@
#ifndef _HP_CONS_LEDGER_H_
#define _HP_CONS_LEDGER_H_
#ifndef _HP_CONS_LEDGER_
#define _HP_CONS_LEDGER_
#include "../p2p/p2p.hpp"

View File

@@ -1,5 +1,4 @@
#include <cstdio>
#include <iostream>
#include "pchheader.hpp"
#include "crypto.hpp"
#include "util.hpp"

View File

@@ -1,7 +1,7 @@
#ifndef _HP_CRYPTO_H_
#define _HP_CRYPTO_H_
#ifndef _HP_CRYPTO_
#define _HP_CRYPTO_
#include <sodium.h>
#include "pchheader.hpp"
/**
* Offers convenience functions for cryptographic operations wrapping libsodium.

View File

@@ -1,8 +1,7 @@
#ifndef _HP_FBSCHEMA_COMMON_HELPERS_H_
#define _HP_FBSCHEMA_COMMON_HELPERS_H_
#ifndef _HP_FBSCHEMA_COMMON_HELPERS_
#define _HP_FBSCHEMA_COMMON_HELPERS_
#include <string>
#include <unordered_set>
#include "../pchheader.hpp"
#include <flatbuffers/flatbuffers.h>
#include "common_schema_generated.h"

View File

@@ -1,8 +1,8 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_H_
#define FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_H_
#ifndef FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_
#define FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_
#include "flatbuffers/flatbuffers.h"
@@ -137,4 +137,4 @@ inline flatbuffers::Offset<ByteArray> CreateByteArrayDirect(
} // namespace fbschema
#endif // FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_H_
#endif // FLATBUFFERS_GENERATED_COMMONSCHEMA_FBSCHEMA_

View File

@@ -1,4 +1,5 @@
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "ledger_schema_generated.h"
#include "../p2p/p2p.hpp"
#include "common_helpers.hpp"

View File

@@ -1,9 +1,8 @@
#ifndef _HP_FBSCHEMA_LEDGER_HELPERS_H_
#define _HP_FBSCHEMA_LEDGER_HELPERS_H_
#ifndef _HP_FBSCHEMA_LEDGER_HELPERS_
#define _HP_FBSCHEMA_LEDGER_HELPERS_
#include <string>
#include <unordered_set>
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "ledger_schema_generated.h"
#include "../p2p/p2p.hpp"

View File

@@ -1,8 +1,8 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_H_
#define FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_H_
#ifndef FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_
#define FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_
#include "flatbuffers/flatbuffers.h"
@@ -245,4 +245,4 @@ inline void FinishSizePrefixedLedgerBuffer(
} // namespace ledger
} // namespace fbschema
#endif // FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_H_
#endif // FLATBUFFERS_GENERATED_LEDGERSCHEMA_FBSCHEMA_LEDGER_

View File

@@ -1,8 +1,8 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_H_
#define FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_H_
#ifndef FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_
#define FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_
#include "flatbuffers/flatbuffers.h"
@@ -168,4 +168,4 @@ inline void FinishSizePrefixedContainerBuffer(
} // namespace p2pmsg
} // namespace fbschema
#endif // FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_H_
#endif // FLATBUFFERS_GENERATED_P2PMSGCONTAINER_FBSCHEMA_P2PMSG_

View File

@@ -1,8 +1,8 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_H_
#define FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_H_
#ifndef FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_
#define FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_
#include "flatbuffers/flatbuffers.h"
@@ -836,4 +836,4 @@ inline void FinishSizePrefixedContentBuffer(
} // namespace p2pmsg
} // namespace fbschema
#endif // FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_H_
#endif // FLATBUFFERS_GENERATED_P2PMSGCONTENT_FBSCHEMA_P2PMSG_

View File

@@ -1,5 +1,5 @@
#include <flatbuffers/flatbuffers.h>
#include <string>
#include "../pchheader.hpp"
#include "../conf.hpp"
#include "../crypto.hpp"
#include "../util.hpp"

View File

@@ -1,8 +1,8 @@
#ifndef _HP_FBSCHEMA_P2PMSG_HELPERS_H_
#define _HP_FBSCHEMA_P2PMSG_HELPERS_H_
#ifndef _HP_FBSCHEMA_P2PMSG_HELPERS_
#define _HP_FBSCHEMA_P2PMSG_HELPERS_
#include <string>
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "p2pmsg_container_generated.h"
#include "p2pmsg_content_generated.h"
#include "../p2p/p2p.hpp"

View File

@@ -1,17 +1,4 @@
#include <iostream>
#include <string>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/keyword_fwd.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include "pchheader.hpp"
#include "conf.hpp"
#include "hplog.hpp"

View File

@@ -1,13 +1,7 @@
#ifndef _HP_HPLOG_H_
#define _HP_HPLOG_H_
#ifndef _HP_HPLOG_
#define _HP_HPLOG_
#include <iostream>
#include <string>
#include <boost/log/core.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include "pchheader.hpp"
#include "conf.hpp"
namespace src = boost::log::sources;

View File

@@ -1,5 +1,4 @@
#include <rapidjson/document.h>
#include <sodium.h>
#include "../pchheader.hpp"
#include "../util.hpp"
#include "../crypto.hpp"
#include "../hplog.hpp"

View File

@@ -1,7 +1,7 @@
#ifndef _HP_JSONSCHEMA_USRMSG_HELPERS_H_
#define _HP_JSONSCHEMA_USRMSG_HELPERS_H_
#ifndef _HP_JSONSCHEMA_USRMSG_HELPERS_
#define _HP_JSONSCHEMA_USRMSG_HELPERS_
#include <string>
#include "../pchheader.hpp"
namespace jsonschema::usrmsg
{

View File

@@ -2,19 +2,14 @@
Entry point for HP Core
**/
// This will direct all boost exceptions to our error handler.
#define BOOST_NO_EXCEPTIONS
#include <cstdio>
#include <iostream>
#include <thread>
#include <unistd.h>
#include "pchheader.hpp"
#include "util.hpp"
#include "conf.hpp"
#include "crypto.hpp"
#include "usr/usr.hpp"
#include "proc.hpp"
#include "hplog.hpp"
#include "usr/usr.hpp"
#include "p2p/p2p.hpp"
#include "cons/cons.hpp"
/**

View File

@@ -1,4 +1,4 @@
#include <iostream>
#include "../pchheader.hpp"
#include "../sock/socket_server.hpp"
#include "../sock/socket_client.hpp"
#include "../conf.hpp"
@@ -8,7 +8,7 @@
#include "p2p.hpp"
#include "peer_session_handler.hpp"
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
namespace ssl = boost::asio::ssl;
namespace p2p
{

View File

@@ -1,10 +1,7 @@
#ifndef _HP_P2P_H_
#define _HP_P2P_H_
#ifndef _HP_P2P_
#define _HP_P2P_
#include <unordered_set>
#include <unordered_map>
#include <list>
#include <mutex>
#include "../pchheader.hpp"
#include "../sock/socket_session.hpp"
#include "peer_session_handler.hpp"

View File

@@ -1,5 +1,4 @@
#include <iostream>
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "../conf.hpp"
#include "../crypto.hpp"
#include "../util.hpp"
@@ -7,6 +6,7 @@
#include "../fbschema/p2pmsg_container_generated.h"
#include "../fbschema/p2pmsg_content_generated.h"
#include "../fbschema/p2pmsg_helpers.hpp"
#include "../sock/socket_message.hpp"
#include "p2p.hpp"
#include "peer_session_handler.hpp"
@@ -15,26 +15,6 @@ namespace p2pmsg = fbschema::p2pmsg;
namespace p2p
{
peer_outbound_message::peer_outbound_message(
std::shared_ptr<flatbuffers::FlatBufferBuilder> _fbbuilder_ptr)
{
fbbuilder_ptr = _fbbuilder_ptr;
}
// Returns a reference to the flatbuffer builder object.
flatbuffers::FlatBufferBuilder &peer_outbound_message::builder()
{
return *fbbuilder_ptr;
}
// Returns a reference to the data buffer that must be written to the socket.
std::string_view peer_outbound_message::buffer()
{
return std::string_view(
reinterpret_cast<const char *>((*fbbuilder_ptr).GetBufferPointer()),
(*fbbuilder_ptr).GetSize());
}
/**
* This gets hit every time a peer connects to HP via the peer port (configured in contract config).
*/

View File

@@ -1,33 +1,14 @@
#ifndef _HP_PEER_SESSION_HANDLER_H_
#define _HP_PEER_SESSION_HANDLER_H_
#ifndef _HP_PEER_SESSION_HANDLER_
#define _HP_PEER_SESSION_HANDLER_
#include <boost/beast/core.hpp>
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "../sock/socket_session_handler.hpp"
#include "../sock/socket_session.hpp"
#include "../sock/socket_message.hpp"
namespace p2p
{
/**
* Represents a peer message generated using flatbuffer that must be sent to the socket.
* We keep a shared_ptr of flatbuffer builder to support broadcasting the same message
* on multiple connections without copying buffer contents.
*/
class peer_outbound_message : public sock::outbound_message
{
std::shared_ptr<flatbuffers::FlatBufferBuilder> fbbuilder_ptr;
public:
peer_outbound_message(std::shared_ptr<flatbuffers::FlatBufferBuilder> _fbbuilder_ptr);
// Returns a reference to the flatbuffer builder object.
flatbuffers::FlatBufferBuilder& builder();
// Returns a reference to the data buffer that must be written to the socket.
virtual std::string_view buffer();
};
class peer_session_handler : public sock::socket_session_handler<peer_outbound_message>
{
public:

57
src/pchheader.hpp Normal file
View File

@@ -0,0 +1,57 @@
#ifndef _HP_PCHHEADER_
#define _HP_PCHHEADER_
// This will direct all boost exceptions to our error handler.
#define BOOST_NO_EXCEPTIONS
#include <bitset>
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/expressions/keyword_fwd.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/thread/thread.hpp>
#include <chrono>
#include <cstdio>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <list>
#include <math.h>
#include <memory>
#include <mutex>
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/schema.h>
#include <sodium.h>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <string_view>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <thread>
#include <unistd.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#endif

View File

@@ -1,14 +1,4 @@
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <unistd.h>
#include <sstream>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <boost/filesystem.hpp>
#include "pchheader.hpp"
#include "proc.hpp"
#include "conf.hpp"
#include "hplog.hpp"

View File

@@ -1,11 +1,7 @@
#ifndef _HP_PROC_H_
#define _HP_PROC_H_
#ifndef _HP_PROC_
#define _HP_PROC_
#include <cstdio>
#include <iostream>
#include <unordered_map>
#include <vector>
#include <list>
#include "pchheader.hpp"
#include "usr/usr.hpp"
#include "util.hpp"

View File

@@ -1,5 +1,5 @@
#ifndef _SOCK_CLIENT_SESSION_H_
#define _SOCK_CLIENT_SESSION_H_
#ifndef _HP_SOCKET_CLIENT_
#define _HP_SOCKET_CLIENT_
#include "socket_session_handler.hpp"
#include "../hplog.hpp"

View File

@@ -0,0 +1,44 @@
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
#include "socket_message.hpp"
namespace usr
{
user_outbound_message::user_outbound_message(std::string &&_msg)
{
msg = std::move(_msg);
}
// Returns the buffer that should be written to the socket.
std::string_view user_outbound_message::buffer()
{
return msg;
}
}
namespace p2p
{
peer_outbound_message::peer_outbound_message(
std::shared_ptr<flatbuffers::FlatBufferBuilder> _fbbuilder_ptr)
{
fbbuilder_ptr = _fbbuilder_ptr;
}
// Returns a reference to the flatbuffer builder object.
flatbuffers::FlatBufferBuilder &peer_outbound_message::builder()
{
return *fbbuilder_ptr;
}
// Returns a reference to the data buffer that must be written to the socket.
std::string_view peer_outbound_message::buffer()
{
return std::string_view(
reinterpret_cast<const char *>((*fbbuilder_ptr).GetBufferPointer()),
(*fbbuilder_ptr).GetSize());
}
}

View File

@@ -0,0 +1,70 @@
#ifndef _HP_SOCKET_MESSAGE_
#define _HP_SOCKET_MESSAGE_
#include <flatbuffers/flatbuffers.h>
#include "../pchheader.hpp"
namespace sock
{
/**
* Represents an outbound message that is sent with a websocket.
* We use this class to wrap different object types holding actual message contents.
* We use this mechanism to achieve end-to-end zero-copy between original message
* content generator and websocket flush.
*/
class outbound_message
{
public:
// Returns a pointer to the internal buffer owned by the message object.
// Contents of this buffer is the message that is sent/received with the socket.
virtual std::string_view buffer() = 0;
};
}
namespace usr
{
/**
* Represents a message (bytes) that is sent to a user.
*/
class user_outbound_message : public sock::outbound_message
{
// Contains message bytes.
std::string msg;
public:
user_outbound_message(std::string &&_msg);
// Returns the buffer that should be written to the socket.
virtual std::string_view buffer();
};
}
namespace p2p
{
/**
* Represents a peer message generated using flatbuffer that must be sent to the socket.
* We keep a shared_ptr of flatbuffer builder to support broadcasting the same message
* on multiple connections without copying buffer contents.
*/
class peer_outbound_message : public sock::outbound_message
{
std::shared_ptr<flatbuffers::FlatBufferBuilder> fbbuilder_ptr;
public:
peer_outbound_message(std::shared_ptr<flatbuffers::FlatBufferBuilder> _fbbuilder_ptr);
// Returns a reference to the flatbuffer builder object.
flatbuffers::FlatBufferBuilder& builder();
// Returns a reference to the data buffer that must be written to the socket.
virtual std::string_view buffer();
};
}
#endif

View File

@@ -1,5 +1,5 @@
#ifndef _SOCK_MONITOR_H_
#define _SOCK_MONITOR_H_
#ifndef _HP_SOCK_MONITOR_
#define _HP_SOCK_MONITOR_
#include "../util.hpp"
#include "socket_session.hpp"

View File

@@ -1,12 +1,12 @@
#ifndef _SOCK_SERVER_LISTENER_H_
#define _SOCK_SERVER_LISTENER_H_
#ifndef _HP_SOCKET_SERVER_
#define _HP_SOCKET_SERVER_
#include "socket_session_handler.hpp"
#include "../conf.hpp"
#include "../hplog.hpp"
namespace net = boost::asio; // namespace asio
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
namespace ssl = boost::asio::ssl;
using tcp = net::ip::tcp;
using error_code = boost::system::error_code;

View File

@@ -1,7 +1,7 @@
#include "socket_session.hpp"
#include "../p2p/peer_session_handler.hpp"
#include "../usr/user_session_handler.hpp"
#include "socket_message.hpp"
#include "socket_monitor.hpp"
#include "socket_session_handler.hpp"
namespace sock
{
@@ -45,8 +45,6 @@ void socket_session<T>::set_threshold(util::SESSION_THRESHOLDS threshold_type, u
template <class T>
void socket_session<T>::run(const std::string &&address, const std::string &&port, bool is_server_session, const session_options &sess_opts)
{
ssl::stream_base::handshake_type handshake_type = ssl::stream_base::client;
if (sess_opts.max_message_size > 0)
{
// Setting maximum file size
@@ -59,6 +57,7 @@ void socket_session<T>::run(const std::string &&address, const std::string &&por
session_threshold max_byte_per_message_threshold{sess_opts.max_bytes_per_minute, 0, 0, 60000};
thresholds.push_back(std::move(max_byte_per_message_threshold));
ssl::stream_base::handshake_type handshake_type = ssl::stream_base::client;
if (is_server_session)
{
/**
@@ -77,11 +76,7 @@ void socket_session<T>::run(const std::string &&address, const std::string &&por
beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));
// Perform the SSL handshake
ws.next_layer().async_handshake(
handshake_type,
[sp = this->shared_from_this()](error_code ec) {
sp->on_ssl_handshake(ec);
});
ws_next_layer_async_handshake(handshake_type);
}
/*
@@ -105,11 +100,7 @@ void socket_session<T>::on_ssl_handshake(error_code ec)
beast::role_type::server));
// Accept the websocket handshake
ws.async_accept(
[sp = this->shared_from_this()](
error_code ec) {
sp->on_accept(ec);
});
ws_async_accept();
}
else
{
@@ -118,11 +109,7 @@ void socket_session<T>::on_ssl_handshake(error_code ec)
beast::role_type::client));
// Perform the websocket handshake
ws.async_handshake(this->address, "/",
[sp = this->shared_from_this()](
error_code ec) {
sp->on_accept(ec);
});
ws_async_handshake();
}
}
@@ -139,12 +126,7 @@ void socket_session<T>::on_accept(error_code ec)
sess_handler.on_connect(this);
// Read a message
ws.async_read(
buffer,
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_read(ec, bytes);
});
ws_async_read();
}
/*
@@ -180,12 +162,7 @@ void socket_session<T>::on_read(error_code ec, std::size_t)
buffer.consume(buffer.size());
// Read another message
ws.async_read(
buffer,
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_read(ec, bytes);
});
ws_async_read();
}
/*
@@ -244,13 +221,7 @@ void socket_session<T>::send(T msg)
std::string_view sv = queue.front().buffer();
// We are not currently writing, so send this immediately
ws.async_write(
// Project the outbound_message buffer from the queue front into the asio buffer.
net::buffer(sv.data(), sv.length()),
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_write(ec, bytes);
});
ws_async_write(sv);
}
/*
@@ -270,12 +241,7 @@ void socket_session<T>::on_write(error_code ec, std::size_t)
if (!queue.empty())
{
std::string_view sv = queue.front().buffer();
ws.async_write(
net::buffer(sv.data(), sv.length()),
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_write(ec, bytes);
});
ws_async_write(sv);
}
}
@@ -286,11 +252,7 @@ template <class T>
void socket_session<T>::close()
{
// Close the WebSocket connection
ws.async_close(websocket::close_code::normal,
[sp = this->shared_from_this()](
error_code ec) {
sp->on_close(ec, 0);
});
ws_async_close();
}
/*
@@ -331,27 +293,8 @@ void socket_session<T>::fail(error_code ec, char const *what)
return;
}
/**
* Declaring templates with possible values for T because keeping all those in hpp file makes compile take a long time
*/
template socket_session<p2p::peer_outbound_message>::socket_session(websocket::stream<beast::ssl_stream<beast::tcp_stream>> websocket, socket_session_handler<p2p::peer_outbound_message> &sess_handler);
template socket_session<p2p::peer_outbound_message>::~socket_session();
template void socket_session<p2p::peer_outbound_message>::set_message_max_size(uint64_t size);
template void socket_session<p2p::peer_outbound_message>::run(const std::string &&address, const std::string &&port, bool is_server_session, const session_options &sess_opts);
template void socket_session<p2p::peer_outbound_message>::send(p2p::peer_outbound_message msg);
template void socket_session<p2p::peer_outbound_message>::set_threshold(util::SESSION_THRESHOLDS threshold_type, uint64_t threshold_limit, uint64_t intervalms);
template void socket_session<p2p::peer_outbound_message>::increment(util::SESSION_THRESHOLDS threshold_type, uint64_t amount);
template void socket_session<p2p::peer_outbound_message>::init_uniqueid();
template void socket_session<p2p::peer_outbound_message>::close();
template socket_session<usr::user_outbound_message>::socket_session(websocket::stream<beast::ssl_stream<beast::tcp_stream>> websocket, socket_session_handler<usr::user_outbound_message> &sess_handler);
template socket_session<usr::user_outbound_message>::~socket_session();
template void socket_session<usr::user_outbound_message>::set_message_max_size(uint64_t size);
template void socket_session<usr::user_outbound_message>::run(const std::string &&address, const std::string &&port, bool is_server_session, const session_options &sess_opts);
template void socket_session<usr::user_outbound_message>::send(usr::user_outbound_message msg);
template void socket_session<usr::user_outbound_message>::set_threshold(util::SESSION_THRESHOLDS threshold_type, uint64_t threshold_limit, uint64_t intervalms);
template void socket_session<usr::user_outbound_message>::increment(util::SESSION_THRESHOLDS threshold_type, uint64_t amount);
template void socket_session<usr::user_outbound_message>::init_uniqueid();
template void socket_session<usr::user_outbound_message>::close();
// Template instantiations.
template class socket_session<p2p::peer_outbound_message>;
template class socket_session<usr::user_outbound_message>;
} // namespace sock

View File

@@ -1,17 +1,7 @@
#ifndef _SOCK_SERVER_SESSION_H_
#define _SOCK_SERVER_SESSION_H_
#ifndef _HP_SOCKET_SESSION_
#define _HP_SOCKET_SESSION_
#include <memory>
#include <vector>
#include <bitset>
#include <unordered_map>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include "socket_session_handler.hpp"
#include "../pchheader.hpp"
#include "../util.hpp"
#include "../hplog.hpp"
@@ -19,28 +9,12 @@ namespace beast = boost::beast;
namespace net = boost::asio;
namespace websocket = boost::beast::websocket;
namespace http = boost::beast::http;
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = net::ip::tcp;
namespace ssl = boost::asio::ssl;
using error_code = boost::system::error_code;
namespace sock
{
/**
* Represents an outbound message that is sent with a websocket.
* We use this class to wrap different object types holding actual message contents.
* We use this mechanism to achieve end-to-end zero-copy between original message
* content generator and websocket flush.
*/
class outbound_message
{
public:
// Returns a pointer to the internal buffer owned by the message object.
// Contents of this buffer is the message that is sent/received with the socket.
virtual std::string_view buffer() = 0;
};
/*
* Use this to keep in track of different thresholds which we need to deal with. e.g - maximum amount of bytes allowed per minute through a session
* threshold_limit - Maximum threshold value which is allowed
@@ -54,9 +28,6 @@ struct session_threshold
uint64_t counter_value;
uint64_t timestamp;
uint64_t intervalms;
// session_threshold(uint64_t threshold_limit, uint64_t intervalms)
// : threshold_limit(threshold_limit), intervalms(intervalms), counter_value(0), timestamp(0) {}
};
// Use this to feed the session with default options from the config file
@@ -93,9 +64,26 @@ class socket_session : public std::enable_shared_from_this<socket_session<T>>
void on_write(error_code ec, std::size_t bytes_transferred);
void on_close(error_code ec, int8_t type);
// Websocket lambda expression helpers.
// Implementation of these are separated to a different .cpp to reduce regular compile time.
void ws_next_layer_async_handshake(ssl::stream_base::handshake_type handshake_type);
void ws_async_accept();
void ws_async_handshake();
void ws_async_read();
void ws_async_write(std::string_view message);
void ws_async_close();
public:
socket_session(websocket::stream<beast::ssl_stream<beast::tcp_stream>> websocket, socket_session_handler<T> &sess_handler);
~socket_session();

View File

@@ -1,5 +1,5 @@
#ifndef _SOCK_SESSION_HANDLER_H_
#define _SOCK_SESSION_HANDLER_H_
#ifndef _HP_SOCKET_SESSION_HANDLER_
#define _HP_SOCKET_SESSION_HANDLER_
#include "socket_session.hpp"

View File

@@ -0,0 +1,86 @@
#include "../pchheader.hpp"
#include "socket_message.hpp"
#include "socket_session.hpp"
namespace beast = boost::beast;
namespace net = boost::asio;
namespace websocket = boost::beast::websocket;
namespace http = boost::beast::http;
namespace ssl = boost::asio::ssl;
using error_code = boost::system::error_code;
namespace sock
{
// The following functions exist to separate out beast web sockets lambda expressions from other code.
// This reduces lambda expression compilation time in regular code changes as long as this file is not touched.
template <class T>
void socket_session<T>::ws_next_layer_async_handshake(ssl::stream_base::handshake_type handshake_type)
{
// Perform the SSL handshake
ws.next_layer().async_handshake(
handshake_type,
[sp = this->shared_from_this()](error_code ec) {
sp->on_ssl_handshake(ec);
});
}
template <class T>
void socket_session<T>::ws_async_accept()
{
ws.async_accept(
[sp = this->shared_from_this()](
error_code ec) {
sp->on_accept(ec);
});
}
template <class T>
void socket_session<T>::ws_async_handshake()
{
ws.async_handshake(this->address, "/",
[sp = this->shared_from_this()](
error_code ec) {
sp->on_accept(ec);
});
}
template <class T>
void socket_session<T>::ws_async_read()
{
ws.async_read(
buffer,
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_read(ec, bytes);
});
}
template <class T>
void socket_session<T>::ws_async_write(std::string_view message)
{
ws.async_write(
// Project the outbound_message buffer from the queue front into the asio buffer.
net::buffer(message.data(), message.length()),
[sp = this->shared_from_this()](
error_code ec, std::size_t bytes) {
sp->on_write(ec, bytes);
});
}
template <class T>
void socket_session<T>::ws_async_close()
{
ws.async_close(websocket::close_code::normal,
[sp = this->shared_from_this()](
error_code ec) {
sp->on_close(ec, 0);
});
}
// Template instantiations.
template class socket_session<p2p::peer_outbound_message>;
template class socket_session<usr::user_outbound_message>;
} // namespace sock

View File

@@ -1,13 +1,9 @@
#include <iostream>
#include <string>
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio.hpp>
#include "../pchheader.hpp"
#include "../util.hpp"
#include "../sock/socket_session.hpp"
#include "../proc.hpp"
#include "../hplog.hpp"
#include "../jsonschema/usrmsg_helpers.hpp"
#include "../sock/socket_session.hpp"
#include "../sock/socket_message.hpp"
#include "usr.hpp"
#include "user_session_handler.hpp"
@@ -17,17 +13,6 @@ namespace beast = boost::beast;
namespace usr
{
user_outbound_message::user_outbound_message(std::string &&_msg)
{
msg = std::move(_msg);
}
// Returns the buffer that should be written to the socket.
std::string_view user_outbound_message::buffer()
{
return msg;
}
/**
* This gets hit every time a client connects to HP via the public port (configured in contract config).
*/
@@ -98,8 +83,6 @@ void user_session_handler::on_close(sock::socket_session<user_outbound_message>
// Session belongs to an authed user.
else if (session->flags[util::SESSION_FLAG::USER_AUTHED])
{
// Wait for SC process completion before we remove existing user.
proc::await_contract_execution();
remove_user(session->uniqueid);
}

View File

@@ -1,28 +1,14 @@
#ifndef _HP_USER_SESSION_HANDLER_H_
#define _HP_USER_SESSION_HANDLER_H_
#ifndef _HP_USER_SESSION_HANDLER_
#define _HP_USER_SESSION_HANDLER_
#include <boost/beast/core.hpp>
#include "../pchheader.hpp"
#include "../sock/socket_session_handler.hpp"
#include "../sock/socket_session.hpp"
#include "../sock/socket_message.hpp"
namespace usr
{
/**
* Represents a message (bytes) that is sent to a user.
*/
class user_outbound_message : public sock::outbound_message
{
// Contains message bytes.
std::string msg;
public:
user_outbound_message(std::string &&_msg);
// Returns the buffer that should be written to the socket.
virtual std::string_view buffer();
};
class user_session_handler : public sock::socket_session_handler<user_outbound_message>
{
public:

View File

@@ -1,7 +1,4 @@
#include <cstdio>
#include <iostream>
#include <unistd.h>
#include <boost/thread/thread.hpp>
#include "../pchheader.hpp"
#include "usr.hpp"
#include "user_session_handler.hpp"
#include "../jsonschema/usrmsg_helpers.hpp"

View File

@@ -1,11 +1,7 @@
#ifndef _HP_USR_H_
#define _HP_USR_H_
#ifndef _HP_USR_
#define _HP_USR_
#include <cstdio>
#include <string_view>
#include <unordered_map>
#include <list>
#include <mutex>
#include "../pchheader.hpp"
#include "../util.hpp"
#include "../sock/socket_session.hpp"
#include "user_session_handler.hpp"

View File

@@ -1,8 +1,4 @@
#include <string>
#include <sodium.h>
#include <sstream>
#include <chrono>
#include <rapidjson/document.h>
#include "pchheader.hpp"
namespace util
{

View File

@@ -1,9 +1,7 @@
#ifndef _HP_UTIL_H_
#define _HP_UTIL_H_
#ifndef _HP_UTIL_
#define _HP_UTIL_
#include <string>
#include <vector>
#include <rapidjson/document.h>
#include "pchheader.hpp"
#include "crypto.hpp"
/**