Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
preset: [default]
include:
- toolchain: gcc
docker: 1.237.0
docker: 1.242.0
compiler: gcc
- toolchain: clang
docker: 1.237.0
docker: 1.242.0
compiler: clang
steps:
- name: Checkout opentxs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
env:
docker: '1.237.0'
docker: '1.242.0'
steps:
- name: Checkout opentxs
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/iwyu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
env:
docker: '1.237.0'
docker: '1.242.0'
steps:
- name: Checkout opentxs
uses: actions/checkout@v3
Expand Down
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ otcommon_print_build_details(METIER_SERVER_PEDANTIC_BUILD "")
otcommon_find_system_libraries()
find_package(
opentxs
1.237
1.242
CONFIG
REQUIRED
)
Expand All @@ -83,4 +83,12 @@ find_package(
# -----------------------------------------------------------------------------
# Build source

add_executable(${PROJECT_NAME} "")
otcommon_configure_target_cxx(${PROJECT_NAME})
otcommon_define_signed_overflow(${PROJECT_NAME})
target_link_libraries(
${PROJECT_NAME} PUBLIC opentxs::libopentxs Boost::program_options
)
install(TARGETS ${PROJECT_NAME})

add_subdirectory(src)
5 changes: 5 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

target_include_directories(
${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}"
)

add_subdirectory(metier_server)
100 changes: 100 additions & 0 deletions src/metier_server/App.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) 2019-2024 The Open-Transactions developers
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "metier_server/App.hpp" // IWYU pragma: associated

#include "metier_server/EventLoop.hpp"

namespace metier_server
{
using namespace std::literals;

App::App(int argc, char** argv, opentxs::alloc::Strategy& alloc) noexcept(false)
: alloc_(alloc)
, options_(argc, argv, alloc_)
{
}

auto App::print_help() noexcept(false) -> int
{
std::cout << options_.options() << '\n' << options_.ot_.HelpText() << '\n';

return 0;
}

auto App::Run() noexcept(false) -> int
{
if (options_.show_help_) {

return print_help();
} else {

return run_daemon();
}
}

auto App::run_daemon() noexcept(false) -> int
{
opentxs::api::Context::PrepareSignalHandling();
auto const& ot = opentxs::start(options_.ot_);
ot.HandleSignals();
auto const& client = ot.StartClientSession(options_.ot_, 0);

if (options_.start_sync_server_) {
constexpr auto prefix = "tcp://";
constexpr auto internal = "0.0.0.0";
constexpr auto sep = ":";
auto const& port = options_.sync_port_;
auto const nextport{port + 1};
auto const started = client.Network().OTDHT().StartListener(
opentxs::String{prefix, alloc_.work_}
.append(internal)
.append(sep)
.append(std::to_string(port)),
opentxs::String{prefix, alloc_.work_}
.append(options_.sync_server_public_ip_)
.append(sep)
.append(std::to_string(port)),
opentxs::String{prefix, alloc_.work_}
.append(internal)
.append(sep)
.append(std::to_string(nextport)),
opentxs::String{prefix, alloc_.work_}
.append(options_.sync_server_public_ip_)
.append(sep)
.append(std::to_string(nextport)));

if (false == started) {

throw std::runtime_error{"failed to start otdht listener"};
}
}

for (auto const& chain : options_.enabled_chains_) {
if (false == client.Network().Blockchain().Enable(chain).IsValid()) {

throw std::runtime_error{"unable to enable "s.append(print(chain))};
}
}

auto const running = client.StartSessionEventLoop(
[](auto const& api, auto& alloc) {
return std::allocate_shared<EventLoop>(alloc.result_, api, alloc);
},
{},
{},
1,
alloc_);

if (false == running) {

throw std::runtime_error{"failed to start event loop"};
}

opentxs::join();

return 0;
}
} // namespace metier_server
26 changes: 26 additions & 0 deletions src/metier_server/App.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2019-2024 The Open-Transactions developers
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <opentxs/opentxs.hpp>

#include "metier_server/Options.hpp"

namespace metier_server
{
class App
{
public:
auto Run() noexcept(false) -> int;

App(int argc, char** argv, opentxs::alloc::Strategy& alloc) noexcept(false);

private:
opentxs::alloc::Strategy& alloc_;
Options const options_;

auto print_help() noexcept(false) -> int;
auto run_daemon() noexcept(false) -> int;
};
} // namespace metier_server
20 changes: 10 additions & 10 deletions src/metier_server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

set(cxx-sources main.cpp)

add_executable(${PROJECT_NAME} ${cxx-sources})
otcommon_configure_target_cxx(${PROJECT_NAME})
otcommon_define_signed_overflow(${PROJECT_NAME})

target_link_libraries(
${PROJECT_NAME} PUBLIC opentxs::libopentxs Boost::program_options
target_sources(
${PROJECT_NAME}
PRIVATE
"App.cpp"
"App.hpp"
"EventLoop.cpp"
"EventLoop.hpp"
"Options.cpp"
"Options.hpp"
"main.cpp"
)

install(TARGETS ${PROJECT_NAME})
161 changes: 161 additions & 0 deletions src/metier_server/EventLoop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Copyright (c) 2019-2024 The Open-Transactions developers
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "metier_server/EventLoop.hpp" // IWYU pragma: associated

namespace metier_server
{
EventLoop::EventLoop(
opentxs::api::Session const& api,
opentxs::alloc::Strategy& alloc,
allocator_type) noexcept(false)
: opentxs::api::session::EventLoop(alloc.result_)
, enabled_chains_(sort_enabled_chains(api, alloc))
, stats_(api.Network().Blockchain().Stats(alloc), alloc.result_)
, chain_print_width_([&] {
if (enabled_chains_.empty()) {

return 0;
} else {
auto const get_width = [](auto type) noexcept {
return static_cast<int>(print(type).size());
};
auto const max = std::ranges::max(enabled_chains_, {}, get_width);

return get_width(max);
}
}())
{
}

auto EventLoop::Description() const noexcept -> std::string_view
{
return "Metier-server"sv;
}

auto EventLoop::get_deleter() noexcept -> delete_function
{
return opentxs::pmr::Deleter::Factory(*this);
}

auto EventLoop::print_status(
opentxs::util::eventloop::state::ProcessMessage& state) noexcept(false)
-> void
{
auto out = std::stringstream{};

{
out << std::setw(chain_print_width_) << " ";
out << std::setw(status_print_width_) << "overall ";
out << std::setw(status_print_width_) << "peer ";
out << std::setw(status_print_width_) << "block ";
out << std::setw(status_print_width_) << "block";
out << std::setw(status_print_width_) << "cfheader";
out << std::setw(status_print_width_) << "cfilter";
out << '\n';
}

{
out << std::setw(chain_print_width_) << " ";
out << std::setw(status_print_width_) << "progress";
out << std::setw(status_print_width_) << "count";
out << std::setw(status_print_width_) << "headers";
out << std::setw(status_print_width_) << "chain";
out << std::setw(status_print_width_) << "chain ";
out << std::setw(status_print_width_) << "chain ";
out << '\n';
}

auto const print_status = [this, &out](auto const chain) {
out << std::setw(chain_print_width_) << print(chain);
out << std::setw(status_print_width_ - 1) << std::fixed
<< std::setprecision(2) << stats_.Progress(chain) << "%";
out << std::setw(status_print_width_) << stats_.PeerCount(chain);
out << std::setw(status_print_width_)
<< stats_.BlockHeaderTip(chain).height_;
out << std::setw(status_print_width_) << stats_.BlockTip(chain).height_;
out << std::setw(status_print_width_)
<< stats_.CfheaderTip(chain).height_;
out << std::setw(status_print_width_)
<< stats_.CfilterTip(chain).height_;
out << '\n';
};
std::ranges::for_each(enabled_chains_, print_status);
std::cout << out.str() << std::endl;
reset_status_timer(state);
}

auto EventLoop::Run(
opentxs::api::Session const&,
opentxs::util::eventloop::state::PreInit&,
opentxs::util::eventloop::Socket&,
std::span<opentxs::util::eventloop::Socket>,
std::span<opentxs::util::eventloop::Socket>,
opentxs::alloc::Strategy&) noexcept(false) -> bool
{
return true;
}

auto EventLoop::Run(
opentxs::api::Session const&,
opentxs::util::eventloop::state::Init& state,
opentxs::alloc::Strategy&) noexcept(false) -> bool
{
reset_status_timer(state);

return true;
}

auto EventLoop::Run(
opentxs::api::Session const&,
opentxs::util::eventloop::state::ProcessMessage& state,
opentxs::util::eventloop::SocketIndex,
std::optional<opentxs::util::eventloop::MessageType> type,
opentxs::util::eventloop::Message&&,
opentxs::alloc::Strategy&) noexcept(false) -> bool
{
using enum opentxs::util::WorkType;

switch (auto const t = type.value_or(value(Unknown)); t) {
case print_status_: {
print_status(state);
} break;
default: {

throw std::runtime_error{
"received message of unsupported type "s.append(
opentxs::print_work_type(t))};
}
}

return true;
}

auto EventLoop::sort_enabled_chains(
opentxs::api::Session const& api,
opentxs::alloc::Strategy& alloc) noexcept(false) -> EnabledChains
{
auto sorted = [&] {
auto out = opentxs::Map<
std::string_view,
opentxs::blockchain::Type,
opentxs::NaturalCaseCompare>{alloc.work_};
constexpr auto to_name = [](auto const& chain) {
return std::make_pair(print(chain), chain);
};
auto const enabled =
api.Network().Blockchain().EnabledChains(alloc.WorkOnly());
std::ranges::transform(enabled, std::inserter(out, out.end()), to_name);

return out;
}();
auto out = EnabledChains{alloc.result_};
std::ranges::copy(sorted | std::views::values, std::back_inserter(out));

return out;
}

EventLoop::~EventLoop() = default;
} // namespace metier_server
Loading
Loading