aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/core_rpc_server.cpp72
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h51
2 files changed, 105 insertions, 18 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 5350b6fe0..9fcb4373b 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -240,6 +240,7 @@ namespace cryptonote
// try the pool for any missing txes
size_t found_in_pool = 0;
+ std::unordered_set<crypto::hash> pool_tx_hashes;
if (!missed_txs.empty())
{
std::list<transaction> pool_txs;
@@ -248,9 +249,11 @@ namespace cryptonote
{
for (std::list<transaction>::const_iterator i = pool_txs.begin(); i != pool_txs.end(); ++i)
{
- std::list<crypto::hash>::iterator mi = std::find(missed_txs.begin(), missed_txs.end(), get_transaction_hash(*i));
+ crypto::hash tx_hash = get_transaction_hash(*i);
+ std::list<crypto::hash>::iterator mi = std::find(missed_txs.begin(), missed_txs.end(), tx_hash);
if (mi != missed_txs.end())
{
+ pool_tx_hashes.insert(tx_hash);
missed_txs.erase(mi);
txs.push_back(*i);
++found_in_pool;
@@ -260,12 +263,33 @@ namespace cryptonote
LOG_PRINT_L2("Found " << found_in_pool << "/" << vh.size() << " transactions in the pool");
}
+ std::list<std::string>::const_iterator txhi = req.txs_hashes.begin();
+ std::vector<crypto::hash>::const_iterator vhi = vh.begin();
BOOST_FOREACH(auto& tx, txs)
{
+ res.txs.push_back(COMMAND_RPC_GET_TRANSACTIONS::entry());
+ COMMAND_RPC_GET_TRANSACTIONS::entry &e = res.txs.back();
+
+ crypto::hash tx_hash = *vhi++;
+ e.tx_hash = *txhi++;
blobdata blob = t_serializable_object_to_blob(tx);
- res.txs_as_hex.push_back(string_tools::buff_to_hex_nodelimer(blob));
+ e.as_hex = string_tools::buff_to_hex_nodelimer(blob);
+ if (req.decode_as_json)
+ e.as_json = obj_to_json_str(tx);
+ e.in_pool = pool_tx_hashes.find(tx_hash) != pool_tx_hashes.end();
+ if (e.in_pool)
+ {
+ e.block_height = std::numeric_limits<uint64_t>::max();
+ }
+ else
+ {
+ e.block_height = m_core.get_blockchain_storage().get_db().get_tx_block_height(tx_hash);
+ }
+
+ // fill up old style responses too, in case an old wallet asks
+ res.txs_as_hex.push_back(e.as_hex);
if (req.decode_as_json)
- res.txs_as_json.push_back(obj_to_json_str(tx));
+ res.txs_as_json.push_back(e.as_json);
}
BOOST_FOREACH(const auto& miss_tx, missed_txs)
@@ -273,7 +297,7 @@ namespace cryptonote
res.missed_tx.push_back(string_tools::pod_to_hex(miss_tx));
}
- LOG_PRINT_L2(res.txs_as_hex.size() << " transactions found, " << res.missed_tx.size() << " not found");
+ LOG_PRINT_L2(res.txs.size() << " transactions found, " << res.missed_tx.size() << " not found");
res.status = CORE_RPC_STATUS_OK;
return true;
}
@@ -355,24 +379,40 @@ namespace cryptonote
cryptonote_connection_context fake_context = AUTO_VAL_INIT(fake_context);
tx_verification_context tvc = AUTO_VAL_INIT(tvc);
- if(!m_core.handle_incoming_tx(tx_blob, tvc, false, false))
+ if(!m_core.handle_incoming_tx(tx_blob, tvc, false, false) || tvc.m_verifivation_failed)
{
- LOG_PRINT_L0("[on_send_raw_tx]: Failed to process tx");
- res.status = "Failed";
- return true;
- }
-
- if(tvc.m_verifivation_failed)
- {
- LOG_PRINT_L0("[on_send_raw_tx]: tx verification failed");
+ if (tvc.m_verifivation_failed)
+ {
+ LOG_PRINT_L0("[on_send_raw_tx]: tx verification failed");
+ }
+ else
+ {
+ LOG_PRINT_L0("[on_send_raw_tx]: Failed to process tx");
+ }
res.status = "Failed";
+ if ((res.low_mixin = tvc.m_low_mixin))
+ res.reason = "mixin too low";
+ if ((res.double_spend = tvc.m_double_spend))
+ res.reason = "double spend";
+ if ((res.invalid_input = tvc.m_invalid_input))
+ res.reason = "invalid input";
+ if ((res.invalid_output = tvc.m_invalid_output))
+ res.reason = "invalid output";
+ if ((res.too_big = tvc.m_too_big))
+ res.reason = "too big";
+ if ((res.overspend = tvc.m_overspend))
+ res.reason = "overspend";
+ if ((res.fee_too_low = tvc.m_fee_too_low))
+ res.reason = "fee too low";
return true;
}
- if(!tvc.m_should_be_relayed)
+ if(!tvc.m_should_be_relayed || req.do_not_relay)
{
LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed");
- res.status = "Not relayed";
+ res.reason = "Not relayed";
+ res.not_relayed = true;
+ res.status = CORE_RPC_STATUS_OK;
return true;
}
@@ -627,8 +667,10 @@ namespace cryptonote
LOG_ERROR("Failed to calculate offset for ");
return false;
}
+ blobdata hashing_blob = get_block_hashing_blob(b);
res.prev_hash = string_tools::pod_to_hex(b.prev_id);
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
+ res.blockhashing_blob = string_tools::buff_to_hex_nodelimer(hashing_blob);
res.status = CORE_RPC_STATUS_OK;
return true;
}
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 6d4dd1252..6067a28b7 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -103,18 +103,41 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
+ struct entry
+ {
+ std::string tx_hash;
+ std::string as_hex;
+ std::string as_json;
+ bool in_pool;
+ uint64_t block_height;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(tx_hash)
+ KV_SERIALIZE(as_hex)
+ KV_SERIALIZE(as_json)
+ KV_SERIALIZE(in_pool)
+ KV_SERIALIZE(block_height)
+ END_KV_SERIALIZE_MAP()
+ };
struct response
{
- std::list<std::string> txs_as_hex; //transactions blobs as hex
+ // older compatibility stuff
+ std::list<std::string> txs_as_hex; //transactions blobs as hex (old compat)
+ std::list<std::string> txs_as_json; //transactions decoded as json (old compat)
+
+ // in both old and new
std::list<std::string> missed_tx; //not found transactions
- std::list<std::string> txs_as_json; //transactions decoded as json
+
+ // new style
+ std::vector<entry> txs;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txs_as_hex)
- KV_SERIALIZE(missed_tx)
KV_SERIALIZE(txs_as_json)
+ KV_SERIALIZE(txs)
+ KV_SERIALIZE(missed_tx)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
@@ -221,12 +244,14 @@ namespace cryptonote
struct request
{
std::string tx_as_hex;
+ bool do_not_relay;
request() {}
explicit request(const transaction &);
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_as_hex)
+ KV_SERIALIZE(do_not_relay)
END_KV_SERIALIZE_MAP()
};
@@ -234,9 +259,27 @@ namespace cryptonote
struct response
{
std::string status;
+ std::string reason;
+ bool not_relayed;
+ bool low_mixin;
+ bool double_spend;
+ bool invalid_input;
+ bool invalid_output;
+ bool too_big;
+ bool overspend;
+ bool fee_too_low;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
+ KV_SERIALIZE(reason)
+ KV_SERIALIZE(not_relayed)
+ KV_SERIALIZE(low_mixin)
+ KV_SERIALIZE(double_spend)
+ KV_SERIALIZE(invalid_input)
+ KV_SERIALIZE(invalid_output)
+ KV_SERIALIZE(too_big)
+ KV_SERIALIZE(overspend)
+ KV_SERIALIZE(fee_too_low)
END_KV_SERIALIZE_MAP()
};
};
@@ -427,6 +470,7 @@ namespace cryptonote
uint64_t reserved_offset;
std::string prev_hash;
blobdata blocktemplate_blob;
+ blobdata blockhashing_blob;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
@@ -435,6 +479,7 @@ namespace cryptonote
KV_SERIALIZE(reserved_offset)
KV_SERIALIZE(prev_hash)
KV_SERIALIZE(blocktemplate_blob)
+ KV_SERIALIZE(blockhashing_blob)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};