54 std::vector<std::pair<std::pair<blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, blobdata> > > >
blocks;
59 res.error_details =
"core::find_blockchain_supplement() returned false";
76 res.output_indices.clear();
78 res.error_details =
"failed retrieving a requested block";
85 res.output_indices.clear();
87 res.error_details =
"incorrect number of transactions retrieved for block";
99 res.error_details =
"core::get_tx_outputs_gindexs() returned false";
102 indices.push_back(
std::move(tx_indices));
107 for (
const auto& blob : it->second)
113 res.output_indices.clear();
115 res.error_details =
"failed retrieving a requested transaction";
123 res.error_details =
"core::get_tx_outputs_gindexs() returned false";
127 indices.push_back(
std::move(tx_indices));
140 res.start_height = req.start_height;
144 if (!chain.find_blockchain_supplement(req.known_hashes,
res.hashes,
res.start_height,
res.current_height,
false))
147 res.error_details =
"Blockchain::find_blockchain_supplement() returned false";
156 std::vector<cryptonote::transaction> found_txs_vec;
157 std::vector<crypto::hash> missed_vec;
165 res.error_details =
"core::get_transactions() returned false (exception caught there)";
169 size_t num_found = found_txs_vec.size();
171 std::vector<uint64_t> heights(num_found);
172 std::vector<bool> in_pool(num_found,
false);
173 std::vector<crypto::hash> found_hashes(num_found);
175 for (
size_t i=0; i < num_found; i++)
182 if (!missed_vec.empty())
184 std::vector<cryptonote::transaction> pool_txs;
188 for (
const auto& tx : pool_txs)
192 auto itr = std::find(missed_vec.begin(), missed_vec.end(), h);
194 if (itr != missed_vec.end())
196 found_hashes.push_back(h);
197 found_txs_vec.push_back(tx);
198 heights.push_back(std::numeric_limits<uint64_t>::max());
199 in_pool.push_back(
true);
200 missed_vec.erase(itr);
205 for (
size_t i=0; i < found_hashes.size(); i++)
208 info.height = heights[i];
209 info.in_pool = in_pool[i];
223 std::vector<bool> chain_spent_status;
224 std::vector<bool> pool_spent_status;
229 if ((chain_spent_status.size() != req.key_images.size()) || (pool_spent_status.size() != req.key_images.size()))
232 res.error_details =
"tx_pool::have_key_images_as_spent() gave vectors of wrong size(s).";
236 for(
size_t i=0; i < req.key_images.size(); i++)
238 if ( chain_spent_status[i] )
242 else if ( pool_spent_status[i] )
256 res.error_details =
"core::get_tx_outputs_gindexs() returned false";
274 MERROR(
"[SendRawTxHex]: Failed to parse tx from hexbuff: " << req.tx_as_hex);
276 res.error_details =
"Invalid hex";
279 handleTxBlob(tx_blob, req.relay,
res);
284 if (!m_p2p.get_payload_object().is_synchronized())
287 res.error_details =
"Not ready to accept transactions; try again later";
298 MERROR(
"[SendRawTx]: tx verification failed");
302 MERROR(
"[SendRawTx]: Failed to process tx");
305 res.error_details =
"";
309 res.error_details =
"mixin too low";
313 if (!
res.error_details.empty())
res.error_details +=
" and ";
314 res.error_details =
"double spend";
318 if (!
res.error_details.empty())
res.error_details +=
" and ";
319 res.error_details =
"utxo is already spent or is nonexistent";
323 if (!
res.error_details.empty())
res.error_details +=
" and ";
324 res.error_details =
"invalid input";
328 if (!
res.error_details.empty())
res.error_details +=
" and ";
329 res.error_details =
"invalid output";
333 if (!
res.error_details.empty())
res.error_details +=
" and ";
334 res.error_details =
"too big";
338 if (!
res.error_details.empty())
res.error_details +=
" and ";
339 res.error_details =
"overspend";
343 if (!
res.error_details.empty())
res.error_details +=
" and ";
344 res.error_details =
"fee too low";
348 if (!
res.error_details.empty())
res.error_details +=
" and ";
349 res.error_details =
"tx is not ringct";
353 if (!
res.error_details.empty())
res.error_details +=
" and ";
354 res.error_details =
"this is an outbound transaction from the smartchain bridge portal address";
358 if (!
res.error_details.empty())
res.error_details +=
" and ";
359 res.error_details =
"the bridge source address in the tx extra is invalid";
363 if (!
res.error_details.empty())
res.error_details +=
" and ";
364 res.error_details =
"the bridge smartchain address in the tx extra is invalid";
366 if (
res.error_details.empty())
368 res.error_details =
"an unknown issue was found with the transaction";
376 MERROR(
"[SendRawTx]: tx accepted, but not relayed");
377 res.error_details =
"Not relayed";
385 r.txs.push_back(tx_blob);
400 res.error_details =
"Failed, wrong address";
405 if (
info.is_subaddress)
407 res.error_details =
"Failed, mining to subaddress isn't supported yet";
413 unsigned int concurrency_count = boost::thread::hardware_concurrency() * 4;
416 if(concurrency_count == 0)
418 concurrency_count = 257;
423 if(req.threads_count > concurrency_count)
425 res.error_details =
"Failed, too many threads relative to CPU cores.";
431 if(!m_core.
get_miner().
start(
info.address, static_cast<size_t>(req.threads_count), req.do_background_mining, req.ignore_battery))
433 res.error_details =
"Failed, mining not started";
439 res.error_details =
"";
449 if (
res.info.height >
res.info.target_height)
451 res.info.target_height =
res.info.height;
456 res.info.wide_difficulty = chain.get_difficulty_for_next_block();
457 res.info.difficulty = (
res.info.wide_difficulty & 0xffffffffffffffff).convert_to<uint64_t>();
459 res.info.target = chain.get_difficulty_target();
461 res.info.tx_count = chain.get_total_transactions() -
res.info.height;
465 res.info.alt_blocks_count = chain.get_alternative_blocks_count();
467 uint64_t total_conn = m_p2p.get_public_connections_count();
468 res.info.outgoing_connections_count = m_p2p.get_public_outgoing_connections_count();
469 res.info.incoming_connections_count = total_conn -
res.info.outgoing_connections_count;
471 res.info.white_peerlist_size = m_p2p.get_public_white_peers_count();
473 res.info.grey_peerlist_size = m_p2p.get_public_gray_peers_count();
479 res.info.cumulative_difficulty = (
res.info.wide_cumulative_difficulty & 0xffffffffffffffff).convert_to<uint64_t>();
486 res.error_details =
"";
493 res.error_details =
"Failed, mining not stopped";
500 res.error_details =
"";
517 res.error_details =
"";
525 res.error_details =
"Error storing the blockchain";
537 res.hash = crypto::null_hash;
539 res.error_details =
"height given is higher than current chain height";
551 res.error_details =
"RPC method not yet implemented.";
557 res.error_details =
"RPC method not yet implemented.";
564 if (!getBlockHeaderByHash(block_hash,
res.header))
567 res.error_details =
"Requested block does not exist";
576 if (!getBlockHeaderByHash(req.hash,
res.header))
579 res.error_details =
"Requested block does not exist";
590 if (!getBlockHeaderByHash(block_hash,
res.header))
593 res.error_details =
"Requested block does not exist";
602 res.headers.resize(req.heights.size());
604 for (
size_t i=0; i < req.heights.size(); i++)
608 if (!getBlockHeaderByHash(block_hash,
res.headers[i]))
611 res.error_details =
"A requested block does not exist";
622 res.error_details =
"RPC method not yet implemented.";
628 res.error_details =
"RPC method not yet implemented.";
634 res.error_details =
"RPC method not yet implemented.";
639 if (req.level < 0 || req.level > 4)
642 res.error_details =
"Error: log level not valid";
662 res.error_details =
"RPC method not yet implemented.";
668 res.error_details =
"RPC method not yet implemented.";
674 res.error_details =
"RPC method not yet implemented.";
680 res.error_details =
"RPC method not yet implemented.";
686 res.error_details =
"RPC method not yet implemented.";
702 res.error_details =
"RPC method not yet implemented.";
708 res.error_details =
"RPC method not yet implemented.";
714 res.error_details =
"RPC method not yet implemented.";
719 std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t> > histogram;
724 catch (
const std::exception &e)
727 res.error_details = e.what();
731 res.histogram.clear();
732 res.histogram.reserve(histogram.size());
733 for (
const auto &i: histogram)
735 if (std::get<0>(i.second) >= req.min_count && (std::get<0>(i.second) <= req.max_count || req.max_count == 0))
736 res.histogram.emplace_back(
output_amount_count{i.first, std::get<0>(i.second), std::get<1>(i.second), std::get<2>(i.second)});
746 for (
const auto& i : req.outputs)
755 catch (
const std::exception& e)
758 res.error_details = e.what();
767 res.version = DAEMON_RPC_VERSION_ZMQ;
778 res.size_scale = 1024;
793 res.distributions.reserve(req.amounts.size());
798 auto data =
rpc::RpcHandler::get_output_distribution([
this](
uint64_t amount,
uint64_t from,
uint64_t to,
uint64_t &start_height, std::vector<uint64_t> &distribution,
uint64_t &base) {
return m_core.
get_output_distribution(amount, from, to, start_height, distribution, base); }, amount, req.from_height, req_to_height, [
this](
uint64_t height) {
return m_core.
get_blockchain_storage().
get_db().
get_block_hash_from_height(
height); }, req.cumulative, m_core.
get_current_blockchain_height());
801 res.distributions.clear();
803 res.error_details =
"Failed to get output distribution";
810 catch (
const std::exception& e)
812 res.distributions.clear();
814 res.error_details = e.what();
827 header.
hash = hash_in;
845 header.
reward += out.amount;
856 MDEBUG(
"Handling RPC request: " << request);
898 if (resp_message == NULL)
913 catch (
const std::exception& e)
uint64_t get_current_cumulative_block_weight_limit() const
gets the block weight limit based on recent blocks
bool m_bad_bridge_smartchain_address
virtual uint64_t get_tx_block_height(const crypto::hash &h) const =0
fetches the height of a transaction's block
std::vector< crypto::hash > tx_hashes
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT
bool m_bad_bridge_source_address
std::string get_account_address_as_str(network_type nettype, bool subaddress, account_public_address const &adr)
void get_output_key_mask_unlocked(const uint64_t &amount, const uint64_t &index, crypto::public_key &key, rct::key &mask, bool &unlocked) const
gets an output's key and unlocked state
std::vector< tx_output_indices > block_output_indices
SendRawTx::Response Response
bool m_verification_failed
epee::misc_utils::struct_init< response_t > response
virtual crypto::hash get_block_hash_from_height(const uint64_t &height) const =0
fetch a block's hash
std::string BAD_REQUEST(const std::string &request)
bool store_blockchain()
stores the blockchain
bool are_key_images_spent_in_pool(const std::vector< crypto::key_image > &key_im, std::vector< bool > &spent) const
check if multiple key images are spent in the transaction pool
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
std::vector< uint64_t > tx_output_indices
virtual difficulty_type get_block_cumulative_difficulty(const uint64_t &height) const =0
fetch a block's cumulative difficulty
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request &arg, cryptonote_connection_context &exclude_context)=0
network_type get_nettype() const
get the network type we're on
static const char * STATUS_FAILED
rapidjson::Value & getID()
uint64_t get_current_cumulative_block_weight_median() const
gets the block weight median based on recent blocks (same window as for the limit) ...
std::vector< tx_out > vout
uint8_t get_current_hard_fork_version() const
gets the current hardfork version in use/voted for
Holds cryptonote related classes and helpers.
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector< uint64_t > &distribution, uint64_t &base) const
gets per block distribution of outputs of a given amount
std::string getRequestType() const
bool start(const account_public_address &adr, size_t threads_count, bool do_background=false, bool ignore_battery=false)
std::vector< txin_v > vin
blobdata tx_to_blob(const transaction &tx)
bool handle_incoming_tx(const blobdata &tx_blob, tx_verification_context &tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
handles an incoming transaction
std::map< uint64_t, std::tuple< uint64_t, uint64_t, uint64_t > > get_output_histogram(const std::vector< uint64_t > &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count=0) const
return a histogram of outputs on the blockchain
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
uint32_t get_threads_count() const
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
bool get_pool_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
i_cryptonote_protocol * get_protocol()
get the cryptonote protocol instance
HardFork::State get_hard_fork_state() const
gets the hardfork voting state object
static uint64_t get_fee_quantization_mask()
get fee quantization mask
uint64_t get_target_blockchain_height() const
gets the target blockchain height
const account_public_address & get_mining_address() const
void handle(const GetHeight::Request &req, GetHeight::Response &res)
unsigned __int64 uint64_t
const char *const ELECTRONEUM_VERSION
#define REQ_RESP_TYPES_MACRO(runtime_str, type, reqjson, resp_message_ptr, handler)
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
bool parse_and_validate_tx_from_blob(const blobdata &tx_blob, transaction &tx)
uint64_t get_speed() const
version
Supported socks variants.
const BlockchainDB & get_db() const
get a reference to the BlockchainDB in use by Blockchain
bool m_portal_outbound_tx
size_t get_pool_transactions_count() const
get the total number of transactions in the pool
uint64_t get_dynamic_base_fee_estimate(uint64_t grace_blocks) const
get dynamic per kB or byte fee estimate for the next few blocks
miner & get_miner()
gets the miner instance
Blockchain & get_blockchain_storage()
gets the Blockchain instance
const T & move(const T &t)
bool get_tx_outputs_gindexs(const crypto::hash &tx_id, std::vector< uint64_t > &indexs) const
gets the global indices for outputs from a given transaction
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
crypto::hash get_transaction_hash(const transaction &t)
difficulty_type block_difficulty(uint64_t i) const
gets the difficulty of the block with a given height
static FullMessage responseMessage(Message *message)
bool get_account_address_from_str(address_parse_info &info, network_type nettype, std::string const &str)
bool get_is_background_mining_enabled() const
bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
get information about hardfork voting for a version
bool are_key_images_spent(const std::vector< crypto::key_image > &key_im, std::vector< bool > &spent) const
check if multiple key images are spent
static boost::optional< output_distribution_data > get_output_distribution(const std::function< bool(uint64_t, uint64_t, uint64_t, uint64_t &, std::vector< uint64_t > &, uint64_t &)> &f, uint64_t amount, uint64_t from_height, uint64_t to_height, const std::function< crypto::hash(uint64_t)> &get_hash, bool cumulative, uint64_t blockchain_height)
rapidjson::Value & getMessage()
static const char * STATUS_OK
#define HF_VERSION_PER_BYTE_FEE
epee::misc_utils::struct_init< request_t > request
bool get_transactions(const std::vector< crypto::hash > &txs_ids, std::vector< cryptonote::blobdata > &txs, std::vector< crypto::hash > &missed_txs) const
bool get_pool_for_rpc(std::vector< cryptonote::rpc::tx_in_pool > &tx_infos, cryptonote::rpc::key_images_with_tx_hashes &key_image_infos) const
get information about all transactions and key images in the pool
void mlog_set_log_level(int level)
bool find_blockchain_supplement(const std::list< crypto::hash > &qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request &resp) const
get recent block hashes for a foreign chain
bool parse_and_validate_block_from_blob(const blobdata &b_blob, block &b, crypto::hash *block_hash)
std::vector< cryptonote::transaction > transactions
std::string BAD_JSON(const std::string &error_details)
std::time_t get_start_time() const
gets start_time