Commit tx IPC
This commit is contained in:
parent
322900b374
commit
bcbc24a456
|
@ -161,7 +161,49 @@ namespace IPC
|
|||
|
||||
void send_raw_transaction(wap_proto_t *message)
|
||||
{
|
||||
if (!check_core_busy()) {
|
||||
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||
return;
|
||||
}
|
||||
std::string tx_blob;
|
||||
zchunk_t *tx_as_hex_chunk = wap_proto_tx_as_hex(message);
|
||||
char *tx_as_hex = (char*)zchunk_data(tx_as_hex_chunk);
|
||||
std::string tx_as_hex_string(tx_as_hex, zchunk_size(tx_as_hex_chunk));
|
||||
if (!string_tools::parse_hexstr_to_binbuff(tx_as_hex_string, tx_blob))
|
||||
{
|
||||
LOG_PRINT_L0("[on_send_raw_tx]: Failed to parse tx from hexbuff: " << tx_as_hex_string);
|
||||
wap_proto_set_status(message, STATUS_INVALID_TX);
|
||||
return;
|
||||
}
|
||||
|
||||
cryptonote::cryptonote_connection_context fake_context = AUTO_VAL_INIT(fake_context);
|
||||
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
if (!core->handle_incoming_tx(tx_blob, tvc, false))
|
||||
{
|
||||
LOG_PRINT_L0("[on_send_raw_tx]: Failed to process tx");
|
||||
wap_proto_set_status(message, STATUS_INVALID_TX);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tvc.m_verifivation_failed)
|
||||
{
|
||||
LOG_PRINT_L0("[on_send_raw_tx]: tx verification failed");
|
||||
wap_proto_set_status(message, STATUS_TX_VERIFICATION_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tvc.m_should_be_relayed)
|
||||
{
|
||||
LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed");
|
||||
wap_proto_set_status(message, STATUS_TX_NOT_RELAYED);
|
||||
return;
|
||||
}
|
||||
|
||||
cryptonote::NOTIFY_NEW_TRANSACTIONS::request r;
|
||||
r.txs.push_back(tx_blob);
|
||||
core->get_protocol()->relay_transactions(r, fake_context);
|
||||
//TODO: make sure that tx has reached other nodes here, probably wait to receive reflections from other nodes
|
||||
wap_proto_set_status(message, STATUS_OK);
|
||||
}
|
||||
|
||||
void get_output_indexes(wap_proto_t *message)
|
||||
|
@ -186,5 +228,80 @@ namespace IPC
|
|||
wap_proto_set_o_indexes(message, &frame);
|
||||
wap_proto_set_status(message, STATUS_OK);
|
||||
}
|
||||
|
||||
void get_random_outs(wap_proto_t *message) {
|
||||
if (!check_core_busy()) {
|
||||
wap_proto_set_status(message, STATUS_CORE_BUSY);
|
||||
return;
|
||||
}
|
||||
// The core does its stuff with old style RPC objects.
|
||||
// So we construct and read from those objects.
|
||||
cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req;
|
||||
uint64_t outs_count = wap_proto_outs_count(message);
|
||||
req.outs_count = outs_count;
|
||||
zframe_t *amounts_frame = wap_proto_amounts(message);
|
||||
uint64_t amounts_count = zframe_size(amounts_frame) / sizeof(uint64_t);
|
||||
uint64_t *amounts = (uint64_t*)zframe_data(amounts_frame);
|
||||
for (unsigned int i = 0; i < amounts_count; i++) {
|
||||
req.amounts.push_back(amounts[i]);
|
||||
}
|
||||
cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response res;
|
||||
if (!core->get_random_outs_for_amounts(req, res))
|
||||
{
|
||||
wap_proto_set_status(message, STATUS_RANDOM_OUTS_FAILED);
|
||||
}
|
||||
|
||||
// We have to convert the result into a JSON string.
|
||||
rapidjson::Document result_json;
|
||||
result_json.SetObject();
|
||||
rapidjson::Document::AllocatorType &allocator = result_json.GetAllocator();
|
||||
rapidjson::Value outputs_json(rapidjson::kArrayType);
|
||||
|
||||
typedef cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount outs_for_amount;
|
||||
typedef cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
||||
for (unsigned int i = 0; i < res.outs.size(); i++) {
|
||||
rapidjson::Value output(rapidjson::kObjectType);
|
||||
outs_for_amount out = res.outs[i];
|
||||
rapidjson::Value output_entries(rapidjson::kArrayType);
|
||||
for (std::list<out_entry>::iterator it = out.outs.begin(); it != out.outs.end(); it++) {
|
||||
rapidjson::Value output_entry(rapidjson::kObjectType);
|
||||
out_entry entry = *it;
|
||||
output_entry.AddMember("global_amount_index", entry.global_amount_index, allocator);
|
||||
rapidjson::Value string_value(rapidjson::kStringType);
|
||||
string_value.SetString(entry.out_key.data, 32, allocator);
|
||||
output_entry.AddMember("out_key", string_value.Move(), allocator);
|
||||
output_entries.PushBack(output_entry, allocator);
|
||||
}
|
||||
output.AddMember("amount", out.amount, allocator);
|
||||
output.AddMember("outs", output_entries, allocator);
|
||||
outputs_json.PushBack(output, allocator);
|
||||
}
|
||||
result_json.AddMember("outputs", outputs_json, allocator);
|
||||
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
result_json.Accept(writer);
|
||||
std::string block_string = buffer.GetString();
|
||||
|
||||
std::cout << block_string << std::endl;
|
||||
|
||||
zframe_t *frame = zframe_new(block_string.c_str(), block_string.length());
|
||||
wap_proto_set_random_outputs(message, &frame);
|
||||
|
||||
std::stringstream ss;
|
||||
std::for_each(res.outs.begin(), res.outs.end(), [&](outs_for_amount& ofa)
|
||||
{
|
||||
ss << "[" << ofa.amount << "]:";
|
||||
CHECK_AND_ASSERT_MES(ofa.outs.size(), ;, "internal error: ofa.outs.size() is empty for amount " << ofa.amount);
|
||||
std::for_each(ofa.outs.begin(), ofa.outs.end(), [&](out_entry& oe)
|
||||
{
|
||||
ss << oe.global_amount_index << " ";
|
||||
});
|
||||
ss << ENDL;
|
||||
});
|
||||
std::string s = ss.str();
|
||||
LOG_PRINT_L2("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: " << ENDL << s);
|
||||
wap_proto_set_status(message, STATUS_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,12 +60,17 @@ namespace IPC
|
|||
const uint64_t STATUS_MINING_NOT_STARTED = 3;
|
||||
const uint64_t STATUS_WRONG_BLOCK_ID_LENGTH = 4;
|
||||
const uint64_t STATUS_INTERNAL_ERROR = 5;
|
||||
const uint64_t STATUS_INVALID_TX = 6;
|
||||
const uint64_t STATUS_TX_VERIFICATION_FAILED = 7;
|
||||
const uint64_t STATUS_TX_NOT_RELAYED = 8;
|
||||
const uint64_t STATUS_RANDOM_OUTS_FAILED = 9;
|
||||
namespace Daemon
|
||||
{
|
||||
void start_mining(wap_proto_t *message);
|
||||
void retrieve_blocks(wap_proto_t *message);
|
||||
void send_raw_transaction(wap_proto_t *message);
|
||||
void get_output_indexes(wap_proto_t *message);
|
||||
void get_random_outs(wap_proto_t *message);
|
||||
void init(cryptonote::core *p_core,
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > *p_p2p,
|
||||
bool p_testnet);
|
||||
|
|
|
@ -54,6 +54,12 @@ WAP_EXPORT zactor_t *
|
|||
WAP_EXPORT zsock_t *
|
||||
wap_client_msgpipe (wap_client_t *self);
|
||||
|
||||
// Return true if client is currently connected, else false. Note that the
|
||||
// client will automatically re-connect if the server dies and restarts after
|
||||
// a successful first connection.
|
||||
WAP_EXPORT bool
|
||||
wap_client_connected (wap_client_t *self);
|
||||
|
||||
// Connect to server endpoint, with specified timeout in msecs (zero means wait
|
||||
// forever). Constructor succeeds if connection is successful. The caller may
|
||||
// specify its address.
|
||||
|
@ -69,7 +75,7 @@ WAP_EXPORT int
|
|||
// Send a raw transaction to the daemon.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
WAP_EXPORT int
|
||||
wap_client_put (wap_client_t *self, zchunk_t **tx_data_p);
|
||||
wap_client_put (wap_client_t *self, zchunk_t **tx_as_hex_p);
|
||||
|
||||
// Request a set of blocks from the server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
@ -86,6 +92,11 @@ WAP_EXPORT int
|
|||
WAP_EXPORT int
|
||||
wap_client_output_indexes (wap_client_t *self, const char *tx_id);
|
||||
|
||||
// Ask for tx output indexes.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
WAP_EXPORT int
|
||||
wap_client_random_outs (wap_client_t *self, uint64_t outs_count, zframe_t **amounts_p);
|
||||
|
||||
// Send start command to server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
WAP_EXPORT int
|
||||
|
@ -124,6 +135,10 @@ WAP_EXPORT zchunk_t *
|
|||
WAP_EXPORT zframe_t *
|
||||
wap_client_o_indexes (wap_client_t *self);
|
||||
|
||||
// Return last received random_outputs
|
||||
WAP_EXPORT zframe_t *
|
||||
wap_client_random_outputs (wap_client_t *self);
|
||||
|
||||
// Self test of this class
|
||||
WAP_EXPORT void
|
||||
wap_client_test (bool verbose);
|
||||
|
|
|
@ -31,10 +31,11 @@ typedef enum {
|
|||
expect_start_ok_state = 8,
|
||||
expect_stop_ok_state = 9,
|
||||
expect_output_indexes_ok_state = 10,
|
||||
expect_close_ok_state = 11,
|
||||
defaults_state = 12,
|
||||
have_error_state = 13,
|
||||
reexpect_open_ok_state = 14
|
||||
expect_random_outs_ok_state = 11,
|
||||
expect_close_ok_state = 12,
|
||||
defaults_state = 13,
|
||||
have_error_state = 14,
|
||||
reexpect_open_ok_state = 15
|
||||
} state_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -50,19 +51,22 @@ typedef enum {
|
|||
start_event = 9,
|
||||
stop_event = 10,
|
||||
output_indexes_event = 11,
|
||||
destructor_event = 12,
|
||||
blocks_ok_event = 13,
|
||||
get_ok_event = 14,
|
||||
put_ok_event = 15,
|
||||
save_ok_event = 16,
|
||||
start_ok_event = 17,
|
||||
stop_ok_event = 18,
|
||||
output_indexes_ok_event = 19,
|
||||
close_ok_event = 20,
|
||||
ping_ok_event = 21,
|
||||
error_event = 22,
|
||||
command_invalid_event = 23,
|
||||
other_event = 24
|
||||
random_outs_event = 12,
|
||||
destructor_event = 13,
|
||||
blocks_ok_event = 14,
|
||||
get_ok_event = 15,
|
||||
put_ok_event = 16,
|
||||
save_ok_event = 17,
|
||||
start_ok_event = 18,
|
||||
stop_ok_event = 19,
|
||||
output_indexes_ok_event = 20,
|
||||
random_outs_ok_event = 21,
|
||||
close_ok_event = 22,
|
||||
ping_ok_event = 23,
|
||||
error_event = 24,
|
||||
exception_event = 25,
|
||||
command_invalid_event = 26,
|
||||
other_event = 27
|
||||
} event_t;
|
||||
|
||||
// Names for state machine logging and error reporting
|
||||
|
@ -79,6 +83,7 @@ s_state_name [] = {
|
|||
"expect start ok",
|
||||
"expect stop ok",
|
||||
"expect output indexes ok",
|
||||
"expect random outs ok",
|
||||
"expect close ok",
|
||||
"defaults",
|
||||
"have error",
|
||||
|
@ -99,6 +104,7 @@ s_event_name [] = {
|
|||
"START",
|
||||
"STOP",
|
||||
"OUTPUT_INDEXES",
|
||||
"RANDOM_OUTS",
|
||||
"destructor",
|
||||
"BLOCKS_OK",
|
||||
"GET_OK",
|
||||
|
@ -107,9 +113,11 @@ s_event_name [] = {
|
|||
"START_OK",
|
||||
"STOP_OK",
|
||||
"OUTPUT_INDEXES_OK",
|
||||
"RANDOM_OUTS_OK",
|
||||
"CLOSE_OK",
|
||||
"PING_OK",
|
||||
"ERROR",
|
||||
"exception",
|
||||
"command_invalid",
|
||||
"other"
|
||||
};
|
||||
|
@ -127,8 +135,10 @@ struct _client_args_t {
|
|||
char *identity;
|
||||
zlist_t *block_ids;
|
||||
uint64_t start_height;
|
||||
zchunk_t *tx_data;
|
||||
zchunk_t *tx_as_hex;
|
||||
char *tx_id;
|
||||
uint64_t outs_count;
|
||||
zframe_t *amounts;
|
||||
char *address;
|
||||
uint64_t thread_count;
|
||||
};
|
||||
|
@ -141,6 +151,7 @@ typedef struct {
|
|||
zloop_t *loop; // Listen to pipe and dealer
|
||||
wap_proto_t *message; // Message received or sent
|
||||
client_args_t args; // Method arguments structure
|
||||
bool connected; // True if client is connected
|
||||
bool terminated; // True if client is shutdown
|
||||
bool fsm_stopped; // "terminate" action called
|
||||
size_t timeout; // inactivity timeout, msecs
|
||||
|
@ -178,7 +189,7 @@ static void
|
|||
static void
|
||||
signal_success (client_t *self);
|
||||
static void
|
||||
use_heartbeat_timer (client_t *self);
|
||||
client_is_connected (client_t *self);
|
||||
static void
|
||||
signal_server_not_present (client_t *self);
|
||||
static void
|
||||
|
@ -193,6 +204,10 @@ static void
|
|||
prepare_start_command (client_t *self);
|
||||
static void
|
||||
prepare_get_output_indexes_command (client_t *self);
|
||||
static void
|
||||
prepare_get_random_outs_command (client_t *self);
|
||||
static void
|
||||
check_if_connection_is_dead (client_t *self);
|
||||
static void
|
||||
signal_have_blocks_ok (client_t *self);
|
||||
static void
|
||||
|
@ -207,6 +222,8 @@ static void
|
|||
signal_have_stop_ok (client_t *self);
|
||||
static void
|
||||
signal_have_output_indexes_ok (client_t *self);
|
||||
static void
|
||||
signal_have_random_outs_ok (client_t *self);
|
||||
static void
|
||||
signal_failure (client_t *self);
|
||||
static void
|
||||
|
@ -263,8 +280,9 @@ s_client_destroy (s_client_t **self_p)
|
|||
zstr_free (&self->args.endpoint);
|
||||
zstr_free (&self->args.identity);
|
||||
zlist_destroy (&self->args.block_ids);
|
||||
zchunk_destroy (&self->args.tx_data);
|
||||
zchunk_destroy (&self->args.tx_as_hex);
|
||||
zstr_free (&self->args.tx_id);
|
||||
zframe_destroy (&self->args.amounts);
|
||||
zstr_free (&self->args.address);
|
||||
client_terminate (&self->client);
|
||||
wap_proto_destroy (&self->message);
|
||||
|
@ -322,9 +340,11 @@ engine_set_wakeup_event (client_t *client, size_t delay, event_t event)
|
|||
}
|
||||
}
|
||||
|
||||
// Set timeout for next protocol read. By default, will wait forever
|
||||
// or until the process is interrupted. The timeout is in milliseconds.
|
||||
// The state machine must handle the "expired" event.
|
||||
// Set heartbeat timeout. By default, the timeout is zero, meaning
|
||||
// infinite. Setting a non-zero timeout causes the state machine to
|
||||
// receive an "expired" event if is no incoming traffic for that many
|
||||
// milliseconds. This cycles over and over until/unless the code sets
|
||||
// a zero timeout. The state machine must handle the "expired" event.
|
||||
|
||||
static void
|
||||
engine_set_timeout (client_t *client, size_t timeout)
|
||||
|
@ -332,6 +352,10 @@ engine_set_timeout (client_t *client, size_t timeout)
|
|||
if (client) {
|
||||
s_client_t *self = (s_client_t *) client;
|
||||
self->timeout = timeout;
|
||||
if (self->expiry_timer) {
|
||||
zloop_timer_end (self->loop, self->expiry_timer);
|
||||
self->expiry_timer = 0;
|
||||
}
|
||||
if (self->timeout)
|
||||
self->expiry_timer = zloop_timer (
|
||||
self->loop, self->timeout, 1, s_client_handle_timeout, self);
|
||||
|
@ -356,6 +380,18 @@ engine_handle_socket (client_t *client, zsock_t *sock, zloop_reader_fn handler)
|
|||
}
|
||||
}
|
||||
|
||||
// Set connected to true/false. The client must call this if it wants
|
||||
// to provide the API with the connected status.
|
||||
|
||||
static void
|
||||
engine_set_connected (client_t *client, bool connected)
|
||||
{
|
||||
if (client) {
|
||||
s_client_t *self = (s_client_t *) client;
|
||||
self->connected = connected;
|
||||
}
|
||||
}
|
||||
|
||||
// Pedantic compilers don't like unused functions, so we call the whole
|
||||
// API, passing null references. It's nasty and horrid and sufficient.
|
||||
|
||||
|
@ -400,6 +436,12 @@ s_protocol_event (s_client_t *self, wap_proto_t *message)
|
|||
case WAP_PROTO_OUTPUT_INDEXES_OK:
|
||||
return output_indexes_ok_event;
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
return random_outs_event;
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
return random_outs_ok_event;
|
||||
break;
|
||||
case WAP_PROTO_GET:
|
||||
return get_event;
|
||||
break;
|
||||
|
@ -526,10 +568,10 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
signal_success (&self->client);
|
||||
}
|
||||
if (!self->exception) {
|
||||
// use heartbeat timer
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ use heartbeat timer");
|
||||
use_heartbeat_timer (&self->client);
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
if (!self->exception)
|
||||
self->state = connected_state;
|
||||
|
@ -551,9 +593,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -566,6 +611,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -695,6 +746,24 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
self->state = expect_output_indexes_ok_state;
|
||||
}
|
||||
else
|
||||
if (self->event == random_outs_event) {
|
||||
if (!self->exception) {
|
||||
// prepare get random outs command
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ prepare get random outs command");
|
||||
prepare_get_random_outs_command (&self->client);
|
||||
}
|
||||
if (!self->exception) {
|
||||
// send RANDOM_OUTS
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ send RANDOM_OUTS");
|
||||
wap_proto_set_id (self->message, WAP_PROTO_RANDOM_OUTS);
|
||||
wap_proto_send (self->message, self->dealer);
|
||||
}
|
||||
if (!self->exception)
|
||||
self->state = expect_random_outs_ok_state;
|
||||
}
|
||||
else
|
||||
if (self->event == destructor_event) {
|
||||
if (!self->exception) {
|
||||
// send CLOSE
|
||||
|
@ -708,6 +777,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == expired_event) {
|
||||
if (!self->exception) {
|
||||
// check if connection is dead
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ check if connection is dead");
|
||||
check_if_connection_is_dead (&self->client);
|
||||
}
|
||||
if (!self->exception) {
|
||||
// send PING
|
||||
if (wap_client_verbose)
|
||||
|
@ -718,9 +793,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -733,6 +811,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -754,9 +838,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -769,6 +856,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -790,9 +883,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -805,6 +901,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -826,9 +928,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -841,6 +946,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -862,9 +973,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -877,6 +991,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -898,9 +1018,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -913,6 +1036,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -934,9 +1063,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -949,6 +1081,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -970,9 +1108,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -985,6 +1126,57 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ *");
|
||||
}
|
||||
break;
|
||||
|
||||
case expect_random_outs_ok_state:
|
||||
if (self->event == random_outs_ok_event) {
|
||||
if (!self->exception) {
|
||||
// signal have random outs ok
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ signal have random outs ok");
|
||||
signal_have_random_outs_ok (&self->client);
|
||||
}
|
||||
if (!self->exception)
|
||||
self->state = connected_state;
|
||||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
if (!self->exception) {
|
||||
// check status code
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ check status code");
|
||||
check_status_code (&self->client);
|
||||
}
|
||||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -1025,9 +1217,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -1040,6 +1235,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -1050,9 +1251,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
|
||||
case defaults_state:
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -1065,6 +1269,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -1117,19 +1327,22 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
case reexpect_open_ok_state:
|
||||
if (self->event == open_ok_event) {
|
||||
if (!self->exception) {
|
||||
// use heartbeat timer
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ use heartbeat timer");
|
||||
use_heartbeat_timer (&self->client);
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
if (!self->exception)
|
||||
self->state = connected_state;
|
||||
}
|
||||
else
|
||||
if (self->event == ping_ok_event) {
|
||||
// No action - just logging
|
||||
if (!self->exception) {
|
||||
// client is connected
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ ping_ok");
|
||||
zsys_debug ("wap_client: $ client is connected");
|
||||
client_is_connected (&self->client);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == error_event) {
|
||||
|
@ -1142,6 +1355,12 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
if (!self->exception)
|
||||
self->state = have_error_state;
|
||||
}
|
||||
else
|
||||
if (self->event == exception_event) {
|
||||
// No action - just logging
|
||||
if (wap_client_verbose)
|
||||
zsys_debug ("wap_client: $ exception");
|
||||
}
|
||||
else {
|
||||
// Handle unexpected protocol events
|
||||
// No action - just logging
|
||||
|
@ -1169,7 +1388,13 @@ s_client_handle_timeout (zloop_t *loop, int timer_id, void *argument)
|
|||
{
|
||||
s_client_t *self = (s_client_t *) argument;
|
||||
s_client_execute (self, expired_event);
|
||||
return self->terminated? -1: 0;
|
||||
if (self->terminated)
|
||||
return -1;
|
||||
|
||||
if (self->timeout > 0)
|
||||
self->expiry_timer = zloop_timer (
|
||||
loop, self->timeout, 1, s_client_handle_timeout, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// zloop callback when client wakeup timer expires
|
||||
|
@ -1198,6 +1423,9 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
|||
if (streq (method, "$TERM"))
|
||||
self->terminated = true; // Shutdown the engine
|
||||
else
|
||||
if (streq (method, "$CONNECTED"))
|
||||
zsock_send (self->cmdpipe, "i", self->connected);
|
||||
else
|
||||
if (streq (method, "CONNECT")) {
|
||||
zstr_free (&self->args.endpoint);
|
||||
zstr_free (&self->args.identity);
|
||||
|
@ -1216,8 +1444,8 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
|||
}
|
||||
else
|
||||
if (streq (method, "PUT")) {
|
||||
zchunk_destroy (&self->args.tx_data);
|
||||
zsock_recv (self->cmdpipe, "p", &self->args.tx_data);
|
||||
zchunk_destroy (&self->args.tx_as_hex);
|
||||
zsock_recv (self->cmdpipe, "p", &self->args.tx_as_hex);
|
||||
s_client_execute (self, put_event);
|
||||
}
|
||||
else
|
||||
|
@ -1237,6 +1465,12 @@ s_client_handle_cmdpipe (zloop_t *loop, zsock_t *reader, void *argument)
|
|||
s_client_execute (self, output_indexes_event);
|
||||
}
|
||||
else
|
||||
if (streq (method, "RANDOM OUTS")) {
|
||||
zframe_destroy (&self->args.amounts);
|
||||
zsock_recv (self->cmdpipe, "8p", &self->args.outs_count, &self->args.amounts);
|
||||
s_client_execute (self, random_outs_event);
|
||||
}
|
||||
else
|
||||
if (streq (method, "START")) {
|
||||
zstr_free (&self->args.address);
|
||||
zsock_recv (self->cmdpipe, "s8", &self->args.address, &self->args.thread_count);
|
||||
|
@ -1357,6 +1591,7 @@ wap_client (zsock_t *cmdpipe, void *msgpipe)
|
|||
struct _wap_client_t {
|
||||
zactor_t *actor; // Client actor
|
||||
zsock_t *msgpipe; // Pipe for async message flow
|
||||
bool connected; // Client currently connected or not
|
||||
int status; // Returned by actor reply
|
||||
char *reason; // Returned by actor reply
|
||||
uint64_t start_height; // Returned by actor reply
|
||||
|
@ -1364,6 +1599,7 @@ struct _wap_client_t {
|
|||
zmsg_t *block_data; // Returned by actor reply
|
||||
zchunk_t *tx_data; // Returned by actor reply
|
||||
zframe_t *o_indexes; // Returned by actor reply
|
||||
zframe_t *random_outputs; // Returned by actor reply
|
||||
};
|
||||
|
||||
|
||||
|
@ -1415,6 +1651,7 @@ wap_client_destroy (wap_client_t **self_p)
|
|||
zmsg_destroy (&self->block_data);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
zframe_destroy (&self->o_indexes);
|
||||
zframe_destroy (&self->random_outputs);
|
||||
free (self);
|
||||
*self_p = NULL;
|
||||
}
|
||||
|
@ -1448,6 +1685,22 @@ wap_client_msgpipe (wap_client_t *self)
|
|||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Return true if client is currently connected, else false. Note that the
|
||||
// client will automatically re-connect if the server dies and restarts after
|
||||
// a successful first connection.
|
||||
|
||||
bool
|
||||
wap_client_connected (wap_client_t *self)
|
||||
{
|
||||
assert (self);
|
||||
bool connected;
|
||||
zsock_send (self->actor, "s", "$CONNECTED");
|
||||
zsock_recv (self->actor, "i", &connected);
|
||||
return connected;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Get valid reply from actor; discard replies that does not match. Current
|
||||
// implementation filters on first frame of message. Blocks until a valid
|
||||
|
@ -1500,6 +1753,11 @@ s_accept_reply (wap_client_t *self, ...)
|
|||
zsock_recv (self->actor, "8p", &self->status, &self->o_indexes);
|
||||
}
|
||||
else
|
||||
if (streq (reply, "RANDOM OUTS OK")) {
|
||||
zframe_destroy (&self->random_outputs);
|
||||
zsock_recv (self->actor, "8p", &self->status, &self->random_outputs);
|
||||
}
|
||||
else
|
||||
if (streq (reply, "START OK")) {
|
||||
zsock_recv (self->actor, "8", &self->status);
|
||||
}
|
||||
|
@ -1580,12 +1838,12 @@ wap_client_blocks (wap_client_t *self, zlist_t **block_ids_p, uint64_t start_hei
|
|||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
||||
int
|
||||
wap_client_put (wap_client_t *self, zchunk_t **tx_data_p)
|
||||
wap_client_put (wap_client_t *self, zchunk_t **tx_as_hex_p)
|
||||
{
|
||||
assert (self);
|
||||
|
||||
zsock_send (self->actor, "sp", "PUT", *tx_data_p);
|
||||
*tx_data_p = NULL; // Take ownership of tx_data
|
||||
zsock_send (self->actor, "sp", "PUT", *tx_as_hex_p);
|
||||
*tx_as_hex_p = NULL; // Take ownership of tx_as_hex
|
||||
if (s_accept_reply (self, "PUT OK", "FAILURE", NULL))
|
||||
return -1; // Interrupted or timed-out
|
||||
return self->status;
|
||||
|
@ -1640,6 +1898,23 @@ wap_client_output_indexes (wap_client_t *self, const char *tx_id)
|
|||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Ask for tx output indexes.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
||||
int
|
||||
wap_client_random_outs (wap_client_t *self, uint64_t outs_count, zframe_t **amounts_p)
|
||||
{
|
||||
assert (self);
|
||||
|
||||
zsock_send (self->actor, "s8p", "RANDOM OUTS", outs_count, *amounts_p);
|
||||
*amounts_p = NULL; // Take ownership of amounts
|
||||
if (s_accept_reply (self, "RANDOM OUTS OK", "FAILURE", NULL))
|
||||
return -1; // Interrupted or timed-out
|
||||
return self->status;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Send start command to server.
|
||||
// Returns >= 0 if successful, -1 if interrupted.
|
||||
|
@ -1747,3 +2022,14 @@ wap_client_o_indexes (wap_client_t *self)
|
|||
assert (self);
|
||||
return self->o_indexes;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Return last received random_outputs
|
||||
|
||||
zframe_t *
|
||||
wap_client_random_outputs (wap_client_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->random_outputs;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* =========================================================================
|
||||
wap_proto - Wallet Access Protocol
|
||||
|
||||
|
||||
Codec header for wap_proto.
|
||||
|
||||
** WARNING *************************************************************
|
||||
|
@ -43,7 +43,7 @@ BLOCKS-OK, or ERROR if the request is invalid.
|
|||
|
||||
PUT - Wallet sends a raw transaction to the daemon. Daemon replies with
|
||||
PUT-OK, or ERROR.
|
||||
tx_data chunk Transaction data
|
||||
tx_as_hex chunk Transaction as hex
|
||||
|
||||
PUT_OK - Daemon confirms that it accepted the raw transaction.
|
||||
status number 8 Transaction ID
|
||||
|
@ -55,6 +55,14 @@ PUT-OK, or ERROR.
|
|||
status number 8 Status
|
||||
o_indexes frame Output Indexes
|
||||
|
||||
RANDOM_OUTS - Get random outputs for amounts.
|
||||
outs_count number 8 Outs count
|
||||
amounts frame Amounts
|
||||
|
||||
RANDOM_OUTS_OK - Daemon returns random outputs for amounts.
|
||||
status number 8 Status
|
||||
random_outputs frame Outputs
|
||||
|
||||
GET - Wallet requests transaction data from the daemon. Daemon replies
|
||||
with GET-OK, or ERROR.
|
||||
tx_id string Transaction ID
|
||||
|
@ -113,19 +121,21 @@ Daemon will reply with CLOSE-OK or ERROR.
|
|||
#define WAP_PROTO_PUT_OK 6
|
||||
#define WAP_PROTO_OUTPUT_INDEXES 7
|
||||
#define WAP_PROTO_OUTPUT_INDEXES_OK 8
|
||||
#define WAP_PROTO_GET 9
|
||||
#define WAP_PROTO_GET_OK 10
|
||||
#define WAP_PROTO_SAVE 11
|
||||
#define WAP_PROTO_SAVE_OK 12
|
||||
#define WAP_PROTO_START 13
|
||||
#define WAP_PROTO_START_OK 14
|
||||
#define WAP_PROTO_STOP 15
|
||||
#define WAP_PROTO_STOP_OK 16
|
||||
#define WAP_PROTO_CLOSE 17
|
||||
#define WAP_PROTO_CLOSE_OK 18
|
||||
#define WAP_PROTO_PING 19
|
||||
#define WAP_PROTO_PING_OK 20
|
||||
#define WAP_PROTO_ERROR 21
|
||||
#define WAP_PROTO_RANDOM_OUTS 9
|
||||
#define WAP_PROTO_RANDOM_OUTS_OK 10
|
||||
#define WAP_PROTO_GET 11
|
||||
#define WAP_PROTO_GET_OK 12
|
||||
#define WAP_PROTO_SAVE 13
|
||||
#define WAP_PROTO_SAVE_OK 14
|
||||
#define WAP_PROTO_START 15
|
||||
#define WAP_PROTO_START_OK 16
|
||||
#define WAP_PROTO_STOP 17
|
||||
#define WAP_PROTO_STOP_OK 18
|
||||
#define WAP_PROTO_CLOSE 19
|
||||
#define WAP_PROTO_CLOSE_OK 20
|
||||
#define WAP_PROTO_PING 21
|
||||
#define WAP_PROTO_PING_OK 22
|
||||
#define WAP_PROTO_ERROR 23
|
||||
|
||||
#include <czmq.h>
|
||||
|
||||
|
@ -156,7 +166,7 @@ int
|
|||
// Send the wap_proto to the output socket, does not destroy it
|
||||
int
|
||||
wap_proto_send (wap_proto_t *self, zsock_t *output);
|
||||
|
||||
|
||||
// Print contents of message to stdout
|
||||
void
|
||||
wap_proto_print (wap_proto_t *self);
|
||||
|
@ -219,15 +229,15 @@ zmsg_t *
|
|||
void
|
||||
wap_proto_set_block_data (wap_proto_t *self, zmsg_t **msg_p);
|
||||
|
||||
// Get a copy of the tx_data field
|
||||
// Get a copy of the tx_as_hex field
|
||||
zchunk_t *
|
||||
wap_proto_tx_data (wap_proto_t *self);
|
||||
// Get the tx_data field and transfer ownership to caller
|
||||
wap_proto_tx_as_hex (wap_proto_t *self);
|
||||
// Get the tx_as_hex field and transfer ownership to caller
|
||||
zchunk_t *
|
||||
wap_proto_get_tx_data (wap_proto_t *self);
|
||||
// Set the tx_data field, transferring ownership from caller
|
||||
wap_proto_get_tx_as_hex (wap_proto_t *self);
|
||||
// Set the tx_as_hex field, transferring ownership from caller
|
||||
void
|
||||
wap_proto_set_tx_data (wap_proto_t *self, zchunk_t **chunk_p);
|
||||
wap_proto_set_tx_as_hex (wap_proto_t *self, zchunk_t **chunk_p);
|
||||
|
||||
// Get/set the tx_id field
|
||||
const char *
|
||||
|
@ -245,6 +255,42 @@ zframe_t *
|
|||
void
|
||||
wap_proto_set_o_indexes (wap_proto_t *self, zframe_t **frame_p);
|
||||
|
||||
// Get/set the outs_count field
|
||||
uint64_t
|
||||
wap_proto_outs_count (wap_proto_t *self);
|
||||
void
|
||||
wap_proto_set_outs_count (wap_proto_t *self, uint64_t outs_count);
|
||||
|
||||
// Get a copy of the amounts field
|
||||
zframe_t *
|
||||
wap_proto_amounts (wap_proto_t *self);
|
||||
// Get the amounts field and transfer ownership to caller
|
||||
zframe_t *
|
||||
wap_proto_get_amounts (wap_proto_t *self);
|
||||
// Set the amounts field, transferring ownership from caller
|
||||
void
|
||||
wap_proto_set_amounts (wap_proto_t *self, zframe_t **frame_p);
|
||||
|
||||
// Get a copy of the random_outputs field
|
||||
zframe_t *
|
||||
wap_proto_random_outputs (wap_proto_t *self);
|
||||
// Get the random_outputs field and transfer ownership to caller
|
||||
zframe_t *
|
||||
wap_proto_get_random_outputs (wap_proto_t *self);
|
||||
// Set the random_outputs field, transferring ownership from caller
|
||||
void
|
||||
wap_proto_set_random_outputs (wap_proto_t *self, zframe_t **frame_p);
|
||||
|
||||
// Get a copy of the tx_data field
|
||||
zchunk_t *
|
||||
wap_proto_tx_data (wap_proto_t *self);
|
||||
// Get the tx_data field and transfer ownership to caller
|
||||
zchunk_t *
|
||||
wap_proto_get_tx_data (wap_proto_t *self);
|
||||
// Set the tx_data field, transferring ownership from caller
|
||||
void
|
||||
wap_proto_set_tx_data (wap_proto_t *self, zchunk_t **chunk_p);
|
||||
|
||||
// Get/set the address field
|
||||
const char *
|
||||
wap_proto_address (wap_proto_t *self);
|
||||
|
|
|
@ -38,11 +38,12 @@ typedef enum {
|
|||
start_event = 7,
|
||||
stop_event = 8,
|
||||
output_indexes_event = 9,
|
||||
close_event = 10,
|
||||
ping_event = 11,
|
||||
expired_event = 12,
|
||||
exception_event = 13,
|
||||
settled_event = 14
|
||||
random_outs_event = 10,
|
||||
close_event = 11,
|
||||
ping_event = 12,
|
||||
expired_event = 13,
|
||||
exception_event = 14,
|
||||
settled_event = 15
|
||||
} event_t;
|
||||
|
||||
// Names for state machine logging and error reporting
|
||||
|
@ -67,6 +68,7 @@ s_event_name [] = {
|
|||
"START",
|
||||
"STOP",
|
||||
"OUTPUT_INDEXES",
|
||||
"RANDOM_OUTS",
|
||||
"CLOSE",
|
||||
"PING",
|
||||
"expired",
|
||||
|
@ -148,6 +150,8 @@ static void
|
|||
stop_mining_process (client_t *self);
|
||||
static void
|
||||
output_indexes (client_t *self);
|
||||
static void
|
||||
random_outs (client_t *self);
|
||||
static void
|
||||
deregister_wallet (client_t *self);
|
||||
static void
|
||||
|
@ -344,6 +348,9 @@ s_protocol_event (wap_proto_t *message)
|
|||
case WAP_PROTO_OUTPUT_INDEXES:
|
||||
return output_indexes_event;
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
return random_outs_event;
|
||||
break;
|
||||
case WAP_PROTO_GET:
|
||||
return get_event;
|
||||
break;
|
||||
|
@ -691,6 +698,24 @@ s_client_execute (s_client_t *self, event_t event)
|
|||
}
|
||||
}
|
||||
else
|
||||
if (self->event == random_outs_event) {
|
||||
if (!self->exception) {
|
||||
// random outs
|
||||
if (self->server->verbose)
|
||||
zsys_debug ("%s: $ random outs", self->log_prefix);
|
||||
random_outs (&self->client);
|
||||
}
|
||||
if (!self->exception) {
|
||||
// send RANDOM_OUTS_OK
|
||||
if (self->server->verbose)
|
||||
zsys_debug ("%s: $ send RANDOM_OUTS_OK",
|
||||
self->log_prefix);
|
||||
wap_proto_set_id (self->server->message, WAP_PROTO_RANDOM_OUTS_OK);
|
||||
wap_proto_set_routing_id (self->server->message, self->routing_id);
|
||||
wap_proto_send (self->server->message, self->server->router);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (self->event == close_event) {
|
||||
if (!self->exception) {
|
||||
// send CLOSE_OK
|
||||
|
@ -1092,6 +1117,7 @@ s_server_config_service (s_server_t *self)
|
|||
if (zsock_bind (self->router, "%s", endpoint) == -1)
|
||||
zsys_warning ("could not bind to %s (%s)", endpoint, zmq_strerror (zmq_errno ()));
|
||||
}
|
||||
#if (ZMQ_VERSION_MAJOR >= 4)
|
||||
else
|
||||
if (streq (zconfig_name (section), "security")) {
|
||||
char *mechanism = zconfig_resolve (section, "mechanism", "null");
|
||||
|
@ -1109,6 +1135,7 @@ s_server_config_service (s_server_t *self)
|
|||
else
|
||||
zsys_warning ("mechanism=%s is not supported", mechanism);
|
||||
}
|
||||
#endif
|
||||
section = zconfig_next (section);
|
||||
}
|
||||
s_server_config_global (self);
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct {
|
|||
|
||||
// Own properties
|
||||
int heartbeat_timer; // Timeout for heartbeats to server
|
||||
int retries; // How many heartbeats we've tried
|
||||
} client_t;
|
||||
|
||||
// Include the generated client engine
|
||||
|
@ -97,6 +98,32 @@ use_connect_timeout (client_t *self)
|
|||
engine_set_timeout (self, self->args->timeout);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// client_is_connected
|
||||
//
|
||||
|
||||
static void
|
||||
client_is_connected (client_t *self)
|
||||
{
|
||||
self->retries = 0;
|
||||
engine_set_connected (self, true);
|
||||
engine_set_timeout (self, self->heartbeat_timer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// check_if_connection_is_dead
|
||||
//
|
||||
|
||||
static void
|
||||
check_if_connection_is_dead (client_t *self)
|
||||
{
|
||||
// We send at most 3 heartbeats before expiring the server
|
||||
if (++self->retries >= 3) {
|
||||
engine_set_timeout (self, 0);
|
||||
engine_set_connected (self, false);
|
||||
engine_set_exception (self, exception_event);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// use_heartbeat_timer
|
||||
|
@ -163,7 +190,7 @@ prepare_start_command (client_t *self)
|
|||
static void
|
||||
prepare_put_command (client_t *self)
|
||||
{
|
||||
wap_proto_set_tx_data (self->message, &self->args->tx_data);
|
||||
wap_proto_set_tx_as_hex (self->message, &self->args->tx_as_hex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,7 +201,7 @@ prepare_put_command (client_t *self)
|
|||
static void
|
||||
signal_have_put_ok (client_t *self)
|
||||
{
|
||||
zsock_send (self->cmdpipe, "s8s", "PUT OK", 0,
|
||||
zsock_send (self->cmdpipe, "s8s", "PUT OK", wap_proto_status(self->message),
|
||||
wap_proto_tx_id (self->message));
|
||||
}
|
||||
|
||||
|
@ -325,3 +352,25 @@ signal_server_not_present (client_t *self)
|
|||
zsock_send (self->cmdpipe, "sis", "FAILURE", -1, "Server is not reachable");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// prepare_get_random_outs_command
|
||||
//
|
||||
|
||||
static void
|
||||
prepare_get_random_outs_command (client_t *self)
|
||||
{
|
||||
wap_proto_set_amounts (self->message, &self->args->amounts);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// signal_have_random_outs_ok
|
||||
//
|
||||
|
||||
static void
|
||||
signal_have_random_outs_ok (client_t *self)
|
||||
{
|
||||
zsock_send (self->cmdpipe, "s8p", "RANDOM OUTS OK",
|
||||
wap_proto_status (self->message),
|
||||
wap_proto_get_random_outputs (self->message));
|
||||
}
|
||||
|
|
|
@ -34,29 +34,37 @@ struct _wap_proto_t {
|
|||
int id; // wap_proto message ID
|
||||
byte *needle; // Read/write pointer for serialization
|
||||
byte *ceiling; // Valid upper limit for read pointer
|
||||
/* Wallet identity */
|
||||
// Wallet identity
|
||||
char identity [256];
|
||||
/* */
|
||||
// block_ids
|
||||
zlist_t *block_ids;
|
||||
/* */
|
||||
// start_height
|
||||
uint64_t start_height;
|
||||
/* */
|
||||
// status
|
||||
uint64_t status;
|
||||
/* */
|
||||
// curr_height
|
||||
uint64_t curr_height;
|
||||
/* Frames of block data */
|
||||
// Frames of block data
|
||||
zmsg_t *block_data;
|
||||
/* Transaction data */
|
||||
zchunk_t *tx_data;
|
||||
/* Transaction ID */
|
||||
// Transaction as hex
|
||||
zchunk_t *tx_as_hex;
|
||||
// Transaction ID
|
||||
char tx_id [256];
|
||||
/* Output Indexes */
|
||||
// Output Indexes
|
||||
zframe_t *o_indexes;
|
||||
/* */
|
||||
// Outs count
|
||||
uint64_t outs_count;
|
||||
// Amounts
|
||||
zframe_t *amounts;
|
||||
// Outputs
|
||||
zframe_t *random_outputs;
|
||||
// Transaction data
|
||||
zchunk_t *tx_data;
|
||||
// address
|
||||
char address [256];
|
||||
/* */
|
||||
// thread_count
|
||||
uint64_t thread_count;
|
||||
/* Printable explanation */
|
||||
// Printable explanation
|
||||
char reason [256];
|
||||
};
|
||||
|
||||
|
@ -236,8 +244,11 @@ wap_proto_destroy (wap_proto_t **self_p)
|
|||
if (self->block_ids)
|
||||
zlist_destroy (&self->block_ids);
|
||||
zmsg_destroy (&self->block_data);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
zchunk_destroy (&self->tx_as_hex);
|
||||
zframe_destroy (&self->o_indexes);
|
||||
zframe_destroy (&self->amounts);
|
||||
zframe_destroy (&self->random_outputs);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
|
||||
// Free object itself
|
||||
free (self);
|
||||
|
@ -254,7 +265,7 @@ int
|
|||
wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
||||
{
|
||||
assert (input);
|
||||
|
||||
|
||||
if (zsock_type (input) == ZMQ_ROUTER) {
|
||||
zframe_destroy (&self->routing_id);
|
||||
self->routing_id = zframe_recv (input);
|
||||
|
@ -273,7 +284,7 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
|||
// Get and check protocol signature
|
||||
self->needle = (byte *) zmq_msg_data (&frame);
|
||||
self->ceiling = self->needle + zmq_msg_size (&frame);
|
||||
|
||||
|
||||
uint16_t signature;
|
||||
GET_NUMBER2 (signature);
|
||||
if (signature != (0xAAA0 | 0)) {
|
||||
|
@ -342,11 +353,11 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
|||
size_t chunk_size;
|
||||
GET_NUMBER4 (chunk_size);
|
||||
if (self->needle + chunk_size > (self->ceiling)) {
|
||||
zsys_warning ("wap_proto: tx_data is missing data");
|
||||
zsys_warning ("wap_proto: tx_as_hex is missing data");
|
||||
goto malformed;
|
||||
}
|
||||
zchunk_destroy (&self->tx_data);
|
||||
self->tx_data = zchunk_new (self->needle, chunk_size);
|
||||
zchunk_destroy (&self->tx_as_hex);
|
||||
self->tx_as_hex = zchunk_new (self->needle, chunk_size);
|
||||
self->needle += chunk_size;
|
||||
}
|
||||
break;
|
||||
|
@ -370,6 +381,28 @@ wap_proto_recv (wap_proto_t *self, zsock_t *input)
|
|||
self->o_indexes = zframe_recv (input);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
GET_NUMBER8 (self->outs_count);
|
||||
// Get next frame off socket
|
||||
if (!zsock_rcvmore (input)) {
|
||||
zsys_warning ("wap_proto: amounts is missing");
|
||||
goto malformed;
|
||||
}
|
||||
zframe_destroy (&self->amounts);
|
||||
self->amounts = zframe_recv (input);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
GET_NUMBER8 (self->status);
|
||||
// Get next frame off socket
|
||||
if (!zsock_rcvmore (input)) {
|
||||
zsys_warning ("wap_proto: random_outputs is missing");
|
||||
goto malformed;
|
||||
}
|
||||
zframe_destroy (&self->random_outputs);
|
||||
self->random_outputs = zframe_recv (input);
|
||||
break;
|
||||
|
||||
case WAP_PROTO_GET:
|
||||
GET_STRING (self->tx_id);
|
||||
break;
|
||||
|
@ -480,8 +513,8 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
break;
|
||||
case WAP_PROTO_PUT:
|
||||
frame_size += 4; // Size is 4 octets
|
||||
if (self->tx_data)
|
||||
frame_size += zchunk_size (self->tx_data);
|
||||
if (self->tx_as_hex)
|
||||
frame_size += zchunk_size (self->tx_as_hex);
|
||||
break;
|
||||
case WAP_PROTO_PUT_OK:
|
||||
frame_size += 8; // status
|
||||
|
@ -492,6 +525,12 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
case WAP_PROTO_OUTPUT_INDEXES_OK:
|
||||
frame_size += 8; // status
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
frame_size += 8; // outs_count
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
frame_size += 8; // status
|
||||
break;
|
||||
case WAP_PROTO_GET:
|
||||
frame_size += 1 + strlen (self->tx_id);
|
||||
break;
|
||||
|
@ -520,7 +559,7 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
PUT_NUMBER1 (self->id);
|
||||
bool send_block_data = false;
|
||||
size_t nbr_frames = 1; // Total number of frames to send
|
||||
|
||||
|
||||
switch (self->id) {
|
||||
case WAP_PROTO_OPEN:
|
||||
PUT_STRING ("WAP");
|
||||
|
@ -551,12 +590,12 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
break;
|
||||
|
||||
case WAP_PROTO_PUT:
|
||||
if (self->tx_data) {
|
||||
PUT_NUMBER4 (zchunk_size (self->tx_data));
|
||||
if (self->tx_as_hex) {
|
||||
PUT_NUMBER4 (zchunk_size (self->tx_as_hex));
|
||||
memcpy (self->needle,
|
||||
zchunk_data (self->tx_data),
|
||||
zchunk_size (self->tx_data));
|
||||
self->needle += zchunk_size (self->tx_data);
|
||||
zchunk_data (self->tx_as_hex),
|
||||
zchunk_size (self->tx_as_hex));
|
||||
self->needle += zchunk_size (self->tx_as_hex);
|
||||
}
|
||||
else
|
||||
PUT_NUMBER4 (0); // Empty chunk
|
||||
|
@ -575,6 +614,16 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
nbr_frames++;
|
||||
break;
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
PUT_NUMBER8 (self->outs_count);
|
||||
nbr_frames++;
|
||||
break;
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
PUT_NUMBER8 (self->status);
|
||||
nbr_frames++;
|
||||
break;
|
||||
|
||||
case WAP_PROTO_GET:
|
||||
PUT_STRING (self->tx_id);
|
||||
break;
|
||||
|
@ -608,7 +657,7 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
}
|
||||
// Now send the data frame
|
||||
zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);
|
||||
|
||||
|
||||
// Now send any frame fields, in order
|
||||
if (self->id == WAP_PROTO_OUTPUT_INDEXES_OK) {
|
||||
// If o_indexes isn't set, send an empty frame
|
||||
|
@ -617,6 +666,22 @@ wap_proto_send (wap_proto_t *self, zsock_t *output)
|
|||
else
|
||||
zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0));
|
||||
}
|
||||
// Now send any frame fields, in order
|
||||
if (self->id == WAP_PROTO_RANDOM_OUTS) {
|
||||
// If amounts isn't set, send an empty frame
|
||||
if (self->amounts)
|
||||
zframe_send (&self->amounts, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0));
|
||||
else
|
||||
zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0));
|
||||
}
|
||||
// Now send any frame fields, in order
|
||||
if (self->id == WAP_PROTO_RANDOM_OUTS_OK) {
|
||||
// If random_outputs isn't set, send an empty frame
|
||||
if (self->random_outputs)
|
||||
zframe_send (&self->random_outputs, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0));
|
||||
else
|
||||
zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0));
|
||||
}
|
||||
// Now send the block_data if necessary
|
||||
if (send_block_data) {
|
||||
if (self->block_data) {
|
||||
|
@ -650,11 +715,11 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug (" identity=");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_OPEN_OK:
|
||||
zsys_debug ("WAP_PROTO_OPEN_OK:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_BLOCKS:
|
||||
zsys_debug ("WAP_PROTO_BLOCKS:");
|
||||
zsys_debug (" block_ids=");
|
||||
|
@ -667,7 +732,7 @@ wap_proto_print (wap_proto_t *self)
|
|||
}
|
||||
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);
|
||||
|
@ -679,17 +744,17 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug ("(NULL)");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_PUT:
|
||||
zsys_debug ("WAP_PROTO_PUT:");
|
||||
zsys_debug (" tx_data=[ ... ]");
|
||||
zsys_debug (" tx_as_hex=[ ... ]");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_PUT_OK:
|
||||
zsys_debug ("WAP_PROTO_PUT_OK:");
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_OUTPUT_INDEXES:
|
||||
zsys_debug ("WAP_PROTO_OUTPUT_INDEXES:");
|
||||
if (self->tx_id)
|
||||
|
@ -697,7 +762,7 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug (" tx_id=");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_OUTPUT_INDEXES_OK:
|
||||
zsys_debug ("WAP_PROTO_OUTPUT_INDEXES_OK:");
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
|
@ -707,7 +772,27 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug ("(NULL)");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
zsys_debug ("WAP_PROTO_RANDOM_OUTS:");
|
||||
zsys_debug (" outs_count=%ld", (long) self->outs_count);
|
||||
zsys_debug (" amounts=");
|
||||
if (self->amounts)
|
||||
zframe_print (self->amounts, NULL);
|
||||
else
|
||||
zsys_debug ("(NULL)");
|
||||
break;
|
||||
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
zsys_debug ("WAP_PROTO_RANDOM_OUTS_OK:");
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
zsys_debug (" random_outputs=");
|
||||
if (self->random_outputs)
|
||||
zframe_print (self->random_outputs, NULL);
|
||||
else
|
||||
zsys_debug ("(NULL)");
|
||||
break;
|
||||
|
||||
case WAP_PROTO_GET:
|
||||
zsys_debug ("WAP_PROTO_GET:");
|
||||
if (self->tx_id)
|
||||
|
@ -715,20 +800,20 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug (" tx_id=");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_GET_OK:
|
||||
zsys_debug ("WAP_PROTO_GET_OK:");
|
||||
zsys_debug (" tx_data=[ ... ]");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_SAVE:
|
||||
zsys_debug ("WAP_PROTO_SAVE:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_SAVE_OK:
|
||||
zsys_debug ("WAP_PROTO_SAVE_OK:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_START:
|
||||
zsys_debug ("WAP_PROTO_START:");
|
||||
if (self->address)
|
||||
|
@ -737,36 +822,36 @@ wap_proto_print (wap_proto_t *self)
|
|||
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 (" status=%ld", (long) self->status);
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_STOP:
|
||||
zsys_debug ("WAP_PROTO_STOP:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_STOP_OK:
|
||||
zsys_debug ("WAP_PROTO_STOP_OK:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_CLOSE:
|
||||
zsys_debug ("WAP_PROTO_CLOSE:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_CLOSE_OK:
|
||||
zsys_debug ("WAP_PROTO_CLOSE_OK:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_PING:
|
||||
zsys_debug ("WAP_PROTO_PING:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_PING_OK:
|
||||
zsys_debug ("WAP_PROTO_PING_OK:");
|
||||
break;
|
||||
|
||||
|
||||
case WAP_PROTO_ERROR:
|
||||
zsys_debug ("WAP_PROTO_ERROR:");
|
||||
zsys_debug (" status=%ld", (long) self->status);
|
||||
|
@ -775,7 +860,7 @@ wap_proto_print (wap_proto_t *self)
|
|||
else
|
||||
zsys_debug (" reason=");
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,6 +932,12 @@ wap_proto_command (wap_proto_t *self)
|
|||
case WAP_PROTO_OUTPUT_INDEXES_OK:
|
||||
return ("OUTPUT_INDEXES_OK");
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS:
|
||||
return ("RANDOM_OUTS");
|
||||
break;
|
||||
case WAP_PROTO_RANDOM_OUTS_OK:
|
||||
return ("RANDOM_OUTS_OK");
|
||||
break;
|
||||
case WAP_PROTO_GET:
|
||||
return ("GET");
|
||||
break;
|
||||
|
@ -1035,34 +1126,34 @@ wap_proto_set_block_data (wap_proto_t *self, zmsg_t **msg_p)
|
|||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get the tx_data field without transferring ownership
|
||||
// Get the tx_as_hex field without transferring ownership
|
||||
|
||||
zchunk_t *
|
||||
wap_proto_tx_data (wap_proto_t *self)
|
||||
wap_proto_tx_as_hex (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->tx_data;
|
||||
return self->tx_as_hex;
|
||||
}
|
||||
|
||||
// Get the tx_data field and transfer ownership to caller
|
||||
// Get the tx_as_hex field and transfer ownership to caller
|
||||
|
||||
zchunk_t *
|
||||
wap_proto_get_tx_data (wap_proto_t *self)
|
||||
wap_proto_get_tx_as_hex (wap_proto_t *self)
|
||||
{
|
||||
zchunk_t *tx_data = self->tx_data;
|
||||
self->tx_data = NULL;
|
||||
return tx_data;
|
||||
zchunk_t *tx_as_hex = self->tx_as_hex;
|
||||
self->tx_as_hex = NULL;
|
||||
return tx_as_hex;
|
||||
}
|
||||
|
||||
// Set the tx_data field, transferring ownership from caller
|
||||
// Set the tx_as_hex field, transferring ownership from caller
|
||||
|
||||
void
|
||||
wap_proto_set_tx_data (wap_proto_t *self, zchunk_t **chunk_p)
|
||||
wap_proto_set_tx_as_hex (wap_proto_t *self, zchunk_t **chunk_p)
|
||||
{
|
||||
assert (self);
|
||||
assert (chunk_p);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
self->tx_data = *chunk_p;
|
||||
zchunk_destroy (&self->tx_as_hex);
|
||||
self->tx_as_hex = *chunk_p;
|
||||
*chunk_p = NULL;
|
||||
}
|
||||
|
||||
|
@ -1122,6 +1213,123 @@ wap_proto_set_o_indexes (wap_proto_t *self, zframe_t **frame_p)
|
|||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the outs_count field
|
||||
|
||||
uint64_t
|
||||
wap_proto_outs_count (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->outs_count;
|
||||
}
|
||||
|
||||
void
|
||||
wap_proto_set_outs_count (wap_proto_t *self, uint64_t outs_count)
|
||||
{
|
||||
assert (self);
|
||||
self->outs_count = outs_count;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get the amounts field without transferring ownership
|
||||
|
||||
zframe_t *
|
||||
wap_proto_amounts (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->amounts;
|
||||
}
|
||||
|
||||
// Get the amounts field and transfer ownership to caller
|
||||
|
||||
zframe_t *
|
||||
wap_proto_get_amounts (wap_proto_t *self)
|
||||
{
|
||||
zframe_t *amounts = self->amounts;
|
||||
self->amounts = NULL;
|
||||
return amounts;
|
||||
}
|
||||
|
||||
// Set the amounts field, transferring ownership from caller
|
||||
|
||||
void
|
||||
wap_proto_set_amounts (wap_proto_t *self, zframe_t **frame_p)
|
||||
{
|
||||
assert (self);
|
||||
assert (frame_p);
|
||||
zframe_destroy (&self->amounts);
|
||||
self->amounts = *frame_p;
|
||||
*frame_p = NULL;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get the random_outputs field without transferring ownership
|
||||
|
||||
zframe_t *
|
||||
wap_proto_random_outputs (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->random_outputs;
|
||||
}
|
||||
|
||||
// Get the random_outputs field and transfer ownership to caller
|
||||
|
||||
zframe_t *
|
||||
wap_proto_get_random_outputs (wap_proto_t *self)
|
||||
{
|
||||
zframe_t *random_outputs = self->random_outputs;
|
||||
self->random_outputs = NULL;
|
||||
return random_outputs;
|
||||
}
|
||||
|
||||
// Set the random_outputs field, transferring ownership from caller
|
||||
|
||||
void
|
||||
wap_proto_set_random_outputs (wap_proto_t *self, zframe_t **frame_p)
|
||||
{
|
||||
assert (self);
|
||||
assert (frame_p);
|
||||
zframe_destroy (&self->random_outputs);
|
||||
self->random_outputs = *frame_p;
|
||||
*frame_p = NULL;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get the tx_data field without transferring ownership
|
||||
|
||||
zchunk_t *
|
||||
wap_proto_tx_data (wap_proto_t *self)
|
||||
{
|
||||
assert (self);
|
||||
return self->tx_data;
|
||||
}
|
||||
|
||||
// Get the tx_data field and transfer ownership to caller
|
||||
|
||||
zchunk_t *
|
||||
wap_proto_get_tx_data (wap_proto_t *self)
|
||||
{
|
||||
zchunk_t *tx_data = self->tx_data;
|
||||
self->tx_data = NULL;
|
||||
return tx_data;
|
||||
}
|
||||
|
||||
// Set the tx_data field, transferring ownership from caller
|
||||
|
||||
void
|
||||
wap_proto_set_tx_data (wap_proto_t *self, zchunk_t **chunk_p)
|
||||
{
|
||||
assert (self);
|
||||
assert (chunk_p);
|
||||
zchunk_destroy (&self->tx_data);
|
||||
self->tx_data = *chunk_p;
|
||||
*chunk_p = NULL;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get/set the address field
|
||||
|
||||
|
@ -1191,7 +1399,7 @@ wap_proto_set_reason (wap_proto_t *self, const char *value)
|
|||
int
|
||||
wap_proto_test (bool verbose)
|
||||
{
|
||||
printf (" * wap_proto: ");
|
||||
printf (" * wap_proto:");
|
||||
|
||||
// Silence an "unused" warning by "using" the verbose variable
|
||||
if (verbose) {;}
|
||||
|
@ -1203,13 +1411,16 @@ wap_proto_test (bool verbose)
|
|||
wap_proto_destroy (&self);
|
||||
|
||||
// Create pair of sockets we can send through
|
||||
zsock_t *input = zsock_new (ZMQ_ROUTER);
|
||||
assert (input);
|
||||
zsock_connect (input, "inproc://selftest-wap_proto");
|
||||
|
||||
// We must bind before connect if we wish to remain compatible with ZeroMQ < v4
|
||||
zsock_t *output = zsock_new (ZMQ_DEALER);
|
||||
assert (output);
|
||||
zsock_bind (output, "inproc://selftest-wap_proto");
|
||||
int rc = zsock_bind (output, "inproc://selftest-wap_proto");
|
||||
assert (rc == 0);
|
||||
|
||||
zsock_t *input = zsock_new (ZMQ_ROUTER);
|
||||
assert (input);
|
||||
rc = zsock_connect (input, "inproc://selftest-wap_proto");
|
||||
assert (rc == 0);
|
||||
|
||||
// Encode/send/decode and verify each message type
|
||||
int instance;
|
||||
|
@ -1255,6 +1466,7 @@ 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);
|
||||
zlist_destroy (&blocks_block_ids);
|
||||
assert (wap_proto_start_height (self) == 123);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_BLOCKS_OK);
|
||||
|
@ -1264,7 +1476,7 @@ wap_proto_test (bool verbose)
|
|||
wap_proto_set_curr_height (self, 123);
|
||||
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");
|
||||
zmsg_addstr (wap_proto_block_data (self), "Captcha Diem");
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
@ -1276,11 +1488,15 @@ wap_proto_test (bool verbose)
|
|||
assert (wap_proto_start_height (self) == 123);
|
||||
assert (wap_proto_curr_height (self) == 123);
|
||||
assert (zmsg_size (wap_proto_block_data (self)) == 1);
|
||||
char *content = zmsg_popstr (wap_proto_block_data (self));
|
||||
assert (streq (content, "Captcha Diem"));
|
||||
zstr_free (&content);
|
||||
zmsg_destroy (&blocks_ok_block_data);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_PUT);
|
||||
|
||||
zchunk_t *put_tx_data = zchunk_new ("Captcha Diem", 12);
|
||||
wap_proto_set_tx_data (self, &put_tx_data);
|
||||
zchunk_t *put_tx_as_hex = zchunk_new ("Captcha Diem", 12);
|
||||
wap_proto_set_tx_as_hex (self, &put_tx_as_hex);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
@ -1288,7 +1504,8 @@ wap_proto_test (bool verbose)
|
|||
for (instance = 0; instance < 2; instance++) {
|
||||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (memcmp (zchunk_data (wap_proto_tx_data (self)), "Captcha Diem", 12) == 0);
|
||||
assert (memcmp (zchunk_data (wap_proto_tx_as_hex (self)), "Captcha Diem", 12) == 0);
|
||||
zchunk_destroy (&put_tx_as_hex);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_PUT_OK);
|
||||
|
||||
|
@ -1328,6 +1545,39 @@ wap_proto_test (bool verbose)
|
|||
assert (wap_proto_routing_id (self));
|
||||
assert (wap_proto_status (self) == 123);
|
||||
assert (zframe_streq (wap_proto_o_indexes (self), "Captcha Diem"));
|
||||
zframe_destroy (&output_indexes_ok_o_indexes);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_RANDOM_OUTS);
|
||||
|
||||
wap_proto_set_outs_count (self, 123);
|
||||
zframe_t *random_outs_amounts = zframe_new ("Captcha Diem", 12);
|
||||
wap_proto_set_amounts (self, &random_outs_amounts);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
||||
for (instance = 0; instance < 2; instance++) {
|
||||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (wap_proto_outs_count (self) == 123);
|
||||
assert (zframe_streq (wap_proto_amounts (self), "Captcha Diem"));
|
||||
zframe_destroy (&random_outs_amounts);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_RANDOM_OUTS_OK);
|
||||
|
||||
wap_proto_set_status (self, 123);
|
||||
zframe_t *random_outs_ok_random_outputs = zframe_new ("Captcha Diem", 12);
|
||||
wap_proto_set_random_outputs (self, &random_outs_ok_random_outputs);
|
||||
// Send twice
|
||||
wap_proto_send (self, output);
|
||||
wap_proto_send (self, output);
|
||||
|
||||
for (instance = 0; instance < 2; instance++) {
|
||||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (wap_proto_status (self) == 123);
|
||||
assert (zframe_streq (wap_proto_random_outputs (self), "Captcha Diem"));
|
||||
zframe_destroy (&random_outs_ok_random_outputs);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_GET);
|
||||
|
||||
|
@ -1353,6 +1603,7 @@ wap_proto_test (bool verbose)
|
|||
wap_proto_recv (self, input);
|
||||
assert (wap_proto_routing_id (self));
|
||||
assert (memcmp (zchunk_data (wap_proto_tx_data (self)), "Captcha Diem", 12) == 0);
|
||||
zchunk_destroy (&get_ok_tx_data);
|
||||
}
|
||||
wap_proto_set_id (self, WAP_PROTO_SAVE);
|
||||
|
||||
|
|
|
@ -261,3 +261,13 @@ signal_command_not_valid (client_t *self)
|
|||
{
|
||||
wap_proto_set_status (self->message, WAP_PROTO_COMMAND_INVALID);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// random_outs
|
||||
//
|
||||
|
||||
static void
|
||||
random_outs (client_t *self)
|
||||
{
|
||||
IPC::Daemon::get_random_outs(self->message);
|
||||
}
|
||||
|
|
|
@ -1065,9 +1065,10 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
{
|
||||
if (!try_connect_to_daemon())
|
||||
return true;
|
||||
/*if (!try_connect_to_daemon())
|
||||
return true;*/
|
||||
|
||||
std::cout << "1\n";
|
||||
std::vector<std::string> local_args = args_;
|
||||
if(local_args.size() < 3)
|
||||
{
|
||||
|
@ -1075,6 +1076,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::cout << "2\n";
|
||||
size_t fake_outs_count;
|
||||
if(!epee::string_tools::get_xtype_from_string(fake_outs_count, local_args[0]))
|
||||
{
|
||||
|
@ -1083,6 +1085,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
}
|
||||
local_args.erase(local_args.begin());
|
||||
|
||||
std::cout << "3\n";
|
||||
std::vector<uint8_t> extra;
|
||||
if (1 == local_args.size() % 2)
|
||||
{
|
||||
|
@ -1105,6 +1108,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "4\n";
|
||||
vector<cryptonote::tx_destination_entry> dsts;
|
||||
for (size_t i = 0; i < local_args.size(); i += 2)
|
||||
{
|
||||
|
@ -1179,14 +1183,17 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
dsts.push_back(de);
|
||||
}
|
||||
|
||||
std::cout << "5\n";
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra);
|
||||
|
||||
std::cout << "5a\n";
|
||||
// if more than one tx necessary, prompt user to confirm
|
||||
if (ptx_vector.size() > 1)
|
||||
{
|
||||
std::cout << "5b\n";
|
||||
std::string prompt_str = "Your transaction needs to be split into ";
|
||||
prompt_str += std::to_string(ptx_vector.size());
|
||||
prompt_str += " transactions. This will result in a transaction fee being applied to each transaction";
|
||||
|
@ -1202,6 +1209,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "6\n";
|
||||
// actually commit the transactions
|
||||
while (!ptx_vector.empty())
|
||||
{
|
||||
|
@ -1219,6 +1227,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
}
|
||||
catch (const tools::error::no_connection_to_daemon&)
|
||||
{
|
||||
std::cout << "7\n";
|
||||
fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running.";
|
||||
}
|
||||
catch (const tools::error::wallet_rpc_error& e)
|
||||
|
|
|
@ -1130,13 +1130,21 @@ std::string wallet2::address_from_txt_record(const std::string& s)
|
|||
void wallet2::commit_tx(pending_tx& ptx)
|
||||
{
|
||||
using namespace cryptonote;
|
||||
COMMAND_RPC_SEND_RAW_TX::request req;
|
||||
/*COMMAND_RPC_SEND_RAW_TX::request req;
|
||||
req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx));
|
||||
COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
|
||||
bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client, 200000);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "sendrawtransaction");
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "sendrawtransaction");
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);*/
|
||||
|
||||
std::string tx_as_hex_string = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx));
|
||||
zchunk_t *tx_as_hex = zchunk_new((void*)tx_as_hex_string.c_str(), tx_as_hex_string.length());
|
||||
int rc = wap_client_put(client, &tx_as_hex);
|
||||
uint64_t status = wap_client_status(client);
|
||||
THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "sendrawtransaction");
|
||||
THROW_WALLET_EXCEPTION_IF((status == IPC::STATUS_INVALID_TX) || (status == IPC::STATUS_TX_VERIFICATION_FAILED) ||
|
||||
(status == IPC::STATUS_TX_NOT_RELAYED), error::tx_rejected, ptx.tx, status);
|
||||
|
||||
add_unconfirmed_tx(ptx.tx, ptx.change_dts.amount);
|
||||
|
||||
|
@ -1171,6 +1179,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
|||
// failsafe split attempt counter
|
||||
size_t attempt_count = 0;
|
||||
|
||||
std::cout << "a\n";
|
||||
for(attempt_count = 1; ;attempt_count++)
|
||||
{
|
||||
auto split_values = split_amounts(dsts, attempt_count);
|
||||
|
@ -1190,11 +1199,14 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
|||
cryptonote::transaction tx;
|
||||
pending_tx ptx;
|
||||
|
||||
std::cout << "b\n";
|
||||
// loop until fee is met without increasing tx size to next KB boundary.
|
||||
uint64_t needed_fee = 0;
|
||||
do
|
||||
{
|
||||
std::cout << "c\n";
|
||||
transfer(dst_vector, fake_outs_count, unlock_time, needed_fee, extra, tx, ptx);
|
||||
std::cout << "d\n";
|
||||
auto txBlob = t_serializable_object_to_blob(ptx.tx);
|
||||
uint64_t txSize = txBlob.size();
|
||||
uint64_t numKB = txSize / 1024;
|
||||
|
|
|
@ -471,23 +471,54 @@ namespace tools
|
|||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response daemon_resp = AUTO_VAL_INIT(daemon_resp);
|
||||
if(fake_outputs_count)
|
||||
{
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
|
||||
req.outs_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key
|
||||
// COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
|
||||
// req.outs_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key
|
||||
uint64_t outs_count = fake_outputs_count + 1;
|
||||
std::vector<uint64_t> amounts;
|
||||
BOOST_FOREACH(transfer_container::iterator it, selected_transfers)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(it->m_tx.vout.size() <= it->m_internal_output_index, error::wallet_internal_error,
|
||||
"m_internal_output_index = " + std::to_string(it->m_internal_output_index) +
|
||||
" is greater or equal to outputs count = " + std::to_string(it->m_tx.vout.size()));
|
||||
req.amounts.push_back(it->amount());
|
||||
amounts.push_back(it->amount());
|
||||
}
|
||||
|
||||
bool r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000);
|
||||
zframe_t *amounts_frame = zframe_new(&amounts[0], amounts.size() * sizeof(uint64_t));
|
||||
int rc = wap_client_random_outs(client, outs_count, &amounts_frame);
|
||||
/*bool r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getrandom_outs.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::get_random_outs_error, daemon_resp.status);
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_resp.outs.size() != selected_transfers.size(), error::wallet_internal_error,
|
||||
"daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " +
|
||||
std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(selected_transfers.size()));
|
||||
std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(selected_transfers.size()));*/
|
||||
|
||||
uint64_t status = wap_client_status(client);
|
||||
THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "getrandomouts");
|
||||
// TODO: Use a code to string mapping of errors
|
||||
THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_RANDOM_OUTS_FAILED, error::get_random_outs_error, "IPC::STATUS_RANDOM_OUTS_FAILED");
|
||||
THROW_WALLET_EXCEPTION_IF(status != IPC::STATUS_OK, error::get_random_outs_error, "!IPC:STATUS_OK");
|
||||
|
||||
// Convert ZMQ response back into RPC response object.
|
||||
zframe_t *outputs_frame = wap_client_random_outputs(client);
|
||||
uint64_t frame_size = zframe_size(outputs_frame);
|
||||
char *frame_data = reinterpret_cast<char*>(zframe_data(outputs_frame));
|
||||
std::string tmp(frame_data, frame_size);
|
||||
std::cout << tmp << std::endl;
|
||||
rapidjson::Document json;
|
||||
THROW_WALLET_EXCEPTION_IF(json.Parse(frame_data, frame_size).HasParseError(), error::get_random_outs_error, "Couldn't JSON parse random outputs.");
|
||||
for (rapidjson::SizeType i = 0; i < json["outputs"].Size(); i++) {
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount output;
|
||||
output.amount = json["outputs"][i]["amount"].GetInt();
|
||||
for (rapidjson::SizeType j = 0; j < json["outputs"][i]["outs"].Size(); j++) {
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry entry;
|
||||
entry.global_amount_index = json["outputs"][i]["outs"][j]["global_amount_index"].GetInt();
|
||||
std::string out_key(json["outputs"][i]["outs"][j]["out_key"].GetString(), json["outputs"][i]["outs"][j]["out_key"].GetStringLength());
|
||||
memcpy(entry.out_key.data, out_key.c_str(), 32);
|
||||
output.outs.push_back(entry);
|
||||
}
|
||||
daemon_resp.outs.push_back(output);
|
||||
}
|
||||
|
||||
std::vector<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs;
|
||||
BOOST_FOREACH(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs, daemon_resp.outs)
|
||||
|
|
|
@ -439,7 +439,7 @@ namespace tools
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_rejected : public transfer_error
|
||||
{
|
||||
explicit tx_rejected(std::string&& loc, const cryptonote::transaction& tx, const std::string& status)
|
||||
explicit tx_rejected(std::string&& loc, const cryptonote::transaction& tx, uint64_t status)
|
||||
: transfer_error(std::move(loc), "transaction was rejected by daemon")
|
||||
, m_tx(tx)
|
||||
, m_status(status)
|
||||
|
@ -447,7 +447,7 @@ namespace tools
|
|||
}
|
||||
|
||||
const cryptonote::transaction& tx() const { return m_tx; }
|
||||
const std::string& status() const { return m_status; }
|
||||
uint64_t status() const { return m_status; }
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
|
@ -460,7 +460,7 @@ namespace tools
|
|||
|
||||
private:
|
||||
cryptonote::transaction m_tx;
|
||||
std::string m_status;
|
||||
uint64_t m_status;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_sum_overflow : public transfer_error
|
||||
|
|
Loading…
Reference in New Issue