From f3c095ae6ae698ca376fe68eb4a943b550346a11 Mon Sep 17 00:00:00 2001 From: woodser Date: Fri, 21 Jun 2019 17:32:51 -0400 Subject: [PATCH] define output stack; cleanup daemon model impl --- src/daemon/MoneroDaemonModel.cpp | 155 +++++++++++++++++-------------- src/daemon/MoneroDaemonModel.h | 3 +- src/wallet/MoneroWallet.cpp | 2 +- src/wallet/MoneroWallet.h | 2 +- src/wallet/MoneroWalletModel.cpp | 27 ++++++ src/wallet/MoneroWalletModel.h | 29 +++--- 6 files changed, 132 insertions(+), 86 deletions(-) diff --git a/src/daemon/MoneroDaemonModel.cpp b/src/daemon/MoneroDaemonModel.cpp index bc665d3..205361b 100644 --- a/src/daemon/MoneroDaemonModel.cpp +++ b/src/daemon/MoneroDaemonModel.cpp @@ -6,8 +6,6 @@ /** * Public library interface. - * - * TODO: separate per model class like wallet (cleanup) */ namespace monero { @@ -15,12 +13,14 @@ namespace monero { const string MoneroTx::DEFAULT_PAYMENT_ID = string("0000000000000000"); - // -------------------------- MODEL SERIALIZATION --------------------------- + // ------------------------- SERIALIZABLE STRUCT ---------------------------- string SerializableStruct::serialize() const { return MoneroUtils::serialize(toPropertyTree()); } + // ------------------------- MONERO BLOCK HEADER ---------------------------- + boost::property_tree::ptree MoneroBlockHeader::toPropertyTree() const { //cout << "MoneroBlockHeader::toPropertyTree(block)" << endl; boost::property_tree::ptree node; @@ -45,6 +45,31 @@ namespace monero { return node; } + void MoneroBlockHeader::merge(const shared_ptr& self, const shared_ptr& other) { + if (this != self.get()) throw runtime_error("this != self"); + if (self == other) return; + id = MoneroUtils::reconcile(id, other->id); + height = MoneroUtils::reconcile(height, other->height, boost::none, boost::none, true); // height can increase + timestamp = MoneroUtils::reconcile(timestamp, other->timestamp, boost::none, boost::none, true); // timestamp can increase + size = MoneroUtils::reconcile(size, other->size); + weight = MoneroUtils::reconcile(weight, other->weight); + longTermWeight = MoneroUtils::reconcile(longTermWeight, other->longTermWeight); + depth = MoneroUtils::reconcile(depth, other->depth); + difficulty = MoneroUtils::reconcile(difficulty, other->difficulty); + cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, other->cumulativeDifficulty); + majorVersion = MoneroUtils::reconcile(majorVersion, other->majorVersion); + minorVersion = MoneroUtils::reconcile(minorVersion, other->minorVersion); + nonce = MoneroUtils::reconcile(nonce, other->nonce); + coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, other->coinbaseTxId); + numTxs = MoneroUtils::reconcile(numTxs, other->numTxs); + orphanStatus = MoneroUtils::reconcile(orphanStatus, other->orphanStatus); + prevId = MoneroUtils::reconcile(prevId, other->prevId); + reward = MoneroUtils::reconcile(reward, other->reward); + powHash = MoneroUtils::reconcile(powHash, other->powHash); + } + + // ----------------------------- MONERO BLOCK ------------------------------- + boost::property_tree::ptree MoneroBlock::toPropertyTree() const { //cout << "MoneroBlock::toPropertyTree(block)" << endl; boost::property_tree::ptree node = MoneroBlockHeader::toPropertyTree(); @@ -55,6 +80,48 @@ namespace monero { return node; } + void MoneroBlock::merge(const shared_ptr& self, const shared_ptr& other) { + if (this != self.get()) throw runtime_error("this != self"); + if (self == other) return; + + // merge header fields + MoneroBlockHeader::merge(self, other); + + // convert other to MoneroBlock* + MoneroBlock* otherBlock = static_cast(other.get()); + + // merge coinbase tx + if (coinbaseTx == boost::none) coinbaseTx = otherBlock->coinbaseTx; + else if (otherBlock->coinbaseTx != boost::none) (**coinbaseTx).merge(*coinbaseTx, *otherBlock->coinbaseTx); + + // merge non-coinbase txs + if (txs.empty()) txs = otherBlock->txs; + else if (!otherBlock->txs.empty()) { + for (const shared_ptr& thatTx : otherBlock->txs) { + bool found = false; + for (const shared_ptr& thisTx : txs) { + if (thatTx->id == thisTx->id) { + thisTx->merge(thisTx, thatTx); + found = true; + break; + } + } + if (!found) txs.push_back(thatTx); + } + } + if (!txs.empty()) { + for (const shared_ptr& tx : txs) { + tx->block = static_pointer_cast(self); + } + } + + // merge other fields + hex = MoneroUtils::reconcile(hex, otherBlock->hex); + //txIds = MoneroUtils::reconcile(txIds, otherBlock->txIds); // TODO: implement + } + + // ------------------------------- MONERO TX -------------------------------- + boost::property_tree::ptree MoneroTx::toPropertyTree() const { //cout << "MoneroTx::txToPropertyTree(tx)" << endl; boost::property_tree::ptree node; @@ -98,71 +165,6 @@ namespace monero { return node; } - // -------------------------- MODEL IMPLEMENTATION -------------------------- - - void MoneroBlockHeader::merge(const shared_ptr& self, const shared_ptr& other) { - if (this != self.get()) throw runtime_error("this != self"); - if (self == other) return; - id = MoneroUtils::reconcile(id, other->id); - height = MoneroUtils::reconcile(height, other->height, boost::none, boost::none, true); // height can increase - timestamp = MoneroUtils::reconcile(timestamp, other->timestamp, boost::none, boost::none, true); // timestamp can increase - size = MoneroUtils::reconcile(size, other->size); - weight = MoneroUtils::reconcile(weight, other->weight); - longTermWeight = MoneroUtils::reconcile(longTermWeight, other->longTermWeight); - depth = MoneroUtils::reconcile(depth, other->depth); - difficulty = MoneroUtils::reconcile(difficulty, other->difficulty); - cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, other->cumulativeDifficulty); - majorVersion = MoneroUtils::reconcile(majorVersion, other->majorVersion); - minorVersion = MoneroUtils::reconcile(minorVersion, other->minorVersion); - nonce = MoneroUtils::reconcile(nonce, other->nonce); - coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, other->coinbaseTxId); - numTxs = MoneroUtils::reconcile(numTxs, other->numTxs); - orphanStatus = MoneroUtils::reconcile(orphanStatus, other->orphanStatus); - prevId = MoneroUtils::reconcile(prevId, other->prevId); - reward = MoneroUtils::reconcile(reward, other->reward); - powHash = MoneroUtils::reconcile(powHash, other->powHash); - } - - void MoneroBlock::merge(const shared_ptr& self, const shared_ptr& other) { - if (this != self.get()) throw runtime_error("this != self"); - if (self == other) return; - - // merge header fields - MoneroBlockHeader::merge(self, other); - - // convert other to MoneroBlock* - MoneroBlock* otherBlock = static_cast(other.get()); - - // merge coinbase tx - if (coinbaseTx == boost::none) coinbaseTx = otherBlock->coinbaseTx; - else if (otherBlock->coinbaseTx != boost::none) (**coinbaseTx).merge(*coinbaseTx, *otherBlock->coinbaseTx); - - // merge non-coinbase txs - if (txs.empty()) txs = otherBlock->txs; - else if (!otherBlock->txs.empty()) { - for (const shared_ptr& thatTx : otherBlock->txs) { - bool found = false; - for (const shared_ptr& thisTx : txs) { - if (thatTx->id == thisTx->id) { - thisTx->merge(thisTx, thatTx); - found = true; - break; - } - } - if (!found) txs.push_back(thatTx); - } - } - if (!txs.empty()) { - for (const shared_ptr& tx : txs) { - tx->block = static_pointer_cast(self); - } - } - - // merge other fields - hex = MoneroUtils::reconcile(hex, otherBlock->hex); - //txIds = MoneroUtils::reconcile(txIds, otherBlock->txIds); // TODO: implement - } - boost::optional MoneroTx::getHeight() const { if (block == boost::none) return boost::none; return *((*block)->height); @@ -278,9 +280,14 @@ namespace monero { } } - void MoneroKeyImage::merge(const shared_ptr& self, const shared_ptr& other) { - cout << "MoneroKeyImage::merge()" << endl; - throw runtime_error("Not implemented"); + // ------------------------------ MONERO OUTPUT ----------------------------- + + boost::property_tree::ptree MoneroOutput::toPropertyTree() const { + //cout << "MoneroOutput::txToPropertyTree(tx)" << endl; + boost::property_tree::ptree node; + //if (id != boost::none) node.put("id", *id); TODO + throw runtime_error("MoneroOutput toPropertyTree() not implemented"); + return node; } void MoneroOutput::merge(const shared_ptr& self, const shared_ptr& other) { @@ -288,6 +295,10 @@ namespace monero { throw runtime_error("Not implemented"); } - // ---------------------------- PRIVATE HELPERS ----------------------------- + // --------------------------- MONERO KEY IMAGE ----------------------------- + void MoneroKeyImage::merge(const shared_ptr& self, const shared_ptr& other) { + cout << "MoneroKeyImage::merge()" << endl; + throw runtime_error("Not implemented"); + } } diff --git a/src/daemon/MoneroDaemonModel.h b/src/daemon/MoneroDaemonModel.h index 4c0762b..f6c5162 100644 --- a/src/daemon/MoneroDaemonModel.h +++ b/src/daemon/MoneroDaemonModel.h @@ -160,7 +160,7 @@ namespace monero { /** * Models a Monero transaction output. */ - struct MoneroOutput { + struct MoneroOutput : public SerializableStruct { shared_ptr tx; boost::optional> keyImage; boost::optional amount; @@ -168,6 +168,7 @@ namespace monero { vector ringOutputIndices; boost::optional stealthPublicKey; + boost::property_tree::ptree toPropertyTree() const; void merge(const shared_ptr& self, const shared_ptr& other); }; } diff --git a/src/wallet/MoneroWallet.cpp b/src/wallet/MoneroWallet.cpp index 1eea5d1..74388af 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -639,7 +639,7 @@ namespace monero { return transfers; } - vector MoneroWallet::getOutputs(const MoneroOutputRequest& request) const { + vector> MoneroWallet::getOutputs(const MoneroOutputRequest& request) const { cout << "getOutputs(request)" << endl; throw runtime_error("Not implemented"); } diff --git a/src/wallet/MoneroWallet.h b/src/wallet/MoneroWallet.h index f8d4e85..250e545 100644 --- a/src/wallet/MoneroWallet.h +++ b/src/wallet/MoneroWallet.h @@ -586,7 +586,7 @@ namespace monero { * @param request specifies request options (optional) * @return List are wallet outputs per the request */ - vector getOutputs(const MoneroOutputRequest& request) const; + vector> getOutputs(const MoneroOutputRequest& request) const; // // /** // * Get all signed key images. diff --git a/src/wallet/MoneroWalletModel.cpp b/src/wallet/MoneroWalletModel.cpp index ee81a80..7a48256 100644 --- a/src/wallet/MoneroWalletModel.cpp +++ b/src/wallet/MoneroWalletModel.cpp @@ -308,4 +308,31 @@ namespace monero { if (txRequest != boost::none && !(*txRequest)->meetsCriteria(transfer->tx.get())) return false; return true; } + + // ------------------------- MONERO OUTPUT WALLET --------------------------- + + boost::property_tree::ptree MoneroOutputWallet::toPropertyTree() const { + //cout << "MoneroTransfer::toPropertyTree(node)" << endl; + boost::property_tree::ptree node = MoneroOutput::toPropertyTree(); + if (accountIndex != boost::none) node.put("accountIndex", *accountIndex); + if (subaddressIndex != boost::none) node.put("subaddressIndex", *subaddressIndex); + if (isSpent != boost::none) node.put("isSpent", *isSpent); + if (isUnlocked != boost::none) node.put("isUnlocked", *isUnlocked); + if (isFrozen != boost::none) node.put("isFrozen", *isFrozen); + return node; + } + + // ------------------------ MONERO OUTPUT REQUEST --------------------------- + + boost::property_tree::ptree MoneroOutputRequest::toPropertyTree() const { + cout << "MoneroOutputRequest::toPropertyTree(node)" << endl; + boost::property_tree::ptree node = MoneroOutputWallet::toPropertyTree(); + if (!subaddressIndices.empty()) throw runtime_error("MoneroOutputRequest toPropertyTree() subaddressIndices not implemented"); + return node; + } + + bool MoneroOutputRequest::meetsCriteria(MoneroOutputWallet* output) const { + cout << "MoneroOutputRequest::meetsCriteria()" << endl; + throw runtime_error("Not implemented"); + } } diff --git a/src/wallet/MoneroWalletModel.h b/src/wallet/MoneroWalletModel.h index 5c3ecc4..297f7b3 100644 --- a/src/wallet/MoneroWalletModel.h +++ b/src/wallet/MoneroWalletModel.h @@ -141,6 +141,7 @@ namespace monero { vector> destinations; boost::optional hasDestinations; boost::optional> txRequest; + boost::optional getIsIncoming() const; boost::property_tree::ptree toPropertyTree() const; bool meetsCriteria(MoneroTransfer* transfer) const; @@ -155,6 +156,22 @@ namespace monero { boost::optional isSpent; boost::optional isUnlocked; boost::optional isFrozen; + + boost::property_tree::ptree toPropertyTree() const; + }; + + /** + * Configures a request to retrieve wallet outputs (i.e. outputs that the wallet has or had the + * ability to spend). + * + * All outputs are returned except those that do not meet the criteria defined in this request. + */ + struct MoneroOutputRequest : public MoneroOutputWallet { + vector subaddressIndices; + boost::optional> txRequest; + + boost::property_tree::ptree toPropertyTree() const; + bool meetsCriteria(MoneroOutputWallet* output) const; }; /** @@ -185,19 +202,9 @@ namespace monero { boost::optional maxHeight; boost::optional includeOutputs; boost::optional> transferRequest; + boost::optional> outputRequest; boost::property_tree::ptree toPropertyTree() const; bool meetsCriteria(MoneroTxWallet* tx) const; }; - - /** - * Configures a request to retrieve wallet outputs (i.e. outputs that the wallet has or had the - * ability to spend). - * - * All outputs are returned except those that do not meet the criteria defined in this request. - */ - struct MoneroOutputRequest : public MoneroOutput { - vector subaddressIndices; - boost::optional> txRequest; - }; }