get_block_hash, get_block_template IPC + deprecated RPC
This commit is contained in:
parent
26f7c3d5a9
commit
c7d27d4979
|
@ -57,6 +57,25 @@ namespace
|
||||||
}
|
}
|
||||||
return check_core_busy();
|
return check_core_busy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// equivalent of strstr, but with arbitrary bytes (ie, NULs)
|
||||||
|
// This does not differentiate between "not found" and "found at offset 0"
|
||||||
|
// (taken straight from core_rpc_server.cpp)
|
||||||
|
uint64_t slow_memmem(const void *start_buff, size_t buflen, const void *pat, size_t patlen)
|
||||||
|
{
|
||||||
|
const void *buf = start_buff;
|
||||||
|
const void *end = (const char*)buf + buflen;
|
||||||
|
if (patlen > buflen || patlen == 0) return 0;
|
||||||
|
while (buflen > 0 && (buf = memchr(buf, ((const char*)pat)[0], buflen-patlen + 1)))
|
||||||
|
{
|
||||||
|
if (memcmp(buf,pat,patlen) == 0)
|
||||||
|
return (const char*)buf - (const char*)start_buff;
|
||||||
|
buf = (const char*)buf + 1;
|
||||||
|
buflen = (const char*)end - (const char*)buf;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace IPC
|
namespace IPC
|
||||||
|
@ -483,5 +502,89 @@ namespace IPC
|
||||||
p2p->set_save_graph(false);
|
p2p->set_save_graph(false);
|
||||||
wap_proto_set_status(message, STATUS_OK);
|
wap_proto_set_status(message, STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_block_hash(wap_proto_t *message) {
|
||||||
|
if (!check_core_busy())
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64_t height = wap_proto_height(message);
|
||||||
|
if (core->get_current_blockchain_height() <= height)
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_HEIGHT_TOO_BIG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string hash = string_tools::pod_to_hex(core->get_block_id_by_height(height));
|
||||||
|
zchunk_t *hash_chunk = zchunk_new((void*)(hash.c_str()), hash.length());
|
||||||
|
wap_proto_set_hash(message, &hash_chunk);
|
||||||
|
wap_proto_set_status(message, STATUS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_block_template(wap_proto_t *message) {
|
||||||
|
if (!check_core_ready())
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t reserve_size = wap_proto_reserve_size(message);
|
||||||
|
if (reserve_size > 255)
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_RESERVE_SIZE_TOO_BIG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptonote::account_public_address acc = AUTO_VAL_INIT(acc);
|
||||||
|
|
||||||
|
zchunk_t *address_chunk = wap_proto_address(message);
|
||||||
|
std::string address((char*)zchunk_data(address_chunk), zchunk_size(address_chunk));
|
||||||
|
if (!address.size() || !cryptonote::get_account_address_from_str(acc, testnet, address))
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_WRONG_ADDRESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptonote::block b = AUTO_VAL_INIT(b);
|
||||||
|
cryptonote::blobdata blob_reserve;
|
||||||
|
blob_reserve.resize(reserve_size, 0);
|
||||||
|
uint64_t difficulty = wap_proto_difficulty(message);
|
||||||
|
uint64_t height;
|
||||||
|
if (!core->get_block_template(b, acc, difficulty, height, blob_reserve))
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_INTERNAL_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cryptonote::blobdata block_blob = t_serializable_object_to_blob(b);
|
||||||
|
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx);
|
||||||
|
if (tx_pub_key == cryptonote::null_pkey)
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_INTERNAL_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64_t reserved_offset = slow_memmem((void*)block_blob.data(), block_blob.size(), &tx_pub_key, sizeof(tx_pub_key));
|
||||||
|
if (!reserved_offset)
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_INTERNAL_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reserved_offset += sizeof(tx_pub_key) + 3; // 3 bytes: tag for TX_EXTRA_TAG_PUBKEY(1 byte), tag for TX_EXTRA_NONCE(1 byte), counter in TX_EXTRA_NONCE(1 byte)
|
||||||
|
if (reserved_offset + reserve_size > block_blob.size())
|
||||||
|
{
|
||||||
|
wap_proto_set_status(message, STATUS_INTERNAL_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wap_proto_set_height(message, height);
|
||||||
|
wap_proto_set_difficulty(message, difficulty);
|
||||||
|
wap_proto_set_reserved_offset(message, reserved_offset);
|
||||||
|
std::string prev_hash = string_tools::pod_to_hex(b.prev_id);
|
||||||
|
zchunk_t *prev_hash_chunk = zchunk_new((void*)prev_hash.c_str(), prev_hash.length());
|
||||||
|
wap_proto_set_prev_hash(message, &prev_hash_chunk);
|
||||||
|
|
||||||
|
cryptonote::blobdata blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
|
||||||
|
zchunk_t *blob_chunk = zchunk_new((void*)blocktemplate_blob.c_str(), blocktemplate_blob.length());
|
||||||
|
wap_proto_set_block_template_blob(message, &blob_chunk);
|
||||||
|
wap_proto_set_status(message, STATUS_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,10 @@ namespace IPC
|
||||||
const uint64_t STATUS_RANDOM_OUTS_FAILED = 9;
|
const uint64_t STATUS_RANDOM_OUTS_FAILED = 9;
|
||||||
const uint64_t STATUS_MINING_NOT_STOPPED = 10;
|
const uint64_t STATUS_MINING_NOT_STOPPED = 10;
|
||||||
const uint64_t STATUS_NOT_MINING = 11;
|
const uint64_t STATUS_NOT_MINING = 11;
|
||||||
const uint64_t STATUS_INVALID_LOG_LEVEL = 11;
|
const uint64_t STATUS_INVALID_LOG_LEVEL = 12;
|
||||||
const uint64_t STATUS_ERROR_STORING_BLOCKCHAIN = 11;
|
const uint64_t STATUS_ERROR_STORING_BLOCKCHAIN = 13;
|
||||||
|
const uint64_t STATUS_HEIGHT_TOO_BIG = 13;
|
||||||
|
const uint64_t STATUS_RESERVE_SIZE_TOO_BIG = 14;
|
||||||
namespace Daemon
|
namespace Daemon
|
||||||
{
|
{
|
||||||
void start_mining(wap_proto_t *message);
|
void start_mining(wap_proto_t *message);
|
||||||
|
@ -85,6 +87,8 @@ namespace IPC
|
||||||
void set_log_level(wap_proto_t *message);
|
void set_log_level(wap_proto_t *message);
|
||||||
void start_save_graph(wap_proto_t *message);
|
void start_save_graph(wap_proto_t *message);
|
||||||
void stop_save_graph(wap_proto_t *message);
|
void stop_save_graph(wap_proto_t *message);
|
||||||
|
void get_block_hash(wap_proto_t *message);
|
||||||
|
void get_block_template(wap_proto_t *message);
|
||||||
void init(cryptonote::core &p_core,
|
void init(cryptonote::core &p_core,
|
||||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > &p_p2p,
|
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > &p_p2p,
|
||||||
bool p_testnet);
|
bool p_testnet);
|
||||||
|
|
|
@ -147,6 +147,16 @@ WAP_EXPORT int
|
||||||
WAP_EXPORT int
|
WAP_EXPORT int
|
||||||
wap_client_stop_save_graph (wap_client_t *self);
|
wap_client_stop_save_graph (wap_client_t *self);
|
||||||
|
|
||||||
|
// Get block hash
|
||||||
|
// Returns >= 0 if successful, -1 if interrupted.
|
||||||
|
WAP_EXPORT int
|
||||||
|
wap_client_get_block_hash (wap_client_t *self, uint64_t height);
|
||||||
|
|
||||||
|
// Get block template
|
||||||
|
// Returns >= 0 if successful, -1 if interrupted.
|
||||||
|
WAP_EXPORT int
|
||||||
|
wap_client_get_block_template (wap_client_t *self, uint64_t reserve_size, zchunk_t **address_p);
|
||||||
|
|
||||||
// Return last received status
|
// Return last received status
|
||||||
WAP_EXPORT int
|
WAP_EXPORT int
|
||||||
wap_client_status (wap_client_t *self);
|
wap_client_status (wap_client_t *self);
|
||||||
|
@ -243,6 +253,22 @@ WAP_EXPORT uint64_t
|
||||||
WAP_EXPORT zchunk_t *
|
WAP_EXPORT zchunk_t *
|
||||||
wap_client_address (wap_client_t *self);
|
wap_client_address (wap_client_t *self);
|
||||||
|
|
||||||
|
// Return last received hash
|
||||||
|
WAP_EXPORT zchunk_t *
|
||||||
|
wap_client_hash (wap_client_t *self);
|
||||||
|
|
||||||
|
// Return last received reserved_offset
|
||||||
|
WAP_EXPORT uint64_t
|
||||||
|
wap_client_reserved_offset (wap_client_t *self);
|
||||||
|
|
||||||
|
// Return last received prev_hash
|
||||||
|
WAP_EXPORT zchunk_t *
|
||||||
|
wap_client_prev_hash (wap_client_t *self);
|
||||||
|
|
||||||
|
// Return last received block_template_blob
|
||||||
|
WAP_EXPORT zchunk_t *
|
||||||
|
wap_client_block_template_blob (wap_client_t *self);
|
||||||
|
|
||||||
// Self test of this class
|
// Self test of this class
|
||||||
WAP_EXPORT void
|
WAP_EXPORT void
|
||||||
wap_client_test (bool verbose);
|
wap_client_test (bool verbose);
|
||||||
|
|
|
@ -40,10 +40,12 @@ typedef enum {
|
||||||
expect_set_log_level_ok_state = 17,
|
expect_set_log_level_ok_state = 17,
|
||||||
expect_start_save_graph_ok_state = 18,
|
expect_start_save_graph_ok_state = 18,
|
||||||
expect_stop_save_graph_ok_state = 19,
|
expect_stop_save_graph_ok_state = 19,
|
||||||
expect_close_ok_state = 20,
|
expect_get_block_hash_ok_state = 20,
|
||||||
defaults_state = 21,
|
expect_get_block_template_ok_state = 21,
|
||||||
have_error_state = 22,
|
expect_close_ok_state = 22,
|
||||||
reexpect_open_ok_state = 23
|
defaults_state = 23,
|
||||||
|
have_error_state = 24,
|
||||||
|
reexpect_open_ok_state = 25
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -68,29 +70,33 @@ typedef enum {
|
||||||
set_log_level_event = 18,
|
set_log_level_event = 18,
|
||||||
start_save_graph_event = 19,
|
start_save_graph_event = 19,
|
||||||
stop_save_graph_event = 20,
|
stop_save_graph_event = 20,
|
||||||
destructor_event = 21,
|
get_block_hash_event = 21,
|
||||||
blocks_ok_event = 22,
|
get_block_template_event = 22,
|
||||||
get_ok_event = 23,
|
destructor_event = 23,
|
||||||
put_ok_event = 24,
|
blocks_ok_event = 24,
|
||||||
save_bc_ok_event = 25,
|
get_ok_event = 25,
|
||||||
start_ok_event = 26,
|
put_ok_event = 26,
|
||||||
stop_ok_event = 27,
|
save_bc_ok_event = 27,
|
||||||
output_indexes_ok_event = 28,
|
start_ok_event = 28,
|
||||||
random_outs_ok_event = 29,
|
stop_ok_event = 29,
|
||||||
get_height_ok_event = 30,
|
output_indexes_ok_event = 30,
|
||||||
get_info_ok_event = 31,
|
random_outs_ok_event = 31,
|
||||||
get_peer_list_ok_event = 32,
|
get_height_ok_event = 32,
|
||||||
get_mining_status_ok_event = 33,
|
get_info_ok_event = 33,
|
||||||
set_log_hash_rate_ok_event = 34,
|
get_peer_list_ok_event = 34,
|
||||||
set_log_level_ok_event = 35,
|
get_mining_status_ok_event = 35,
|
||||||
start_save_graph_ok_event = 36,
|
set_log_hash_rate_ok_event = 36,
|
||||||
stop_save_graph_ok_event = 37,
|
set_log_level_ok_event = 37,
|
||||||
close_ok_event = 38,
|
start_save_graph_ok_event = 38,
|
||||||
ping_ok_event = 39,
|
stop_save_graph_ok_event = 39,
|
||||||
error_event = 40,
|
get_block_hash_ok_event = 40,
|
||||||
exception_event = 41,
|
get_block_template_ok_event = 41,
|
||||||
command_invalid_event = 42,
|
close_ok_event = 42,
|
||||||
other_event = 43
|
ping_ok_event = 43,
|
||||||
|
error_event = 44,
|
||||||
|
exception_event = 45,
|
||||||
|
command_invalid_event = 46,
|
||||||
|
other_event = 47
|
||||||
} event_t;
|
} event_t;
|
||||||
|
|
||||||
// Names for state machine logging and error reporting
|
// Names for state machine logging and error reporting
|
||||||
|
@ -116,6 +122,8 @@ s_state_name [] = {
|
||||||
"expect set log level ok",
|
"expect set log level ok",
|
||||||
"expect start save graph ok",
|
"expect start save graph ok",
|
||||||
"expect stop save graph ok",
|
"expect stop save graph ok",
|
||||||
|
"expect get block hash ok",
|
||||||
|
"expect get block template ok",
|
||||||
"expect close ok",
|
"expect close ok",
|
||||||
"defaults",
|
"defaults",
|
||||||
"have error",
|
"have error",
|
||||||
|
@ -145,6 +153,8 @@ s_event_name [] = {
|
||||||
"SET_LOG_LEVEL",
|
"SET_LOG_LEVEL",
|
||||||
"START_SAVE_GRAPH",
|
"START_SAVE_GRAPH",
|
||||||
"STOP_SAVE_GRAPH",
|
"STOP_SAVE_GRAPH",
|
||||||
|
"GET_BLOCK_HASH",
|
||||||
|
"GET_BLOCK_TEMPLATE",
|
||||||
"destructor",
|
"destructor",
|
||||||
"BLOCKS_OK",
|
"BLOCKS_OK",
|
||||||
"GET_OK",
|
"GET_OK",
|
||||||
|
@ -162,6 +172,8 @@ s_event_name [] = {
|
||||||
"SET_LOG_LEVEL_OK",
|
"SET_LOG_LEVEL_OK",
|
||||||
"START_SAVE_GRAPH_OK",
|
"START_SAVE_GRAPH_OK",
|
||||||
"STOP_SAVE_GRAPH_OK",
|
"STOP_SAVE_GRAPH_OK",
|
||||||
|
"GET_BLOCK_HASH_OK",
|
||||||
|
"GET_BLOCK_TEMPLATE_OK",
|
||||||
"CLOSE_OK",
|
"CLOSE_OK",
|
||||||
"PING_OK",
|
"PING_OK",
|
||||||
"ERROR",
|
"ERROR",
|
||||||
|
@ -191,6 +203,8 @@ struct _client_args_t {
|
||||||
uint64_t thread_count;
|
uint64_t thread_count;
|
||||||
uint8_t visible;
|
uint8_t visible;
|
||||||
uint8_t level;
|
uint8_t level;
|
||||||
|
uint64_t height;
|
||||||
|
uint64_t reserve_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -258,6 +272,10 @@ static void
|
||||||
prepare_set_log_hash_rate_command (client_t *self);
|
prepare_set_log_hash_rate_command (client_t *self);
|
||||||
static void
|
static void
|
||||||
prepare_set_log_level_command (client_t *self);
|
prepare_set_log_level_command (client_t *self);
|
||||||
|
static void
|
||||||
|
prepare_get_block_hash_command (client_t *self);
|
||||||
|
static void
|
||||||
|
prepare_get_block_template_command (client_t *self);
|
||||||
static void
|
static void
|
||||||
check_if_connection_is_dead (client_t *self);
|
check_if_connection_is_dead (client_t *self);
|
||||||
static void
|
static void
|
||||||
|
@ -292,6 +310,10 @@ static void
|
||||||
signal_have_start_save_graph_ok (client_t *self);
|
signal_have_start_save_graph_ok (client_t *self);
|
||||||
static void
|
static void
|
||||||
signal_have_stop_save_graph_ok (client_t *self);
|
signal_have_stop_save_graph_ok (client_t *self);
|
||||||
|
static void
|
||||||
|
signal_have_get_block_hash_ok (client_t *self);
|
||||||
|
static void
|
||||||
|
signal_have_get_block_template_ok (client_t *self);
|
||||||
static void
|
static void
|
||||||
signal_failure (client_t *self);
|
signal_failure (client_t *self);
|
||||||
static void
|
static void
|
||||||
|
@ -577,6 +599,18 @@ s_protocol_event (s_client_t *self, wap_proto_t *message)
|
||||||
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
||||||
return stop_save_graph_ok_event;
|
return stop_save_graph_ok_event;
|
||||||
break;
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
return get_block_hash_event;
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
return get_block_hash_ok_event;
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
return get_block_template_event;
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
return get_block_template_ok_event;
|
||||||
|
break;
|
||||||
case WAP_PROTO_STOP:
|
case WAP_PROTO_STOP:
|
||||||
return stop_event;
|
return stop_event;
|
||||||
break;
|
break;
|
||||||
|
@ -983,6 +1017,42 @@ s_client_execute (s_client_t *self, event_t event)
|
||||||
self->state = expect_stop_save_graph_ok_state;
|
self->state = expect_stop_save_graph_ok_state;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if (self->event == get_block_hash_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// prepare get block hash command
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ prepare get block hash command");
|
||||||
|
prepare_get_block_hash_command (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception) {
|
||||||
|
// send GET_BLOCK_HASH
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ send GET_BLOCK_HASH");
|
||||||
|
wap_proto_set_id (self->message, WAP_PROTO_GET_BLOCK_HASH);
|
||||||
|
wap_proto_send (self->message, self->dealer);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = expect_get_block_hash_ok_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == get_block_template_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// prepare get block template command
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ prepare get block template command");
|
||||||
|
prepare_get_block_template_command (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception) {
|
||||||
|
// send GET_BLOCK_TEMPLATE
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ send GET_BLOCK_TEMPLATE");
|
||||||
|
wap_proto_set_id (self->message, WAP_PROTO_GET_BLOCK_TEMPLATE);
|
||||||
|
wap_proto_send (self->message, self->dealer);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = expect_get_block_template_ok_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
if (self->event == destructor_event) {
|
if (self->event == destructor_event) {
|
||||||
if (!self->exception) {
|
if (!self->exception) {
|
||||||
// send CLOSE
|
// send CLOSE
|
||||||
|
@ -1764,6 +1834,96 @@ s_client_execute (s_client_t *self, event_t event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case expect_get_block_hash_ok_state:
|
||||||
|
if (self->event == get_block_hash_ok_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// signal have get block hash ok
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ signal have get block hash ok");
|
||||||
|
signal_have_get_block_hash_ok (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = connected_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == ping_ok_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// client is connected
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ client is connected");
|
||||||
|
client_is_connected (&self->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == error_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// check status code
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ check status code");
|
||||||
|
check_status_code (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = have_error_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == exception_event) {
|
||||||
|
// No action - just logging
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ exception");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Handle unexpected protocol events
|
||||||
|
// No action - just logging
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ *");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case expect_get_block_template_ok_state:
|
||||||
|
if (self->event == get_block_template_ok_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// signal have get block template ok
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ signal have get block template ok");
|
||||||
|
signal_have_get_block_template_ok (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = connected_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == ping_ok_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// client is connected
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ client is connected");
|
||||||
|
client_is_connected (&self->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == error_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// check status code
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ check status code");
|
||||||
|
check_status_code (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception)
|
||||||
|
self->state = have_error_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == exception_event) {
|
||||||
|
// No action - just logging
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ exception");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Handle unexpected protocol events
|
||||||
|
// No action - just logging
|
||||||
|
if (wap_client_verbose)
|
||||||
|
zsys_debug ("wap_client: $ *");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case expect_close_ok_state:
|
case expect_close_ok_state:
|
||||||
if (self->event == close_ok_event) {
|
if (self->event == close_ok_event) {
|
||||||
if (!self->exception) {
|
if (!self->exception) {
|
||||||
|
@ -2093,6 +2253,17 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
||||||
if (streq (method, "STOP SAVE GRAPH")) {
|
if (streq (method, "STOP SAVE GRAPH")) {
|
||||||
s_client_execute (self, stop_save_graph_event);
|
s_client_execute (self, stop_save_graph_event);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (streq (method, "GET BLOCK HASH")) {
|
||||||
|
zsock_recv (self->cmdpipe, "8", &self->args.height);
|
||||||
|
s_client_execute (self, get_block_hash_event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (streq (method, "GET BLOCK TEMPLATE")) {
|
||||||
|
zchunk_destroy (&self->args.address);
|
||||||
|
zsock_recv (self->cmdpipe, "8p", &self->args.reserve_size, &self->args.address);
|
||||||
|
s_client_execute (self, get_block_template_event);
|
||||||
|
}
|
||||||
// Cleanup pipe if any argument frames are still waiting to be eaten
|
// Cleanup pipe if any argument frames are still waiting to be eaten
|
||||||
if (zsock_rcvmore (self->cmdpipe)) {
|
if (zsock_rcvmore (self->cmdpipe)) {
|
||||||
zsys_error ("wap_client: trailing API command frames (%s)", method);
|
zsys_error ("wap_client: trailing API command frames (%s)", method);
|
||||||
|
@ -2229,6 +2400,10 @@ struct _wap_client_t {
|
||||||
uint64_t speed; // Returned by actor reply
|
uint64_t speed; // Returned by actor reply
|
||||||
uint64_t thread_count; // Returned by actor reply
|
uint64_t thread_count; // Returned by actor reply
|
||||||
zchunk_t *address; // Returned by actor reply
|
zchunk_t *address; // Returned by actor reply
|
||||||
|
zchunk_t *hash; // Returned by actor reply
|
||||||
|
uint64_t reserved_offset; // Returned by actor reply
|
||||||
|
zchunk_t *prev_hash; // Returned by actor reply
|
||||||
|
zchunk_t *block_template_blob; // Returned by actor reply
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2284,6 +2459,9 @@ wap_client_destroy (wap_client_t **self_p)
|
||||||
zframe_destroy (&self->white_list);
|
zframe_destroy (&self->white_list);
|
||||||
zframe_destroy (&self->gray_list);
|
zframe_destroy (&self->gray_list);
|
||||||
zchunk_destroy (&self->address);
|
zchunk_destroy (&self->address);
|
||||||
|
zchunk_destroy (&self->hash);
|
||||||
|
zchunk_destroy (&self->prev_hash);
|
||||||
|
zchunk_destroy (&self->block_template_blob);
|
||||||
free (self);
|
free (self);
|
||||||
*self_p = NULL;
|
*self_p = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2432,6 +2610,17 @@ s_accept_reply (wap_client_t *self, ...)
|
||||||
if (streq (reply, "STOP SAVE GRAPH OK")) {
|
if (streq (reply, "STOP SAVE GRAPH OK")) {
|
||||||
zsock_recv (self->actor, "8", &self->status);
|
zsock_recv (self->actor, "8", &self->status);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (streq (reply, "GET BLOCK HASH OK")) {
|
||||||
|
zchunk_destroy (&self->hash);
|
||||||
|
zsock_recv (self->actor, "8p", &self->status, &self->hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (streq (reply, "GET BLOCK TEMPLATE OK")) {
|
||||||
|
zchunk_destroy (&self->prev_hash);
|
||||||
|
zchunk_destroy (&self->block_template_blob);
|
||||||
|
zsock_recv (self->actor, "8888pp", &self->status, &self->reserved_offset, &self->height, &self->difficulty, &self->prev_hash, &self->block_template_blob);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filter = va_arg (args, char *);
|
filter = va_arg (args, char *);
|
||||||
|
@ -2745,6 +2934,39 @@ wap_client_stop_save_graph (wap_client_t *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Get block hash
|
||||||
|
// Returns >= 0 if successful, -1 if interrupted.
|
||||||
|
|
||||||
|
int
|
||||||
|
wap_client_get_block_hash (wap_client_t *self, uint64_t height)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
|
||||||
|
zsock_send (self->actor, "s8", "GET BLOCK HASH", height);
|
||||||
|
if (s_accept_reply (self, "GET BLOCK HASH OK", "FAILURE", NULL))
|
||||||
|
return -1; // Interrupted or timed-out
|
||||||
|
return self->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Get block template
|
||||||
|
// Returns >= 0 if successful, -1 if interrupted.
|
||||||
|
|
||||||
|
int
|
||||||
|
wap_client_get_block_template (wap_client_t *self, uint64_t reserve_size, zchunk_t **address_p)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
|
||||||
|
zsock_send (self->actor, "s8p", "GET BLOCK TEMPLATE", reserve_size, *address_p);
|
||||||
|
*address_p = NULL; // Take ownership of address
|
||||||
|
if (s_accept_reply (self, "GET BLOCK TEMPLATE OK", "FAILURE", NULL))
|
||||||
|
return -1; // Interrupted or timed-out
|
||||||
|
return self->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Return last received status
|
// Return last received status
|
||||||
|
|
||||||
|
@ -3007,3 +3229,47 @@ wap_client_address (wap_client_t *self)
|
||||||
assert (self);
|
assert (self);
|
||||||
return self->address;
|
return self->address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Return last received hash
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_client_hash (wap_client_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Return last received reserved_offset
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
wap_client_reserved_offset (wap_client_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->reserved_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Return last received prev_hash
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_client_prev_hash (wap_client_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->prev_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Return last received block_template_blob
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_client_block_template_blob (wap_client_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->block_template_blob;
|
||||||
|
}
|
||||||
|
|
|
@ -142,6 +142,25 @@ ERROR.
|
||||||
STOP_SAVE_GRAPH_OK - This is a codec for a Bitcoin Wallet Access Protocol (RFC tbd)
|
STOP_SAVE_GRAPH_OK - This is a codec for a Bitcoin Wallet Access Protocol (RFC tbd)
|
||||||
status number 8 Status
|
status number 8 Status
|
||||||
|
|
||||||
|
GET_BLOCK_HASH - get_block_hash IPC
|
||||||
|
height number 8 Height
|
||||||
|
|
||||||
|
GET_BLOCK_HASH_OK - This is a codec for a Bitcoin Wallet Access Protocol (RFC tbd)
|
||||||
|
status number 8 Status
|
||||||
|
hash chunk Hash
|
||||||
|
|
||||||
|
GET_BLOCK_TEMPLATE - get_block_template IPC
|
||||||
|
reserve_size number 8 Reserve size
|
||||||
|
address chunk Address
|
||||||
|
|
||||||
|
GET_BLOCK_TEMPLATE_OK - This is a codec for a Bitcoin Wallet Access Protocol (RFC tbd)
|
||||||
|
status number 8 Status
|
||||||
|
reserved_offset number 8 Rservered Offset
|
||||||
|
height number 8 Height
|
||||||
|
difficulty number 8 Difficulty
|
||||||
|
prev_hash chunk Previous Hash
|
||||||
|
block_template_blob chunk Block template blob
|
||||||
|
|
||||||
STOP - Wallet asks daemon to start mining. Daemon replies with STOP-OK, or
|
STOP - Wallet asks daemon to start mining. Daemon replies with STOP-OK, or
|
||||||
ERROR.
|
ERROR.
|
||||||
|
|
||||||
|
@ -205,13 +224,17 @@ Daemon will reply with CLOSE-OK or ERROR.
|
||||||
#define WAP_PROTO_START_SAVE_GRAPH_OK 30
|
#define WAP_PROTO_START_SAVE_GRAPH_OK 30
|
||||||
#define WAP_PROTO_STOP_SAVE_GRAPH 31
|
#define WAP_PROTO_STOP_SAVE_GRAPH 31
|
||||||
#define WAP_PROTO_STOP_SAVE_GRAPH_OK 32
|
#define WAP_PROTO_STOP_SAVE_GRAPH_OK 32
|
||||||
#define WAP_PROTO_STOP 33
|
#define WAP_PROTO_GET_BLOCK_HASH 33
|
||||||
#define WAP_PROTO_STOP_OK 34
|
#define WAP_PROTO_GET_BLOCK_HASH_OK 34
|
||||||
#define WAP_PROTO_CLOSE 35
|
#define WAP_PROTO_GET_BLOCK_TEMPLATE 35
|
||||||
#define WAP_PROTO_CLOSE_OK 36
|
#define WAP_PROTO_GET_BLOCK_TEMPLATE_OK 36
|
||||||
#define WAP_PROTO_PING 37
|
#define WAP_PROTO_STOP 37
|
||||||
#define WAP_PROTO_PING_OK 38
|
#define WAP_PROTO_STOP_OK 38
|
||||||
#define WAP_PROTO_ERROR 39
|
#define WAP_PROTO_CLOSE 39
|
||||||
|
#define WAP_PROTO_CLOSE_OK 40
|
||||||
|
#define WAP_PROTO_PING 41
|
||||||
|
#define WAP_PROTO_PING_OK 42
|
||||||
|
#define WAP_PROTO_ERROR 43
|
||||||
|
|
||||||
#include <czmq.h>
|
#include <czmq.h>
|
||||||
|
|
||||||
|
@ -491,6 +514,48 @@ byte
|
||||||
void
|
void
|
||||||
wap_proto_set_level (wap_proto_t *self, byte level);
|
wap_proto_set_level (wap_proto_t *self, byte level);
|
||||||
|
|
||||||
|
// Get a copy of the hash field
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_hash (wap_proto_t *self);
|
||||||
|
// Get the hash field and transfer ownership to caller
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_hash (wap_proto_t *self);
|
||||||
|
// Set the hash field, transferring ownership from caller
|
||||||
|
void
|
||||||
|
wap_proto_set_hash (wap_proto_t *self, zchunk_t **chunk_p);
|
||||||
|
|
||||||
|
// Get/set the reserve_size field
|
||||||
|
uint64_t
|
||||||
|
wap_proto_reserve_size (wap_proto_t *self);
|
||||||
|
void
|
||||||
|
wap_proto_set_reserve_size (wap_proto_t *self, uint64_t reserve_size);
|
||||||
|
|
||||||
|
// Get/set the reserved_offset field
|
||||||
|
uint64_t
|
||||||
|
wap_proto_reserved_offset (wap_proto_t *self);
|
||||||
|
void
|
||||||
|
wap_proto_set_reserved_offset (wap_proto_t *self, uint64_t reserved_offset);
|
||||||
|
|
||||||
|
// Get a copy of the prev_hash field
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_prev_hash (wap_proto_t *self);
|
||||||
|
// Get the prev_hash field and transfer ownership to caller
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_prev_hash (wap_proto_t *self);
|
||||||
|
// Set the prev_hash field, transferring ownership from caller
|
||||||
|
void
|
||||||
|
wap_proto_set_prev_hash (wap_proto_t *self, zchunk_t **chunk_p);
|
||||||
|
|
||||||
|
// Get a copy of the block_template_blob field
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_block_template_blob (wap_proto_t *self);
|
||||||
|
// Get the block_template_blob field and transfer ownership to caller
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_block_template_blob (wap_proto_t *self);
|
||||||
|
// Set the block_template_blob field, transferring ownership from caller
|
||||||
|
void
|
||||||
|
wap_proto_set_block_template_blob (wap_proto_t *self, zchunk_t **chunk_p);
|
||||||
|
|
||||||
// Get/set the reason field
|
// Get/set the reason field
|
||||||
const char *
|
const char *
|
||||||
wap_proto_reason (wap_proto_t *self);
|
wap_proto_reason (wap_proto_t *self);
|
||||||
|
|
|
@ -47,11 +47,13 @@ typedef enum {
|
||||||
set_log_level_event = 16,
|
set_log_level_event = 16,
|
||||||
start_save_graph_event = 17,
|
start_save_graph_event = 17,
|
||||||
stop_save_graph_event = 18,
|
stop_save_graph_event = 18,
|
||||||
close_event = 19,
|
get_block_hash_event = 19,
|
||||||
ping_event = 20,
|
get_block_template_event = 20,
|
||||||
expired_event = 21,
|
close_event = 21,
|
||||||
exception_event = 22,
|
ping_event = 22,
|
||||||
settled_event = 23
|
expired_event = 23,
|
||||||
|
exception_event = 24,
|
||||||
|
settled_event = 25
|
||||||
} event_t;
|
} event_t;
|
||||||
|
|
||||||
// Names for state machine logging and error reporting
|
// Names for state machine logging and error reporting
|
||||||
|
@ -85,6 +87,8 @@ s_event_name [] = {
|
||||||
"SET_LOG_LEVEL",
|
"SET_LOG_LEVEL",
|
||||||
"START_SAVE_GRAPH",
|
"START_SAVE_GRAPH",
|
||||||
"STOP_SAVE_GRAPH",
|
"STOP_SAVE_GRAPH",
|
||||||
|
"GET_BLOCK_HASH",
|
||||||
|
"GET_BLOCK_TEMPLATE",
|
||||||
"CLOSE",
|
"CLOSE",
|
||||||
"PING",
|
"PING",
|
||||||
"expired",
|
"expired",
|
||||||
|
@ -186,6 +190,10 @@ static void
|
||||||
start_save_graph (client_t *self);
|
start_save_graph (client_t *self);
|
||||||
static void
|
static void
|
||||||
stop_save_graph (client_t *self);
|
stop_save_graph (client_t *self);
|
||||||
|
static void
|
||||||
|
get_block_hash (client_t *self);
|
||||||
|
static void
|
||||||
|
get_block_template (client_t *self);
|
||||||
static void
|
static void
|
||||||
deregister_wallet (client_t *self);
|
deregister_wallet (client_t *self);
|
||||||
static void
|
static void
|
||||||
|
@ -418,6 +426,12 @@ s_protocol_event (wap_proto_t *message)
|
||||||
case WAP_PROTO_STOP_SAVE_GRAPH:
|
case WAP_PROTO_STOP_SAVE_GRAPH:
|
||||||
return stop_save_graph_event;
|
return stop_save_graph_event;
|
||||||
break;
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
return get_block_hash_event;
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
return get_block_template_event;
|
||||||
|
break;
|
||||||
case WAP_PROTO_STOP:
|
case WAP_PROTO_STOP:
|
||||||
return stop_event;
|
return stop_event;
|
||||||
break;
|
break;
|
||||||
|
@ -924,6 +938,42 @@ s_client_execute (s_client_t *self, event_t event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if (self->event == get_block_hash_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// get block hash
|
||||||
|
if (self->server->verbose)
|
||||||
|
zsys_debug ("%s: $ get block hash", self->log_prefix);
|
||||||
|
get_block_hash (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception) {
|
||||||
|
// send GET_BLOCK_HASH_OK
|
||||||
|
if (self->server->verbose)
|
||||||
|
zsys_debug ("%s: $ send GET_BLOCK_HASH_OK",
|
||||||
|
self->log_prefix);
|
||||||
|
wap_proto_set_id (self->server->message, WAP_PROTO_GET_BLOCK_HASH_OK);
|
||||||
|
wap_proto_set_routing_id (self->server->message, self->routing_id);
|
||||||
|
wap_proto_send (self->server->message, self->server->router);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (self->event == get_block_template_event) {
|
||||||
|
if (!self->exception) {
|
||||||
|
// get block template
|
||||||
|
if (self->server->verbose)
|
||||||
|
zsys_debug ("%s: $ get block template", self->log_prefix);
|
||||||
|
get_block_template (&self->client);
|
||||||
|
}
|
||||||
|
if (!self->exception) {
|
||||||
|
// send GET_BLOCK_TEMPLATE_OK
|
||||||
|
if (self->server->verbose)
|
||||||
|
zsys_debug ("%s: $ send GET_BLOCK_TEMPLATE_OK",
|
||||||
|
self->log_prefix);
|
||||||
|
wap_proto_set_id (self->server->message, WAP_PROTO_GET_BLOCK_TEMPLATE_OK);
|
||||||
|
wap_proto_set_routing_id (self->server->message, self->routing_id);
|
||||||
|
wap_proto_send (self->server->message, self->server->router);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
if (self->event == close_event) {
|
if (self->event == close_event) {
|
||||||
if (!self->exception) {
|
if (!self->exception) {
|
||||||
// send CLOSE_OK
|
// send CLOSE_OK
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "wap_classes.h"
|
#include "wap_classes.h"
|
||||||
// TODO: Change these to match your project's needs
|
|
||||||
#include "../include/wap_proto.h"
|
|
||||||
#include "../include/wap_client.h"
|
|
||||||
|
|
||||||
// Forward reference to method arguments structure
|
// Forward reference to method arguments structure
|
||||||
typedef struct _client_args_t client_args_t;
|
typedef struct _client_args_t client_args_t;
|
||||||
|
@ -98,6 +95,7 @@ use_connect_timeout (client_t *self)
|
||||||
engine_set_timeout (self, self->args->timeout);
|
engine_set_timeout (self, self->args->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// client_is_connected
|
// client_is_connected
|
||||||
//
|
//
|
||||||
|
@ -110,6 +108,7 @@ client_is_connected (client_t *self)
|
||||||
engine_set_timeout (self, self->heartbeat_timer);
|
engine_set_timeout (self, self->heartbeat_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// check_if_connection_is_dead
|
// check_if_connection_is_dead
|
||||||
//
|
//
|
||||||
|
@ -125,17 +124,6 @@ check_if_connection_is_dead (client_t *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// use_heartbeat_timer
|
|
||||||
//
|
|
||||||
|
|
||||||
static void
|
|
||||||
use_heartbeat_timer (client_t *self)
|
|
||||||
{
|
|
||||||
engine_set_timeout (self, self->heartbeat_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// prepare_blocks_command
|
// prepare_blocks_command
|
||||||
|
@ -148,15 +136,6 @@ prepare_blocks_command (client_t *self)
|
||||||
wap_proto_set_start_height (self->message, self->args->start_height);
|
wap_proto_set_start_height (self->message, self->args->start_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// prepare_get_output_indexes_command
|
|
||||||
//
|
|
||||||
|
|
||||||
static void
|
|
||||||
prepare_get_output_indexes_command (client_t *self)
|
|
||||||
{
|
|
||||||
wap_proto_set_tx_id (self->message, &self->args->tx_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// signal_have_blocks_ok
|
// signal_have_blocks_ok
|
||||||
|
@ -165,10 +144,13 @@ prepare_get_output_indexes_command (client_t *self)
|
||||||
static void
|
static void
|
||||||
signal_have_blocks_ok (client_t *self)
|
signal_have_blocks_ok (client_t *self)
|
||||||
{
|
{
|
||||||
|
zmsg_t *msg = wap_proto_get_block_data (self->message);
|
||||||
|
assert(msg != 0);
|
||||||
|
printf("%p <--\n", (void*)msg);
|
||||||
zsock_send (self->cmdpipe, "s888p", "BLOCKS OK", wap_proto_status(self->message),
|
zsock_send (self->cmdpipe, "s888p", "BLOCKS OK", wap_proto_status(self->message),
|
||||||
wap_proto_start_height (self->message),
|
wap_proto_start_height (self->message),
|
||||||
wap_proto_curr_height (self->message),
|
wap_proto_curr_height (self->message),
|
||||||
wap_proto_get_block_data (self->message));
|
msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,8 +183,8 @@ prepare_put_command (client_t *self)
|
||||||
static void
|
static void
|
||||||
signal_have_put_ok (client_t *self)
|
signal_have_put_ok (client_t *self)
|
||||||
{
|
{
|
||||||
zsock_send (self->cmdpipe, "s8s", "PUT OK", wap_proto_status(self->message),
|
zsock_send (self->cmdpipe, "s8", "PUT OK",
|
||||||
wap_proto_tx_id (self->message));
|
wap_proto_status (self->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,10 +206,21 @@ prepare_get_command (client_t *self)
|
||||||
static void
|
static void
|
||||||
signal_have_get_ok (client_t *self)
|
signal_have_get_ok (client_t *self)
|
||||||
{
|
{
|
||||||
zsock_send (self->cmdpipe, "s8p", "GET OK", 0,
|
zsock_send (self->cmdpipe, "sip", "GET OK", 0,
|
||||||
wap_proto_get_tx_data (self->message));
|
wap_proto_get_tx_data (self->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// signal_have_get_height_ok
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_have_get_height_ok (client_t *self)
|
||||||
|
{
|
||||||
|
zsock_send (self->cmdpipe, "si8", "GET HEIGHT OK", 0,
|
||||||
|
wap_proto_height (self->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// signal_have_save_ok
|
// signal_have_save_ok
|
||||||
|
@ -258,31 +251,9 @@ signal_have_start_ok (client_t *self)
|
||||||
static void
|
static void
|
||||||
signal_have_stop_ok (client_t *self)
|
signal_have_stop_ok (client_t *self)
|
||||||
{
|
{
|
||||||
zsock_send (self->cmdpipe, "s8", "STOP OK", 0);
|
zsock_send (self->cmdpipe, "si", "STOP OK", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// signal_have_get_height_ok
|
|
||||||
//
|
|
||||||
|
|
||||||
static void
|
|
||||||
signal_have_get_height_ok (client_t *self)
|
|
||||||
{
|
|
||||||
zsock_send (self->cmdpipe, "si8", "GET HEIGHT OK", 0,
|
|
||||||
wap_proto_height (self->message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// signal_have_output_indexes_ok
|
|
||||||
//
|
|
||||||
|
|
||||||
static void
|
|
||||||
signal_have_output_indexes_ok (client_t *self)
|
|
||||||
{
|
|
||||||
zsock_send (self->cmdpipe, "s8p", "OUTPUT INDEXES OK",
|
|
||||||
wap_proto_status (self->message),
|
|
||||||
wap_proto_get_o_indexes (self->message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// signal_success
|
// signal_success
|
||||||
|
@ -352,6 +323,37 @@ signal_server_not_present (client_t *self)
|
||||||
zsock_send (self->cmdpipe, "sis", "FAILURE", -1, "Server is not reachable");
|
zsock_send (self->cmdpipe, "sis", "FAILURE", -1, "Server is not reachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// prepare_get_output_indexes_command
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_get_output_indexes_command (client_t *self)
|
||||||
|
{
|
||||||
|
wap_proto_set_tx_id (self->message, &self->args->tx_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// signal_have_output_indexes_ok
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_have_output_indexes_ok (client_t *self)
|
||||||
|
{
|
||||||
|
zsock_send (self->cmdpipe, "s8p", "OUTPUT INDEXES OK",
|
||||||
|
wap_proto_status (self->message),
|
||||||
|
wap_proto_get_o_indexes (self->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
void wap_client_test(bool verbose) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// prepare_get_random_outs_command
|
// prepare_get_random_outs_command
|
||||||
//
|
//
|
||||||
|
@ -359,7 +361,6 @@ signal_server_not_present (client_t *self)
|
||||||
static void
|
static void
|
||||||
prepare_get_random_outs_command (client_t *self)
|
prepare_get_random_outs_command (client_t *self)
|
||||||
{
|
{
|
||||||
wap_proto_set_outs_count(self->message, self->args->outs_count);
|
|
||||||
wap_proto_set_amounts (self->message, &self->args->amounts);
|
wap_proto_set_amounts (self->message, &self->args->amounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +377,8 @@ signal_have_random_outs_ok (client_t *self)
|
||||||
wap_proto_get_random_outputs (self->message));
|
wap_proto_get_random_outputs (self->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// signal_have_get_info_ok
|
// signal_have_get_info_ok
|
||||||
//
|
//
|
||||||
|
@ -397,8 +400,9 @@ signal_have_get_info_ok (client_t *self)
|
||||||
wap_proto_grey_peerlist_size (self->message));
|
wap_proto_grey_peerlist_size (self->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// signal_have_get_get_peer_list_ok
|
// signal_have_get_peer_list_ok
|
||||||
//
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -488,3 +492,52 @@ signal_have_stop_save_graph_ok (client_t *self)
|
||||||
zsock_send (self->cmdpipe, "s8", "STOP SAVE GRAPH OK",
|
zsock_send (self->cmdpipe, "s8", "STOP SAVE GRAPH OK",
|
||||||
wap_proto_status (self->message));
|
wap_proto_status (self->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// prepare_get_block_hash_command
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_get_block_hash_command (client_t *self)
|
||||||
|
{
|
||||||
|
wap_proto_set_height (self->message, self->args->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// signal_have_get_block_hash_ok
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_have_get_block_hash_ok (client_t *self)
|
||||||
|
{
|
||||||
|
zsock_send (self->cmdpipe, "s8p", "GET BLOCK HASH OK",
|
||||||
|
wap_proto_status (self->message), wap_proto_get_hash (self->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// prepare_get_block_template_command
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_get_block_template_command (client_t *self)
|
||||||
|
{
|
||||||
|
wap_proto_set_reserve_size (self->message, self->args->reserve_size);
|
||||||
|
wap_proto_set_address (self->message, &self->args->address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// signal_have_get_block_template_ok
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_have_get_block_template_ok (client_t *self)
|
||||||
|
{
|
||||||
|
zsock_send (self->cmdpipe, "s8888pp", "GET BLOCK TEMPLATE OK",
|
||||||
|
wap_proto_status (self->message),
|
||||||
|
wap_proto_reserved_offset (self->message),
|
||||||
|
wap_proto_height (self->message),
|
||||||
|
wap_proto_difficulty (self->message),
|
||||||
|
wap_proto_get_prev_hash (self->message),
|
||||||
|
wap_proto_get_block_template_blob (self->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,11 @@ struct _wap_proto_t {
|
||||||
uint64_t speed; // Speed
|
uint64_t speed; // Speed
|
||||||
byte visible; // Visible
|
byte visible; // Visible
|
||||||
byte level; // Level
|
byte level; // Level
|
||||||
|
zchunk_t *hash; // Hash
|
||||||
|
uint64_t reserve_size; // Reserve size
|
||||||
|
uint64_t reserved_offset; // Rservered Offset
|
||||||
|
zchunk_t *prev_hash; // Previous Hash
|
||||||
|
zchunk_t *block_template_blob; // Block template blob
|
||||||
char reason [256]; // Printable explanation
|
char reason [256]; // Printable explanation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -253,6 +258,9 @@ wap_proto_destroy (wap_proto_t **self_p)
|
||||||
zchunk_destroy (&self->address);
|
zchunk_destroy (&self->address);
|
||||||
zframe_destroy (&self->white_list);
|
zframe_destroy (&self->white_list);
|
||||||
zframe_destroy (&self->gray_list);
|
zframe_destroy (&self->gray_list);
|
||||||
|
zchunk_destroy (&self->hash);
|
||||||
|
zchunk_destroy (&self->prev_hash);
|
||||||
|
zchunk_destroy (&self->block_template_blob);
|
||||||
|
|
||||||
// Free object itself
|
// Free object itself
|
||||||
free (self);
|
free (self);
|
||||||
|
@ -568,6 +576,69 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
||||||
GET_NUMBER8 (self->status);
|
GET_NUMBER8 (self->status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
GET_NUMBER8 (self->height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
GET_NUMBER8 (self->status);
|
||||||
|
{
|
||||||
|
size_t chunk_size;
|
||||||
|
GET_NUMBER4 (chunk_size);
|
||||||
|
if (self->needle + chunk_size > (self->ceiling)) {
|
||||||
|
zsys_warning ("wap_proto: hash is missing data");
|
||||||
|
goto malformed;
|
||||||
|
}
|
||||||
|
zchunk_destroy (&self->hash);
|
||||||
|
self->hash = zchunk_new (self->needle, chunk_size);
|
||||||
|
self->needle += chunk_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
GET_NUMBER8 (self->reserve_size);
|
||||||
|
{
|
||||||
|
size_t chunk_size;
|
||||||
|
GET_NUMBER4 (chunk_size);
|
||||||
|
if (self->needle + chunk_size > (self->ceiling)) {
|
||||||
|
zsys_warning ("wap_proto: address is missing data");
|
||||||
|
goto malformed;
|
||||||
|
}
|
||||||
|
zchunk_destroy (&self->address);
|
||||||
|
self->address = zchunk_new (self->needle, chunk_size);
|
||||||
|
self->needle += chunk_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
GET_NUMBER8 (self->status);
|
||||||
|
GET_NUMBER8 (self->reserved_offset);
|
||||||
|
GET_NUMBER8 (self->height);
|
||||||
|
GET_NUMBER8 (self->difficulty);
|
||||||
|
{
|
||||||
|
size_t chunk_size;
|
||||||
|
GET_NUMBER4 (chunk_size);
|
||||||
|
if (self->needle + chunk_size > (self->ceiling)) {
|
||||||
|
zsys_warning ("wap_proto: prev_hash is missing data");
|
||||||
|
goto malformed;
|
||||||
|
}
|
||||||
|
zchunk_destroy (&self->prev_hash);
|
||||||
|
self->prev_hash = zchunk_new (self->needle, chunk_size);
|
||||||
|
self->needle += chunk_size;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size_t chunk_size;
|
||||||
|
GET_NUMBER4 (chunk_size);
|
||||||
|
if (self->needle + chunk_size > (self->ceiling)) {
|
||||||
|
zsys_warning ("wap_proto: block_template_blob is missing data");
|
||||||
|
goto malformed;
|
||||||
|
}
|
||||||
|
zchunk_destroy (&self->block_template_blob);
|
||||||
|
self->block_template_blob = zchunk_new (self->needle, chunk_size);
|
||||||
|
self->needle += chunk_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WAP_PROTO_STOP:
|
case WAP_PROTO_STOP:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -734,6 +805,33 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
||||||
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
||||||
frame_size += 8; // status
|
frame_size += 8; // status
|
||||||
break;
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
frame_size += 8; // height
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
frame_size += 8; // status
|
||||||
|
frame_size += 4; // Size is 4 octets
|
||||||
|
if (self->hash)
|
||||||
|
frame_size += zchunk_size (self->hash);
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
frame_size += 8; // reserve_size
|
||||||
|
frame_size += 4; // Size is 4 octets
|
||||||
|
if (self->address)
|
||||||
|
frame_size += zchunk_size (self->address);
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
frame_size += 8; // status
|
||||||
|
frame_size += 8; // reserved_offset
|
||||||
|
frame_size += 8; // height
|
||||||
|
frame_size += 8; // difficulty
|
||||||
|
frame_size += 4; // Size is 4 octets
|
||||||
|
if (self->prev_hash)
|
||||||
|
frame_size += zchunk_size (self->prev_hash);
|
||||||
|
frame_size += 4; // Size is 4 octets
|
||||||
|
if (self->block_template_blob)
|
||||||
|
frame_size += zchunk_size (self->block_template_blob);
|
||||||
|
break;
|
||||||
case WAP_PROTO_ERROR:
|
case WAP_PROTO_ERROR:
|
||||||
frame_size += 2; // status
|
frame_size += 2; // status
|
||||||
frame_size += 1 + strlen (self->reason);
|
frame_size += 1 + strlen (self->reason);
|
||||||
|
@ -930,6 +1028,61 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
||||||
PUT_NUMBER8 (self->status);
|
PUT_NUMBER8 (self->status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
PUT_NUMBER8 (self->height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
PUT_NUMBER8 (self->status);
|
||||||
|
if (self->hash) {
|
||||||
|
PUT_NUMBER4 (zchunk_size (self->hash));
|
||||||
|
memcpy (self->needle,
|
||||||
|
zchunk_data (self->hash),
|
||||||
|
zchunk_size (self->hash));
|
||||||
|
self->needle += zchunk_size (self->hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PUT_NUMBER4 (0); // Empty chunk
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
PUT_NUMBER8 (self->reserve_size);
|
||||||
|
if (self->address) {
|
||||||
|
PUT_NUMBER4 (zchunk_size (self->address));
|
||||||
|
memcpy (self->needle,
|
||||||
|
zchunk_data (self->address),
|
||||||
|
zchunk_size (self->address));
|
||||||
|
self->needle += zchunk_size (self->address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PUT_NUMBER4 (0); // Empty chunk
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
PUT_NUMBER8 (self->status);
|
||||||
|
PUT_NUMBER8 (self->reserved_offset);
|
||||||
|
PUT_NUMBER8 (self->height);
|
||||||
|
PUT_NUMBER8 (self->difficulty);
|
||||||
|
if (self->prev_hash) {
|
||||||
|
PUT_NUMBER4 (zchunk_size (self->prev_hash));
|
||||||
|
memcpy (self->needle,
|
||||||
|
zchunk_data (self->prev_hash),
|
||||||
|
zchunk_size (self->prev_hash));
|
||||||
|
self->needle += zchunk_size (self->prev_hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PUT_NUMBER4 (0); // Empty chunk
|
||||||
|
if (self->block_template_blob) {
|
||||||
|
PUT_NUMBER4 (zchunk_size (self->block_template_blob));
|
||||||
|
memcpy (self->needle,
|
||||||
|
zchunk_data (self->block_template_blob),
|
||||||
|
zchunk_size (self->block_template_blob));
|
||||||
|
self->needle += zchunk_size (self->block_template_blob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PUT_NUMBER4 (0); // Empty chunk
|
||||||
|
break;
|
||||||
|
|
||||||
case WAP_PROTO_ERROR:
|
case WAP_PROTO_ERROR:
|
||||||
PUT_NUMBER2 (self->status);
|
PUT_NUMBER2 (self->status);
|
||||||
PUT_STRING (self->reason);
|
PUT_STRING (self->reason);
|
||||||
|
@ -1210,6 +1363,33 @@ wap_proto_print (wap_proto_t *self)
|
||||||
zsys_debug (" status=%ld", (long) self->status);
|
zsys_debug (" status=%ld", (long) self->status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
zsys_debug ("WAP_PROTO_GET_BLOCK_HASH:");
|
||||||
|
zsys_debug (" height=%ld", (long) self->height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
zsys_debug ("WAP_PROTO_GET_BLOCK_HASH_OK:");
|
||||||
|
zsys_debug (" status=%ld", (long) self->status);
|
||||||
|
zsys_debug (" hash=[ ... ]");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
zsys_debug ("WAP_PROTO_GET_BLOCK_TEMPLATE:");
|
||||||
|
zsys_debug (" reserve_size=%ld", (long) self->reserve_size);
|
||||||
|
zsys_debug (" address=[ ... ]");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
zsys_debug ("WAP_PROTO_GET_BLOCK_TEMPLATE_OK:");
|
||||||
|
zsys_debug (" status=%ld", (long) self->status);
|
||||||
|
zsys_debug (" reserved_offset=%ld", (long) self->reserved_offset);
|
||||||
|
zsys_debug (" height=%ld", (long) self->height);
|
||||||
|
zsys_debug (" difficulty=%ld", (long) self->difficulty);
|
||||||
|
zsys_debug (" prev_hash=[ ... ]");
|
||||||
|
zsys_debug (" block_template_blob=[ ... ]");
|
||||||
|
break;
|
||||||
|
|
||||||
case WAP_PROTO_STOP:
|
case WAP_PROTO_STOP:
|
||||||
zsys_debug ("WAP_PROTO_STOP:");
|
zsys_debug ("WAP_PROTO_STOP:");
|
||||||
break;
|
break;
|
||||||
|
@ -1383,6 +1563,18 @@ wap_proto_command (wap_proto_t *self)
|
||||||
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
case WAP_PROTO_STOP_SAVE_GRAPH_OK:
|
||||||
return ("STOP_SAVE_GRAPH_OK");
|
return ("STOP_SAVE_GRAPH_OK");
|
||||||
break;
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH:
|
||||||
|
return ("GET_BLOCK_HASH");
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_HASH_OK:
|
||||||
|
return ("GET_BLOCK_HASH_OK");
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE:
|
||||||
|
return ("GET_BLOCK_TEMPLATE");
|
||||||
|
break;
|
||||||
|
case WAP_PROTO_GET_BLOCK_TEMPLATE_OK:
|
||||||
|
return ("GET_BLOCK_TEMPLATE_OK");
|
||||||
|
break;
|
||||||
case WAP_PROTO_STOP:
|
case WAP_PROTO_STOP:
|
||||||
return ("STOP");
|
return ("STOP");
|
||||||
break;
|
break;
|
||||||
|
@ -2137,6 +2329,141 @@ wap_proto_set_level (wap_proto_t *self, byte level)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Get the hash field without transferring ownership
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_hash (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the hash field and transfer ownership to caller
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_hash (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
zchunk_t *hash = self->hash;
|
||||||
|
self->hash = NULL;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the hash field, transferring ownership from caller
|
||||||
|
|
||||||
|
void
|
||||||
|
wap_proto_set_hash (wap_proto_t *self, zchunk_t **chunk_p)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
assert (chunk_p);
|
||||||
|
zchunk_destroy (&self->hash);
|
||||||
|
self->hash = *chunk_p;
|
||||||
|
*chunk_p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Get/set the reserve_size field
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
wap_proto_reserve_size (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->reserve_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wap_proto_set_reserve_size (wap_proto_t *self, uint64_t reserve_size)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
self->reserve_size = reserve_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Get/set the reserved_offset field
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
wap_proto_reserved_offset (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->reserved_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wap_proto_set_reserved_offset (wap_proto_t *self, uint64_t reserved_offset)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
self->reserved_offset = reserved_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Get the prev_hash field without transferring ownership
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_prev_hash (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->prev_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the prev_hash field and transfer ownership to caller
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_prev_hash (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
zchunk_t *prev_hash = self->prev_hash;
|
||||||
|
self->prev_hash = NULL;
|
||||||
|
return prev_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the prev_hash field, transferring ownership from caller
|
||||||
|
|
||||||
|
void
|
||||||
|
wap_proto_set_prev_hash (wap_proto_t *self, zchunk_t **chunk_p)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
assert (chunk_p);
|
||||||
|
zchunk_destroy (&self->prev_hash);
|
||||||
|
self->prev_hash = *chunk_p;
|
||||||
|
*chunk_p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Get the block_template_blob field without transferring ownership
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_block_template_blob (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
return self->block_template_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the block_template_blob field and transfer ownership to caller
|
||||||
|
|
||||||
|
zchunk_t *
|
||||||
|
wap_proto_get_block_template_blob (wap_proto_t *self)
|
||||||
|
{
|
||||||
|
zchunk_t *block_template_blob = self->block_template_blob;
|
||||||
|
self->block_template_blob = NULL;
|
||||||
|
return block_template_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the block_template_blob field, transferring ownership from caller
|
||||||
|
|
||||||
|
void
|
||||||
|
wap_proto_set_block_template_blob (wap_proto_t *self, zchunk_t **chunk_p)
|
||||||
|
{
|
||||||
|
assert (self);
|
||||||
|
assert (chunk_p);
|
||||||
|
zchunk_destroy (&self->block_template_blob);
|
||||||
|
self->block_template_blob = *chunk_p;
|
||||||
|
*chunk_p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Get/set the reason field
|
// Get/set the reason field
|
||||||
|
|
||||||
|
@ -2646,6 +2973,76 @@ wap_proto_test (bool verbose)
|
||||||
assert (wap_proto_routing_id (self));
|
assert (wap_proto_routing_id (self));
|
||||||
assert (wap_proto_status (self) == 123);
|
assert (wap_proto_status (self) == 123);
|
||||||
}
|
}
|
||||||
|
wap_proto_set_id (self, WAP_PROTO_GET_BLOCK_HASH);
|
||||||
|
|
||||||
|
wap_proto_set_height (self, 123);
|
||||||
|
// Send twice
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
|
||||||
|
for (instance = 0; instance < 2; instance++) {
|
||||||
|
wap_proto_recv (self, input);
|
||||||
|
assert (wap_proto_routing_id (self));
|
||||||
|
assert (wap_proto_height (self) == 123);
|
||||||
|
}
|
||||||
|
wap_proto_set_id (self, WAP_PROTO_GET_BLOCK_HASH_OK);
|
||||||
|
|
||||||
|
wap_proto_set_status (self, 123);
|
||||||
|
zchunk_t *get_block_hash_ok_hash = zchunk_new ("Captcha Diem", 12);
|
||||||
|
wap_proto_set_hash (self, &get_block_hash_ok_hash);
|
||||||
|
// Send twice
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
|
||||||
|
for (instance = 0; instance < 2; instance++) {
|
||||||
|
wap_proto_recv (self, input);
|
||||||
|
assert (wap_proto_routing_id (self));
|
||||||
|
assert (wap_proto_status (self) == 123);
|
||||||
|
assert (memcmp (zchunk_data (wap_proto_hash (self)), "Captcha Diem", 12) == 0);
|
||||||
|
zchunk_destroy (&get_block_hash_ok_hash);
|
||||||
|
}
|
||||||
|
wap_proto_set_id (self, WAP_PROTO_GET_BLOCK_TEMPLATE);
|
||||||
|
|
||||||
|
wap_proto_set_reserve_size (self, 123);
|
||||||
|
zchunk_t *get_block_template_address = zchunk_new ("Captcha Diem", 12);
|
||||||
|
wap_proto_set_address (self, &get_block_template_address);
|
||||||
|
// Send twice
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
|
||||||
|
for (instance = 0; instance < 2; instance++) {
|
||||||
|
wap_proto_recv (self, input);
|
||||||
|
assert (wap_proto_routing_id (self));
|
||||||
|
assert (wap_proto_reserve_size (self) == 123);
|
||||||
|
assert (memcmp (zchunk_data (wap_proto_address (self)), "Captcha Diem", 12) == 0);
|
||||||
|
zchunk_destroy (&get_block_template_address);
|
||||||
|
}
|
||||||
|
wap_proto_set_id (self, WAP_PROTO_GET_BLOCK_TEMPLATE_OK);
|
||||||
|
|
||||||
|
wap_proto_set_status (self, 123);
|
||||||
|
wap_proto_set_reserved_offset (self, 123);
|
||||||
|
wap_proto_set_height (self, 123);
|
||||||
|
wap_proto_set_difficulty (self, 123);
|
||||||
|
zchunk_t *get_block_template_ok_prev_hash = zchunk_new ("Captcha Diem", 12);
|
||||||
|
wap_proto_set_prev_hash (self, &get_block_template_ok_prev_hash);
|
||||||
|
zchunk_t *get_block_template_ok_block_template_blob = zchunk_new ("Captcha Diem", 12);
|
||||||
|
wap_proto_set_block_template_blob (self, &get_block_template_ok_block_template_blob);
|
||||||
|
// Send twice
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
wap_proto_send (self, output);
|
||||||
|
|
||||||
|
for (instance = 0; instance < 2; instance++) {
|
||||||
|
wap_proto_recv (self, input);
|
||||||
|
assert (wap_proto_routing_id (self));
|
||||||
|
assert (wap_proto_status (self) == 123);
|
||||||
|
assert (wap_proto_reserved_offset (self) == 123);
|
||||||
|
assert (wap_proto_height (self) == 123);
|
||||||
|
assert (wap_proto_difficulty (self) == 123);
|
||||||
|
assert (memcmp (zchunk_data (wap_proto_prev_hash (self)), "Captcha Diem", 12) == 0);
|
||||||
|
zchunk_destroy (&get_block_template_ok_prev_hash);
|
||||||
|
assert (memcmp (zchunk_data (wap_proto_block_template_blob (self)), "Captcha Diem", 12) == 0);
|
||||||
|
zchunk_destroy (&get_block_template_ok_block_template_blob);
|
||||||
|
}
|
||||||
wap_proto_set_id (self, WAP_PROTO_STOP);
|
wap_proto_set_id (self, WAP_PROTO_STOP);
|
||||||
|
|
||||||
// Send twice
|
// Send twice
|
||||||
|
|
|
@ -362,3 +362,23 @@ stop_save_graph (client_t *self)
|
||||||
{
|
{
|
||||||
IPC::Daemon::stop_save_graph(self->message);
|
IPC::Daemon::stop_save_graph(self->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// get_block_hash
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_block_hash (client_t *self)
|
||||||
|
{
|
||||||
|
IPC::Daemon::get_block_hash(self->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// get_block_template
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_block_template (client_t *self)
|
||||||
|
{
|
||||||
|
IPC::Daemon::get_block_template(self->message);
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
// Trivial and error responses may be returned with ns_create_rpc_reply and ns_create_rpc_error
|
// Trivial and error responses may be returned with ns_create_rpc_reply and ns_create_rpc_error
|
||||||
// respectively.
|
// respectively.
|
||||||
|
|
||||||
|
// TODO: Add core busy checks to all methods here
|
||||||
|
|
||||||
#include "daemon_deprecated_rpc.h"
|
#include "daemon_deprecated_rpc.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
// TODO: put right error codes here
|
||||||
int daemon_connection_error = -326701;
|
int daemon_connection_error = -326701;
|
||||||
int parse_error = -32700;
|
int parse_error = -32700;
|
||||||
int invalid_request = -32600;
|
int invalid_request = -32600;
|
||||||
|
@ -43,26 +46,21 @@ namespace
|
||||||
return ipc_client && wap_client_connected(ipc_client);
|
return ipc_client && wap_client_connected(ipc_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect_to_daemon() {
|
bool connect_to_daemon() {
|
||||||
if (check_connection_to_daemon()) {
|
if (check_connection_to_daemon()) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
ipc_client = wap_client_new();
|
ipc_client = wap_client_new();
|
||||||
wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity");
|
wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity");
|
||||||
|
return check_connection_to_daemon();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a response string given a result JSON object.
|
* \brief Initializes a rapidjson response object
|
||||||
*
|
|
||||||
* It also adds boilerplate properties like id, method.
|
|
||||||
* \param req net_skeleton request object
|
* \param req net_skeleton request object
|
||||||
* \param result_json rapidjson result object
|
* \param response_json net_skeleton request object to fill
|
||||||
* \param response_json "Root" rapidjson document that will eventually have the whole response
|
|
||||||
* \param response Response as a string gets written here.
|
|
||||||
*/
|
*/
|
||||||
void construct_response_string(struct ns_rpc_request *req, rapidjson::Value &result_json,
|
void init_response_object(struct ns_rpc_request *req, rapidjson::Document &response_json) {
|
||||||
rapidjson::Document &response_json, std::string &response)
|
|
||||||
{
|
|
||||||
response_json.SetObject();
|
response_json.SetObject();
|
||||||
response_json.AddMember("jsonrpc", "2.0" , response_json.GetAllocator());
|
response_json.AddMember("jsonrpc", "2.0" , response_json.GetAllocator());
|
||||||
rapidjson::Value string_value(rapidjson::kStringType);
|
rapidjson::Value string_value(rapidjson::kStringType);
|
||||||
|
@ -78,6 +76,21 @@ namespace
|
||||||
response_json.AddMember("id", string_value, response_json.GetAllocator());
|
response_json.AddMember("id", string_value, response_json.GetAllocator());
|
||||||
string_value.SetString(req->method[0].ptr, req->method[0].len);
|
string_value.SetString(req->method[0].ptr, req->method[0].len);
|
||||||
response_json.AddMember("method", string_value, response_json.GetAllocator());
|
response_json.AddMember("method", string_value, response_json.GetAllocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a response string given a result JSON object.
|
||||||
|
*
|
||||||
|
* It also adds boilerplate properties like id, method.
|
||||||
|
* \param req net_skeleton request object
|
||||||
|
* \param result_json rapidjson result object
|
||||||
|
* \param response_json "Root" rapidjson document that will eventually have the whole response
|
||||||
|
* \param response Response as a string gets written here.
|
||||||
|
*/
|
||||||
|
void construct_response_string(struct ns_rpc_request *req, rapidjson::Value &result_json,
|
||||||
|
rapidjson::Document &response_json, std::string &response)
|
||||||
|
{
|
||||||
|
init_response_object(req, response_json);
|
||||||
response_json.AddMember("result", result_json, response_json.GetAllocator());
|
response_json.AddMember("result", result_json, response_json.GetAllocator());
|
||||||
rapidjson::StringBuffer buffer;
|
rapidjson::StringBuffer buffer;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||||
|
@ -85,6 +98,30 @@ namespace
|
||||||
// Write string to `response`.
|
// Write string to `response`.
|
||||||
response = buffer.GetString();
|
response = buffer.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a response string given a result string.
|
||||||
|
*
|
||||||
|
* It also adds boilerplate properties like id, method.
|
||||||
|
* \param req net_skeleton request object
|
||||||
|
* \param result rapidjson result object
|
||||||
|
* \param response_json "Root" rapidjson document that will eventually have the whole response
|
||||||
|
* \param response Response as a string gets written here.
|
||||||
|
*/
|
||||||
|
void construct_response_string(struct ns_rpc_request *req, const std::string &result,
|
||||||
|
rapidjson::Document &response_json, std::string &response)
|
||||||
|
{
|
||||||
|
init_response_object(req, response_json);
|
||||||
|
rapidjson::Value string_value(rapidjson::kStringType);
|
||||||
|
string_value.SetString(result.c_str(), result.length());
|
||||||
|
response_json.AddMember("result", string_value, response_json.GetAllocator());
|
||||||
|
rapidjson::StringBuffer buffer;
|
||||||
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||||
|
response_json.Accept(writer);
|
||||||
|
// Write string to `response`.
|
||||||
|
response = buffer.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Implementation of 'getheight' method.
|
* \brief Implementation of 'getheight' method.
|
||||||
* \param buf Buffer to fill in response.
|
* \param buf Buffer to fill in response.
|
||||||
|
@ -94,12 +131,20 @@ namespace
|
||||||
*/
|
*/
|
||||||
int getheight(char *buf, int len, struct ns_rpc_request *req)
|
int getheight(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_get_height(ipc_client);
|
int rc = wap_client_get_height(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
uint64_t height = wap_client_height(ipc_client);
|
uint64_t height = wap_client_height(ipc_client);
|
||||||
rapidjson::Document response_json;
|
rapidjson::Document response_json;
|
||||||
rapidjson::Value result_json;
|
rapidjson::Value result_json;
|
||||||
|
@ -122,7 +167,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int startmining(char *buf, int len, struct ns_rpc_request *req)
|
int startmining(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
if (req->params == NULL)
|
if (req->params == NULL)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_params,
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
@ -160,7 +208,10 @@ namespace
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
uint64_t status = wap_client_status(ipc_client);
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
if (status == IPC::STATUS_WRONG_ADDRESS)
|
if (status == IPC::STATUS_WRONG_ADDRESS)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_params,
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
@ -183,12 +234,20 @@ namespace
|
||||||
*/
|
*/
|
||||||
int stopmining(char *buf, int len, struct ns_rpc_request *req)
|
int stopmining(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_stop(ipc_client);
|
int rc = wap_client_stop(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
if (wap_client_status(ipc_client) != IPC::STATUS_OK)
|
if (wap_client_status(ipc_client) != IPC::STATUS_OK)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_request,
|
return ns_rpc_create_error(buf, len, req, invalid_request,
|
||||||
|
@ -206,13 +265,21 @@ namespace
|
||||||
*/
|
*/
|
||||||
int getinfo(char *buf, int len, struct ns_rpc_request *req)
|
int getinfo(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_get_info(ipc_client);
|
int rc = wap_client_get_info(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
if (wap_client_status(ipc_client) != IPC::STATUS_OK)
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
|
if (status != IPC::STATUS_OK)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_request,
|
return ns_rpc_create_error(buf, len, req, invalid_request,
|
||||||
"Failed to get info", "{}");
|
"Failed to get info", "{}");
|
||||||
|
@ -257,7 +324,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int getpeerlist(char *buf, int len, struct ns_rpc_request *req)
|
int getpeerlist(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_get_peer_list(ipc_client);
|
int rc = wap_client_get_peer_list(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
@ -309,13 +379,20 @@ namespace
|
||||||
*/
|
*/
|
||||||
int getminingstatus(char *buf, int len, struct ns_rpc_request *req)
|
int getminingstatus(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_get_mining_status(ipc_client);
|
int rc = wap_client_get_mining_status(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
rapidjson::Document response_json;
|
rapidjson::Document response_json;
|
||||||
rapidjson::Document::AllocatorType &allocator = response_json.GetAllocator();
|
rapidjson::Document::AllocatorType &allocator = response_json.GetAllocator();
|
||||||
rapidjson::Value result_json;
|
rapidjson::Value result_json;
|
||||||
|
@ -346,7 +423,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int setloghashrate(char *buf, int len, struct ns_rpc_request *req)
|
int setloghashrate(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
if (req->params == NULL)
|
if (req->params == NULL)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_params,
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
@ -376,8 +456,12 @@ namespace
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
if (wap_client_status(ipc_client) == IPC::STATUS_NOT_MINING) {
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
|
if (status == IPC::STATUS_NOT_MINING) {
|
||||||
return ns_rpc_create_error(buf, len, req, not_mining_error,
|
return ns_rpc_create_error(buf, len, req, not_mining_error,
|
||||||
"Not mining", "{}");
|
"Not mining", "{}");
|
||||||
}
|
}
|
||||||
|
@ -394,7 +478,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int setloglevel(char *buf, int len, struct ns_rpc_request *req)
|
int setloglevel(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
if (req->params == NULL)
|
if (req->params == NULL)
|
||||||
{
|
{
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_params,
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
@ -423,8 +510,12 @@ namespace
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
if (wap_client_status(ipc_client) == IPC::STATUS_INVALID_LOG_LEVEL) {
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
|
if (status == IPC::STATUS_INVALID_LOG_LEVEL) {
|
||||||
return ns_rpc_create_error(buf, len, req, invalid_params,
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
"Invalid log level", "{}");
|
"Invalid log level", "{}");
|
||||||
}
|
}
|
||||||
|
@ -441,12 +532,20 @@ namespace
|
||||||
*/
|
*/
|
||||||
int getblockcount(char *buf, int len, struct ns_rpc_request *req)
|
int getblockcount(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_get_height(ipc_client);
|
int rc = wap_client_get_height(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
"Couldn't connect to daemon.", "{}");
|
"Couldn't connect to daemon.", "{}");
|
||||||
}
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
uint64_t count = wap_client_height(ipc_client);
|
uint64_t count = wap_client_height(ipc_client);
|
||||||
rapidjson::Document response_json;
|
rapidjson::Document response_json;
|
||||||
rapidjson::Value result_json;
|
rapidjson::Value result_json;
|
||||||
|
@ -469,7 +568,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int startsavegraph(char *buf, int len, struct ns_rpc_request *req)
|
int startsavegraph(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_start_save_graph(ipc_client);
|
int rc = wap_client_start_save_graph(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
@ -487,7 +589,10 @@ namespace
|
||||||
*/
|
*/
|
||||||
int stopsavegraph(char *buf, int len, struct ns_rpc_request *req)
|
int stopsavegraph(char *buf, int len, struct ns_rpc_request *req)
|
||||||
{
|
{
|
||||||
connect_to_daemon();
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
int rc = wap_client_stop_save_graph(ipc_client);
|
int rc = wap_client_stop_save_graph(ipc_client);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
@ -495,6 +600,152 @@ namespace
|
||||||
}
|
}
|
||||||
return ns_rpc_create_reply(buf, len, req, "{s:s}", "status", STATUS_OK);
|
return ns_rpc_create_reply(buf, len, req, "{s:s}", "status", STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Implementation of 'getblockhash' method.
|
||||||
|
* \param buf Buffer to fill in response.
|
||||||
|
* \param len Max length of response.
|
||||||
|
* \param req net_skeleton RPC request
|
||||||
|
* \return Actual response length.
|
||||||
|
*/
|
||||||
|
int getblockhash(char *buf, int len, struct ns_rpc_request *req)
|
||||||
|
{
|
||||||
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
|
if (req->params == NULL)
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Parameters missing.", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Document request_json;
|
||||||
|
char request_buf[1000];
|
||||||
|
strncpy(request_buf, req->params[0].ptr, req->params[0].len);
|
||||||
|
request_buf[req->params[0].len] = '\0';
|
||||||
|
if (request_json.Parse(request_buf).HasParseError())
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, parse_error,
|
||||||
|
"Invalid JSON passed", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request_json.IsArray() || request_json.Size() < 1 || !request_json[(unsigned int)0].IsNumber())
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Incorrect 'height' field", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int height = request_json[(unsigned int)0].GetUint();
|
||||||
|
int rc = wap_client_get_block_hash(ipc_client, height);
|
||||||
|
if (rc < 0) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
|
if (status == IPC::STATUS_HEIGHT_TOO_BIG) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Height too big.", "{}");
|
||||||
|
}
|
||||||
|
zchunk_t *hash_chunk = wap_client_hash(ipc_client);
|
||||||
|
std::string hash((char*)zchunk_data(hash_chunk), zchunk_size(hash_chunk));
|
||||||
|
std::string response;
|
||||||
|
rapidjson::Document response_json;
|
||||||
|
construct_response_string(req, hash, response_json, response);
|
||||||
|
size_t copy_length = ((uint32_t)len > response.length()) ? response.length() + 1 : (uint32_t)len;
|
||||||
|
strncpy(buf, response.c_str(), copy_length);
|
||||||
|
return response.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Implementation of 'getblocktemplate' method.
|
||||||
|
* \param buf Buffer to fill in response.
|
||||||
|
* \param len Max length of response.
|
||||||
|
* \param req net_skeleton RPC request
|
||||||
|
* \return Actual response length.
|
||||||
|
*/
|
||||||
|
int getblocktemplate(char *buf, int len, struct ns_rpc_request *req)
|
||||||
|
{
|
||||||
|
if (!connect_to_daemon()) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
|
if (req->params == NULL)
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Parameters missing.", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Document request_json;
|
||||||
|
char request_buf[1000];
|
||||||
|
strncpy(request_buf, req->params[0].ptr, req->params[0].len);
|
||||||
|
request_buf[req->params[0].len] = '\0';
|
||||||
|
if (request_json.Parse(request_buf).HasParseError())
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, parse_error,
|
||||||
|
"Invalid JSON passed", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request_json.HasMember("reserve_size") || !request_json["reserve_size"].IsNumber())
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Incorrect 'reserve_size' field", "{}");
|
||||||
|
}
|
||||||
|
if (!request_json.HasMember("wallet_address") || !request_json["wallet_address"].IsString())
|
||||||
|
{
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Incorrect 'wallet_address' field", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t reserve_size = request_json["reserve_size"].GetUint();
|
||||||
|
std::string wallet_address = request_json["wallet_address"].GetString();
|
||||||
|
zchunk_t *address_chunk = zchunk_new((void*)wallet_address.c_str(), wallet_address.length());
|
||||||
|
int rc = wap_client_get_block_template(ipc_client, reserve_size, &address_chunk);
|
||||||
|
if (rc < 0) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, daemon_connection_error,
|
||||||
|
"Couldn't connect to daemon.", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t status = wap_client_status(ipc_client);
|
||||||
|
if (status == IPC::STATUS_CORE_BUSY) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, internal_error,
|
||||||
|
"Core busy.", "{}");
|
||||||
|
}
|
||||||
|
if (status == IPC::STATUS_RESERVE_SIZE_TOO_BIG) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Reserve size too big.", "{}");
|
||||||
|
}
|
||||||
|
if (status == IPC::STATUS_WRONG_ADDRESS) {
|
||||||
|
return ns_rpc_create_error(buf, len, req, invalid_params,
|
||||||
|
"Wrong address.", "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Document response_json;
|
||||||
|
rapidjson::Document::AllocatorType &allocator = response_json.GetAllocator();
|
||||||
|
rapidjson::Value result_json;
|
||||||
|
result_json.SetObject();
|
||||||
|
result_json.AddMember("difficulty", wap_client_difficulty(ipc_client), allocator);
|
||||||
|
result_json.AddMember("height", wap_client_height(ipc_client), allocator);
|
||||||
|
result_json.AddMember("reserved_offset", wap_client_reserved_offset(ipc_client), allocator);
|
||||||
|
zchunk_t *prev_hash_chunk = wap_client_prev_hash(ipc_client);
|
||||||
|
rapidjson::Value string_value(rapidjson::kStringType);
|
||||||
|
string_value.SetString((char*)zchunk_data(prev_hash_chunk), zchunk_size(prev_hash_chunk));
|
||||||
|
result_json.AddMember("prev_hash", string_value, allocator);
|
||||||
|
zchunk_t *block_template_chunk = wap_client_prev_hash(ipc_client);
|
||||||
|
string_value.SetString((char*)zchunk_data(block_template_chunk), zchunk_size(block_template_chunk));
|
||||||
|
result_json.AddMember("blocktemplate_blob", string_value, allocator);
|
||||||
|
std::string response;
|
||||||
|
construct_response_string(req, result_json, response_json, response);
|
||||||
|
size_t copy_length = ((uint32_t)len > response.length()) ? response.length() + 1 : (uint32_t)len;
|
||||||
|
strncpy(buf, response.c_str(), copy_length);
|
||||||
|
return response.length();
|
||||||
|
}
|
||||||
|
|
||||||
// Contains a list of method names.
|
// Contains a list of method names.
|
||||||
const char *method_names[] = {
|
const char *method_names[] = {
|
||||||
"getheight",
|
"getheight",
|
||||||
|
@ -508,6 +759,8 @@ namespace
|
||||||
"getblockcount",
|
"getblockcount",
|
||||||
"startsavegraph",
|
"startsavegraph",
|
||||||
"stopsavegraph",
|
"stopsavegraph",
|
||||||
|
"getblockhash",
|
||||||
|
"getblocktemplate",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -524,6 +777,8 @@ namespace
|
||||||
getblockcount,
|
getblockcount,
|
||||||
startsavegraph,
|
startsavegraph,
|
||||||
stopsavegraph,
|
stopsavegraph,
|
||||||
|
getblockhash,
|
||||||
|
getblocktemplate,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue