diff --git a/src/daemon/MoneroDaemon.cpp b/src/daemon/MoneroDaemon.cpp index 390b665..ca994ce 100644 --- a/src/daemon/MoneroDaemon.cpp +++ b/src/daemon/MoneroDaemon.cpp @@ -12,13 +12,65 @@ namespace monero { // -------------------------- MODEL SERIALIZATION --------------------------- string SerializableStruct::serialize() const { + return MoneroUtils::serialize(toPropertyTree2()); + } + + boost::property_tree::ptree SerializableStruct::toPropertyTree2() const { boost::property_tree::ptree node; toPropertyTree(node); - return MoneroUtils::serialize(node); + return node; + } + + void MoneroBlockHeader::toPropertyTree(boost::property_tree::ptree& node) const { + cout << "MoneroBlockHeader::toPropertyTree(block)" << endl; + throw runtime_error("not implemented"); + } + + void MoneroBlock::toPropertyTree(boost::property_tree::ptree& node) const { + cout << "MoneroBlock::toPropertyTree(block)" << endl; + if (height != boost::none) node.put("height", *height); // TODO: finish this, add txs + //node.add_child("txs", toPropertyTree(txs)); // TODO: txs is vector> so need to handle } void MoneroTx::toPropertyTree(boost::property_tree::ptree& node) const { - throw runtime_error("Not implemented"); + cout << "MoneroTx::txToPropertyTree(tx)" << endl; + if (id != boost::none) node.put("id", *id); + if (version != boost::none) node.put("version", *version); + if (isCoinbase != boost::none) node.put("isCoinbase", *isCoinbase); + if (paymentId != boost::none) node.put("paymentId", *paymentId); + if (fee != boost::none) node.put("fee", *fee); + if (mixin != boost::none) node.put("mixin", *mixin); + if (doNotRelay != boost::none) node.put("doNotRelay", *doNotRelay); + if (isRelayed != boost::none) node.put("isRelayed", *isRelayed); + if (isConfirmed != boost::none) node.put("isConfirmed", *isConfirmed); + if (inTxPool != boost::none) node.put("inTxPool", *inTxPool); + if (numConfirmations != boost::none) node.put("numConfirmations", *numConfirmations); + if (unlockTime != boost::none) node.put("unlockTime", *unlockTime); + if (lastRelayedTimestamp != boost::none) node.put("lastRelayedTimestamp", *lastRelayedTimestamp); + if (receivedTimestamp != boost::none) node.put("receivedTimestamp", *receivedTimestamp); + if (isDoubleSpend != boost::none) node.put("isDoubleSpend", *isDoubleSpend); + if (key != boost::none) node.put("key", *key); + if (fullHex != boost::none) node.put("fullHex", *fullHex); + if (prunedHex != boost::none) node.put("prunedHex", *prunedHex); + if (prunableHex != boost::none) node.put("prunableHex", *prunableHex); + 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()) throw runtime_error("not implemented"); + if (!vouts.empty()) throw runtime_error("not implemented"); + if (!outputIndices.empty()) throw runtime_error("not implemented"); + if (metadata != boost::none) node.put("metadata", *metadata); + if (commonTxSets != boost::none) throw runtime_error("not implemented"); + if (!extra.empty()) throw runtime_error("not implemented"); + if (rctSignatures != boost::none) throw runtime_error("not implemented"); + if (rctSigPrunable != boost::none) throw runtime_error("not implemented"); + if (isKeptByBlock != boost::none) node.put("isKeptByBlock", *isKeptByBlock); + if (isFailed != boost::none) node.put("isFailed", *isFailed); + if (lastFailedHeight != boost::none) node.put("lastFailedHeight", *lastFailedHeight); + if (lastFailedId != boost::none) node.put("lastFailedId", *lastFailedId); + if (maxUsedBlockHeight != boost::none) node.put("maxUsedBlockHeight", *maxUsedBlockHeight); + if (maxUsedBlockId != boost::none) node.put("maxUsedBlockId", *maxUsedBlockId); + if (!signatures.empty()) throw runtime_error("not implemented"); } // ---------------------------- PRIVATE HELPERS ----------------------------- diff --git a/src/daemon/MoneroDaemon.h b/src/daemon/MoneroDaemon.h index 650679b..c482b83 100644 --- a/src/daemon/MoneroDaemon.h +++ b/src/daemon/MoneroDaemon.h @@ -23,9 +23,16 @@ namespace monero { string serialize() const; /** - * Initializes a property tree node from this struct. + * Convert the struct to a property tree. * - * @param node is the node to initialize + * @return the converted property tree + */ + boost::property_tree::ptree toPropertyTree2() const; + + /** + * Convert the struct to a property tree. + * + * @param node is the property tree node to initialize from the struct */ virtual void toPropertyTree(boost::property_tree::ptree& node) const = 0; }; @@ -98,13 +105,14 @@ namespace monero { boost::optional maxUsedBlockHeight; boost::optional maxUsedBlockId; vector signatures; - virtual void toPropertyTree(boost::property_tree::ptree& node) const; + + void toPropertyTree(boost::property_tree::ptree& node) const; }; /** * Models a Monero block header which contains information about the block. */ - struct MoneroBlockHeader { + struct MoneroBlockHeader : public SerializableStruct { boost::optional id; boost::optional height; boost::optional timestamp; @@ -122,6 +130,8 @@ namespace monero { boost::optional orphanStatus; boost::optional prevId; boost::optional reward; + + void toPropertyTree(boost::property_tree::ptree& node) const; }; /** @@ -132,6 +142,8 @@ namespace monero { boost::optional coinbaseTx; vector> txs; vector txIds; + + void toPropertyTree(boost::property_tree::ptree& node) const; }; /** diff --git a/src/utils/MoneroUtils.cpp b/src/utils/MoneroUtils.cpp index 67ddbc9..4fee706 100644 --- a/src/utils/MoneroUtils.cpp +++ b/src/utils/MoneroUtils.cpp @@ -119,112 +119,3 @@ string MoneroUtils::serialize(const boost::property_tree::ptree& node) { boost::property_tree::write_json(ss, node, false); return ss.str(); } - -boost::property_tree::ptree MoneroUtils::toPropertyTree(const MoneroAccount& account) { - cout << "toPropertyTree(account)" << endl; - boost::property_tree::ptree accountNode; - if (account.index != boost::none) accountNode.put("index", *account.index); - if (account.primaryAddress != boost::none) accountNode.put("primaryAddress", *account.primaryAddress); - if (account.balance != boost::none) accountNode.put("balance", *account.balance); - if (account.unlockedBalance != boost::none) accountNode.put("unlockedBalance", *account.unlockedBalance); - if (!account.subaddresses.empty()) { - boost::property_tree::ptree subaddressesNode; - for (const auto& subaddress : account.subaddresses) { - subaddressesNode.push_back(std::make_pair("", toPropertyTree(subaddress))); - } - accountNode.add_child("subaddresses", subaddressesNode); - } - return accountNode; -} - -boost::property_tree::ptree MoneroUtils::toPropertyTree(const MoneroSubaddress& subaddress) { - cout << "toPropertyTree(subaddress)" << endl; - boost::property_tree::ptree subaddressNode; - if (subaddress.accountIndex != boost::none) subaddressNode.put("accountIndex", *subaddress.accountIndex); - if (subaddress.index != boost::none) subaddressNode.put("index", *subaddress.index); - if (subaddress.address != boost::none) subaddressNode.put("address", *subaddress.address); - if (subaddress.label != boost::none) subaddressNode.put("label", *subaddress.label); - if (subaddress.balance != boost::none) subaddressNode.put("balance", *subaddress.balance); - if (subaddress.unlockedBalance != boost::none) subaddressNode.put("unlockedBalance", *subaddress.unlockedBalance); - if (subaddress.numUnspentOutputs != boost::none) subaddressNode.put("numUnspentOutputs", *subaddress.numUnspentOutputs); - if (subaddress.isUsed != boost::none) subaddressNode.put("isUsed", *subaddress.isUsed); - if (subaddress.numBlocksToUnlock != boost::none) subaddressNode.put("numBlocksToUnlock", *subaddress.numBlocksToUnlock); - return subaddressNode; -} - -boost::property_tree::ptree MoneroUtils::toPropertyTree(const MoneroBlock& block) { - cout << "toPropertyTree(block)" << endl; - boost::property_tree::ptree blockNode; - if (block.height != boost::none) blockNode.put("height", *block.height); // TODO: finish this, add txs - //blockNode.add_child("txs", toPropertyTree(block.txs)); // TODO: block.txs is vector> so need to handle - return blockNode; -} - -boost::property_tree::ptree MoneroUtils::txToPropertyTree(const MoneroTx& tx) { - cout << "txToPropertyTree(tx)" << endl; - boost::property_tree::ptree txNode; - if (tx.id != boost::none) txNode.put("id", *tx.id); - if (tx.version != boost::none) txNode.put("version", *tx.version); - if (tx.isCoinbase != boost::none) txNode.put("isCoinbase", *tx.isCoinbase); - if (tx.paymentId != boost::none) txNode.put("paymentId", *tx.paymentId); - if (tx.fee != boost::none) txNode.put("fee", *tx.fee); - if (tx.mixin != boost::none) txNode.put("mixin", *tx.mixin); - if (tx.doNotRelay != boost::none) txNode.put("doNotRelay", *tx.doNotRelay); - if (tx.isRelayed != boost::none) txNode.put("isRelayed", *tx.isRelayed); - if (tx.isConfirmed != boost::none) txNode.put("isConfirmed", *tx.isConfirmed); - if (tx.inTxPool != boost::none) txNode.put("inTxPool", *tx.inTxPool); - if (tx.numConfirmations != boost::none) txNode.put("numConfirmations", *tx.numConfirmations); - if (tx.unlockTime != boost::none) txNode.put("unlockTime", *tx.unlockTime); - if (tx.lastRelayedTimestamp != boost::none) txNode.put("lastRelayedTimestamp", *tx.lastRelayedTimestamp); - if (tx.receivedTimestamp != boost::none) txNode.put("receivedTimestamp", *tx.receivedTimestamp); - if (tx.isDoubleSpend != boost::none) txNode.put("isDoubleSpend", *tx.isDoubleSpend); - if (tx.key != boost::none) txNode.put("key", *tx.key); - if (tx.fullHex != boost::none) txNode.put("fullHex", *tx.fullHex); - if (tx.prunedHex != boost::none) txNode.put("prunedHex", *tx.prunedHex); - if (tx.prunableHex != boost::none) txNode.put("prunableHex", *tx.prunableHex); - if (tx.prunableHash != boost::none) txNode.put("prunableHash", *tx.prunableHash); - if (tx.size != boost::none) txNode.put("size", *tx.size); - if (tx.weight != boost::none) txNode.put("weight", *tx.weight); - if (!tx.vins.empty()) throw runtime_error("not implemented"); - if (!tx.vouts.empty()) throw runtime_error("not implemented"); - if (!tx.outputIndices.empty()) throw runtime_error("not implemented"); - if (tx.metadata != boost::none) txNode.put("metadata", *tx.metadata); - if (tx.commonTxSets != boost::none) throw runtime_error("not implemented"); - if (!tx.extra.empty()) throw runtime_error("not implemented"); - if (tx.rctSignatures != boost::none) throw runtime_error("not implemented"); - if (tx.rctSigPrunable != boost::none) throw runtime_error("not implemented"); - if (tx.isKeptByBlock != boost::none) txNode.put("isKeptByBlock", *tx.isKeptByBlock); - if (tx.isFailed != boost::none) txNode.put("isFailed", *tx.isFailed); - if (tx.lastFailedHeight != boost::none) txNode.put("lastFailedHeight", *tx.lastFailedHeight); - if (tx.lastFailedId != boost::none) txNode.put("lastFailedId", *tx.lastFailedId); - if (tx.maxUsedBlockHeight != boost::none) txNode.put("maxUsedBlockHeight", *tx.maxUsedBlockHeight); - if (tx.maxUsedBlockId != boost::none) txNode.put("maxUsedBlockId", *tx.maxUsedBlockId); - if (!tx.signatures.empty()) throw runtime_error("not implemented"); - return txNode; -} - -boost::property_tree::ptree MoneroUtils::txWalletToPropertyTree(const MoneroTxWallet& tx) { - cout << "txWalletToPropertyTree(tx)" << endl; - boost::property_tree::ptree txNode = txToPropertyTree(tx); - if (!tx.vouts.empty()) throw runtime_error("not implemented"); - if (!tx.incomingTransfers.empty()) throw runtime_error("not implemented"); - if (tx.outgoingTransfer != boost::none) throw runtime_error("not implemented"); - if (tx.numSuggestedConfirmations != boost::none) txNode.put("numSuggestedConfirmations", *tx.numSuggestedConfirmations); - if (tx.note != boost::none) txNode.put("note", *tx.note); - return txNode; -} - -boost::property_tree::ptree MoneroUtils::txRequestToPropertyTree(const MoneroTxRequest& tx) { - cout << "txWalletToPropertyTree(tx)" << endl; - boost::property_tree::ptree txNode = txWalletToPropertyTree(tx); - if (tx.isOutgoing != boost::none) txNode.put("isOutgoing", *tx.isOutgoing); - if (tx.isIncoming != boost::none) txNode.put("isIncoming", *tx.isIncoming); - if (!tx.txIds.empty()) throw runtime_error("not implemented"); - if (tx.hasPaymentId != boost::none) txNode.put("hasPaymentId", *tx.hasPaymentId); - if (!tx.paymentIds.empty()) throw runtime_error("not implemented"); - if (tx.minHeight != boost::none) txNode.put("minHeight", *tx.minHeight); - if (tx.maxHeight != boost::none) txNode.put("maxHeight", *tx.maxHeight); - if (tx.includeOutputs != boost::none) txNode.put("includeOutputs", *tx.includeOutputs); - if (tx.transferRequest != boost::none) throw runtime_error("not implemented"); - return txNode; -} diff --git a/src/utils/MoneroUtils.h b/src/utils/MoneroUtils.h index b99fc24..5f49b93 100644 --- a/src/utils/MoneroUtils.h +++ b/src/utils/MoneroUtils.h @@ -62,18 +62,6 @@ namespace MoneroUtils string serialize(const boost::property_tree::ptree& node); - boost::property_tree::ptree toPropertyTree(const MoneroAccount& account); - - boost::property_tree::ptree toPropertyTree(const MoneroSubaddress& subaddress); - - boost::property_tree::ptree toPropertyTree(const MoneroBlock& block); - - boost::property_tree::ptree txToPropertyTree(const MoneroTx& tx); - - boost::property_tree::ptree txWalletToPropertyTree(const MoneroTxWallet& tx); - - boost::property_tree::ptree txRequestToPropertyTree(const MoneroTxRequest& tx); - // // 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) { cout << "toPropertyTree(types)" << endl; diff --git a/src/wallet/MoneroWallet.cpp b/src/wallet/MoneroWallet.cpp index 08f4d62..c0beb94 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -16,6 +16,34 @@ namespace monero { // -------------------------- MODEL SERIALIZATION --------------------------- + void MoneroAccount::toPropertyTree(boost::property_tree::ptree& node) const { + cout << "MoneroAccount::toPropertyTree(node)" << endl; + if (index != boost::none) node.put("index", *index); + if (primaryAddress != boost::none) node.put("primaryAddress", *primaryAddress); + if (balance != boost::none) node.put("balance", *balance); + if (unlockedBalance != boost::none) node.put("unlockedBalance", *unlockedBalance); + if (!subaddresses.empty()) { + boost::property_tree::ptree subaddressesNode; + for (const auto& subaddress : subaddresses) { + subaddressesNode.push_back(std::make_pair("", subaddress.toPropertyTree2())); + } + node.add_child("subaddresses", subaddressesNode); + } + } + + void MoneroSubaddress::toPropertyTree(boost::property_tree::ptree& node) const { + cout << "MoneroSubaddress::toPropertyTree(node)" << endl; + if (accountIndex != boost::none) node.put("accountIndex", *accountIndex); + if (index != boost::none) node.put("index", *index); + if (address != boost::none) node.put("address", *address); + if (label != boost::none) node.put("label", *label); + if (balance != boost::none) node.put("balance", *balance); + if (unlockedBalance != boost::none) node.put("unlockedBalance", *unlockedBalance); + if (numUnspentOutputs != boost::none) node.put("numUnspentOutputs", *numUnspentOutputs); + if (isUsed != boost::none) node.put("isUsed", *isUsed); + if (numBlocksToUnlock != boost::none) node.put("numBlocksToUnlock", *numBlocksToUnlock); + } + void MoneroTxWallet::toPropertyTree(boost::property_tree::ptree& node) const { throw runtime_error("Not implemented"); } @@ -24,6 +52,32 @@ namespace monero { throw runtime_error("Not implemented"); } + //boost::property_tree::ptree MoneroUtils::txWalletToPropertyTree(const MoneroTxWallet& tx) { + // cout << "txWalletToPropertyTree(tx)" << endl; + // boost::property_tree::ptree txNode = txToPropertyTree(tx); + // if (!tx.vouts.empty()) throw runtime_error("not implemented"); + // if (!tx.incomingTransfers.empty()) throw runtime_error("not implemented"); + // if (tx.outgoingTransfer != boost::none) throw runtime_error("not implemented"); + // if (tx.numSuggestedConfirmations != boost::none) txNode.put("numSuggestedConfirmations", *tx.numSuggestedConfirmations); + // if (tx.note != boost::none) txNode.put("note", *tx.note); + // return txNode; + //} + // + //boost::property_tree::ptree MoneroUtils::txRequestToPropertyTree(const MoneroTxRequest& tx) { + // cout << "txWalletToPropertyTree(tx)" << endl; + // boost::property_tree::ptree txNode = txWalletToPropertyTree(tx); + // if (tx.isOutgoing != boost::none) txNode.put("isOutgoing", *tx.isOutgoing); + // if (tx.isIncoming != boost::none) txNode.put("isIncoming", *tx.isIncoming); + // if (!tx.txIds.empty()) throw runtime_error("not implemented"); + // if (tx.hasPaymentId != boost::none) txNode.put("hasPaymentId", *tx.hasPaymentId); + // if (!tx.paymentIds.empty()) throw runtime_error("not implemented"); + // if (tx.minHeight != boost::none) txNode.put("minHeight", *tx.minHeight); + // if (tx.maxHeight != boost::none) txNode.put("maxHeight", *tx.maxHeight); + // if (tx.includeOutputs != boost::none) txNode.put("includeOutputs", *tx.includeOutputs); + // if (tx.transferRequest != boost::none) throw runtime_error("not implemented"); + // return txNode; + //} + // ---------------------------- PRIVATE HELPERS ----------------------------- bool boolEquals(bool val, const boost::optional& optVal) { @@ -483,9 +537,9 @@ namespace monero { // print for debug std::stringstream ss; - boost::property_tree::write_json(ss, MoneroUtils::txRequestToPropertyTree(request), false); - string requestStr = ss.str(); - cout << "Tx request: " << requestStr << endl; + //boost::property_tree::write_json(ss, MoneroUtils::txRequestToPropertyTree(request), false); + //string requestStr = ss.str(); + //cout << "Tx request: " << requestStr << endl; diff --git a/src/wallet/MoneroWallet.h b/src/wallet/MoneroWallet.h index 34acb04..b597bde 100644 --- a/src/wallet/MoneroWallet.h +++ b/src/wallet/MoneroWallet.h @@ -29,7 +29,7 @@ namespace monero { /** * Models a Monero subaddress. */ - struct MoneroSubaddress { + struct MoneroSubaddress : public SerializableStruct { boost::optional accountIndex; boost::optional index; boost::optional address; @@ -50,12 +50,14 @@ namespace monero { // KV_SERIALIZE(isUsed) // KV_SERIALIZE(numBlocksToUnlock) // END_KV_SERIALIZE_MAP() + + void toPropertyTree(boost::property_tree::ptree& node) const; }; /** * Models a Monero account. */ - struct MoneroAccount { + struct MoneroAccount : public SerializableStruct { boost::optional index; boost::optional primaryAddress; boost::optional label; @@ -72,6 +74,8 @@ namespace monero { // KV_SERIALIZE(tag) // KV_SERIALIZE(subaddresses) // END_KV_SERIALIZE_MAP() + + void toPropertyTree(boost::property_tree::ptree& node) const; }; // forward declarations