Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SpacesInAngles: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: c++17
Standard: c++20
UseTab: Never
SortIncludes: true
ColumnLimit: 100
Expand Down
42 changes: 31 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

cmake_minimum_required(VERSION 3.18)
cmake_minimum_required(VERSION 3.20)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand All @@ -20,7 +20,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_library(spns STATIC
add_library(spns-hivemind SHARED
spns/hivemind.cpp
spns/pg.cpp
spns/swarmpubkey.cpp
Expand All @@ -35,6 +35,8 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(SODIUM REQUIRED IMPORTED_TARGET libsodium>=1.0.18)
pkg_check_modules(OXENC REQUIRED IMPORTED_TARGET liboxenc>=1.4.0)
pkg_check_modules(OXENMQ REQUIRED IMPORTED_TARGET liboxenmq>=1.2.22)
pkg_check_modules(LIBQUIC REQUIRED IMPORTED_TARGET liboxenquic>=1.7)
pkg_check_modules(FMT REQUIRED IMPORTED_TARGET fmt>=10)
pkg_check_modules(OXENLOGGING REQUIRED IMPORTED_TARGET liboxen-logging>=1.2.0)
pkg_check_modules(NLOHMANN_JSON REQUIRED IMPORTED_TARGET nlohmann_json>=3.7.0)
pkg_check_modules(SYSTEMD REQUIRED IMPORTED_TARGET libsystemd)
Expand All @@ -52,26 +54,44 @@ endif()
include(cmake/submodule_check.cmake)
include(cmake/system_or_submodule.cmake)

system_or_submodule(LIBPQXX libpqxx libpqxx::pqxx libpqxx>=7.10.0 libpqxx)
system_or_submodule(LIBPQXX libpqxx libpqxx::pqxx libpqxx>=8 libpqxx)

target_link_libraries(spns PRIVATE
target_link_libraries(spns-hivemind PRIVATE
PkgConfig::SODIUM
PkgConfig::OXENC
PkgConfig::OXENMQ
PkgConfig::OXENLOGGING
PkgConfig::LIBQUIC
PkgConfig::NLOHMANN_JSON
PkgConfig::SYSTEMD
PUBLIC
libpqxx::pqxx)
libpqxx::pqxx
PkgConfig::OXENLOGGING
PkgConfig::FMT)

set_target_properties(spns PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON)
set_target_properties(spns-hivemind PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON)

set(PYBIND11_FINDPYTHON ON CACHE INTERNAL "")
add_subdirectory(pybind11)
pybind11_add_module(
core
spns_hivemind
spns/pybind.cpp)
target_link_libraries(spns_hivemind PUBLIC spns-hivemind)

add_executable(spns spns/main.cpp)
target_link_libraries(spns PUBLIC spns-hivemind PRIVATE pybind11::embed)
set_target_properties(spns PROPERTIES
INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
OUTPUT_NAME SPNS)

include(GNUInstallDirs)
install(TARGETS spns spns-hivemind
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

target_link_libraries(core PUBLIC spns)
set_target_properties(core PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/spns)
execute_process(COMMAND ${Python_EXECUTABLE} -m site --user-site
OUTPUT_VARIABLE PYTHON_USER_SITE
OUTPUT_STRIP_TRAILING_WHITESPACE)
install(TARGETS spns_hivemind DESTINATION ${PYTHON_USER_SITE})
cmake_path(ABSOLUTE_PATH CMAKE_INSTALL_PREFIX NORMALIZE OUTPUT_VARIABLE install_path)
set_target_properties(spns_hivemind PROPERTIES INSTALL_RPATH "${install_path}/${CMAKE_INSTALL_LIBDIR}")
2 changes: 1 addition & 1 deletion libpqxx
Submodule libpqxx updated 329 files
35 changes: 17 additions & 18 deletions spns.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@ listen = ipc://./hivemind.sock
# connecting to the listen_curve address.
listen_curve_admin = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

# Optional address(es) on which we listen for public quic requests (i.e. subscribe or unsubscribe
# from clients). This is an alternative to submitting via onion request can be used instead of
# OMQ, e.g. over Session Router. `[keys]:quic` must be set when this option is enabled.
#
# The first address in this list that is either an IPv4 address, or the IPv6 any address (`[::]`)
# will be used for *outgoing* connections to SNs.
quic_listen = [::]:5522

# OMQ address where we can make RPC requests to oxend. This can be a local oxend (e.g.
# ipc:///path/to/oxend.sock), a plaintext address, or a curve-encrypted address with pubkey.
oxend_rpc = tcp://localhost:22029

# How often (in seconds) the main process re-checks existing subscriptions (for push renewals, expiries, etc.)
subs_interval = 10

# How many SN connections we attempt to establish at once. Can be large to make a huge burst of
# connections at startup, or lower to pace those connections a little more.
max_connects = 1000
Expand All @@ -37,15 +42,6 @@ max_connects = 1000
# often last somewhat longer than this, but this is the minimum).
filter_lifetime = 300

# How many separate oxenmq instances to start to talk to network service nodes. Increasing this can
# be helpful if a single oxenmq instance (typically the proxy thread) starts bottlenecking under
# heavy load. If this is set to 1 or greater then this many extra servers are started and each
# connection to a remote service node is assigned in round-robin order across the instances, while
# the main local oxenmq instance will be used only for non-push requests (subscriptions, timers,
# communication with notifiers, local admin stats endpoints, etc.). If unset or set to 0 then just
# one oxenmq instance will be used for everything (both local and push traffic).
#omq_push_instances = 4

# How long the main hivemind process will wait at startup before establishing connections to
# the network's service nodes. This delay is designed to allow subordinate notification processes
# to connect to the hivemind to ensure that notification services are ready after a restart before
Expand All @@ -61,18 +57,21 @@ startup_wait = 8.0

[keys]

# This section lists the files containing keys needed by the PN server. Each file is the 32-bytes
# private key, either in binary or as a single 64-character hex string.
#
# You can generate these X25519 keys using:
# This section lists the files containing keys needed by the PN server.


# These two keys are X25519 keys used for internal hivemind communications and for decode onion
# requests. You can generate these X25519 keys using:
#
# ./make-x25519-key.py FILENAME
#

hivemind = key_x25519

onionreq = onionreq_x25519

# This key is the Ed25519 used for the QUIC listener, if QUIC listening is enabled via the
# [hivemind] quic_listen option. You can create it using `session-router-config --key FILENAME`
# (from the session-router-bin package).
quic = key_ed25519

[notify-firebase]

Expand Down
22 changes: 8 additions & 14 deletions spns/bytes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <fmt/format.h>
#include <oxenc/base64.h>
#include <oxenc/common.h>
#include <oxenc/hex.h>

#include <array>
Expand All @@ -19,12 +20,14 @@ struct bytes : std::array<std::byte, N> {
static constexpr size_t SIZE = N;

using std::array<std::byte, N>::data;
std::basic_string_view<std::byte> view() const { return {data(), SIZE}; }
std::string_view sv() const { return {reinterpret_cast<const char*>(data()), SIZE}; }
std::basic_string_view<unsigned char> usv() const {
return {reinterpret_cast<const unsigned char*>(data()), SIZE};
constexpr std::span<const std::byte, N> span() const { return {data(), SIZE}; }
template <oxenc::basic_char Char>
std::span<const Char, N> span() const {
return std::span<const Char, N>{reinterpret_cast<const Char*>(data()), SIZE};
}

std::string_view sv() const { return {reinterpret_cast<const char*>(data()), SIZE}; }

std::string hex() const { return oxenc::to_hex(this->begin(), this->end()); }

// Implicit conversion to unsigned char* for easier passing into libsodium functions
Expand Down Expand Up @@ -52,6 +55,7 @@ concept bytes_subtype = is_bytes<T>;

struct AccountID : bytes<33> {};
struct Ed25519PK : bytes<32> {};
struct Ed25519Secret : bytes<64> {};
struct X25519PK : bytes<32> {};
struct X25519SK : bytes<32> {};
struct SubaccountTag : bytes<36> {};
Expand All @@ -78,16 +82,6 @@ struct Subaccount {
}
};

template <typename T, std::enable_if_t<is_bytes<T>, int> = 0>
inline std::basic_string_view<std::byte> as_bsv(const T& v) {
return {reinterpret_cast<const std::byte*>(v.data()), T::SIZE};
}

template <typename T, std::enable_if_t<is_bytes<T>, int> = 0>
inline std::basic_string_view<unsigned char> as_usv(const T& v) {
return {reinterpret_cast<const unsigned char*>(v.data()), v.size()};
}

// std::hash-implementing class that "hashes" by just reading the size_t-size bytes starting at the
// 16th byte.
template <typename T, typename = std::enable_if_t<is_bytes<T> && (T::SIZE >= 32)>>
Expand Down
Loading