diff --git a/src/daemon/MoneroDaemonModel.cpp b/src/daemon/MoneroDaemonModel.cpp index 50fe198..2db6e68 100644 --- a/src/daemon/MoneroDaemonModel.cpp +++ b/src/daemon/MoneroDaemonModel.cpp @@ -255,12 +255,12 @@ namespace monero { if (prunableHash != boost::none) node.put("prunableHash", *prunableHash); if (size != boost::none) node.put("size", *size); if (weight != boost::none) node.put("weight", *weight); - if (!vins.empty()) node.add_child("vouts", MoneroUtils::toPropertyTree(vouts)); + if (!vins.empty()) node.add_child("vins", MoneroUtils::toPropertyTree(vins)); if (!vouts.empty()) node.add_child("vouts", MoneroUtils::toPropertyTree(vouts)); if (!outputIndices.empty()) throw runtime_error("outputIndices not implemented"); if (metadata != boost::none) node.put("metadata", *metadata); if (commonTxSets != boost::none) throw runtime_error("commonTxSets not implemented"); - if (!extra.empty()) throw runtime_error("extra not implemented"); + if (!extra.empty()) node.add_child("extra", MoneroUtils::toPropertyTree(extra)); if (rctSignatures != boost::none) throw runtime_error("rctSignatures not implemented"); if (rctSigPrunable != boost::none) throw runtime_error("rctSigPrunable not implemented"); if (isKeptByBlock != boost::none) node.put("isKeptByBlock", *isKeptByBlock); @@ -435,7 +435,7 @@ namespace monero { if (src->keyImage != boost::none) tgt->keyImage = src->keyImage.get()->copy(src->keyImage.get(), make_shared()); tgt->amount = src->amount; tgt->index = src->index; - if (!src->ringOutputIndices.empty()) tgt->ringOutputIndices = vector(src->ringOutputIndices); + if (!src->ringOutputIndices.empty()) tgt->ringOutputIndices = vector(src->ringOutputIndices); tgt->stealthPublicKey = src->stealthPublicKey; return tgt; } @@ -445,7 +445,7 @@ namespace monero { if (keyImage != boost::none) node.add_child("keyImage", (*keyImage)->toPropertyTree()); if (amount != boost::none) node.put("amount", *amount); if (index != boost::none) node.put("index", *index); - if (!ringOutputIndices.empty()) throw runtime_error("MoneroOutput::toPropertyTree() ringOutputIndices not implemented"); + if (!ringOutputIndices.empty()) node.add_child("ringOutputIndices", MoneroUtils::toPropertyTree(ringOutputIndices)); if (stealthPublicKey != boost::none) node.put("stealthPublicKey", *stealthPublicKey); return node; } diff --git a/src/daemon/MoneroDaemonModel.h b/src/daemon/MoneroDaemonModel.h index 95d2879..1e13554 100644 --- a/src/daemon/MoneroDaemonModel.h +++ b/src/daemon/MoneroDaemonModel.h @@ -157,7 +157,7 @@ namespace monero { static const string DEFAULT_PAYMENT_ID; // default payment id "0000000000000000" boost::optional> block; boost::optional id; - boost::optional version; + boost::optional version; boost::optional isCoinbase; boost::optional paymentId; boost::optional fee; @@ -183,7 +183,7 @@ namespace monero { vector outputIndices; boost::optional metadata; boost::optional commonTxSets; - vector extra; + vector extra; boost::optional rctSignatures; // TODO: implement boost::optional rctSigPrunable; // TODO: implement boost::optional isKeptByBlock; @@ -220,7 +220,7 @@ namespace monero { boost::optional> keyImage; boost::optional amount; boost::optional index; - vector ringOutputIndices; + vector ringOutputIndices; boost::optional stealthPublicKey; shared_ptr copy(const shared_ptr& src, const shared_ptr& tgt) const; diff --git a/src/utils/MoneroUtils.cpp b/src/utils/MoneroUtils.cpp index c7e87ee..f752c85 100644 --- a/src/utils/MoneroUtils.cpp +++ b/src/utils/MoneroUtils.cpp @@ -450,7 +450,7 @@ string MoneroUtils::serialize(const boost::property_tree::ptree& node) { return str.substr(0, str.size() - 1); // strip newline } -boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector strs) { +boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector& strs) { boost::property_tree::ptree strsNode; for (const auto& str : strs) { boost::property_tree::ptree strNode; @@ -460,7 +460,28 @@ boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector str return strsNode; } -boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector nums) { +boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector& nums) { + boost::property_tree::ptree numsNode; + for (const auto& num : nums) { + boost::property_tree::ptree numNode; + numNode.put("", num); + numsNode.push_back(std::make_pair("", numNode)); + } + return numsNode; +} + +// TODO: remove these redundant implementations for different sizes? +boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector& nums) { + boost::property_tree::ptree numsNode; + for (const auto& num : nums) { + boost::property_tree::ptree numNode; + numNode.put("", num); + numsNode.push_back(std::make_pair("", numNode)); + } + return numsNode; +} + +boost::property_tree::ptree MoneroUtils::toPropertyTree(const vector& nums) { boost::property_tree::ptree numsNode; for (const auto& num : nums) { boost::property_tree::ptree numNode; @@ -488,17 +509,41 @@ shared_ptr MoneroUtils::cnBlockToBlock(const cryptonote::block& cnB shared_ptr MoneroUtils::cnTxToTx(const cryptonote::transaction& cnTx, bool initAsTxWallet) { shared_ptr tx = initAsTxWallet ? make_shared() : make_shared(); - //tx->version = cnTx.version; + tx->version = cnTx.version; tx->unlockTime = cnTx.unlock_time; tx->id = epee::string_tools::pod_to_hex(cnTx.hash); + tx->extra = cnTx.extra; + + // init vins + for (const txin_v& cnVin : cnTx.vin) { + if (cnVin.which() != 0 && cnVin.which() != 3) throw runtime_error("Unsupported variant type"); + if (tx->isCoinbase == boost::none) tx->isCoinbase = cnVin.which() == 0; + if (cnVin.which() != 3) continue; // only process txin_to_key of variant TODO: support other types, like 0 "gen" which is miner tx? + shared_ptr vin = initAsTxWallet ? make_shared() : make_shared(); + vin->tx = tx; + tx->vins.push_back(vin); + const txin_to_key& txin = boost::get(cnVin); + vin->amount = txin.amount; + vin->ringOutputIndices = txin.key_offsets; + crypto::key_image cnKeyImage = txin.k_image; + vin->keyImage = make_shared(); + vin->keyImage.get()->hex = epee::string_tools::pod_to_hex(cnKeyImage); + } + + // init vouts + for (const tx_out& cnVout : cnTx.vout) { + shared_ptr vout = initAsTxWallet ? make_shared() : make_shared(); + vout->tx = tx; + tx->vouts.push_back(vout); + vout->amount = cnVout.amount; + const crypto::public_key& cnStealthPublicKey = boost::get(cnVout.target).key; + vout->stealthPublicKey = epee::string_tools::pod_to_hex(cnStealthPublicKey); + } + return tx; - // TODO: finish this -// std::vector vin; -// std::vector vout; -// std::vector extra; + // TODO: finish this, cryptonote::transaction has: // std::vector > signatures; // rct::rctSig rct_signatures; // mutable size_t blob_size; -// throw runtime_error("cnTransactionToTx not implemented"); } diff --git a/src/utils/MoneroUtils.h b/src/utils/MoneroUtils.h index c698795..3e9d158 100644 --- a/src/utils/MoneroUtils.h +++ b/src/utils/MoneroUtils.h @@ -116,10 +116,10 @@ namespace MoneroUtils return ss.str(); } - // ------------------------- VALUE RECONCILATION- --------------------------- + // ----------------------------- PROPERTY TREE ------------------------------ // TODO: template implementation here, could move to MoneroUtils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation - template boost::property_tree::ptree toPropertyTree(const vector> types) { + template boost::property_tree::ptree toPropertyTree(const vector>& types) { boost::property_tree::ptree typeNodes; for (const auto& type : types) { typeNodes.push_back(std::make_pair("", type->toPropertyTree())); @@ -128,7 +128,7 @@ namespace MoneroUtils } // TODO: template implementation here, could move to MoneroUtils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation - template boost::property_tree::ptree toPropertyTree(const vector types) { + template boost::property_tree::ptree toPropertyTree(const vector& types) { boost::property_tree::ptree typeNodes; for (const auto& type : types) { typeNodes.push_back(std::make_pair("", type.toPropertyTree())); @@ -136,9 +136,12 @@ namespace MoneroUtils return typeNodes; } - boost::property_tree::ptree toPropertyTree(const vector strs); - boost::property_tree::ptree toPropertyTree(const vector nums); + boost::property_tree::ptree toPropertyTree(const vector& strs); + boost::property_tree::ptree toPropertyTree(const vector& nums); + boost::property_tree::ptree toPropertyTree(const vector& nums); + boost::property_tree::ptree toPropertyTree(const vector& nums); + // ------------------------- VALUE RECONCILATION- --------------------------- // TODO: refactor common template code template ::value, T>::type* = nullptr> diff --git a/src/wallet/MoneroWallet.cpp b/src/wallet/MoneroWallet.cpp index 9b34800..f2c44b2 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -716,7 +716,6 @@ namespace monero { if (listener == boost::none) return; // create native library tx - // TODO **: fill this out shared_ptr block = make_shared(); block->height = height; shared_ptr tx = static_pointer_cast(MoneroUtils::cnTxToTx(cnTx, true));