1
0
Fork 0
forked from lthn/blockchain

internal stratum server

This commit is contained in:
sowle 2019-03-29 05:43:23 +03:00
parent 7c4a65ef2a
commit a62abcf0b5
7 changed files with 1530 additions and 10 deletions

View file

@ -49,6 +49,7 @@ file(GLOB_RECURSE DAEMON daemon/*)
file(GLOB_RECURSE P2P p2p/*)
file(GLOB_RECURSE RPC rpc/*)
file(GLOB_RECURSE STRATUM stratum/*)
file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
file(GLOB_RECURSE CONN_TOOL connectivity_tool/*)
file(GLOB_RECURSE WALLET wallet/*)
@ -73,6 +74,7 @@ source_group(currency_protocol FILES ${CURRENCY_PROTOCOL})
source_group(daemon FILES ${DAEMON})
source_group(p2p FILES ${P2P})
source_group(rpc FILES ${RPC})
source_group(stratum FILES ${STRATUM})
source_group(simplewallet FILES ${SIMPLEWALLET})
source_group(connectivity-tool FILES ${CONN_TOOL})
source_group(wallet FILES ${WALLET})
@ -106,6 +108,10 @@ add_library(rpc ${RPC})
add_dependencies(rpc version ${PCH_LIB_NAME})
ENABLE_SHARED_PCH(RPC)
add_library(stratum ${STRATUM})
add_dependencies(stratum version ${PCH_LIB_NAME})
ENABLE_SHARED_PCH(STRATUM)
add_library(wallet ${WALLET})
add_dependencies(wallet version ${PCH_LIB_NAME})
ENABLE_SHARED_PCH(WALLET)
@ -114,7 +120,7 @@ target_link_libraries(currency_core lmdb)
add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL})
add_dependencies(daemon version)
target_link_libraries(daemon rpc currency_core crypto common upnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(daemon rpc stratum currency_core crypto common upnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
ENABLE_SHARED_PCH(DAEMON)
ENABLE_SHARED_PCH_EXECUTABLE(daemon)
@ -130,7 +136,7 @@ target_link_libraries(simplewallet wallet rpc currency_core crypto common zlibst
ENABLE_SHARED_PCH(SIMPLEWALLET)
ENABLE_SHARED_PCH_EXECUTABLE(simplewallet)
set_property(TARGET common crypto currency_core rpc wallet PROPERTY FOLDER "libs")
set_property(TARGET common crypto currency_core rpc stratum wallet PROPERTY FOLDER "libs")
set_property(TARGET daemon simplewallet connectivity_tool PROPERTY FOLDER "prog")
set_property(TARGET daemon PROPERTY OUTPUT_NAME "zanod")

View file

@ -27,6 +27,7 @@
namespace currency
{
int ethash_height_to_epoch(uint64_t height);
crypto::hash get_block_longhash(uint64_t h, const crypto::hash& block_long_ash, uint64_t nonce);
void get_block_longhash(const block& b, crypto::hash& res);
crypto::hash get_block_longhash(const block& b);

View file

@ -114,12 +114,12 @@ namespace currency {
return false;
// usual slow check
boost::multiprecision::uint512_t hashVal = 0;
for (int i = 1; i < 4; i++)
{ // highest word is zero
hashVal |= swap64le(((const uint64_t *)&h)[3 - i]);
hashVal << 64;
for(int i = 0; i < 4; i++)
{
hashVal <<= 64;
hashVal |= swap64le(((const uint64_t *) &h)[3-i]);
}
return (hashVal * difficulty > max256bit);
return (hashVal * difficulty <= max256bit);
}
uint64_t difficulty_to_boundary(wide_difficulty_type difficulty)

View file

@ -20,6 +20,7 @@ using namespace epee;
#include "currency_core/checkpoints_create.h"
#include "currency_core/currency_core.h"
#include "rpc/core_rpc_server.h"
#include "stratum/stratum_server.h"
#include "currency_protocol/currency_protocol_handler.h"
#include "daemon_commands_handler.h"
#include "common/miniupnp_helper.h"
@ -85,6 +86,7 @@ int main(int argc, char* argv[])
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >::init_options(desc_cmd_sett);
currency::miner::init_options(desc_cmd_sett);
bc_services::bc_offers_service::init_options(desc_cmd_sett);
currency::stratum_server::init_options(desc_cmd_sett);
po::options_description desc_options("Allowed options");
@ -146,8 +148,8 @@ int main(int argc, char* argv[])
}
// stratum server is enabled if any of its options present
bool stratum_enabled = currency::stratum_server::should_start(vm);
LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0);
//create objects and link them
@ -162,6 +164,9 @@ int main(int argc, char* argv[])
daemon_cmmands_handler dch(p2psrv, rpc_server);
tools::miniupnp_helper upnp_helper;
//ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
if (stratum_enabled)
stratum_server_ptr = std::make_shared<currency::stratum_server>(&ccore);
if (command_line::get_arg(vm, command_line::arg_show_rpc_autodoc))
{
@ -201,6 +206,13 @@ int main(int argc, char* argv[])
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core rpc server.");
LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << rpc_server.get_binded_port(), LOG_LEVEL_0);
if (stratum_enabled)
{
LOG_PRINT_L0("Initializing stratum server...");
res = stratum_server_ptr->init(vm);
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize stratum server.");
}
//initialize core here
LOG_PRINT_L0("Initializing core...");
res = ccore.init(vm);
@ -231,16 +243,34 @@ int main(int argc, char* argv[])
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core rpc server.");
LOG_PRINT_L0("Core rpc server started ok");
if (stratum_enabled)
{
LOG_PRINT_L0("Starting stratum server...");
res = stratum_server_ptr->run(false);
CHECK_AND_ASSERT_MES(res, 1, "Failed to start stratum server.");
LOG_PRINT_L0("Stratum server started ok");
}
tools::signal_handler::install([&dch, &p2psrv] {
tools::signal_handler::install([&dch, &p2psrv, &stratum_server_ptr] {
dch.stop_handling();
p2psrv.send_stop_signal();
if (stratum_server_ptr)
stratum_server_ptr->send_stop_signal();
});
LOG_PRINT_L0("Starting p2p net loop...");
p2psrv.run();
LOG_PRINT_L0("p2p net loop stopped");
//stop components
if (stratum_enabled)
{
LOG_PRINT_L0("Stopping stratum server...");
stratum_server_ptr->send_stop_signal();
stratum_server_ptr->timed_wait_server_stop(1000);
LOG_PRINT_L0("Stratum server stopped");
}
LOG_PRINT_L0("Stopping core rpc server...");
rpc_server.send_stop_signal();
rpc_server.timed_wait_server_stop(5000);
@ -253,6 +283,9 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Deinitializing market...");
(static_cast<currency::i_bc_service&>(offers_service)).deinit();
LOG_PRINT_L0("Deinitializing stratum server ...");
stratum_server_ptr.reset();
LOG_PRINT_L0("Deinitializing rpc server ...");
rpc_server.deinit();
LOG_PRINT_L0("Deinitializing currency_protocol...");

View file

@ -0,0 +1,248 @@
// Copyright (c) 2018-2019 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <string>
#include "epee/include/misc_language.h"
#include "epee/include/storages/parserse_base_utils.h"
#include "epee/include/storages/portable_storage.h"
#include "ethereum/libethash/ethash/ethash.h"
#include "ethereum/libethash/ethash/keccak.h"
#include "currency_core/currency_format_utils.h"
namespace stratum
{
//------------------------------------------------------------------------------------------------------------------------------
// Small helper for extracting separate JSON-RPC requests from input buffer.
// TODO: currently it does not handle curly brackets within strings to make things simplier
struct json_helper
{
void feed(const std::string& s)
{
feed(s.c_str(), s.size());
}
void feed(const char* str, size_t size)
{
m_buffer.append(str, size);
int b_count = 0;
for(size_t i = 0; i < m_buffer.size(); )
{
char c = m_buffer[i];
if (c == '{')
++b_count;
else if (c == '}')
{
if (--b_count == 0)
{
m_objects.push_back(m_buffer.substr(0, i + 1));
m_buffer.erase(0, i + 1);
i = 0;
continue;
}
}
++i;
}
}
bool has_objects() const
{
return !m_objects.empty();
}
bool pop_object(std::string &destination)
{
if (m_objects.empty())
return false;
destination = m_objects.front();
m_objects.pop_front();
return true;
}
std::string m_buffer;
std::list<std::string> m_objects;
};
template<class t_value>
bool ps_get_value_noexcept(epee::serialization::portable_storage& ps, const std::string& value_name, t_value& val, epee::serialization::portable_storage::hsection hparent_section)
{
try
{
return ps.get_value(value_name, val, hparent_section);
}
catch (...)
{
return false;
}
}
std::string trim_0x(const std::string& s)
{
if (s.length() >= 2 && s[0] == '0' && s[1] == 'x')
return s.substr(2);
return s;
}
constexpr char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
constexpr char hexmap_backward[] =
{ //0 1 2 3 4 5 6 7 8 9 A B C D E F
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 0
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 1
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 2
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 20, 20, 20, 20, 20, // 3
20, 10, 11, 12, 13, 14, 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 4
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 5
20, 10, 11, 12, 13, 14, 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 6
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 7
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 8
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 9
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // A
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // B
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // C
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // D
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // E
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 // F
};
template<class pod_t>
std::string pod_to_net_format(const pod_t &h)
{
const char* data = reinterpret_cast<const char*>(&h);
size_t len = sizeof h;
std::string s(len * 2, ' ');
for (size_t i = 0; i < len; ++i) {
s[2 * i] = hexmap[(data[i] & 0xF0) >> 4];
s[2 * i + 1] = hexmap[(data[i] & 0x0F)];
}
return "0x" + s;
}
template<class pod_t>
std::string pod_to_net_format_reverse(const pod_t &h)
{
const char* data = reinterpret_cast<const char*>(&h);
size_t len = sizeof h;
std::string s(len * 2, ' ');
for (size_t i = 0; i < len; ++i) {
s[2 * i] = hexmap[(data[len - i - 1] & 0xF0) >> 4]; // reverse bytes order in data
s[2 * i + 1] = hexmap[(data[len - i - 1] & 0x0F)];
}
return "0x" + s;
}
template<class pod_t>
bool pod_from_net_format(const std::string& str, pod_t& result, bool assume_following_zeroes = false)
{
std::string s = trim_0x(str);
if (s.size() != sizeof(pod_t) * 2)
{
if (!assume_following_zeroes || s.size() > sizeof(pod_t) * 2)
return false; // invalid string length
s.insert(s.size() - 1, sizeof(pod_t) * 2 - s.size(), '0'); // add zeroes at the end
}
const unsigned char* hex_str = reinterpret_cast<const unsigned char*>(s.c_str());
char* pod_data = reinterpret_cast<char*>(&result);
for (size_t i = 0; i < sizeof(pod_t); ++i)
{
char a = hexmap_backward[hex_str[2 * i + 1]];
char b = hexmap_backward[hex_str[2 * i + 0]];
if (a > 15 || b > 15)
return false; // invalid character
pod_data[i] = a | (b << 4);
}
return true;
}
template<class pod_t>
bool pod_from_net_format_reverse(const std::string& str, pod_t& result, bool assume_leading_zeroes = false)
{
std::string s = trim_0x(str);
if (s.size() != sizeof(pod_t) * 2)
{
if (!assume_leading_zeroes || s.size() > sizeof(pod_t) * 2)
return false; // invalid string length
s.insert(0, sizeof(pod_t) * 2 - s.size(), '0'); // add zeroes at the beginning
}
const unsigned char* hex_str = reinterpret_cast<const unsigned char*>(s.c_str());
char* pod_data = reinterpret_cast<char*>(&result);
for (size_t i = 0; i < sizeof(pod_t); ++i)
{
char a = hexmap_backward[hex_str[2 * i + 1]];
char b = hexmap_backward[hex_str[2 * i + 0]];
if (a > 15 || b > 15)
return false; // invalid character
pod_data[sizeof(pod_t) - i - 1] = a | (b << 4); // reverse byte order
}
return true;
}
uint64_t epoch_by_seedhash(const ethash_hash256& seed_hash)
{
ethash_hash256 epoch_seed = {};
for (uint32_t i = 0; i < 2016; ++i) // 2016 epoches will be enough until 2038
{
if (memcmp(&seed_hash, &epoch_seed, sizeof seed_hash) == 0)
return i;
epoch_seed = ethash_keccak256_32(epoch_seed.bytes);
}
return UINT64_MAX;
}
//------------------------------------------------------------------------------------------------------------------------------
// http://www.jsonrpc.org/specification
// 'id' -- an identifier established by the Client that MUST contain a String, Number, or NULL value if included.
// The Server MUST reply with the same value in the Response object if included.
struct jsonrpc_id_null_t {};
typedef boost::variant<int64_t, std::string, jsonrpc_id_null_t> jsonrpc_id_t;
std::string jsonrpc_id_to_value_str(const jsonrpc_id_t& id)
{
if (id.type() == typeid(int64_t))
return boost::to_string(boost::get<int64_t>(id));
if (id.type() == typeid(std::string))
return '"' + boost::to_string(boost::get<std::string>(id)) + '"';
return "null";
}
namespace details
{
struct jsonrpc_id_visitor : public boost::static_visitor<>
{
explicit jsonrpc_id_visitor(jsonrpc_id_t &value) : m_value(value) {}
void operator()(const uint64_t id) { m_value = id; }
void operator()(const int64_t id) { m_value = id; }
void operator()(const std::string& id) { m_value = id; }
template<typename T>
void operator()(const T&) { /* nothing */ }
jsonrpc_id_t &m_value;
};
}
bool read_jsonrpc_id(epee::serialization::portable_storage& ps, jsonrpc_id_t& result)
{
epee::serialization::storage_entry se;
if (!ps.get_value("id", se, nullptr))
return false;
details::jsonrpc_id_visitor vis(result);
boost::apply_visitor(vis, se);
return true;
}
} // namespace stratum
inline std::ostream &operator <<(std::ostream &o, const ethash_hash256 &v) { return print256(o, v); }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,42 @@
// Copyright (c) 2018-2019 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "stratum"
namespace currency
{
class core;
struct stratum_server_impl;
class stratum_server
{
public:
static void init_options(boost::program_options::options_description& desc);
static bool should_start(const boost::program_options::variables_map& vm);
stratum_server(core* c);
~stratum_server();
bool init(const boost::program_options::variables_map& vm);
bool run(bool wait = true);
bool deinit();
bool timed_wait_server_stop(uint64_t ms);
bool send_stop_signal();
private:
size_t m_threads_count;
stratum_server_impl* m_impl;
core* m_p_core;
};
}
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL NULL