start_mining and get_blocks IPC
This commit is contained in:
parent
3fba3fec57
commit
d75b5dd60b
|
@ -26,6 +26,8 @@
|
|||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_L0("Protocol initialized OK");
|
||||
|
||||
LOG_PRINT_L0("Initializing core IPC server...");
|
||||
IPC::Daemon::init(&ccore, &p2psrv);
|
||||
IPC::Daemon::init(&ccore, &p2psrv, testnet_mode);
|
||||
LOG_PRINT_L0("Initializing core RPC server...");
|
||||
RPC::Daemon::init(&ccore, &p2psrv, testnet_mode);
|
||||
std::string ip_address, port;
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace
|
|||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > *p2p;
|
||||
/*!< Pointer to p2p node server */
|
||||
zactor_t *server;
|
||||
bool testnet;
|
||||
bool check_core_busy()
|
||||
{
|
||||
if (p2p->get_payload_object().get_core().get_blockchain_storage().is_storing_blockchain())
|
||||
|
@ -53,10 +54,12 @@ namespace IPC
|
|||
namespace Daemon
|
||||
{
|
||||
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)
|
||||
{
|
||||
p2p = p_p2p;
|
||||
core = p_core;
|
||||
testnet = p_testnet;
|
||||
server = zactor_new (wap_server, NULL);
|
||||
zsock_send (server, "ss", "BIND", "ipc://@/monero");
|
||||
zsock_send (server, "sss", "SET", "server/timeout", "5000");
|
||||
|
@ -64,12 +67,95 @@ namespace IPC
|
|||
|
||||
void start_mining(wap_proto_t *message)
|
||||
{
|
||||
uint64_t start_height = wap_proto_start_height(message);
|
||||
wap_proto_set_curr_height(message, 2 * start_height);
|
||||
if (!check_core_busy()) {
|
||||
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||
return;
|
||||
}
|
||||
cryptonote::account_public_address adr;
|
||||
const char *address = wap_proto_address(message);
|
||||
if (!get_account_address_from_str(adr, testnet, std::string(address)))
|
||||
{
|
||||
wap_proto_set_status(message, STATUS_WRONG_ADDRESS);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::thread::attributes attrs;
|
||||
attrs.set_stack_size(THREAD_STACK_SIZE);
|
||||
|
||||
uint64_t threads_count = wap_proto_thread_count(message);
|
||||
if (!core->get_miner().start(adr, static_cast<size_t>(threads_count), attrs))
|
||||
{
|
||||
wap_proto_set_status(message, STATUS_MINING_NOT_STARTED);
|
||||
return;
|
||||
}
|
||||
wap_proto_set_status(message, STATUS_OK);
|
||||
}
|
||||
|
||||
void getblocks(wap_proto_t *message)
|
||||
void retrieve_blocks(wap_proto_t *message)
|
||||
{
|
||||
if (!check_core_busy()) {
|
||||
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||
return;
|
||||
}
|
||||
uint64_t start_height = wap_proto_start_height(message);
|
||||
zlist_t *z_block_ids = wap_proto_block_ids(message);
|
||||
|
||||
std::list<crypto::hash> block_ids;
|
||||
char *block_id = (char*)zlist_first(z_block_ids);
|
||||
while (block_id) {
|
||||
crypto::hash hash;
|
||||
memcpy(hash.data, block_id, crypto::HASH_SIZE);
|
||||
block_ids.push_back(hash);
|
||||
block_id = (char*)zlist_next(z_block_ids);
|
||||
}
|
||||
|
||||
std::list<std::pair<cryptonote::block, std::list<cryptonote::transaction> > > bs;
|
||||
uint64_t result_current_height = 0;
|
||||
uint64_t result_start_height = 0;
|
||||
if (!core->find_blockchain_supplement(start_height, block_ids, bs, result_current_height,
|
||||
result_start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
|
||||
{
|
||||
wap_proto_set_status(message, STATUS_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document result_json;
|
||||
result_json.SetObject();
|
||||
rapidjson::Document::AllocatorType &allocator = result_json.GetAllocator();
|
||||
rapidjson::Value block_json(rapidjson::kArrayType);
|
||||
std::string blob;
|
||||
BOOST_FOREACH(auto &b, bs)
|
||||
{
|
||||
rapidjson::Value this_block(rapidjson::kObjectType);
|
||||
blob = block_to_blob(b.first);
|
||||
rapidjson::Value string_value(rapidjson::kStringType);
|
||||
string_value.SetString(blob.c_str(), blob.length(), allocator);
|
||||
this_block.AddMember("block", string_value.Move(), allocator);
|
||||
rapidjson::Value txs_blocks(rapidjson::kArrayType);
|
||||
BOOST_FOREACH(auto &t, b.second)
|
||||
{
|
||||
rapidjson::Value string_value(rapidjson::kStringType);
|
||||
blob = cryptonote::tx_to_blob(t);
|
||||
string_value.SetString(blob.c_str(), blob.length(), allocator);
|
||||
txs_blocks.PushBack(string_value.Move(), allocator);
|
||||
}
|
||||
this_block.AddMember("txs", txs_blocks, allocator);
|
||||
block_json.PushBack(this_block, allocator);
|
||||
}
|
||||
|
||||
result_json.AddMember("blocks", block_json, allocator);
|
||||
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
result_json.Accept(writer);
|
||||
std::string block_string = buffer.GetString();
|
||||
zmsg_t *block_data = zmsg_new();
|
||||
zframe_t *frame = zframe_new(block_string.c_str(), block_string.length());
|
||||
zmsg_prepend(block_data, &frame);
|
||||
wap_proto_set_start_height(message, result_start_height);
|
||||
wap_proto_set_curr_height(message, result_current_height);
|
||||
wap_proto_set_status(message, STATUS_OK);
|
||||
wap_proto_set_block_data(message, &block_data);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -45,17 +45,30 @@ using namespace epee;
|
|||
#include "crypto/hash.h"
|
||||
#include "wap_library.h"
|
||||
#include "wap_classes.h"
|
||||
#include "net/http_server_impl_base.h"
|
||||
#include "cryptonote_core/cryptonote_basic_impl.h"
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
namespace IPC
|
||||
{
|
||||
const uint64_t STATUS_OK = 0;
|
||||
const uint64_t STATUS_CORE_BUSY = 1;
|
||||
const uint64_t STATUS_WRONG_ADDRESS = 2;
|
||||
const uint64_t STATUS_MINING_NOT_STARTED = 3;
|
||||
const uint64_t STATUS_WRONG_BLOCK_ID_LENGTH = 4;
|
||||
const uint64_t STATUS_INTERNAL_ERROR = 5;
|
||||
namespace Daemon
|
||||
{
|
||||
void start_mining(wap_proto_t *message);
|
||||
void get_blocks(wap_proto_t *message);
|
||||
void retrieve_blocks(wap_proto_t *message);
|
||||
void send_transactions(wap_proto_t *message);
|
||||
void get_o_indexes(wap_proto_t *message);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ WAP_EXPORT zsock_t *
|
|||
// Request a set of blocks from the server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
WAP_EXPORT int
|
||||
wap_client_blocks (wap_client_t *self, zlist_t **block_ids_p);
|
||||
wap_client_blocks (wap_client_t *self, zlist_t **block_ids_p, uint64_t start_height);
|
||||
|
||||
// Send a raw transaction to the daemon.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
@ -77,7 +77,7 @@ WAP_EXPORT int
|
|||
// Send start command to server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
WAP_EXPORT int
|
||||
wap_client_start (wap_client_t *self, uint64_t start_height);
|
||||
wap_client_start (wap_client_t *self, const char *address, uint64_t thread_count);
|
||||
|
||||
// Send stop command to server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
@ -93,17 +93,13 @@ WAP_EXPORT const char *
|
|||
wap_client_reason (wap_client_t *self);
|
||||
|
||||
// Return last received start_height
|
||||
WAP_EXPORT uint32_t
|
||||
WAP_EXPORT uint64_t
|
||||
wap_client_start_height (wap_client_t *self);
|
||||
|
||||
// Return last received curr_height
|
||||
WAP_EXPORT uint32_t
|
||||
WAP_EXPORT uint64_t
|
||||
wap_client_curr_height (wap_client_t *self);
|
||||
|
||||
// Return last received block_status
|
||||
WAP_EXPORT const char *
|
||||
wap_client_block_status (wap_client_t *self);
|
||||
|
||||
// Return last received block_data
|
||||
WAP_EXPORT zmsg_t *
|
||||
wap_client_block_data (wap_client_t *self);
|
||||
|
@ -116,6 +112,10 @@ WAP_EXPORT const char *
|
|||
WAP_EXPORT zchunk_t *
|
||||
wap_client_tx_data (wap_client_t *self);
|
||||
|
||||
// Self test of this class
|
||||
WAP_EXPORT void
|
||||
wap_client_test (bool verbose);
|
||||
|
||||
// To enable verbose tracing (animation) of wap_client instances, set
|
||||
// this to true. This lets you trace from and including construction.
|
||||
WAP_EXPORT extern volatile int
|
||||
|
|
|
@ -120,9 +120,11 @@ struct _client_args_t {
|
|||
uint32_t timeout;
|
||||
char *identity;
|
||||
zlist_t *block_ids;
|
||||
uint64_t start_height;
|
||||
zchunk_t *tx_data;
|
||||
char *tx_id;
|
||||
uint64_t start_height;
|
||||
char *address;
|
||||
uint64_t thread_count;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -252,6 +254,7 @@ s_client_destroy (s_client_t **self_p)
|
|||
zlist_destroy (&self->args.block_ids);
|
||||
zchunk_destroy (&self->args.tx_data);
|
||||
zstr_free (&self->args.tx_id);
|
||||
zstr_free (&self->args.address);
|
||||
client_terminate (&self->client);
|
||||
wap_proto_destroy (&self->message);
|
||||
zsock_destroy (&self->msgpipe);
|
||||
|
@ -1069,7 +1072,7 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
|||
else
|
||||
if (streq (method, "BLOCKS")) {
|
||||
zlist_destroy (&self->args.block_ids);
|
||||
zsock_recv (self->cmdpipe, "p", &self->args.block_ids);
|
||||
zsock_recv (self->cmdpipe, "pi", &self->args.block_ids, &self->args.start_height);
|
||||
s_client_execute (self, blocks_event);
|
||||
}
|
||||
else
|
||||
|
@ -1090,7 +1093,8 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
|||
}
|
||||
else
|
||||
if (streq (method, "START")) {
|
||||
zsock_recv (self->cmdpipe, "i", &self->args.start_height);
|
||||
zstr_free (&self->args.address);
|
||||
zsock_recv (self->cmdpipe, "si", &self->args.address, &self->args.thread_count);
|
||||
s_client_execute (self, start_event);
|
||||
}
|
||||
else
|
||||
|
@ -1207,9 +1211,8 @@ struct _wap_client_t {
|
|||
zsock_t *msgpipe; // Pipe for async message flow
|
||||
int status; // Returned by actor reply
|
||||
char *reason; // Returned by actor reply
|
||||
uint32_t start_height; // Returned by actor reply
|
||||
uint32_t curr_height; // Returned by actor reply
|
||||
char *block_status; // Returned by actor reply
|
||||
uint64_t start_height; // Returned by actor reply
|
||||
uint64_t curr_height; // Returned by actor reply
|
||||
zmsg_t *block_data; // Returned by actor reply
|
||||
char *tx_id; // Returned by actor reply
|
||||
zchunk_t *tx_data; // Returned by actor reply
|
||||
|
@ -1268,7 +1271,6 @@ wap_client_destroy (wap_client_t **self_p)
|
|||
zactor_destroy (&self->actor);
|
||||
zsock_destroy (&self->msgpipe);
|
||||
zstr_free (&self->reason);
|
||||
zstr_free (&self->block_status);
|
||||
zmsg_destroy (&self->block_data);
|
||||
zstr_free (&self->tx_id);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
|
@ -1335,9 +1337,8 @@ s_accept_reply (wap_client_t *self, ...)
|
|||
}
|
||||
else
|
||||
if (streq (reply, "BLOCKS OK")) {
|
||||
zstr_free (&self->block_status);
|
||||
zmsg_destroy (&self->block_data);
|
||||
zsock_recv (self->actor, "iiisp", &self->status, &self->start_height, &self->curr_height, &self->block_status, &self->block_data);
|
||||
zsock_recv (self->actor, "iiip", &self->status, &self->start_height, &self->curr_height, &self->block_data);
|
||||
}
|
||||
else
|
||||
if (streq (reply, "PUT OK")) {
|
||||
|
@ -1355,7 +1356,7 @@ s_accept_reply (wap_client_t *self, ...)
|
|||
}
|
||||
else
|
||||
if (streq (reply, "START OK")) {
|
||||
zsock_recv (self->actor, "ii", &self->status, &self->curr_height);
|
||||
zsock_recv (self->actor, "i", &self->status);
|
||||
}
|
||||
else
|
||||
if (streq (reply, "STOP OK")) {
|
||||
|
@ -1415,10 +1416,10 @@ wap_client_destructor (wap_client_t *self)
|
|||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
||||
int
|
||||
wap_client_blocks (wap_client_t *self, zlist_t **block_ids_p)
|
||||
wap_client_blocks (wap_client_t *self, zlist_t **block_ids_p, uint64_t start_height)
|
||||
{
|
||||
assert (self);
|
||||
zsock_send (self->actor, "sp", "BLOCKS", *block_ids_p);
|
||||
zsock_send (self->actor, "spi", "BLOCKS", *block_ids_p, start_height);
|
||||
*block_ids_p = NULL; // Take ownership of block_ids
|
||||
if (s_accept_reply (self, "BLOCKS OK", "FAILURE", NULL))
|
||||
return -1; // Interrupted or timed-out
|
||||
|
@ -1477,10 +1478,10 @@ wap_client_save (wap_client_t *self)
|
|||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
||||
int
|
||||
wap_client_start (wap_client_t *self, uint64_t start_height)
|
||||
wap_client_start (wap_client_t *self, const char *address, uint64_t thread_count)
|
||||
{
|
||||
assert (self);
|
||||
zsock_send (self->actor, "si", "START", start_height);
|
||||
zsock_send (self->actor, "ssi", "START", address, thread_count);
|
||||
if (s_accept_reply (self, "START OK", "FAILURE", NULL))
|
||||
return -1; // Interrupted or timed-out
|
||||
return self->status;
|
||||
|
@ -1527,7 +1528,7 @@ wap_client_reason (wap_client_t *self)
|
|||
// ---------------------------------------------------------------------------
|
||||
// Return last received start_height
|
||||
|
||||
uint32_t
|
||||
uint64_t
|
||||
wap_client_start_height (wap_client_t *self)
|
||||
{
|
||||
assert (self);
|
||||
|
@ -1538,7 +1539,7 @@ wap_client_start_height (wap_client_t *self)
|
|||
// ---------------------------------------------------------------------------
|
||||
// Return last received curr_height
|
||||
|
||||
uint32_t
|
||||
uint64_t
|
||||
wap_client_curr_height (wap_client_t *self)
|
||||
{
|
||||
assert (self);
|
||||
|
@ -1546,17 +1547,6 @@ wap_client_curr_height (wap_client_t *self)
|
|||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Return last received block_status
|
||||
|
||||
const char *
|
||||
wap_client_block_status (wap_client_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->block_status;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Return last received block_data
|
||||
|
||||
|
|
|
@ -33,11 +33,12 @@
|
|||
BLOCKS - Wallet requests a set of blocks from the daemon. Daemon replies with
|
||||
BLOCKS-OK, or ERROR if the request is invalid.
|
||||
block_ids strings
|
||||
start_height number 8
|
||||
|
||||
BLOCKS_OK - Daemon returns a set of blocks to the wallet.
|
||||
status number 8
|
||||
start_height number 8
|
||||
curr_height number 8
|
||||
block_status string
|
||||
block_data msg Frames of block data
|
||||
|
||||
PUT - Wallet sends a raw transaction to the daemon. Daemon replies with
|
||||
|
@ -60,10 +61,11 @@ with GET-OK, or ERROR.
|
|||
|
||||
START - Wallet asks daemon to start mining. Daemon replies with START-OK, or
|
||||
ERROR.
|
||||
start_height number 8
|
||||
address string
|
||||
thread_count number 8
|
||||
|
||||
START_OK - Daemon replies to a start mining request.
|
||||
curr_height number 8
|
||||
status number 8
|
||||
|
||||
STOP - Wallet asks daemon to start mining. Daemon replies with START-OK, or
|
||||
ERROR.
|
||||
|
@ -186,18 +188,18 @@ uint64_t
|
|||
void
|
||||
wap_proto_set_start_height (wap_proto_t *self, uint64_t start_height);
|
||||
|
||||
// Get/set the status field
|
||||
uint64_t
|
||||
wap_proto_status (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_status (wap_proto_t *self, uint64_t status);
|
||||
|
||||
// Get/set the curr_height field
|
||||
uint64_t
|
||||
wap_proto_curr_height (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_curr_height (wap_proto_t *self, uint64_t curr_height);
|
||||
|
||||
// Get/set the block_status field
|
||||
const char *
|
||||
wap_proto_block_status (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_block_status (wap_proto_t *self, const char *value);
|
||||
|
||||
// Get a copy of the block_data field
|
||||
zmsg_t *
|
||||
wap_proto_block_data (wap_proto_t *self);
|
||||
|
@ -224,11 +226,17 @@ const char *
|
|||
void
|
||||
wap_proto_set_tx_id (wap_proto_t *self, const char *value);
|
||||
|
||||
// Get/set the status field
|
||||
uint16_t
|
||||
wap_proto_status (wap_proto_t *self);
|
||||
// Get/set the address field
|
||||
const char *
|
||||
wap_proto_address (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_status (wap_proto_t *self, uint16_t status);
|
||||
wap_proto_set_address (wap_proto_t *self, const char *value);
|
||||
|
||||
// Get/set the thread_count field
|
||||
uint64_t
|
||||
wap_proto_thread_count (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_thread_count (wap_proto_t *self, uint64_t thread_count);
|
||||
|
||||
// Get/set the reason field
|
||||
const char *
|
||||
|
|
|
@ -118,6 +118,7 @@ static void
|
|||
prepare_blocks_command (client_t *self)
|
||||
{
|
||||
wap_proto_set_block_ids (self->message, &self->args->block_ids);
|
||||
wap_proto_set_start_height (self->message, self->args->start_height);
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,10 +129,9 @@ prepare_blocks_command (client_t *self)
|
|||
static void
|
||||
signal_have_blocks_ok (client_t *self)
|
||||
{
|
||||
zsock_send (self->cmdpipe, "siiisp", "BLOCKS OK", 0,
|
||||
zsock_send (self->cmdpipe, "siiip", "BLOCKS OK", wap_proto_status(self->message),
|
||||
wap_proto_start_height (self->message),
|
||||
wap_proto_curr_height (self->message),
|
||||
wap_proto_block_status (self->message),
|
||||
wap_proto_get_block_data (self->message));
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,8 @@ signal_have_blocks_ok (client_t *self)
|
|||
static void
|
||||
prepare_start_command (client_t *self)
|
||||
{
|
||||
wap_proto_set_start_height (self->message, self->args->start_height);
|
||||
wap_proto_set_address (self->message, self->args->address);
|
||||
wap_proto_set_thread_count (self->message, self->args->thread_count);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -221,8 +222,7 @@ signal_have_save_ok (client_t *self)
|
|||
static void
|
||||
signal_have_start_ok (client_t *self)
|
||||
{
|
||||
zsock_send (self->cmdpipe, "sii", "START OK", 0,
|
||||
wap_proto_curr_height (self->message));
|
||||
zsock_send(self->cmdpipe, "si", "START OK", wap_proto_status(self->message));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,12 +37,13 @@ struct _wap_proto_t {
|
|||
char identity [256]; // Wallet identity
|
||||
zlist_t *block_ids; //
|
||||
uint64_t start_height; //
|
||||
uint64_t status; //
|
||||
uint64_t curr_height; //
|
||||
char block_status [256]; //
|
||||
zmsg_t *block_data; // Frames of block data
|
||||
zchunk_t *tx_data; // Transaction data
|
||||
char tx_id [256]; // Transaction ID
|
||||
uint16_t status; // Error status
|
||||
char address [256]; //
|
||||
uint64_t thread_count; //
|
||||
char reason [256]; // Printable explanation
|
||||
};
|
||||
|
||||
|
@ -307,12 +308,13 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
|||
free (string);
|
||||
}
|
||||
}
|
||||
GET_NUMBER8 (self->start_height);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_BLOCKS_OK:
|
||||
GET_NUMBER8 (self->status);
|
||||
GET_NUMBER8 (self->start_height);
|
||||
GET_NUMBER8 (self->curr_height);
|
||||
GET_STRING (self->block_status);
|
||||
// Get zero or more remaining frames
|
||||
zmsg_destroy (&self->block_data);
|
||||
if (zsock_rcvmore (input))
|
||||
|
@ -362,11 +364,12 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
|||
break;
|
||||
|
||||
case WAP_PROTO_START:
|
||||
GET_NUMBER8 (self->start_height);
|
||||
GET_STRING (self->address);
|
||||
GET_NUMBER8 (self->thread_count);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_START_OK:
|
||||
GET_NUMBER8 (self->curr_height);
|
||||
GET_NUMBER8 (self->status);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_STOP:
|
||||
|
@ -437,11 +440,12 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
block_ids = (char *) zlist_next (self->block_ids);
|
||||
}
|
||||
}
|
||||
frame_size += 8; // start_height
|
||||
break;
|
||||
case WAP_PROTO_BLOCKS_OK:
|
||||
frame_size += 8; // status
|
||||
frame_size += 8; // start_height
|
||||
frame_size += 8; // curr_height
|
||||
frame_size += 1 + strlen (self->block_status);
|
||||
break;
|
||||
case WAP_PROTO_PUT:
|
||||
frame_size += 4; // Size is 4 octets
|
||||
|
@ -460,10 +464,11 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
frame_size += zchunk_size (self->tx_data);
|
||||
break;
|
||||
case WAP_PROTO_START:
|
||||
frame_size += 8; // start_height
|
||||
frame_size += 1 + strlen (self->address);
|
||||
frame_size += 8; // thread_count
|
||||
break;
|
||||
case WAP_PROTO_START_OK:
|
||||
frame_size += 8; // curr_height
|
||||
frame_size += 8; // status
|
||||
break;
|
||||
case WAP_PROTO_ERROR:
|
||||
frame_size += 2; // status
|
||||
|
@ -497,12 +502,13 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
}
|
||||
else
|
||||
PUT_NUMBER4 (0); // Empty string array
|
||||
PUT_NUMBER8 (self->start_height);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_BLOCKS_OK:
|
||||
PUT_NUMBER8 (self->status);
|
||||
PUT_NUMBER8 (self->start_height);
|
||||
PUT_NUMBER8 (self->curr_height);
|
||||
PUT_STRING (self->block_status);
|
||||
nbr_frames += self->block_data? zmsg_size (self->block_data): 1;
|
||||
send_block_data = true;
|
||||
break;
|
||||
|
@ -540,11 +546,12 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
break;
|
||||
|
||||
case WAP_PROTO_START:
|
||||
PUT_NUMBER8 (self->start_height);
|
||||
PUT_STRING (self->address);
|
||||
PUT_NUMBER8 (self->thread_count);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_START_OK:
|
||||
PUT_NUMBER8 (self->curr_height);
|
||||
PUT_NUMBER8 (self->status);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_ERROR:
|
||||
|
@ -604,16 +611,14 @@ wap_proto_print (wap_proto_t *self)
|
|||
block_ids = (char *) zlist_next (self->block_ids);
|
||||
}
|
||||
}
|
||||
zsys_debug (" start_height=%ld", (long) self->start_height);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_BLOCKS_OK:
|
||||
zsys_debug ("WAP_PROTO_BLOCKS_OK:");
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
zsys_debug (" start_height=%ld", (long) self->start_height);
|
||||
zsys_debug (" curr_height=%ld", (long) self->curr_height);
|
||||
if (self->block_status)
|
||||
zsys_debug (" block_status='%s'", self->block_status);
|
||||
else
|
||||
zsys_debug (" block_status=");
|
||||
zsys_debug (" block_data=");
|
||||
if (self->block_data)
|
||||
zmsg_print (self->block_data);
|
||||
|
@ -657,12 +662,16 @@ wap_proto_print (wap_proto_t *self)
|
|||
|
||||
case WAP_PROTO_START:
|
||||
zsys_debug ("WAP_PROTO_START:");
|
||||
zsys_debug (" start_height=%ld", (long) self->start_height);
|
||||
if (self->address)
|
||||
zsys_debug (" address='%s'", self->address);
|
||||
else
|
||||
zsys_debug (" address=");
|
||||
zsys_debug (" thread_count=%ld", (long) self->thread_count);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_START_OK:
|
||||
zsys_debug ("WAP_PROTO_START_OK:");
|
||||
zsys_debug (" curr_height=%ld", (long) self->curr_height);
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_STOP:
|
||||
|
@ -881,6 +890,24 @@ wap_proto_set_start_height (wap_proto_t *self, uint64_t start_height)
|
|||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the status field
|
||||
|
||||
uint64_t
|
||||
wap_proto_status (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->status;
|
||||
}
|
||||
|
||||
void
|
||||
wap_proto_set_status (wap_proto_t *self, uint64_t status)
|
||||
{
|
||||
assert (self);
|
||||
self->status = status;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the curr_height field
|
||||
|
||||
|
@ -899,28 +926,6 @@ wap_proto_set_curr_height (wap_proto_t *self, uint64_t curr_height)
|
|||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the block_status field
|
||||
|
||||
const char *
|
||||
wap_proto_block_status (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->block_status;
|
||||
}
|
||||
|
||||
void
|
||||
wap_proto_set_block_status (wap_proto_t *self, const char *value)
|
||||
{
|
||||
assert (self);
|
||||
assert (value);
|
||||
if (value == self->block_status)
|
||||
return;
|
||||
strncpy (self->block_status, value, 255);
|
||||
self->block_status [255] = 0;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get the block_data field without transferring ownership
|
||||
|
||||
|
@ -1010,20 +1015,42 @@ wap_proto_set_tx_id (wap_proto_t *self, const char *value)
|
|||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the status field
|
||||
// Get/set the address field
|
||||
|
||||
uint16_t
|
||||
wap_proto_status (wap_proto_t *self)
|
||||
const char *
|
||||
wap_proto_address (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->status;
|
||||
return self->address;
|
||||
}
|
||||
|
||||
void
|
||||
wap_proto_set_status (wap_proto_t *self, uint16_t status)
|
||||
wap_proto_set_address (wap_proto_t *self, const char *value)
|
||||
{
|
||||
assert (self);
|
||||
self->status = status;
|
||||
assert (value);
|
||||
if (value == self->address)
|
||||
return;
|
||||
strncpy (self->address, value, 255);
|
||||
self->address [255] = 0;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the thread_count field
|
||||
|
||||
uint64_t
|
||||
wap_proto_thread_count (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->thread_count;
|
||||
}
|
||||
|
||||
void
|
||||
wap_proto_set_thread_count (wap_proto_t *self, uint64_t thread_count)
|
||||
{
|
||||
assert (self);
|
||||
self->thread_count = thread_count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1104,6 +1131,7 @@ wap_proto_test (bool verbose)
|
|||
zlist_append (blocks_block_ids, "Name: Brutus");
|
||||
zlist_append (blocks_block_ids, "Age: 43");
|
||||
wap_proto_set_block_ids (self, &blocks_block_ids);
|
||||
wap_proto_set_start_height (self, 123);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
@ -1116,12 +1144,13 @@ wap_proto_test (bool verbose)
|
|||
assert (streq ((char *) zlist_first (block_ids), "Name: Brutus"));
|
||||
assert (streq ((char *) zlist_next (block_ids), "Age: 43"));
|
||||
zlist_destroy (&block_ids);
|
||||
assert (wap_proto_start_height (self) == 123);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_BLOCKS_OK);
|
||||
|
||||
wap_proto_set_status (self, 123);
|
||||
wap_proto_set_start_height (self, 123);
|
||||
wap_proto_set_curr_height (self, 123);
|
||||
wap_proto_set_block_status (self, "Life is short but Now lasts for ever");
|
||||
zmsg_t *blocks_ok_block_data = zmsg_new ();
|
||||
wap_proto_set_block_data (self, &blocks_ok_block_data);
|
||||
zmsg_addstr (wap_proto_block_data (self), "Hello, World");
|
||||
|
@ -1132,9 +1161,9 @@ wap_proto_test (bool verbose)
|
|||
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_start_height (self) == 123);
|
||||
assert (wap_proto_curr_height (self) == 123);
|
||||
assert (streq (wap_proto_block_status (self), "Life is short but Now lasts for ever"));
|
||||
assert (zmsg_size (wap_proto_block_data (self)) == 1);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_PUT);
|
||||
|
@ -1209,7 +1238,8 @@ wap_proto_test (bool verbose)
|
|||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_START);
|
||||
|
||||
wap_proto_set_start_height (self, 123);
|
||||
wap_proto_set_address (self, "Life is short but Now lasts for ever");
|
||||
wap_proto_set_thread_count (self, 123);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
@ -1217,11 +1247,12 @@ wap_proto_test (bool verbose)
|
|||
for (instance = 0; instance < 2; instance++) {
|
||||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (wap_proto_start_height (self) == 123);
|
||||
assert (streq (wap_proto_address (self), "Life is short but Now lasts for ever"));
|
||||
assert (wap_proto_thread_count (self) == 123);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_START_OK);
|
||||
|
||||
wap_proto_set_curr_height (self, 123);
|
||||
wap_proto_set_status (self, 123);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
@ -1229,7 +1260,7 @@ wap_proto_test (bool verbose)
|
|||
for (instance = 0; instance < 2; instance++) {
|
||||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (wap_proto_curr_height (self) == 123);
|
||||
assert (wap_proto_status (self) == 123);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_STOP);
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ register_wallet (client_t *self)
|
|||
static void
|
||||
retrieve_blocks (client_t *self)
|
||||
{
|
||||
|
||||
IPC::Daemon::retrieve_blocks(self->message);
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,7 +185,6 @@ start_mining_process (client_t *self)
|
|||
{
|
||||
IPC::Daemon::start_mining(self->message);
|
||||
printf("\n\n Request: %d \n\n", (int)wap_proto_start_height(self->message));
|
||||
// wap_proto_set_curr_height(self->message, 100);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -314,24 +314,49 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids)
|
|||
if(!genesis_included)
|
||||
ids.push_back(m_blockchain[0]);
|
||||
}
|
||||
void wallet2::get_blocks_from_zmq_msg(zmsg_t *msg, std::list<cryptonote::block_complete_entry> &blocks) {
|
||||
zframe_t *frame = zmsg_first(msg);
|
||||
THROW_WALLET_EXCEPTION_IF(!frame, error::get_blocks_error, "getblocks");
|
||||
size_t size = zframe_size(frame);
|
||||
char *block_data = reinterpret_cast<char*>(zframe_data(frame));
|
||||
|
||||
rapidjson::Document json;
|
||||
int _i = 0;
|
||||
THROW_WALLET_EXCEPTION_IF(json.Parse(block_data, size).HasParseError(), error::get_blocks_error, "getblocks");
|
||||
for (rapidjson::SizeType i = 0; i < json["blocks"].Size(); i++) {
|
||||
block_complete_entry block_entry;
|
||||
std::string block_string(json["blocks"][i]["block"].GetString(), json["blocks"][i]["block"].GetStringLength());
|
||||
block_entry.block = block_string;
|
||||
for (rapidjson::SizeType j = 0; j < json["blocks"][i]["txs"].Size(); j++) {
|
||||
block_entry.txs.push_back(std::string(json["blocks"][i]["txs"][j].GetString(), json["blocks"][i]["txs"][j].GetStringLength()));
|
||||
}
|
||||
blocks.push_back(block_entry);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::pull_blocks(uint64_t start_height, size_t& blocks_added)
|
||||
{
|
||||
blocks_added = 0;
|
||||
cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res);
|
||||
get_short_chain_history(req.block_ids);
|
||||
req.start_height = start_height;
|
||||
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getblocks.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblocks.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblocks.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_blocks_error, res.status);
|
||||
std::list<crypto::hash> block_ids;
|
||||
get_short_chain_history(block_ids);
|
||||
zlist_t *list = zlist_new();
|
||||
for (std::list<crypto::hash>::iterator it = block_ids.begin(); it != block_ids.end(); it++) {
|
||||
zlist_append(list, it->data);
|
||||
}
|
||||
int rc = wap_client_blocks(client, &list, start_height);
|
||||
THROW_WALLET_EXCEPTION_IF(rc != 0, error::no_connection_to_daemon, "getblocks");
|
||||
|
||||
size_t current_index = res.start_height;
|
||||
BOOST_FOREACH(auto& bl_entry, res.blocks)
|
||||
uint64_t status = wap_client_status(client);
|
||||
THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "getblocks");
|
||||
THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_INTERNAL_ERROR, error::daemon_internal_error, "getblocks");
|
||||
THROW_WALLET_EXCEPTION_IF(status != IPC::STATUS_OK, error::get_blocks_error, "getblocks");
|
||||
std::list<block_complete_entry> blocks;
|
||||
get_blocks_from_zmq_msg(wap_client_block_data(client), blocks);
|
||||
uint64_t current_index = wap_client_start_height(client);
|
||||
BOOST_FOREACH(auto& bl_entry, blocks)
|
||||
{
|
||||
cryptonote::block bl;
|
||||
r = cryptonote::parse_and_validate_block_from_blob(bl_entry.block, bl);
|
||||
bool r = cryptonote::parse_and_validate_block_from_blob(bl_entry.block, bl);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::block_parse_error, bl_entry.block);
|
||||
|
||||
crypto::hash bl_id = get_block_hash(bl);
|
||||
|
@ -343,9 +368,9 @@ void wallet2::pull_blocks(uint64_t start_height, size_t& blocks_added)
|
|||
else if(bl_id != m_blockchain[current_index])
|
||||
{
|
||||
//split detected here !!!
|
||||
THROW_WALLET_EXCEPTION_IF(current_index == res.start_height, error::wallet_internal_error,
|
||||
THROW_WALLET_EXCEPTION_IF(current_index == start_height, error::wallet_internal_error,
|
||||
"wrong daemon response: split starts from the first block in response " + string_tools::pod_to_hex(bl_id) +
|
||||
" (height " + std::to_string(res.start_height) + "), local block id at this height: " +
|
||||
" (height " + std::to_string(start_height) + "), local block id at this height: " +
|
||||
string_tools::pod_to_hex(m_blockchain[current_index]));
|
||||
|
||||
detach_blockchain(current_index);
|
||||
|
|
|
@ -46,10 +46,9 @@
|
|||
#include "common/unordered_containers_boost_serialization.h"
|
||||
#include "crypto/chacha8.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "wap_library.h"
|
||||
#include "wap_classes.h"
|
||||
|
||||
#include "wallet_errors.h"
|
||||
#include "daemon_ipc_handlers.h"
|
||||
|
||||
#include <iostream>
|
||||
#define DEFAULT_TX_SPENDABLE_AGE 10
|
||||
|
@ -89,9 +88,21 @@ namespace tools
|
|||
if (!client) {
|
||||
// TODO: Daemon not up.
|
||||
}
|
||||
int rc = wap_client_start (client, 25);
|
||||
std::cout << "\n\n Response: " << (int)wap_client_curr_height(client) << std::endl;
|
||||
assert (rc == 0);
|
||||
/*zlist_t *list = zlist_new();
|
||||
char cheese[32];
|
||||
const char *foo = "771fbcd656ec1464d3a02ead5e18644030007a0fc664c0a964d30922821a8148";
|
||||
for (int i = 0; i < 63; i += 2) {
|
||||
std::string x = "";
|
||||
x += foo[i];
|
||||
x += foo[i + 1];
|
||||
cheese[i / 2] = (char)stoi(x, NULL, 16);
|
||||
}
|
||||
zlist_append(list, cheese);
|
||||
uint64_t start_height = 1;
|
||||
int rc = wap_client_blocks(client, &list, start_height);
|
||||
// int rc = wap_client_start(client, 25);
|
||||
// std::cout << "\n\n Response: " << (int)wap_client_curr_height(client) << std::endl;
|
||||
assert (rc == 0);*/
|
||||
};
|
||||
struct transfer_details
|
||||
{
|
||||
|
@ -283,6 +294,7 @@ namespace tools
|
|||
bool is_tx_spendtime_unlocked(uint64_t unlock_time) const;
|
||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||
bool clear();
|
||||
void get_blocks_from_zmq_msg(zmsg_t *msg, std::list<cryptonote::block_complete_entry> &blocks);
|
||||
void pull_blocks(uint64_t start_height, size_t& blocks_added);
|
||||
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, std::list<transfer_container::iterator>& selected_transfers);
|
||||
bool prepare_file_names(const std::string& file_path);
|
||||
|
|
|
@ -565,6 +565,13 @@ namespace tools
|
|||
{
|
||||
}
|
||||
};
|
||||
struct daemon_internal_error : public wallet_rpc_error
|
||||
{
|
||||
explicit daemon_internal_error(std::string&& loc, const std::string& request)
|
||||
: wallet_rpc_error(std::move(loc), "daemon had an internal error processing the request", request)
|
||||
{
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct no_connection_to_daemon : public wallet_rpc_error
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue