Skip to content
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ find_package(Boost REQUIRED COMPONENTS log log_setup thread filesystem exception
find_package(Boost QUIET OPTIONAL_COMPONENTS system)

find_package(nlohmann_json REQUIRED)
find_package(yaml-cpp REQUIRED) # hoisted to root so yaml-cpp::yaml-cpp is visible to src/c2pool OBJECT libs (sibling of src/core)

# Threading (needed by LevelDB on some platforms)
find_package(Threads REQUIRED)
Expand Down
76 changes: 60 additions & 16 deletions src/c2pool/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,48 +1,79 @@
# Enhanced C2Pool Components

# Hashrate Tracker Library
add_library(c2pool_hashrate
add_library(c2pool_hashrate OBJECT
hashrate/tracker.cpp
)
target_include_directories(c2pool_hashrate PUBLIC .)
target_link_libraries(c2pool_hashrate
target_link_libraries(c2pool_hashrate
yaml-cpp::yaml-cpp
btclibs
core
nlohmann_json::nlohmann_json
# lib does not link core (SCC break); carry Boost.Log explicitly so ld64 resolves
# it on AppleClang arm64 (same carry pattern as c2pool_storage/c2pool_payout, #22/#39).
Boost::log
Boost::log_setup
)
target_include_directories(c2pool_hashrate PRIVATE ${CMAKE_SOURCE_DIR}/src)

# Difficulty Adjustment Engine Library
add_library(c2pool_difficulty
difficulty/adjustment_engine.cpp
)
target_include_directories(c2pool_difficulty PUBLIC .)
target_link_libraries(c2pool_difficulty
target_link_libraries(c2pool_difficulty
yaml-cpp::yaml-cpp
btclibs
core
nlohmann_json::nlohmann_json
# lib does not link core (SCC break); carry Boost.Log explicitly so ld64 resolves
# it on AppleClang arm64 (same carry pattern as c2pool_storage/c2pool_payout, #22/#39).
Boost::log
Boost::log_setup
)
# Stays STATIC (one-way into core, outside the SCC); drop the core link edge so its
# archive does not absorb core OBJECT files (would duplicate at the final link).
target_include_directories(c2pool_difficulty PRIVATE ${CMAKE_SOURCE_DIR}/src)

# Storage Manager Library
add_library(c2pool_storage
add_library(c2pool_storage OBJECT
storage/sharechain_storage.cpp
)
target_include_directories(c2pool_storage PUBLIC .)
target_link_libraries(c2pool_storage
core
target_link_libraries(c2pool_storage
yaml-cpp::yaml-cpp
btclibs
# storage/sharechain_storage.cpp pulls core/leveldb_store.hpp -> <leveldb/db.h>.
# This OBJECT lib deliberately does not link core (SCC break), so it must carry
# the leveldb usage requirement itself. On Conan/MSVC the include dir propagates
# only via the leveldb::leveldb imported target; without this, Windows fails
# C1083 leveldb/db.h (Linux happens to find it on the default system path).
${LEVELDB_LIBRARIES}
# sharechain_storage.cpp uses <core/log.hpp> (LOG_* -> Boost.Log trivial). OBJECT
# lib does not link core (SCC break); carry Boost.Log explicitly so ld64 resolves
# it on AppleClang arm64 (same carry pattern as c2pool_payout/c2pool_merged_mining,
# #22/#39).
Boost::log
Boost::log_setup
)
target_include_directories(c2pool_storage PRIVATE ${CMAKE_SOURCE_DIR}/src)

# Merged Mining Manager Library (integrated mm-adapter)
add_library(c2pool_merged_mining
add_library(c2pool_merged_mining OBJECT
merged/merged_mining.cpp
)
target_include_directories(c2pool_merged_mining PUBLIC .)
target_link_libraries(c2pool_merged_mining
core
yaml-cpp::yaml-cpp
btclibs
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
# merged_mining.cpp uses <core/log.hpp> (LOG_* -> Boost.Log trivial). OBJECT lib
# does not link core (SCC break); carry Boost.Log explicitly so ld64 resolves it
# on AppleClang arm64 (same fix class as c2pool_storage/leveldb, #22/#39).
Boost::log
Boost::log_setup
)
target_include_directories(c2pool_merged_mining PRIVATE ${CMAKE_SOURCE_DIR}/src)

# Enhanced Node Library (header-only template after M6 decoupling).
# Coin-agnostic; callers that use the LTC alias (enhanced_node.hpp) must link
Expand Down Expand Up @@ -80,9 +111,14 @@ target_link_libraries(c2pool
c2pool_merged_mining
core
ltc
# OBJECT sets reachable only transitively via ltc (itself OBJECT) do not
# propagate their objects into the exe link; name them directly (#22/#39).
c2pool_storage
ltc_coin
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
)
target_link_libraries(c2pool c2pool_hashrate pool) # OBJECT-lib SCC direct-naming (#22/#39)

# Enhanced version with explicit name (for backward compatibility)
add_executable(c2pool_enhanced c2pool_refactored.cpp)
Expand All @@ -92,9 +128,12 @@ target_link_libraries(c2pool_enhanced
c2pool_merged_mining
core
ltc
c2pool_storage
ltc_coin
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
)
target_link_libraries(c2pool_enhanced c2pool_hashrate pool) # OBJECT-lib SCC direct-naming (#22/#39)

# Windows: Boost.Asio requires Winsock libraries; /bigobj for large translation units
if(WIN32)
Expand All @@ -111,7 +150,8 @@ endif()

# Test applications
add_executable(test_ltc_node test_ltc_node.cpp)
target_link_libraries(test_ltc_node $<LINK_GROUP:RESCAN,core,sharechain,btclibs,pool,ltc,ltc_coin,c2pool_storage,c2pool_payout,c2pool_hashrate,c2pool_merged_mining>)
target_link_libraries(test_ltc_node core ltc)
target_link_libraries(test_ltc_node c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage ltc_coin pool) # OBJECT-lib SCC direct-naming (#22/#39)
target_link_libraries(test_ltc_node nlohmann_json::nlohmann_json)

# Legacy applications have been archived to ../../archive/
Expand All @@ -122,8 +162,12 @@ target_link_libraries(test_ltc_node nlohmann_json::nlohmann_json)
add_subdirectory(ltc)
add_subdirectory(payout)

# core's web_server.cpp references symbols from c2pool_payout, c2pool_hashrate,
# and secp256k1, so expose them transitively so any target linking core also
# picks them up (fixes link ordering for test executables).
# NOTE: uses plain signature to match core/CMakeLists.txt's style.
target_link_libraries(core c2pool_payout c2pool_hashrate c2pool_merged_mining ltc ${SECP256K1_LIBRARIES})
# core/web_server.cpp references symbols from c2pool_payout, c2pool_hashrate and
# c2pool_merged_mining. With OBJECT libraries every consumer pools ALL of core's
# objects (including web_server.o), so those symbols must reach every core consumer.
# Propagate them as INTERFACE deps (consumers pool their objects) with NO back-edge
# into core: the payout/hashrate/merged OBJECT libs no longer link core (header-only
# access via the global src/ include path), keeping the target graph ACYCLIC so CMake
# accepts the non-STATIC SCC. secp256k1 (external) likewise propagated via INTERFACE.
# Source-level dissolution of these core->c2pool deps is deferred to V37.
target_link_libraries(core INTERFACE c2pool_payout c2pool_hashrate c2pool_merged_mining ${SECP256K1_LIBRARIES})
2 changes: 2 additions & 0 deletions src/c2pool/ltc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
add_executable(ltc_pool_test ltc_pool_test.cpp)
target_link_libraries(ltc_pool_test core btclibs ltc)
target_link_libraries(ltc_pool_test c2pool_payout c2pool_hashrate ltc_coin c2pool_storage c2pool_merged_mining pool) # OBJECT-lib SCC direct-naming (#22/#39)
target_link_libraries(ltc_pool_test nlohmann_json::nlohmann_json)

add_executable(ltc_coin_test ltc_coin_test.cpp)
target_link_libraries(ltc_coin_test core btclibs pool ltc ltc_coin)
target_link_libraries(ltc_coin_test c2pool_payout c2pool_hashrate c2pool_storage c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39)
target_link_libraries(ltc_coin_test nlohmann_json::nlohmann_json)
11 changes: 9 additions & 2 deletions src/c2pool/payout/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# C2Pool Payout Management Library
add_library(c2pool_payout
add_library(c2pool_payout OBJECT
payout_manager.cpp
)

Expand All @@ -10,10 +10,17 @@ target_include_directories(c2pool_payout PUBLIC
)

target_link_libraries(c2pool_payout
yaml-cpp::yaml-cpp
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
# payout_manager.cpp uses <core/log.hpp> (LOG_* -> Boost.Log trivial). This OBJECT
# lib deliberately does not link core (SCC break), so it must carry the Boost.Log
# usage requirement itself via the imported targets. ${Boost_LIBRARIES} alone does
# not reliably resolve the log component through ld64 static archives on AppleClang
# arm64 (GCC/MSVC tolerated it); name Boost::log/log_setup explicitly (#22/#39).
Boost::log
Boost::log_setup
btclibs
core
)

# Ensure headers are available
Expand Down
6 changes: 3 additions & 3 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ find_package(yaml-cpp REQUIRED)
# half landed in 07165699; this wires the leaf library into the build.
add_library(core_util STATIC core_util.cpp)

add_library(core STATIC ${source})
target_link_libraries(core core_util btclibs)
add_library(core OBJECT ${source})
target_link_libraries(core PUBLIC core_util btclibs)

target_link_libraries(core Boost::headers Boost::exception Boost::log Boost::log_setup Boost::thread Boost::filesystem yaml-cpp nlohmann_json::nlohmann_json ${LEVELDB_LIBRARIES})
target_link_libraries(core PUBLIC Boost::headers Boost::exception Boost::log Boost::log_setup Boost::thread Boost::filesystem yaml-cpp nlohmann_json::nlohmann_json ${LEVELDB_LIBRARIES})

# Add LevelDB include directories
target_include_directories(core PUBLIC ${LEVELDB_INCLUDE_DIRS})
Expand Down
23 changes: 4 additions & 19 deletions src/core/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,17 @@

#include <core/log.hpp>
#include <core/socket.hpp>
#include <core/inetwork.hpp>
#include <core/addr_store.hpp>
#include <core/node_interface.hpp>

namespace io = boost::asio;

namespace core
{
// Bug 3 root-cause fix: INetwork inherits enable_shared_from_this so
// Factory::Client / Factory::Server can capture weak_from_this() into
// their async lambdas instead of raw `this`. When the derived node
// (e.g. dash::coin::p2p::NodeP2P) is owned by a shared_ptr, the captured
// weak_ptr keeps it alive across the async callback's execution, fixing
// the use-after-free that produced the 19:23:15 UTC SIGSEGV in
// codecvt::do_length called from the boost::log formatter inside
// NodeP2P::connected on a freed m_target_addr.
//
// For derived nodes NOT owned by shared_ptr (current LTC/DOGE pattern),
// weak_from_this() returns an empty weak_ptr; Factory falls back to the
// raw m_node pointer (preserves prior behavior — LTC/DOGE haven't been
// observed to crash, the disconnect-reconnect cascade is Dash-specific).
struct INetwork : public std::enable_shared_from_this<INetwork>
{
virtual ~INetwork() = default;
virtual void connected(std::shared_ptr<core::Socket> socket) = 0;
virtual void disconnect() = 0;
};
// INetwork moved to core/inetwork.hpp (included above) so socket.hpp can see
// its full definition. See that header for the Bug 3 enable_shared_from_this
// rationale.

class Server
{
Expand Down
37 changes: 37 additions & 0 deletions src/core/inetwork.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <memory>

namespace core
{
// Forward declaration: INetwork only needs Socket as an incomplete type for the
// shared_ptr in connected(); the full Socket definition lives in socket.hpp.
class Socket;

// Bug 3 root-cause fix: INetwork inherits enable_shared_from_this so
// Factory::Client / Factory::Server can capture weak_from_this() into
// their async lambdas instead of raw `this`. When the derived node
// (e.g. dash::coin::p2p::NodeP2P) is owned by a shared_ptr, the captured
// weak_ptr keeps it alive across the async callback's execution, fixing
// the use-after-free that produced the 19:23:15 UTC SIGSEGV in
// codecvt::do_length called from the boost::log formatter inside
// NodeP2P::connected on a freed m_target_addr.
//
// For derived nodes NOT owned by shared_ptr (current LTC/DOGE pattern),
// weak_from_this() returns an empty weak_ptr; Factory falls back to the
// raw m_node pointer (preserves prior behavior — LTC/DOGE haven't been
// observed to crash, the disconnect-reconnect cascade is Dash-specific).
//
// Lives in its own header (not factory.hpp) so socket.hpp can include the full
// definition: make_socket() dynamic_casts to INetwork* and calls
// weak_from_this(), both of which require a complete type. AppleClang/MSVC
// diagnose the incomplete forward-declared type at template-parse time where
// GNU ld-era GCC tolerated it.
struct INetwork : public std::enable_shared_from_this<INetwork>
{
virtual ~INetwork() = default;
virtual void connected(std::shared_ptr<core::Socket> socket) = 0;
virtual void disconnect() = 0;
};

} // namespace core
7 changes: 3 additions & 4 deletions src/core/socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
#include <core/pack_types.hpp>
#include <core/message.hpp>
#include <core/node_interface.hpp>
#include <core/inetwork.hpp>
#include <core/hash.hpp>
#include <core/netaddress.hpp>
#include <core/packet.hpp>

namespace core
{

// Forward-declared to avoid circular include with factory.hpp (which includes
// socket.hpp). Socket needs INetwork only for weak_ptr<INetwork> liveness
// tracking; full definition is needed in socket.cpp via factory.hpp.
struct INetwork;
// INetwork is defined in core/inetwork.hpp (included above) so the make_socket
// template below sees its complete type for the dynamic_cast + weak_from_this().

enum connection_type
{
Expand Down
1 change: 1 addition & 0 deletions src/core/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
if (BUILD_TESTING AND (GTest_FOUND OR GTEST_FOUND))
add_executable(core_test pack_test.cpp events_test.cpp chain_test.cpp packet_test.cpp)
target_link_libraries(core_test PRIVATE GTest::gtest_main core c2pool_merged_mining GTest::gtest)
target_link_libraries(core_test PRIVATE c2pool_payout c2pool_hashrate ltc_coin) # OBJECT-lib SCC direct-naming (#22/#39)

include(GoogleTest)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
Expand Down
2 changes: 1 addition & 1 deletion src/impl/ltc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_subdirectory(coin)

add_library(ltc
add_library(ltc OBJECT
config_coin.hpp config_coin.cpp config_pool.hpp config_pool.cpp config.hpp
node.hpp node.cpp
peer.hpp
Expand Down
2 changes: 1 addition & 1 deletion src/impl/ltc/coin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ set(ltc_coin_interface
)


add_library(ltc_coin ${ltc_coin_interface} ${ltc_coin_impl})
add_library(ltc_coin OBJECT ${ltc_coin_interface} ${ltc_coin_impl})

target_link_libraries(ltc_coin core nlohmann_json::nlohmann_json)
3 changes: 2 additions & 1 deletion src/impl/ltc/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ if (BUILD_TESTING AND GTest_FOUND)
add_executable(share_test share_test.cpp)
target_link_libraries(share_test PRIVATE
GTest::gtest_main GTest::gtest
$<LINK_GROUP:RESCAN,core,sharechain,pool,ltc,btclibs,ltc_coin,c2pool_storage,c2pool_payout,c2pool_hashrate,c2pool_merged_mining>
core ltc
)
target_link_libraries(share_test PRIVATE c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage ltc_coin pool) # OBJECT-lib SCC direct-naming (#22/#39)

include(GoogleTest)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
Expand Down
2 changes: 1 addition & 1 deletion src/pool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ set(pool_source
protocol.hpp
)

add_library(pool STATIC ${pool_source})
add_library(pool OBJECT ${pool_source})
target_link_libraries(pool core)
2 changes: 1 addition & 1 deletion src/sharechain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(SHARECHAIN_SOURCE
${legacy_tracker}
)

add_library(sharechain STATIC ${SHARECHAIN_SOURCE})
add_library(sharechain OBJECT ${SHARECHAIN_SOURCE})
target_link_libraries(sharechain core)

add_subdirectory(test)
3 changes: 2 additions & 1 deletion src/sharechain/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ if (BUILD_TESTING AND GTest_FOUND)
add_executable(sharechain_test share_test.cpp)
target_link_libraries(sharechain_test PRIVATE
GTest::gtest_main GTest::gtest
$<LINK_GROUP:RESCAN,core,sharechain,pool,ltc,btclibs,ltc_coin,c2pool_storage,c2pool_payout,c2pool_hashrate,c2pool_merged_mining>
core ltc
)
target_link_libraries(sharechain_test PRIVATE c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage ltc_coin pool) # OBJECT-lib SCC direct-naming (#22/#39)

include(GoogleTest)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
Expand Down
Loading
Loading