diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h index a16c7eff7..86c786ec3 100644 --- a/src/common/dns_utils.h +++ b/src/common/dns_utils.h @@ -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 #include diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index d99d92ecf..6ac98b4f1 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -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; diff --git a/src/ipc/daemon_ipc_handlers.cpp b/src/ipc/daemon_ipc_handlers.cpp index e3175c9db..d12efde86 100644 --- a/src/ipc/daemon_ipc_handlers.cpp +++ b/src/ipc/daemon_ipc_handlers.cpp @@ -38,6 +38,7 @@ namespace nodetool::node_server > *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 > *p_p2p) + nodetool::node_server > *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,13 +67,96 @@ 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(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 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 > > 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 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) diff --git a/src/ipc/include/daemon_ipc_handlers.h b/src/ipc/include/daemon_ipc_handlers.h index 5ef0aa350..7450a2616 100644 --- a/src/ipc/include/daemon_ipc_handlers.h +++ b/src/ipc/include/daemon_ipc_handlers.h @@ -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 > *p_p2p); + nodetool::node_server > *p_p2p, + bool p_testnet); } } diff --git a/src/ipc/include/wap_client.h b/src/ipc/include/wap_client.h index 83b66b445..8c7688bba 100644 --- a/src/ipc/include/wap_client.h +++ b/src/ipc/include/wap_client.h @@ -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 diff --git a/src/ipc/include/wap_client_engine.inc b/src/ipc/include/wap_client_engine.inc index 995ae8e88..66e5e3535 100644 --- a/src/ipc/include/wap_client_engine.inc +++ b/src/ipc/include/wap_client_engine.inc @@ -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 diff --git a/src/ipc/include/wap_proto.h b/src/ipc/include/wap_proto.h index 8d8611231..c25a44f97 100644 --- a/src/ipc/include/wap_proto.h +++ b/src/ipc/include/wap_proto.h @@ -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 * diff --git a/src/ipc/wap_client/wap_client.c b/src/ipc/wap_client/wap_client.c index d95b4b10c..c377709ac 100644 --- a/src/ipc/wap_client/wap_client.c +++ b/src/ipc/wap_client/wap_client.c @@ -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)); } diff --git a/src/ipc/wap_proto.c b/src/ipc/wap_proto.c index 38c680bbb..d6586c838 100644 --- a/src/ipc/wap_proto.c +++ b/src/ipc/wap_proto.c @@ -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); diff --git a/src/ipc/wap_server/wap_server.c b/src/ipc/wap_server/wap_server.c index f3ccdce4a..a1aa95a0c 100644 --- a/src/ipc/wap_server/wap_server.c +++ b/src/ipc/wap_server/wap_server.c @@ -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); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 295d8b0a1..e7c6d842f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -314,24 +314,49 @@ void wallet2::get_short_chain_history(std::list& ids) if(!genesis_included) ids.push_back(m_blockchain[0]); } +void wallet2::get_blocks_from_zmq_msg(zmsg_t *msg, std::list &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(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 block_ids; + get_short_chain_history(block_ids); + zlist_t *list = zlist_new(); + for (std::list::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 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); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 271229976..14b662956 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -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 #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 &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& selected_transfers); bool prepare_file_names(const std::string& file_path); diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index bf520c36c..7809c3698 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -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 {