| 112 | } |
| 113 | |
| 114 | void Node::getblocktemplate(const api::cnd::GetBlockTemplate::Request &req, api::cnd::GetBlockTemplate::Response &res) { |
| 115 | if (req.reserve_size > extra::Nonce::MAX_COUNT) |
| 116 | throw json_rpc::Error{api::cnd::GetBlockTemplate::TOO_BIG_RESERVE_SIZE, |
| 117 | "To big reserved size, maximum " + common::to_string(extra::Nonce::MAX_COUNT)}; |
| 118 | AccountAddress acc{}; |
| 119 | if (!m_block_chain.get_currency().parse_account_address_string(req.wallet_address, &acc)) |
| 120 | throw api::ErrorAddress( |
| 121 | api::ErrorAddress::ADDRESS_FAILED_TO_PARSE, "Failed to parse wallet address", req.wallet_address); |
| 122 | |
| 123 | BlockTemplate block_template{}; |
| 124 | BinaryArray blob_reserve; |
| 125 | uint8_t reserve_magic = 0xbb; |
| 126 | blob_reserve.resize(req.reserve_size, reserve_magic); |
| 127 | size_t reserve_back_offset = 0; |
| 128 | |
| 129 | try { |
| 130 | m_block_chain.create_mining_block_template(m_block_chain.get_tip_bid(), acc, blob_reserve, req.miner_secret, |
| 131 | &block_template, &res.difficulty, &res.height, &reserve_back_offset); |
| 132 | } catch (const std::exception &ex) { |
| 133 | m_log(logging::ERROR) << logging::BrightRed << "getblocktemplate exception " << ex.what(); |
| 134 | throw; |
| 135 | } |
| 136 | BinaryArray block_blob = seria::to_binary(block_template); |
| 137 | if (req.reserve_size > 0) { |
| 138 | if (reserve_back_offset + blob_reserve.size() > block_blob.size()) { |
| 139 | m_log(logging::ERROR) << "Failed to calculate offset for reserved bytes"; |
| 140 | throw json_rpc::Error{json_rpc::INTERNAL_ERROR, "Internal error: failed to create block template"}; |
| 141 | } |
| 142 | res.reserved_offset = block_blob.size() - reserve_back_offset - blob_reserve.size(); |
| 143 | for (size_t i = 0; i != req.reserve_size; ++i) { |
| 144 | invariant(block_blob.at(res.reserved_offset + i) == reserve_magic, ""); |
| 145 | block_blob.at(res.reserved_offset + i) = 0; |
| 146 | } |
| 147 | } |
| 148 | res.blocktemplate_blob = block_blob; |
| 149 | res.top_block_hash = m_block_chain.get_tip_bid(); |
| 150 | res.transaction_pool_version = m_block_chain.get_tx_pool_version(); |
| 151 | res.previous_block_hash = m_block_chain.get_tip().previous_block_hash; |
| 152 | #if bytecoin_ALLOW_CM |
| 153 | // Experimental, a bit hacky |
| 154 | if (block_template.major_version >= m_block_chain.get_currency().amethyst_block_version) { |
| 155 | try { |
| 156 | block_template.major_version += 1; |
| 157 | auto body_proxy = get_body_proxy_from_template(block_template); |
| 158 | res.cm_prehash = get_block_header_prehash(block_template, body_proxy); |
| 159 | res.cm_path = m_block_chain.get_genesis_bid(); |
| 160 | } catch (const std::exception &) { |
| 161 | } |
| 162 | } |
| 163 | #endif |
| 164 | } |
| 165 | |
| 166 | bool Node::on_get_currency_id(http::Client *, http::RequestBody &&, json_rpc::Request &&, |
| 167 | api::cnd::GetCurrencyId::Request &&, api::cnd::GetCurrencyId::Response &res) { |
nothing calls this directly
no test coverage detected