Skip to content

Commit

Permalink
Merge pull request #34 from luminousmining/feat/server_http
Browse files Browse the repository at this point in the history
api hiveos
  • Loading branch information
luminousmining authored Mar 29, 2024
2 parents b1148df + 3150038 commit b224ab8
Show file tree
Hide file tree
Showing 12 changed files with 311 additions and 2 deletions.
1 change: 1 addition & 0 deletions miner/sources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(algo)
add_subdirectory(api)
add_subdirectory(common)
add_subdirectory(device)
add_subdirectory(network)
Expand Down
1 change: 0 additions & 1 deletion miner/sources/algo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

set(ALGO_HEADERS
algo_type.hpp
bitwise.hpp
Expand Down
17 changes: 17 additions & 0 deletions miner/sources/api/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
set(API_HEADERS
api.hpp
)

set(API_SOURCES
api.cpp
)

target_sources(${MINER_EXE} PUBLIC
${API_HEADERS}
${API_SOURCES}
)

target_sources(${UNIT_TEST_EXE} PUBLIC
${API_HEADERS}
${API_SOURCES}
)
180 changes: 180 additions & 0 deletions miner/sources/api/api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#include <vector>

#include <boost/json.hpp>
#include <boost/json/src.hpp>

#include <api/api.hpp>
#include <common/app.hpp>
#include <common/cast.hpp>
#include <common/custom.hpp>
#include <common/log/log.hpp>


void api::ServerAPI::setDeviceManager(device::DeviceManager* _deviceManager)
{
deviceManager = _deviceManager;
}


void api::ServerAPI::setPort(
uint32_t const _port)
{
port = _port;
}


bool api::ServerAPI::bind()
{
alive.store(true, boost::memory_order::seq_cst);

threadDoAccept.interrupt();
threadDoAccept = boost_thread{ boost::bind(&api::ServerAPI::loopAccept, this) };

return true;
}


void api::ServerAPI::loopAccept()
{
namespace boost_http = boost::beast::http;

boost_io_context ioContext{};
boost_acceptor acceptor{ ioContext, { boost_tcp::v4(), 8080 } };

while (true == alive.load(boost::memory_order::relaxed))
{
////////////////////////////////////////////////////////////////////////
boost_socket socket{ ioContext };
acceptor.accept(socket);

////////////////////////////////////////////////////////////////////////
boost::beast::flat_buffer buffer{};
boost_http::request<boost_http::string_body> request{};
boost_http::read(socket, buffer, request);

////////////////////////////////////////////////////////////////////////
onMessage(socket, request);

////////////////////////////////////////////////////////////////////////
socket.shutdown(boost_tcp::socket::shutdown_send);
}
}


void api::ServerAPI::onMessage(
boost_socket& socket,
boost::beast::http::request<boost::beast::http::string_body> const& request)
{
namespace boost_http = boost::beast::http;

////////////////////////////////////////////////////////////////////////
boost_string_view target{ request.base().target() };

////////////////////////////////////////////////////////////////////////
boost_http::response<boost_http::string_body> response{};
response.version(request.version());
response.result(boost_http::status::ok);
response.set(boost_http::field::server, "LuminousMiner API");
response.set(boost_http::field::content_type, "application/json");

////////////////////////////////////////////////////////////////////////
if ("/hiveos/getStats" == target)
{
onHiveOSGetStats(socket, request, response);
}
else if ("/hiveos/getTotalHashrate" == target)
{
onHiveOSGetTotalHashrate(socket, request, response);
}
}


void api::ServerAPI::onHiveOSGetStats(
boost_socket& socket,
boost_request const& request,
boost_response& response)
{
////////////////////////////////////////////////////////////////////////////
std::string version
{
std::to_string(common::VERSION_MAJOR)
+ "."
+ std::to_string(common::VERSION_MINOR)
};

////////////////////////////////////////////////////////////////////////////
boost::json::object root
{
{ "hs", boost::json::array{} }, // array of hashes
{ "hs_units", "khs" }, // Optional: units that are uses for hashes array, "hs", "khs", "mhs", ... Default "khs".
{ "temp", boost::json::array{} }, // array of miner temps
{ "fan", boost::json::array{} }, // array of miner fans
{ "uptime", 0 }, // seconds elapsed from miner stats
{ "ver", version }, // miner version currently run, parsed from it's api or manifest
{ "ar", boost::json::array{} }, // Optional: acceped, rejected shares
{ "algo", "" }, // Optional: algo used by miner, should one of the exiting in Hive
{ "bus_numbers", boost::json::array{} } // Pci buses array in decimal format. E.g. 0a:00.0 is 10
};
boost::json::array hs{};
boost::json::array temp{};
boost::json::array fan{};
boost::json::array ar{};
boost::json::array busNumbers{};

////////////////////////////////////////////////////////////////////////////
std::vector<device::Device*> devices{ deviceManager->getDevices() };
for (device::Device* device : devices)
{
if (nullptr == device)
{
hs.push_back(0);
}
else
{
hs.push_back(device->getHashrate());
}
temp.push_back(0);
fan.push_back(0);
ar.push_back(0);
busNumbers.push_back(device->id);
}
root["hs"] = hs;
root["temp"] = temp;
root["fan"] = fan;
root["ar"] = ar;
root["bus_numbers"] = busNumbers;

////////////////////////////////////////////////////////////////////////////
response.body() = boost::json::serialize(root);
response.prepare_payload();

////////////////////////////////////////////////////////////////////////////
boost::beast::http::write(socket, response);
}


void api::ServerAPI::onHiveOSGetTotalHashrate(
boost_socket& socket,
boost_request const& request,
boost_response& response)
{
double totalHashrate{ 0.0 };
boost::json::object root{};
std::vector<device::Device*> devices{ deviceManager->getDevices() };

for (device::Device* device : devices)
{
if (nullptr == device)
{
continue;
}
totalHashrate += device->getHashrate();
}

root["total_hash_rate"] = totalHashrate;

response.body() = boost::json::serialize(root);
response.prepare_payload();

boost::beast::http::write(socket, response);
}
59 changes: 59 additions & 0 deletions miner/sources/api/api.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <string>

#include <boost/asio.hpp>
#include <boost/atomic/atomic.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>

#include <device/device_manager.hpp>


namespace api
{
struct ServerAPI
{
public:
using boost_error_code = boost::beast::error_code;
using boost_address = boost::asio::ip::address;
using boost_io_context = boost::asio::io_context;
using boost_tcp = boost::asio::ip::tcp;
using boost_acceptor = boost::asio::ip::tcp::acceptor;
using boost_socket = boost::asio::ip::tcp::socket;
using boost_endpoint = boost::asio::ip::tcp::endpoint;
using boost_thread = boost::thread;
using boost_mutex = boost::mutex;
using boost_atomic_bool = boost::atomic_bool;
using boost_string_view = boost::beast::string_view;
using boost_request = boost::beast::http::request<boost::beast::http::string_body>;
using boost_response = boost::beast::http::response<boost::beast::http::string_body>;

uint32_t port{ 0u };
boost_address address{};
boost_acceptor* acceptor{ nullptr };

boost_thread threadDoAccept{};
boost_mutex mtx{};
boost_atomic_bool alive { false };

void setDeviceManager(device::DeviceManager* _deviceManager);
void setPort(uint32_t const _port);
bool bind();
void loopAccept();

private:
device::DeviceManager* deviceManager{ nullptr };
void onMessage(boost_socket& socket,
boost_request const& request);
void onHiveOSGetStats(boost_socket& socket,
boost_request const& request,
boost_response& response);
void onHiveOSGetTotalHashrate(boost_socket& socket,
boost_request const& request,
boost_response& response);
};
}
2 changes: 1 addition & 1 deletion miner/sources/common/app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
namespace common
{
constexpr uint8_t VERSION_MAJOR{ 0 };
constexpr uint8_t VERSION_MINOR{ 1 };
constexpr uint8_t VERSION_MINOR{ 2 };
}
2 changes: 2 additions & 0 deletions miner/sources/common/cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
#endif // !__LIB_CUDA

////////////////////////////////////////////////////////////////////////////////
#define castU2(value) static_cast<unsigned short>(value)
#define castU8(value) static_cast<uint8_t>(value)
#define castU16(value) static_cast<uint16_t>(value)
#define castU32(value) static_cast<uint32_t>(value)
#define castU64(value) static_cast<uint64_t>(value)
////////////////////////////////////////////////////////////////////////////////
#define cast2(value) static_cast<short>(value)
#define cast8(value) static_cast<int8_t>(value)
#define cast16(value) static_cast<int16_t>(value)
#define cast32(value) static_cast<int32_t>(value)
Expand Down
27 changes: 27 additions & 0 deletions miner/sources/common/log/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ common::Logger& common::Logger::operator<<(
return *this;
}


common::Logger& common::Logger::operator<<(
std::string const& str)
{
Expand All @@ -162,6 +163,32 @@ common::Logger& common::Logger::operator<<(
}


common::Logger& common::Logger::operator<<(
std::string_view const& str)
{
if (typeLog > LOGGER_LEVEL)
{
return *this;
}

ss << std::string(str);
return *this;
}


common::Logger& common::Logger::operator<<(
boost::beast::string_view const& str)
{
if (typeLog > LOGGER_LEVEL)
{
return *this;
}

ss << std::string_view(str.data(), str.size());
return *this;
}


common::Logger& common::Logger::operator<<(
stratum::StratumJobInfo const& jobInfo)
{
Expand Down
6 changes: 6 additions & 0 deletions miner/sources/common/log/log.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#pragma once

#include <sstream>
#include <string>
#include <string_view>

#include <boost/beast/core/string_type.hpp>

#include <algo/hash.hpp>
#include <algo/algo_type.hpp>
Expand Down Expand Up @@ -29,6 +33,8 @@ namespace common
Logger& operator<<(algo::hash1024 const& hash);
Logger& operator<<(algo::hash2048 const& hash);
Logger& operator<<(std::string const& str);
Logger& operator<<(std::string_view const& str);
Logger& operator<<(boost::beast::string_view const& str);
Logger& operator<<(stratum::StratumJobInfo const& jobInfo);

template<typename T>
Expand Down
6 changes: 6 additions & 0 deletions miner/sources/device/device_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ void device::DeviceManager::connectToSmartMining()
}


std::vector<device::Device*>& device::DeviceManager::getDevices()
{
return devices;
}


void device::DeviceManager::loopStatistical()
{
std::string host{};
Expand Down
2 changes: 2 additions & 0 deletions miner/sources/device/device_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace device
void run();
void connectToPools();
void connectToSmartMining();
std::vector<Device*>& getDevices();

void onUpdateJob(uint32_t const stratumUUID,
stratum::StratumJobInfo const& newJobInfo);
void onShareStatus(bool const isValid,
Expand Down
Loading

0 comments on commit b224ab8

Please sign in to comment.