mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Added release build support. (#119)
* Cleaned up and updated cmake to have release build support. * Added segfault handler. * Added latest hpfs release build. * Fixed coding issues revealed by release build.
This commit is contained in:
@@ -1,25 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(HPCore)
|
||||
project(hpcore)
|
||||
|
||||
# Check for gold linker for faster linking time.
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl -ldl,--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()
|
||||
# Force build type to Release build.
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
|
||||
add_definitions("-std=c++17 -ldl") #-ldl to support printing stack trace at runtime
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g") # ensure debug symbols are added
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
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)
|
||||
|
||||
link_directories(/usr/local/lib)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-result")
|
||||
|
||||
# We have 2 executable build outputs: appbill and hpcore
|
||||
|
||||
@@ -63,6 +54,8 @@ add_executable(hpcore
|
||||
)
|
||||
target_link_libraries(hpcore
|
||||
libsodium.a
|
||||
pthread
|
||||
libblake3.so
|
||||
libboost_system.a
|
||||
libboost_thread.a
|
||||
libboost_log.a
|
||||
@@ -70,9 +63,7 @@ target_link_libraries(hpcore
|
||||
libboost_filesystem.a
|
||||
libboost_stacktrace_backtrace.a
|
||||
backtrace
|
||||
pthread
|
||||
${CMAKE_DL_LIBS} # Needed for stacktrace support
|
||||
libblake3.so
|
||||
)
|
||||
add_dependencies(hpcore
|
||||
appbill
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace comm
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR << "fork() failed when starting websocat process.";
|
||||
LOG_ERR << errno << ": fork() failed when starting websocat process.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ namespace comm
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR << "fork() failed when starting websocketd process.";
|
||||
LOG_ERR << errno << ": fork() failed when starting websocketd process.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,12 +202,13 @@ namespace comm
|
||||
{
|
||||
// Prepare the memory segments to map with writev().
|
||||
iovec memsegs[2];
|
||||
uint8_t header_buf[SIZE_HEADER_LEN] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (is_binary)
|
||||
{
|
||||
// In binary mode, we need to prefix every message with the message size header.
|
||||
uint8_t header_buf[SIZE_HEADER_LEN] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint32_t len = message.length();
|
||||
|
||||
// Reserve the first 4 bytes for future (TODO).
|
||||
header_buf[4] = len >> 24;
|
||||
header_buf[5] = (len >> 16) & 0xff;
|
||||
|
||||
39
src/main.cpp
39
src/main.cpp
@@ -77,7 +77,7 @@ void deinit()
|
||||
hplog::deinit();
|
||||
}
|
||||
|
||||
void signal_handler(int signum)
|
||||
void sigint_handler(int signum)
|
||||
{
|
||||
LOG_WARN << "Interrupt signal (" << signum << ") received.";
|
||||
deinit();
|
||||
@@ -85,22 +85,11 @@ void signal_handler(int signum)
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
namespace boost
|
||||
void segfault_handler(int signum)
|
||||
{
|
||||
|
||||
inline void assertion_failed_msg(char const *expr, char const *msg, char const *function, char const * /*file*/, long /*line*/)
|
||||
{
|
||||
LOG_ERR << "Expression '" << expr << "' is false in function '" << function << "': " << (msg ? msg : "<...>") << ".\n"
|
||||
<< "Backtrace:\n"
|
||||
<< boost::stacktrace::stacktrace() << '\n';
|
||||
std::abort();
|
||||
}
|
||||
|
||||
inline void assertion_failed(char const *expr, char const *function, char const *file, long line)
|
||||
{
|
||||
::boost::assertion_failed_msg(expr, 0 /*nullptr*/, function, file, line);
|
||||
}
|
||||
} // namespace boost
|
||||
std::cerr << boost::stacktrace::stacktrace() << "\n";
|
||||
exit(SIGABRT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Global exception handler for std exceptions.
|
||||
@@ -116,18 +105,16 @@ void std_terminate() noexcept
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
LOG_ERR << "std error: " << ex.what() << "\n";
|
||||
LOG_ERR << "std error: " << ex.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERR << "std error: Terminated due to unknown exception"
|
||||
<< "\n";
|
||||
LOG_ERR << "std error: Terminated due to unknown exception";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR << "std error: Terminated due to unknown reason"
|
||||
<< "\n";
|
||||
LOG_ERR << "std error: Terminated due to unknown reason";
|
||||
}
|
||||
|
||||
LOG_ERR << boost::stacktrace::stacktrace();
|
||||
@@ -137,6 +124,11 @@ void std_terminate() noexcept
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Register exception and segfault handlers.
|
||||
std::set_terminate(&std_terminate);
|
||||
signal(SIGSEGV, &segfault_handler);
|
||||
signal(SIGABRT, &segfault_handler);
|
||||
|
||||
// seed rand
|
||||
srand(util::get_epoch_milliseconds());
|
||||
|
||||
@@ -148,9 +140,6 @@ int main(int argc, char **argv)
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
// Register exception handler for std exceptions.
|
||||
std::set_terminate(&std_terminate);
|
||||
|
||||
// Extract the CLI args
|
||||
// This call will populate conf::ctx
|
||||
if (parse_cmd(argc, argv) != 0)
|
||||
@@ -210,7 +199,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// After initializing primary subsystems, register the SIGINT handler.
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGINT, &sigint_handler);
|
||||
|
||||
if (cons::run_consensus() == -1)
|
||||
{
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
// Enable boost strack trace.
|
||||
#define BOOST_STACKTRACE_USE_BACKTRACE
|
||||
// Enable custom handlers for boost assertion failures.
|
||||
#define BOOST_ENABLE_ASSERT_DEBUG_HANDLER
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
29
src/sc.cpp
29
src/sc.cpp
@@ -13,7 +13,7 @@ namespace sc
|
||||
int execute_contract(execution_context &ctx)
|
||||
{
|
||||
// Start the hpfs rw session before starting the contract process.
|
||||
if (start_hpfs_rw_session(ctx) != 0)
|
||||
if (start_hpfs_rw_session(ctx) == -1)
|
||||
return -1;
|
||||
|
||||
// Setup io pipes and feed all inputs to them.
|
||||
@@ -39,7 +39,7 @@ namespace sc
|
||||
ctx.output_fetcher_thread = std::thread(fetch_outputs, std::ref(ctx));
|
||||
|
||||
// Write the inputs into the contract process.
|
||||
if (feed_inputs(ctx) != 0)
|
||||
if (feed_inputs(ctx) == -1)
|
||||
{
|
||||
util::kill_process(pid, true);
|
||||
ctx.contract_pid = 0;
|
||||
@@ -102,7 +102,7 @@ namespace sc
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR << "fork() failed when starting contract process." << (ctx.args.readonly ? " (rdonly)" : "");
|
||||
LOG_ERR << errno << ": fork() failed when starting contract process." << (ctx.args.readonly ? " (rdonly)" : "");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ namespace sc
|
||||
return -1;
|
||||
|
||||
LOG_DBG << "hpfs session started. pid:" << ctx.hpfs_pid << (ctx.args.readonly ? " (rdonly)" : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,9 +230,9 @@ namespace sc
|
||||
|
||||
// Establish contract input pipe.
|
||||
int stdinpipe[2];
|
||||
if (pipe(stdinpipe) != 0)
|
||||
if (pipe(stdinpipe) == -1)
|
||||
{
|
||||
LOG_ERR << "Failed to create pipe to the contract process.";
|
||||
LOG_ERR << errno << ": Failed to create pipe to the contract process.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ namespace sc
|
||||
// Write the json message and close write fd.
|
||||
if (write(stdinpipe[1], json.data(), json.size()) == -1)
|
||||
{
|
||||
LOG_ERR << "Failed to write to stdin of contract process.";
|
||||
LOG_ERR << errno << ": Failed to write to stdin of contract process.";
|
||||
return -1;
|
||||
}
|
||||
close(stdinpipe[1]);
|
||||
@@ -254,15 +255,15 @@ namespace sc
|
||||
int feed_inputs(execution_context &ctx)
|
||||
{
|
||||
// Write any input messages to hp->sc pipe.
|
||||
if (!ctx.args.readonly && write_contract_hp_inputs(ctx) != 0)
|
||||
if (!ctx.args.readonly && write_contract_hp_inputs(ctx) == -1)
|
||||
return -1;
|
||||
|
||||
// Write any NPL messages to contract.
|
||||
if (!ctx.args.readonly && write_npl_messages(ctx) != 0)
|
||||
if (!ctx.args.readonly && write_npl_messages(ctx) == -1)
|
||||
return -1;
|
||||
|
||||
// Write any verified (consensus-reached) user inputs to user pipes.
|
||||
if (write_contract_fdmap_inputs(ctx.userfds, ctx.args.userbufs) != 0)
|
||||
if (write_contract_fdmap_inputs(ctx.userfds, ctx.args.userbufs) == -1)
|
||||
{
|
||||
LOG_ERR << "Failed to write user inputs to contract.";
|
||||
return -1;
|
||||
@@ -307,7 +308,7 @@ namespace sc
|
||||
*/
|
||||
int write_contract_hp_inputs(execution_context &ctx)
|
||||
{
|
||||
if (write_iopipe(ctx.hpscfds, ctx.args.hpscbufs.inputs) != 0)
|
||||
if (write_iopipe(ctx.hpscfds, ctx.args.hpscbufs.inputs) == -1)
|
||||
{
|
||||
LOG_ERR << "Error writing HP inputs to SC";
|
||||
return -1;
|
||||
@@ -441,7 +442,7 @@ namespace sc
|
||||
for (auto &[pubkey, buflist] : bufmap)
|
||||
{
|
||||
std::vector<int> fds = std::vector<int>();
|
||||
if (create_iopipes(fds, !buflist.inputs.empty()) != 0)
|
||||
if (create_iopipes(fds, !buflist.inputs.empty()) == -1)
|
||||
return -1;
|
||||
|
||||
fdmap.emplace(pubkey, std::move(fds));
|
||||
@@ -464,7 +465,7 @@ namespace sc
|
||||
// Loop through input buffers for each pubkey.
|
||||
for (auto &[pubkey, buflist] : bufmap)
|
||||
{
|
||||
if (write_iopipe(fdmap[pubkey], buflist.inputs) != 0)
|
||||
if (write_iopipe(fdmap[pubkey], buflist.inputs) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -519,11 +520,11 @@ namespace sc
|
||||
int create_iopipes(std::vector<int> &fds, const bool create_inpipe)
|
||||
{
|
||||
int inpipe[2] = {-1, -1};
|
||||
if (create_inpipe && pipe(inpipe) != 0)
|
||||
if (create_inpipe && pipe(inpipe) == -1)
|
||||
return -1;
|
||||
|
||||
int outpipe[2] = {-1, -1};
|
||||
if (pipe(outpipe) != 0)
|
||||
if (pipe(outpipe) == -1)
|
||||
{
|
||||
if (create_inpipe)
|
||||
{
|
||||
|
||||
BIN
test/bin/hpfs
BIN
test/bin/hpfs
Binary file not shown.
@@ -156,6 +156,7 @@ if [ $mode = "new" ] || [ $mode = "update" ]; then
|
||||
# Copy required files to hpfiles dir.
|
||||
mkdir -p hpfiles/{bin,ssl,nodejs_contract}
|
||||
strip $hpcore/build/hpcore
|
||||
strip $hpcore/build/appbill
|
||||
cp $hpcore/build/hpcore hpfiles/bin/
|
||||
cp $hpcore/examples/nodejs_contract/{package.json,echo_contract.js,hp-contract-lib.js} hpfiles/nodejs_contract/
|
||||
if [ $mode = "new" ]; then
|
||||
@@ -190,9 +191,9 @@ if [ $mode = "reconfig" ]; then
|
||||
# Run hp setup script on the VM and download the generated hp.cfg
|
||||
vmaddr=${vmaddrs[i]}
|
||||
let nodeid=$i+1
|
||||
sshpass -p $vmpass ssh $vmuser@$vmaddr '~/hpfiles/setup-hp.sh'
|
||||
sshpass -p $vmpass scp $vmuser@$vmaddr:~/contract/cfg/hp.cfg ./cfg/node$nodeid.json
|
||||
{ sshpass -p $vmpass ssh $vmuser@$vmaddr '~/hpfiles/setup-hp.sh' && sshpass -p $vmpass scp $vmuser@$vmaddr:~/contract/cfg/hp.cfg ./cfg/node$nodeid.json; } &
|
||||
done
|
||||
wait
|
||||
fi
|
||||
|
||||
# Locally update values of download hp.cfg files.
|
||||
|
||||
Reference in New Issue
Block a user