From 4d44c773c672829cd00f2badfad614ac5bed4cb4 Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Thu, 7 Mar 2019 22:07:49 -0800 Subject: [PATCH] WIP: Fixed extra field deserialization. --- .../cryptonote_format_utils.cpp | 18 +++++++---- src/rpc/mining.cpp | 30 +++++++++---------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/cn_utils/cryptonote_basic/cryptonote_format_utils.cpp b/src/cn_utils/cryptonote_basic/cryptonote_format_utils.cpp index 135e1a2e3..a7bdb0395 100644 --- a/src/cn_utils/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cn_utils/cryptonote_basic/cryptonote_format_utils.cpp @@ -594,12 +594,18 @@ namespace cryptonote //--------------------------------------------------------------- bool append_keva_block_to_extra(std::vector& tx_extra, const tx_extra_keva_block& keva_block) { - blobdata blob; - if (!t_serializable_object_to_blob(keva_block, blob)) - return false; - - tx_extra.push_back(TX_EXTRA_KEVA_BLOCK_TAG); - std::copy(reinterpret_cast(blob.data()), reinterpret_cast(blob.data() + blob.size()), std::back_inserter(tx_extra)); + // convert to variant + tx_extra_field field = tx_extra_keva_block{ keva_block }; + // serialize + std::ostringstream oss; + binary_archive ar(oss); + bool r = ::do_serialize(ar, field); + CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra keva block"); + // append + std::string tx_extra_str = oss.str(); + size_t pos = tx_extra.size(); + tx_extra.resize(tx_extra.size() + tx_extra_str.size()); + memcpy(&tx_extra[pos], tx_extra_str.data(), tx_extra_str.size()); return true; } //--------------------------------------------------------------- diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index d45456489..d8a9c43d1 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -928,6 +928,20 @@ UniValue getblocktemplate(const JSONRPCRequest& request) } cn_block.miner_tx = miner_tx; + // No transactions other than coinbase. + cn_block.tx_hashes.clear(); + + // Copy keva block to extra so that we can use it in submitblock. + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << *pblock; + std::string kevaBlockData = stream.str(); + cryptonote::tx_extra_keva_block extra_keva_block; + extra_keva_block.keva_block = kevaBlockData; + if (!cryptonote::append_keva_block_to_extra(cn_block.miner_tx.extra, extra_keva_block)) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: failed to add block"); + } + + // Now cn_block is finalized, we can calculate the reserved offset position. cryptonote::blobdata block_blob = cryptonote::t_serializable_object_to_blob(cn_block); crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(cn_block.miner_tx); if(tx_pub_key == crypto::null_pkey) { @@ -942,21 +956,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: Failed to calculate offset"); } - - // No transactions other than coinbase. - cn_block.tx_hashes.clear(); - - // Copy keva block to extra so that we can use it in submitblock. - CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); - stream << *pblock; - std::string kevaBlockData = HexStr(stream.begin(), stream.end()); - cryptonote::tx_extra_keva_block extra_keva_block; - extra_keva_block.keva_block = kevaBlockData; - if (!cryptonote::append_keva_block_to_extra(cn_block.miner_tx.extra, extra_keva_block)) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: failed to add block"); - } - cryptonote::blobdata template_blob = cryptonote::block_to_blob(cn_block); - std::string hex_template_blob = HexStr(template_blob.begin(), template_blob.end()); + std::string hex_template_blob = HexStr(block_blob.begin(), block_blob.end()); UniValue result(UniValue::VOBJ); const uint64_t difficulty = ConvertNBitsToDiff(pblock->nBits);