start_mining and get_blocks IPC

This commit is contained in:
Oran Juice 2015-02-07 02:29:59 +05:30
parent 3fba3fec57
commit d75b5dd60b
No known key found for this signature in database
GPG Key ID: 71C5AF46CCB28124
13 changed files with 305 additions and 132 deletions

View File

@ -26,6 +26,8 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // 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. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <vector> #include <vector>
#include <string> #include <string>

View File

@ -247,7 +247,7 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Protocol initialized OK"); LOG_PRINT_L0("Protocol initialized OK");
LOG_PRINT_L0("Initializing core IPC server..."); 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..."); LOG_PRINT_L0("Initializing core RPC server...");
RPC::Daemon::init(&ccore, &p2psrv, testnet_mode); RPC::Daemon::init(&ccore, &p2psrv, testnet_mode);
std::string ip_address, port; std::string ip_address, port;

View File

@ -38,6 +38,7 @@ namespace
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > *p2p; nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > *p2p;
/*!< Pointer to p2p node server */ /*!< Pointer to p2p node server */
zactor_t *server; zactor_t *server;
bool testnet;
bool check_core_busy() bool check_core_busy()
{ {
if (p2p->get_payload_object().get_core().get_blockchain_storage().is_storing_blockchain()) if (p2p->get_payload_object().get_core().get_blockchain_storage().is_storing_blockchain())
@ -53,10 +54,12 @@ namespace IPC
namespace Daemon namespace Daemon
{ {
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)
{ {
p2p = p_p2p; p2p = p_p2p;
core = p_core; core = p_core;
testnet = p_testnet;
server = zactor_new (wap_server, NULL); server = zactor_new (wap_server, NULL);
zsock_send (server, "ss", "BIND", "ipc://@/monero"); zsock_send (server, "ss", "BIND", "ipc://@/monero");
zsock_send (server, "sss", "SET", "server/timeout", "5000"); zsock_send (server, "sss", "SET", "server/timeout", "5000");
@ -64,13 +67,96 @@ namespace IPC
void start_mining(wap_proto_t *message) void start_mining(wap_proto_t *message)
{ {
uint64_t start_height = wap_proto_start_height(message); if (!check_core_busy()) {
wap_proto_set_curr_height(message, 2 * start_height); 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);
} }
void sendtransactions(wap_proto_t *message) void sendtransactions(wap_proto_t *message)

View File

@ -45,17 +45,30 @@ using namespace epee;
#include "crypto/hash.h" #include "crypto/hash.h"
#include "wap_library.h" #include "wap_library.h"
#include "wap_classes.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 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 namespace Daemon
{ {
void start_mining(wap_proto_t *message); 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 send_transactions(wap_proto_t *message);
void get_o_indexes(wap_proto_t *message); void get_o_indexes(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);
} }
} }

View File

@ -57,7 +57,7 @@ WAP_EXPORT zsock_t *
// Request a set of blocks from the server. // Request a set of blocks from the server.
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
WAP_EXPORT int 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. // Send a raw transaction to the daemon.
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
@ -77,7 +77,7 @@ WAP_EXPORT int
// Send start command to server. // Send start command to server.
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
WAP_EXPORT int 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. // Send stop command to server.
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
@ -93,17 +93,13 @@ WAP_EXPORT const char *
wap_client_reason (wap_client_t *self); wap_client_reason (wap_client_t *self);
// Return last received start_height // Return last received start_height
WAP_EXPORT uint32_t WAP_EXPORT uint64_t
wap_client_start_height (wap_client_t *self); wap_client_start_height (wap_client_t *self);
// Return last received curr_height // Return last received curr_height
WAP_EXPORT uint32_t WAP_EXPORT uint64_t
wap_client_curr_height (wap_client_t *self); 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 // Return last received block_data
WAP_EXPORT zmsg_t * WAP_EXPORT zmsg_t *
wap_client_block_data (wap_client_t *self); wap_client_block_data (wap_client_t *self);
@ -116,6 +112,10 @@ WAP_EXPORT const char *
WAP_EXPORT zchunk_t * WAP_EXPORT zchunk_t *
wap_client_tx_data (wap_client_t *self); 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 // To enable verbose tracing (animation) of wap_client instances, set
// this to true. This lets you trace from and including construction. // this to true. This lets you trace from and including construction.
WAP_EXPORT extern volatile int WAP_EXPORT extern volatile int

View File

@ -120,9 +120,11 @@ struct _client_args_t {
uint32_t timeout; uint32_t timeout;
char *identity; char *identity;
zlist_t *block_ids; zlist_t *block_ids;
uint64_t start_height;
zchunk_t *tx_data; zchunk_t *tx_data;
char *tx_id; char *tx_id;
uint64_t start_height; char *address;
uint64_t thread_count;
}; };
typedef struct { typedef struct {
@ -252,6 +254,7 @@ s_client_destroy (s_client_t **self_p)
zlist_destroy (&self->args.block_ids); zlist_destroy (&self->args.block_ids);
zchunk_destroy (&self->args.tx_data); zchunk_destroy (&self->args.tx_data);
zstr_free (&self->args.tx_id); zstr_free (&self->args.tx_id);
zstr_free (&self->args.address);
client_terminate (&self->client); client_terminate (&self->client);
wap_proto_destroy (&self->message); wap_proto_destroy (&self->message);
zsock_destroy (&self->msgpipe); zsock_destroy (&self->msgpipe);
@ -1069,7 +1072,7 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
else else
if (streq (method, "BLOCKS")) { if (streq (method, "BLOCKS")) {
zlist_destroy (&self->args.block_ids); 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); s_client_execute (self, blocks_event);
} }
else else
@ -1090,7 +1093,8 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
} }
else else
if (streq (method, "START")) { 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); s_client_execute (self, start_event);
} }
else else
@ -1207,9 +1211,8 @@ struct _wap_client_t {
zsock_t *msgpipe; // Pipe for async message flow zsock_t *msgpipe; // Pipe for async message flow
int status; // Returned by actor reply int status; // Returned by actor reply
char *reason; // Returned by actor reply char *reason; // Returned by actor reply
uint32_t start_height; // Returned by actor reply uint64_t start_height; // Returned by actor reply
uint32_t curr_height; // Returned by actor reply uint64_t curr_height; // Returned by actor reply
char *block_status; // Returned by actor reply
zmsg_t *block_data; // Returned by actor reply zmsg_t *block_data; // Returned by actor reply
char *tx_id; // Returned by actor reply char *tx_id; // Returned by actor reply
zchunk_t *tx_data; // 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); zactor_destroy (&self->actor);
zsock_destroy (&self->msgpipe); zsock_destroy (&self->msgpipe);
zstr_free (&self->reason); zstr_free (&self->reason);
zstr_free (&self->block_status);
zmsg_destroy (&self->block_data); zmsg_destroy (&self->block_data);
zstr_free (&self->tx_id); zstr_free (&self->tx_id);
zchunk_destroy (&self->tx_data); zchunk_destroy (&self->tx_data);
@ -1335,9 +1337,8 @@ s_accept_reply (wap_client_t *self, ...)
} }
else else
if (streq (reply, "BLOCKS OK")) { if (streq (reply, "BLOCKS OK")) {
zstr_free (&self->block_status);
zmsg_destroy (&self->block_data); 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 else
if (streq (reply, "PUT OK")) { if (streq (reply, "PUT OK")) {
@ -1355,7 +1356,7 @@ s_accept_reply (wap_client_t *self, ...)
} }
else else
if (streq (reply, "START OK")) { if (streq (reply, "START OK")) {
zsock_recv (self->actor, "ii", &self->status, &self->curr_height); zsock_recv (self->actor, "i", &self->status);
} }
else else
if (streq (reply, "STOP OK")) { if (streq (reply, "STOP OK")) {
@ -1415,10 +1416,10 @@ wap_client_destructor (wap_client_t *self)
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
int 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); 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 *block_ids_p = NULL; // Take ownership of block_ids
if (s_accept_reply (self, "BLOCKS OK", "FAILURE", NULL)) if (s_accept_reply (self, "BLOCKS OK", "FAILURE", NULL))
return -1; // Interrupted or timed-out return -1; // Interrupted or timed-out
@ -1477,10 +1478,10 @@ wap_client_save (wap_client_t *self)
// Returns >= 0 if successful, -1 if interrupted. // Returns >= 0 if successful, -1 if interrupted.
int 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); 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)) if (s_accept_reply (self, "START OK", "FAILURE", NULL))
return -1; // Interrupted or timed-out return -1; // Interrupted or timed-out
return self->status; return self->status;
@ -1527,7 +1528,7 @@ wap_client_reason (wap_client_t *self)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Return last received start_height // Return last received start_height
uint32_t uint64_t
wap_client_start_height (wap_client_t *self) wap_client_start_height (wap_client_t *self)
{ {
assert (self); assert (self);
@ -1538,7 +1539,7 @@ wap_client_start_height (wap_client_t *self)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Return last received curr_height // Return last received curr_height
uint32_t uint64_t
wap_client_curr_height (wap_client_t *self) wap_client_curr_height (wap_client_t *self)
{ {
assert (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 // Return last received block_data

View File

@ -33,11 +33,12 @@
BLOCKS - Wallet requests a set of blocks from the daemon. Daemon replies with BLOCKS - Wallet requests a set of blocks from the daemon. Daemon replies with
BLOCKS-OK, or ERROR if the request is invalid. BLOCKS-OK, or ERROR if the request is invalid.
block_ids strings block_ids strings
start_height number 8
BLOCKS_OK - Daemon returns a set of blocks to the wallet. BLOCKS_OK - Daemon returns a set of blocks to the wallet.
status number 8
start_height number 8 start_height number 8
curr_height number 8 curr_height number 8
block_status string
block_data msg Frames of block data block_data msg Frames of block data
PUT - Wallet sends a raw transaction to the daemon. Daemon replies with 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 START - Wallet asks daemon to start mining. Daemon replies with START-OK, or
ERROR. ERROR.
start_height number 8 address string
thread_count number 8
START_OK - Daemon replies to a start mining request. 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 STOP - Wallet asks daemon to start mining. Daemon replies with START-OK, or
ERROR. ERROR.
@ -186,18 +188,18 @@ uint64_t
void void
wap_proto_set_start_height (wap_proto_t *self, uint64_t start_height); 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 // Get/set the curr_height field
uint64_t uint64_t
wap_proto_curr_height (wap_proto_t *self); wap_proto_curr_height (wap_proto_t *self);
void void
wap_proto_set_curr_height (wap_proto_t *self, uint64_t curr_height); 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 // Get a copy of the block_data field
zmsg_t * zmsg_t *
wap_proto_block_data (wap_proto_t *self); wap_proto_block_data (wap_proto_t *self);
@ -224,11 +226,17 @@ const char *
void void
wap_proto_set_tx_id (wap_proto_t *self, const char *value); wap_proto_set_tx_id (wap_proto_t *self, const char *value);
// Get/set the status field // Get/set the address field
uint16_t const char *
wap_proto_status (wap_proto_t *self); wap_proto_address (wap_proto_t *self);
void 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 // Get/set the reason field
const char * const char *

View File

@ -118,6 +118,7 @@ static void
prepare_blocks_command (client_t *self) prepare_blocks_command (client_t *self)
{ {
wap_proto_set_block_ids (self->message, &self->args->block_ids); 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 static void
signal_have_blocks_ok (client_t *self) 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_start_height (self->message),
wap_proto_curr_height (self->message), wap_proto_curr_height (self->message),
wap_proto_block_status (self->message),
wap_proto_get_block_data (self->message)); wap_proto_get_block_data (self->message));
} }
@ -143,7 +143,8 @@ signal_have_blocks_ok (client_t *self)
static void static void
prepare_start_command (client_t *self) 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 static void
signal_have_start_ok (client_t *self) signal_have_start_ok (client_t *self)
{ {
zsock_send (self->cmdpipe, "sii", "START OK", 0, zsock_send(self->cmdpipe, "si", "START OK", wap_proto_status(self->message));
wap_proto_curr_height (self->message));
} }

View File

@ -37,12 +37,13 @@ struct _wap_proto_t {
char identity [256]; // Wallet identity char identity [256]; // Wallet identity
zlist_t *block_ids; // zlist_t *block_ids; //
uint64_t start_height; // uint64_t start_height; //
uint64_t status; //
uint64_t curr_height; // uint64_t curr_height; //
char block_status [256]; //
zmsg_t *block_data; // Frames of block data zmsg_t *block_data; // Frames of block data
zchunk_t *tx_data; // Transaction data zchunk_t *tx_data; // Transaction data
char tx_id [256]; // Transaction ID char tx_id [256]; // Transaction ID
uint16_t status; // Error status char address [256]; //
uint64_t thread_count; //
char reason [256]; // Printable explanation char reason [256]; // Printable explanation
}; };
@ -307,12 +308,13 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
free (string); free (string);
} }
} }
GET_NUMBER8 (self->start_height);
break; break;
case WAP_PROTO_BLOCKS_OK: case WAP_PROTO_BLOCKS_OK:
GET_NUMBER8 (self->status);
GET_NUMBER8 (self->start_height); GET_NUMBER8 (self->start_height);
GET_NUMBER8 (self->curr_height); GET_NUMBER8 (self->curr_height);
GET_STRING (self->block_status);
// Get zero or more remaining frames // Get zero or more remaining frames
zmsg_destroy (&self->block_data); zmsg_destroy (&self->block_data);
if (zsock_rcvmore (input)) if (zsock_rcvmore (input))
@ -362,11 +364,12 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
break; break;
case WAP_PROTO_START: case WAP_PROTO_START:
GET_NUMBER8 (self->start_height); GET_STRING (self->address);
GET_NUMBER8 (self->thread_count);
break; break;
case WAP_PROTO_START_OK: case WAP_PROTO_START_OK:
GET_NUMBER8 (self->curr_height); GET_NUMBER8 (self->status);
break; break;
case WAP_PROTO_STOP: 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); block_ids = (char *) zlist_next (self->block_ids);
} }
} }
frame_size += 8; // start_height
break; break;
case WAP_PROTO_BLOCKS_OK: case WAP_PROTO_BLOCKS_OK:
frame_size += 8; // status
frame_size += 8; // start_height frame_size += 8; // start_height
frame_size += 8; // curr_height frame_size += 8; // curr_height
frame_size += 1 + strlen (self->block_status);
break; break;
case WAP_PROTO_PUT: case WAP_PROTO_PUT:
frame_size += 4; // Size is 4 octets 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); frame_size += zchunk_size (self->tx_data);
break; break;
case WAP_PROTO_START: case WAP_PROTO_START:
frame_size += 8; // start_height frame_size += 1 + strlen (self->address);
frame_size += 8; // thread_count
break; break;
case WAP_PROTO_START_OK: case WAP_PROTO_START_OK:
frame_size += 8; // curr_height frame_size += 8; // status
break; break;
case WAP_PROTO_ERROR: case WAP_PROTO_ERROR:
frame_size += 2; // status frame_size += 2; // status
@ -497,12 +502,13 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
} }
else else
PUT_NUMBER4 (0); // Empty string array PUT_NUMBER4 (0); // Empty string array
PUT_NUMBER8 (self->start_height);
break; break;
case WAP_PROTO_BLOCKS_OK: case WAP_PROTO_BLOCKS_OK:
PUT_NUMBER8 (self->status);
PUT_NUMBER8 (self->start_height); PUT_NUMBER8 (self->start_height);
PUT_NUMBER8 (self->curr_height); PUT_NUMBER8 (self->curr_height);
PUT_STRING (self->block_status);
nbr_frames += self->block_data? zmsg_size (self->block_data): 1; nbr_frames += self->block_data? zmsg_size (self->block_data): 1;
send_block_data = true; send_block_data = true;
break; break;
@ -540,11 +546,12 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
break; break;
case WAP_PROTO_START: case WAP_PROTO_START:
PUT_NUMBER8 (self->start_height); PUT_STRING (self->address);
PUT_NUMBER8 (self->thread_count);
break; break;
case WAP_PROTO_START_OK: case WAP_PROTO_START_OK:
PUT_NUMBER8 (self->curr_height); PUT_NUMBER8 (self->status);
break; break;
case WAP_PROTO_ERROR: case WAP_PROTO_ERROR:
@ -604,16 +611,14 @@ wap_proto_print (wap_proto_t *self)
block_ids = (char *) zlist_next (self->block_ids); block_ids = (char *) zlist_next (self->block_ids);
} }
} }
zsys_debug (" start_height=%ld", (long) self->start_height);
break; break;
case WAP_PROTO_BLOCKS_OK: case WAP_PROTO_BLOCKS_OK:
zsys_debug ("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 (" start_height=%ld", (long) self->start_height);
zsys_debug (" curr_height=%ld", (long) self->curr_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="); zsys_debug (" block_data=");
if (self->block_data) if (self->block_data)
zmsg_print (self->block_data); zmsg_print (self->block_data);
@ -657,12 +662,16 @@ wap_proto_print (wap_proto_t *self)
case WAP_PROTO_START: case WAP_PROTO_START:
zsys_debug ("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; break;
case WAP_PROTO_START_OK: case WAP_PROTO_START_OK:
zsys_debug ("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; break;
case WAP_PROTO_STOP: 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 // 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 // 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 const char *
wap_proto_status (wap_proto_t *self) wap_proto_address (wap_proto_t *self)
{ {
assert (self); assert (self);
return self->status; return self->address;
} }
void 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); 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, "Name: Brutus");
zlist_append (blocks_block_ids, "Age: 43"); zlist_append (blocks_block_ids, "Age: 43");
wap_proto_set_block_ids (self, &blocks_block_ids); wap_proto_set_block_ids (self, &blocks_block_ids);
wap_proto_set_start_height (self, 123);
// Send twice // Send twice
wap_proto_send (self, output); wap_proto_send (self, output);
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_first (block_ids), "Name: Brutus"));
assert (streq ((char *) zlist_next (block_ids), "Age: 43")); assert (streq ((char *) zlist_next (block_ids), "Age: 43"));
zlist_destroy (&block_ids); zlist_destroy (&block_ids);
assert (wap_proto_start_height (self) == 123);
} }
wap_proto_set_id (self, WAP_PROTO_BLOCKS_OK); 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_start_height (self, 123);
wap_proto_set_curr_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 (); zmsg_t *blocks_ok_block_data = zmsg_new ();
wap_proto_set_block_data (self, &blocks_ok_block_data); wap_proto_set_block_data (self, &blocks_ok_block_data);
zmsg_addstr (wap_proto_block_data (self), "Hello, World"); zmsg_addstr (wap_proto_block_data (self), "Hello, World");
@ -1132,9 +1161,9 @@ wap_proto_test (bool verbose)
for (instance = 0; instance < 2; instance++) { for (instance = 0; instance < 2; instance++) {
wap_proto_recv (self, input); wap_proto_recv (self, input);
assert (wap_proto_routing_id (self)); assert (wap_proto_routing_id (self));
assert (wap_proto_status (self) == 123);
assert (wap_proto_start_height (self) == 123); assert (wap_proto_start_height (self) == 123);
assert (wap_proto_curr_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); assert (zmsg_size (wap_proto_block_data (self)) == 1);
} }
wap_proto_set_id (self, WAP_PROTO_PUT); 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_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 // Send twice
wap_proto_send (self, output); wap_proto_send (self, output);
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++) { for (instance = 0; instance < 2; instance++) {
wap_proto_recv (self, input); wap_proto_recv (self, input);
assert (wap_proto_routing_id (self)); 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_id (self, WAP_PROTO_START_OK);
wap_proto_set_curr_height (self, 123); wap_proto_set_status (self, 123);
// Send twice // Send twice
wap_proto_send (self, output); wap_proto_send (self, output);
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++) { for (instance = 0; instance < 2; instance++) {
wap_proto_recv (self, input); wap_proto_recv (self, input);
assert (wap_proto_routing_id (self)); 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); wap_proto_set_id (self, WAP_PROTO_STOP);

View File

@ -150,7 +150,7 @@ register_wallet (client_t *self)
static void static void
retrieve_blocks (client_t *self) 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); IPC::Daemon::start_mining(self->message);
printf("\n\n Request: %d \n\n", (int)wap_proto_start_height(self->message)); printf("\n\n Request: %d \n\n", (int)wap_proto_start_height(self->message));
// wap_proto_set_curr_height(self->message, 100);
} }

View File

@ -314,24 +314,49 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids)
if(!genesis_included) if(!genesis_included)
ids.push_back(m_blockchain[0]); 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) void wallet2::pull_blocks(uint64_t start_height, size_t& blocks_added)
{ {
blocks_added = 0; blocks_added = 0;
cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::request req = AUTO_VAL_INIT(req); std::list<crypto::hash> block_ids;
cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res); get_short_chain_history(block_ids);
get_short_chain_history(req.block_ids); zlist_t *list = zlist_new();
req.start_height = start_height; for (std::list<crypto::hash>::iterator it = block_ids.begin(); it != block_ids.end(); it++) {
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getblocks.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT); zlist_append(list, it->data);
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"); int rc = wap_client_blocks(client, &list, start_height);
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_blocks_error, res.status); THROW_WALLET_EXCEPTION_IF(rc != 0, error::no_connection_to_daemon, "getblocks");
size_t current_index = res.start_height; uint64_t status = wap_client_status(client);
BOOST_FOREACH(auto& bl_entry, res.blocks) 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; 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); THROW_WALLET_EXCEPTION_IF(!r, error::block_parse_error, bl_entry.block);
crypto::hash bl_id = get_block_hash(bl); 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]) else if(bl_id != m_blockchain[current_index])
{ {
//split detected here !!! //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) + "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])); string_tools::pod_to_hex(m_blockchain[current_index]));
detach_blockchain(current_index); detach_blockchain(current_index);

View File

@ -46,10 +46,9 @@
#include "common/unordered_containers_boost_serialization.h" #include "common/unordered_containers_boost_serialization.h"
#include "crypto/chacha8.h" #include "crypto/chacha8.h"
#include "crypto/hash.h" #include "crypto/hash.h"
#include "wap_library.h"
#include "wap_classes.h"
#include "wallet_errors.h" #include "wallet_errors.h"
#include "daemon_ipc_handlers.h"
#include <iostream> #include <iostream>
#define DEFAULT_TX_SPENDABLE_AGE 10 #define DEFAULT_TX_SPENDABLE_AGE 10
@ -89,9 +88,21 @@ namespace tools
if (!client) { if (!client) {
// TODO: Daemon not up. // TODO: Daemon not up.
} }
int rc = wap_client_start (client, 25); /*zlist_t *list = zlist_new();
std::cout << "\n\n Response: " << (int)wap_client_curr_height(client) << std::endl; char cheese[32];
assert (rc == 0); 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 struct transfer_details
{ {
@ -283,6 +294,7 @@ namespace tools
bool is_tx_spendtime_unlocked(uint64_t unlock_time) const; bool is_tx_spendtime_unlocked(uint64_t unlock_time) const;
bool is_transfer_unlocked(const transfer_details& td) const; bool is_transfer_unlocked(const transfer_details& td) const;
bool clear(); 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); 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); 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); bool prepare_file_names(const std::string& file_path);

View File

@ -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 struct no_connection_to_daemon : public wallet_rpc_error
{ {