From d64689470706dbf33ef525cc2fe37dda7100f3bd Mon Sep 17 00:00:00 2001 From: woodser Date: Sun, 16 Jun 2019 09:48:44 -0400 Subject: [PATCH] merge(self, other) with base shared_ptrs to suppoert merge inheritance --- src/daemon/MoneroDaemon.cpp | 328 ++++++++++++++++++------------------ src/daemon/MoneroDaemon.h | 10 +- src/wallet/MoneroWallet.cpp | 37 ++-- src/wallet/MoneroWallet.h | 5 +- 4 files changed, 193 insertions(+), 187 deletions(-) diff --git a/src/daemon/MoneroDaemon.cpp b/src/daemon/MoneroDaemon.cpp index ed82ae7..67f4ba6 100644 --- a/src/daemon/MoneroDaemon.cpp +++ b/src/daemon/MoneroDaemon.cpp @@ -98,183 +98,183 @@ namespace monero { // -------------------------- MODEL IMPLEMENTATION -------------------------- - void MoneroBlockHeader::merge(const MoneroBlockHeader& header) { + void MoneroBlockHeader::merge(const shared_ptr& header) { cout << "MoneroBlockHeader::merge()" << endl; - if (this == &header) return; - id = MoneroUtils::reconcile(id, header.id); - height = MoneroUtils::reconcile(height, header.height, boost::none, boost::none, true); // height can increase - timestamp = MoneroUtils::reconcile(timestamp, header.timestamp, boost::none, boost::none, true); // timestamp can increase - size = MoneroUtils::reconcile(size, header.size); - weight = MoneroUtils::reconcile(weight, header.weight); - longTermWeight = MoneroUtils::reconcile(longTermWeight, header.longTermWeight); - depth = MoneroUtils::reconcile(depth, header.depth); - difficulty = MoneroUtils::reconcile(difficulty, header.difficulty); - cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, header.cumulativeDifficulty); - majorVersion = MoneroUtils::reconcile(majorVersion, header.majorVersion); - minorVersion = MoneroUtils::reconcile(minorVersion, header.minorVersion); - nonce = MoneroUtils::reconcile(nonce, header.nonce); - coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, header.coinbaseTxId); - numTxs = MoneroUtils::reconcile(numTxs, header.numTxs); - orphanStatus = MoneroUtils::reconcile(orphanStatus, header.orphanStatus); - prevId = MoneroUtils::reconcile(prevId, header.prevId); - reward = MoneroUtils::reconcile(reward, header.reward); - powHash = MoneroUtils::reconcile(powHash, header.powHash); +// if (this == &header) return; +// id = MoneroUtils::reconcile(id, header.id); +// height = MoneroUtils::reconcile(height, header.height, boost::none, boost::none, true); // height can increase +// timestamp = MoneroUtils::reconcile(timestamp, header.timestamp, boost::none, boost::none, true); // timestamp can increase +// size = MoneroUtils::reconcile(size, header.size); +// weight = MoneroUtils::reconcile(weight, header.weight); +// longTermWeight = MoneroUtils::reconcile(longTermWeight, header.longTermWeight); +// depth = MoneroUtils::reconcile(depth, header.depth); +// difficulty = MoneroUtils::reconcile(difficulty, header.difficulty); +// cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, header.cumulativeDifficulty); +// majorVersion = MoneroUtils::reconcile(majorVersion, header.majorVersion); +// minorVersion = MoneroUtils::reconcile(minorVersion, header.minorVersion); +// nonce = MoneroUtils::reconcile(nonce, header.nonce); +// coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, header.coinbaseTxId); +// numTxs = MoneroUtils::reconcile(numTxs, header.numTxs); +// orphanStatus = MoneroUtils::reconcile(orphanStatus, header.orphanStatus); +// prevId = MoneroUtils::reconcile(prevId, header.prevId); +// reward = MoneroUtils::reconcile(reward, header.reward); +// powHash = MoneroUtils::reconcile(powHash, header.powHash); } - void MoneroBlock::merge(const MoneroBlock& block) { + void MoneroBlock::merge(const shared_ptr& block) { cout << "MoneroBlock::merge()" << endl; - if (this == &block) return; - - // merge header fields - MoneroBlockHeader::merge(block); - - // merge coinbase tx - if (coinbaseTx == boost::none) coinbaseTx = block.coinbaseTx; - else if (block.coinbaseTx != boost::none) (**coinbaseTx).merge(**block.coinbaseTx); - - // merge non-coinbase txs - if (txs.empty()) txs = block.txs; - else if (!block.txs.empty()) { - for (const shared_ptr& thatTx : block.txs) { - bool found = false; - for (const shared_ptr& thisTx : txs) { - if (thatTx->id == thisTx->id) { - thisTx->merge(*thatTx); - found = true; - break; - } - } - if (!found) txs.push_back(thatTx); - } - } - if (!txs.empty()) { - for (const shared_ptr& tx : txs) { - tx->block = shared_ptr(this); - } - } - - // merge other fields - hex = MoneroUtils::reconcile(hex, block.hex); - //txIds = MoneroUtils::reconcile(txIds, block.txIds); // TODO: implement - cout << "Returning from block::merge()!" << endl; +// if (this == &block) return; +// +// // merge header fields +// MoneroBlockHeader::merge(block); +// +// // merge coinbase tx +// if (coinbaseTx == boost::none) coinbaseTx = block.coinbaseTx; +// else if (block.coinbaseTx != boost::none) (**coinbaseTx).merge(**block.coinbaseTx); +// +// // merge non-coinbase txs +// if (txs.empty()) txs = block.txs; +// else if (!block.txs.empty()) { +// for (const shared_ptr& thatTx : block.txs) { +// bool found = false; +// for (const shared_ptr& thisTx : txs) { +// if (thatTx->id == thisTx->id) { +// thisTx->merge(*thatTx); +// found = true; +// break; +// } +// } +// if (!found) txs.push_back(thatTx); +// } +// } +// if (!txs.empty()) { +// for (const shared_ptr& tx : txs) { +// tx->block = shared_ptr(this); +// } +// } +// +// // merge other fields +// hex = MoneroUtils::reconcile(hex, block.hex); +// //txIds = MoneroUtils::reconcile(txIds, block.txIds); // TODO: implement +// cout << "Returning from block::merge()!" << endl; } - void MoneroTx::merge(const MoneroTx& tx) { + void MoneroTx::merge(const shared_ptr& self, const shared_ptr& other) { cout << "MoneroTx::merge()" << endl; - if (this == &tx) return; - id = MoneroUtils::reconcile(id, tx.id); - version = MoneroUtils::reconcile(version, tx.version); - paymentId = MoneroUtils::reconcile(paymentId, tx.paymentId); - fee = MoneroUtils::reconcile(fee, tx.fee); - mixin = MoneroUtils::reconcile(mixin, tx.mixin); - isConfirmed = MoneroUtils::reconcile(isConfirmed, tx.isConfirmed); - doNotRelay = MoneroUtils::reconcile(doNotRelay, tx.doNotRelay); - isRelayed = MoneroUtils::reconcile(isRelayed, tx.isRelayed); - isDoubleSpend = MoneroUtils::reconcile(isDoubleSpend, tx.isDoubleSpend); - key = MoneroUtils::reconcile(key, tx.key); - fullHex = MoneroUtils::reconcile(fullHex, tx.fullHex); - prunedHex = MoneroUtils::reconcile(prunedHex, tx.prunedHex); - prunableHex = MoneroUtils::reconcile(prunableHex, tx.prunableHex); - prunableHash = MoneroUtils::reconcile(prunableHash, tx.prunableHash); - size = MoneroUtils::reconcile(size, tx.size); - weight = MoneroUtils::reconcile(weight, tx.weight); - //outputIndices = MoneroUtils::reconcile(outputIndices, tx.outputIndices); // TODO - metadata = MoneroUtils::reconcile(metadata, tx.metadata); - commonTxSets = MoneroUtils::reconcile(commonTxSets, tx.commonTxSets); - //extra = MoneroUtils::reconcile(extra, tx.extra); // TODO - rctSignatures = MoneroUtils::reconcile(rctSignatures, tx.rctSignatures); - rctSigPrunable = MoneroUtils::reconcile(rctSigPrunable, tx.rctSigPrunable); - isKeptByBlock = MoneroUtils::reconcile(isKeptByBlock, tx.isKeptByBlock); - isFailed = MoneroUtils::reconcile(isFailed, tx.isFailed); - lastFailedHeight = MoneroUtils::reconcile(lastFailedHeight, tx.lastFailedHeight); - lastFailedId = MoneroUtils::reconcile(lastFailedId, tx.lastFailedId); - maxUsedBlockHeight = MoneroUtils::reconcile(maxUsedBlockHeight, tx.maxUsedBlockHeight); - maxUsedBlockId = MoneroUtils::reconcile(maxUsedBlockId, tx.maxUsedBlockId); - //signatures = MoneroUtils::reconcile(signatures, tx.signatures); // TODO - unlockTime = MoneroUtils::reconcile(unlockTime, tx.unlockTime); - numConfirmations = MoneroUtils::reconcile(numConfirmations, tx.numConfirmations); - - // merge vins - if (!tx.vins.empty()) { - for (const shared_ptr& merger : tx.vins) { - bool merged = false; - merger->tx = shared_ptr(this); // TODO: can this cause this* to be deleted prematurely? - for (const shared_ptr& mergee : vins) { - if ((*mergee->keyImage)->hex == (*merger->keyImage)->hex) { - mergee->merge(*merger); - merged = true; - break; - } - } - if (!merged) vins.push_back(merger); - } - } - - // merge vouts - if (!tx.vouts.empty()) { - for (const shared_ptr& vout : tx.vouts) vout->tx = shared_ptr(this); - if (vouts.empty()) vouts = tx.vouts; - else { - - // determine if key images present - int numKeyImages = 0; - for (const shared_ptr vout : vouts) { - if (vout->keyImage != boost::none) { - if ((*vout->keyImage)->hex == boost::none) throw runtime_error("Key image hex cannot be null"); - numKeyImages++; - } - } - for (const shared_ptr& vout : tx.vouts) { - if (vout->keyImage != boost::none) { - if ((*vout->keyImage)->hex == boost::none) throw runtime_error("Key image hex cannot be null"); - numKeyImages++; - } - } - if (numKeyImages != 0 && vouts.size() + tx.vouts.size() != numKeyImages) throw runtime_error("Some vouts have a key image and some do not"); - - // merge by key images - if (numKeyImages > 0) { - for (const shared_ptr& merger : tx.vouts) { - bool merged = false; - for (const shared_ptr& mergee : vouts) { - if ((*mergee->keyImage)->hex == (*merger->keyImage)->hex) { - mergee->merge(*merger); - merged = true; - break; - } - } - if (!merged) vouts.push_back(merger); - } - } - - // merge by position - else { - if (vouts.size() != tx.vouts.size()) throw runtime_error("Vout sizes are different"); - for (int i = 0; i < tx.vouts.size(); i++) { - vouts.at(i)->merge(*tx.vouts.at(i)); - } - } - } - } - - // handle unrelayed -> relayed -> confirmed - if (*isConfirmed) { - inTxPool = false; - receivedTimestamp = boost::none; - lastRelayedTimestamp = boost::none; - } else { - inTxPool = MoneroUtils::reconcile(inTxPool, tx.inTxPool, boost::none, true, boost::none); // unrelayed -> tx pool - receivedTimestamp = MoneroUtils::reconcile(receivedTimestamp, tx.receivedTimestamp, boost::none, boost::none, false); // take earliest receive time - lastRelayedTimestamp = MoneroUtils::reconcile(lastRelayedTimestamp, tx.lastRelayedTimestamp, boost::none, boost::none, true); // take latest relay time - } +// if (this == &tx) return; +// id = MoneroUtils::reconcile(id, tx.id); +// version = MoneroUtils::reconcile(version, tx.version); +// paymentId = MoneroUtils::reconcile(paymentId, tx.paymentId); +// fee = MoneroUtils::reconcile(fee, tx.fee); +// mixin = MoneroUtils::reconcile(mixin, tx.mixin); +// isConfirmed = MoneroUtils::reconcile(isConfirmed, tx.isConfirmed); +// doNotRelay = MoneroUtils::reconcile(doNotRelay, tx.doNotRelay); +// isRelayed = MoneroUtils::reconcile(isRelayed, tx.isRelayed); +// isDoubleSpend = MoneroUtils::reconcile(isDoubleSpend, tx.isDoubleSpend); +// key = MoneroUtils::reconcile(key, tx.key); +// fullHex = MoneroUtils::reconcile(fullHex, tx.fullHex); +// prunedHex = MoneroUtils::reconcile(prunedHex, tx.prunedHex); +// prunableHex = MoneroUtils::reconcile(prunableHex, tx.prunableHex); +// prunableHash = MoneroUtils::reconcile(prunableHash, tx.prunableHash); +// size = MoneroUtils::reconcile(size, tx.size); +// weight = MoneroUtils::reconcile(weight, tx.weight); +// //outputIndices = MoneroUtils::reconcile(outputIndices, tx.outputIndices); // TODO +// metadata = MoneroUtils::reconcile(metadata, tx.metadata); +// commonTxSets = MoneroUtils::reconcile(commonTxSets, tx.commonTxSets); +// //extra = MoneroUtils::reconcile(extra, tx.extra); // TODO +// rctSignatures = MoneroUtils::reconcile(rctSignatures, tx.rctSignatures); +// rctSigPrunable = MoneroUtils::reconcile(rctSigPrunable, tx.rctSigPrunable); +// isKeptByBlock = MoneroUtils::reconcile(isKeptByBlock, tx.isKeptByBlock); +// isFailed = MoneroUtils::reconcile(isFailed, tx.isFailed); +// lastFailedHeight = MoneroUtils::reconcile(lastFailedHeight, tx.lastFailedHeight); +// lastFailedId = MoneroUtils::reconcile(lastFailedId, tx.lastFailedId); +// maxUsedBlockHeight = MoneroUtils::reconcile(maxUsedBlockHeight, tx.maxUsedBlockHeight); +// maxUsedBlockId = MoneroUtils::reconcile(maxUsedBlockId, tx.maxUsedBlockId); +// //signatures = MoneroUtils::reconcile(signatures, tx.signatures); // TODO +// unlockTime = MoneroUtils::reconcile(unlockTime, tx.unlockTime); +// numConfirmations = MoneroUtils::reconcile(numConfirmations, tx.numConfirmations); +// +// // merge vins +// if (!tx.vins.empty()) { +// for (const shared_ptr& merger : tx.vins) { +// bool merged = false; +// merger->tx = shared_ptr(this); // TODO: can this cause this* to be deleted prematurely? +// for (const shared_ptr& mergee : vins) { +// if ((*mergee->keyImage)->hex == (*merger->keyImage)->hex) { +// mergee->merge(*merger); +// merged = true; +// break; +// } +// } +// if (!merged) vins.push_back(merger); +// } +// } +// +// // merge vouts +// if (!tx.vouts.empty()) { +// for (const shared_ptr& vout : tx.vouts) vout->tx = shared_ptr(this); +// if (vouts.empty()) vouts = tx.vouts; +// else { +// +// // determine if key images present +// int numKeyImages = 0; +// for (const shared_ptr vout : vouts) { +// if (vout->keyImage != boost::none) { +// if ((*vout->keyImage)->hex == boost::none) throw runtime_error("Key image hex cannot be null"); +// numKeyImages++; +// } +// } +// for (const shared_ptr& vout : tx.vouts) { +// if (vout->keyImage != boost::none) { +// if ((*vout->keyImage)->hex == boost::none) throw runtime_error("Key image hex cannot be null"); +// numKeyImages++; +// } +// } +// if (numKeyImages != 0 && vouts.size() + tx.vouts.size() != numKeyImages) throw runtime_error("Some vouts have a key image and some do not"); +// +// // merge by key images +// if (numKeyImages > 0) { +// for (const shared_ptr& merger : tx.vouts) { +// bool merged = false; +// for (const shared_ptr& mergee : vouts) { +// if ((*mergee->keyImage)->hex == (*merger->keyImage)->hex) { +// mergee->merge(*merger); +// merged = true; +// break; +// } +// } +// if (!merged) vouts.push_back(merger); +// } +// } +// +// // merge by position +// else { +// if (vouts.size() != tx.vouts.size()) throw runtime_error("Vout sizes are different"); +// for (int i = 0; i < tx.vouts.size(); i++) { +// vouts.at(i)->merge(*tx.vouts.at(i)); +// } +// } +// } +// } +// +// // handle unrelayed -> relayed -> confirmed +// if (*isConfirmed) { +// inTxPool = false; +// receivedTimestamp = boost::none; +// lastRelayedTimestamp = boost::none; +// } else { +// inTxPool = MoneroUtils::reconcile(inTxPool, tx.inTxPool, boost::none, true, boost::none); // unrelayed -> tx pool +// receivedTimestamp = MoneroUtils::reconcile(receivedTimestamp, tx.receivedTimestamp, boost::none, boost::none, false); // take earliest receive time +// lastRelayedTimestamp = MoneroUtils::reconcile(lastRelayedTimestamp, tx.lastRelayedTimestamp, boost::none, boost::none, true); // take latest relay time +// } } - void MoneroKeyImage::merge(const MoneroKeyImage& keyImage) { + void MoneroKeyImage::merge(const shared_ptr& self, const shared_ptr& other) { cout << "MoneroKeyImage::merge()" << endl; throw runtime_error("Not implemented"); } - void MoneroOutput::merge(const MoneroOutput& output) { + void MoneroOutput::merge(const shared_ptr& self, const shared_ptr& other) { cout << "MoneroOutput::merge()" << endl; throw runtime_error("Not implemented"); } diff --git a/src/daemon/MoneroDaemon.h b/src/daemon/MoneroDaemon.h index 60dc825..7fde5d3 100644 --- a/src/daemon/MoneroDaemon.h +++ b/src/daemon/MoneroDaemon.h @@ -82,7 +82,7 @@ namespace monero { boost::optional powHash; boost::property_tree::ptree toPropertyTree() const; - void merge(const MoneroBlockHeader& header); + void merge(const shared_ptr& header); }; /** @@ -95,7 +95,7 @@ namespace monero { vector txIds; boost::property_tree::ptree toPropertyTree() const; - void merge(const MoneroBlock& block); + void merge(const shared_ptr& block); }; /** @@ -147,7 +147,7 @@ namespace monero { if (block == boost::none) return boost::none; return *((*block)->height); } - void merge(const MoneroTx& tx); + void merge(const shared_ptr& self, const shared_ptr& other); }; /** @@ -157,7 +157,7 @@ namespace monero { boost::optional hex; boost::optional signature; - void merge(const MoneroKeyImage& keyImage); + void merge(const shared_ptr& self, const shared_ptr& other); }; /** @@ -171,7 +171,7 @@ namespace monero { vector ringOutputIndices; boost::optional stealthPublicKey; - void merge(const MoneroOutput& output); + void merge(const shared_ptr& self, const shared_ptr& other); }; } diff --git a/src/wallet/MoneroWallet.cpp b/src/wallet/MoneroWallet.cpp index f92be1f..aacac8e 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -185,8 +185,8 @@ namespace monero { * @param skipIfAbsent specifies if the tx should not be added if it doesn't already exist * @returns the merged tx */ - void mergeTx(vector>& txs, const shared_ptr& tx, bool skipIfAbsent) { - cout << "mergeTx()" << endl; + void mergeTx(vector>& txs, const shared_ptr& tx, bool skipIfAbsent) { + cout << "mergeTx(txs, txs)" << endl; if (tx->id == boost::none) throw runtime_error("Tx id is not initialized"); for (const auto& aTx: txs) { @@ -209,16 +209,16 @@ namespace monero { (*tx->block)->txs = txs; (*tx->block)->height = *aTx->getHeight(); } - (*aTx->block)->merge(**tx->block); + (*aTx->block)->merge(*tx->block); } else { - aTx->merge(*tx); + aTx->merge(aTx, tx); } return; } // merge common block of different txs if (tx->getHeight() != boost::none && *tx->getHeight() == *aTx->getHeight()) { - (*aTx->block)->merge(**tx->block); + (*aTx->block)->merge(*tx->block); //if (aTx.getIsConfirmed()) assertTrue(aTx.getBlock().getTxs().contains(aTx)); } } @@ -624,7 +624,7 @@ namespace monero { // createSubaddress - vector MoneroWallet::getTxs(const MoneroTxRequest& request) const { + vector> MoneroWallet::getTxs(const MoneroTxRequest& request) const { cout << "getTxs(request)" << endl; // print for debug @@ -673,14 +673,14 @@ namespace monero { // collect unique transactions - vector> txs; + vector> txs; // get confirmed incoming transfers if (isIn) { std::list> payments; wallet2->get_payments(payments, minHeight, maxHeight, accountIndex, subaddressIndices); for (std::list>::const_iterator i = payments.begin(); i != payments.end(); ++i) { - shared_ptr tx = buildTxWithIncomingTransfer(i->second.m_tx_hash, i->first, i->second); + shared_ptr tx = buildTxWithIncomingTransfer(i->second.m_tx_hash, i->first, i->second); mergeTx(txs, tx, false); //txs.push_back(tx); } @@ -706,7 +706,8 @@ namespace monero { // collect resulting transfers vector> transfers; for (int i = 0; i < txs.size(); i++) { - shared_ptr tx = txs[i]; + shared_ptr txBase = txs[i]; + const MoneroTxWallet* tx = static_cast(&*txBase); // shared_ptrs use base class but these are actually MoneroTxWallets for (int j = 0; j < tx->incomingTransfers.size(); j++) { transfers.push_back(tx->incomingTransfers[j]); } @@ -862,16 +863,19 @@ namespace monero { return subaddresses; } - shared_ptr MoneroWallet::buildTxWithIncomingTransfer(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const { + shared_ptr MoneroWallet::buildTxWithIncomingTransfer(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const { cout << "buildTxWithIncomingTransfer()" << endl; + // construct block shared_ptr block = shared_ptr(new MoneroBlock()); block->height = pd.m_block_height; block->timestamp = pd.m_timestamp; - shared_ptr tx = shared_ptr(new MoneroTxWallet()); + // construct tx + shared_ptr txBase = shared_ptr(new MoneroTxWallet()); + MoneroTxWallet* tx = static_cast(&*txBase); // get MoneroTxWallet* from base shared_ptr tx->block = block; - block->txs.push_back(tx); + block->txs.push_back(txBase); tx->id = string_tools::pod_to_hex(pd.m_tx_hash); tx->paymentId = string_tools::pod_to_hex(payment_id); if (tx->paymentId->substr(16).find_first_not_of('0') == std::string::npos) tx->paymentId = tx->paymentId->substr(0, 16); // TODO monero core: this should be part of core wallet @@ -894,9 +898,10 @@ namespace monero { else tx->numConfirmations = chainHeight - *block->height; // construct transfer - shared_ptr incomingTransfer = shared_ptr(new MoneroIncomingTransfer()); - incomingTransfer->tx = tx; - tx->incomingTransfers.push_back(incomingTransfer); + shared_ptr incomingTransferBase = shared_ptr(new MoneroIncomingTransfer()); + MoneroIncomingTransfer* incomingTransfer = static_cast(&*incomingTransferBase); + incomingTransfer->tx = txBase; + tx->incomingTransfers.push_back(incomingTransferBase); incomingTransfer->amount = pd.m_amount; incomingTransfer->accountIndex = pd.m_subaddr_index.major; incomingTransfer->subaddressIndex = pd.m_subaddr_index.minor; @@ -908,7 +913,7 @@ namespace monero { else incomingTransfer->numSuggestedConfirmations = (*incomingTransfer->amount + blockReward - 1) / blockReward; // return pointer to new tx - return tx; + return txBase; } // MoneroTransfer MoneroWallet::convertWallet2IncomingTransfer(const tools::wallet2& wallet2, const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const { diff --git a/src/wallet/MoneroWallet.h b/src/wallet/MoneroWallet.h index 9e4fe7e..ed581ac 100644 --- a/src/wallet/MoneroWallet.h +++ b/src/wallet/MoneroWallet.h @@ -52,6 +52,7 @@ namespace monero { // END_KV_SERIALIZE_MAP() boost::property_tree::ptree toPropertyTree() const; + //void merge(const shared_ptr& self, const shared_ptr& other); }; /** @@ -686,7 +687,7 @@ namespace monero { * @param request filters query results (optional) * @return wallet transactions per the request */ - vector getTxs(const MoneroTxRequest& request) const; + vector> getTxs(const MoneroTxRequest& request) const; // /** // * Get all incoming and outgoing transfers to and from this wallet. An @@ -1267,7 +1268,7 @@ namespace monero { MoneroSyncResult syncAux(boost::optional startHeight, boost::optional endHeight, boost::optional listener); vector getSubaddressesAux(uint32_t accountIdx, vector subaddressIndices, vector transfers) const; - shared_ptr buildTxWithIncomingTransfer(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const; + shared_ptr buildTxWithIncomingTransfer(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const; }; }