diff --git a/src/daemon/MoneroDaemonModel.cpp b/src/daemon/MoneroDaemonModel.cpp index 071fb6f..50fe198 100644 --- a/src/daemon/MoneroDaemonModel.cpp +++ b/src/daemon/MoneroDaemonModel.cpp @@ -409,6 +409,13 @@ namespace monero { // --------------------------- MONERO KEY IMAGE ----------------------------- + shared_ptr MoneroKeyImage::copy(const shared_ptr& src, const shared_ptr& tgt) const { + if (this != src.get()) throw runtime_error("this != src"); + tgt->hex = src->hex; + tgt->signature = src->signature; + return tgt; + } + boost::property_tree::ptree MoneroKeyImage::toPropertyTree() const { boost::property_tree::ptree node; if (hex != boost::none) node.put("hex", *hex); @@ -423,7 +430,14 @@ namespace monero { // ------------------------------ MONERO OUTPUT ----------------------------- shared_ptr MoneroOutput::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroOutput::copy() not implemented"); + if (this != src.get()) throw runtime_error("this != src"); + tgt->tx = src->tx; // reference same parent tx by default + 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); + tgt->stealthPublicKey = src->stealthPublicKey; + return tgt; } boost::property_tree::ptree MoneroOutput::toPropertyTree() const { diff --git a/src/daemon/MoneroDaemonModel.h b/src/daemon/MoneroDaemonModel.h index d3b1f87..7a753f7 100644 --- a/src/daemon/MoneroDaemonModel.h +++ b/src/daemon/MoneroDaemonModel.h @@ -205,6 +205,7 @@ namespace monero { boost::optional hex; boost::optional signature; + shared_ptr copy(const shared_ptr& src, const shared_ptr& tgt) const; 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 6f3623d..358a2b1 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -1394,10 +1394,12 @@ namespace monero { if (request.txRequest == boost::none) req = request.copy(make_shared(request), make_shared()); else { shared_ptr txReq = request.txRequest.get()->copy(request.txRequest.get(), make_shared()); - if (request.txRequest.get()->transferRequest.get().get() == &request) req = txReq->transferRequest.get(); - else { + if (request.txRequest.get()->transferRequest != boost::none && request.txRequest.get()->transferRequest.get().get() == &request) { + req = txReq->transferRequest.get(); + } else { if (request.txRequest.get()->transferRequest != boost::none) throw new runtime_error("Transfer request's tx request must be a circular reference or null"); - req = request.copy(make_shared(request), make_shared()); + shared_ptr requestSp = make_shared(request); // convert request to shared pointer for copy + req = requestSp->copy(requestSp, make_shared()); req->txRequest = txReq; } } diff --git a/src/wallet/MoneroWalletModel.cpp b/src/wallet/MoneroWalletModel.cpp index 635e920..eac187b 100644 --- a/src/wallet/MoneroWalletModel.cpp +++ b/src/wallet/MoneroWalletModel.cpp @@ -121,7 +121,7 @@ namespace monero { if (!src->incomingTransfers.empty()) { tgt->incomingTransfers = vector>(); for (const shared_ptr& transfer : src->incomingTransfers) { - shared_ptr transferCopy = transfer->copy(transfer, shared_ptr()); + shared_ptr transferCopy = transfer->copy(transfer, make_shared()); transferCopy->tx = tgt; tgt->incomingTransfers.push_back(transferCopy); } @@ -211,6 +211,7 @@ namespace monero { tgt->includeOutputs = src->includeOutputs; if (src->transferRequest != boost::none) tgt->transferRequest = src->transferRequest.get()->copy(src->transferRequest.get(), make_shared()); if (src->outputRequest != boost::none) tgt->outputRequest = src->outputRequest.get()->copy(src->outputRequest.get(), make_shared()); + return tgt; }; boost::property_tree::ptree MoneroTxRequest::toPropertyTree() const { @@ -281,6 +282,14 @@ namespace monero { // -------------------------- MONERO DESTINATION ---------------------------- + shared_ptr MoneroDestination::copy(const shared_ptr& src, const shared_ptr& tgt) const { + MTRACE("MoneroDestination::copy(const shared_ptr& src, const shared_ptr& tgt)"); + if (this != src.get()) throw runtime_error("this != src"); + tgt->address = src->address; + tgt->amount = src->amount; + return tgt; + }; + boost::property_tree::ptree MoneroDestination::toPropertyTree() const { boost::property_tree::ptree node; if (address != boost::none) node.put("address", *address); @@ -291,8 +300,13 @@ namespace monero { // ---------------------------- MONERO TRANSFER ----------------------------- shared_ptr MoneroTransfer::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroTransfer::copy() not implemented"); - }; + MTRACE("MoneroTransfer::copy(const shared_ptr& src, const shared_ptr& tgt)"); + tgt->tx = src->tx; // reference parent tx by default + tgt->amount = src->amount; + tgt->accountIndex = src->accountIndex; + tgt->numSuggestedConfirmations = src->numSuggestedConfirmations; + return tgt; + } boost::property_tree::ptree MoneroTransfer::toPropertyTree() const { boost::property_tree::ptree node; @@ -329,10 +343,13 @@ namespace monero { // ----------------------- MONERO INCOMING TRANSFER ------------------------- shared_ptr MoneroIncomingTransfer::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroIncomingTransfer::copy(transfer) not implemented"); - }; + return copy(static_pointer_cast(src), static_pointer_cast(tgt)); + } shared_ptr MoneroIncomingTransfer::copy(const shared_ptr& src, const shared_ptr& tgt) const { + + + throw runtime_error("MoneroIncomingTransfer::copy(inTransfer) not implemented"); }; @@ -359,7 +376,7 @@ namespace monero { // ----------------------- MONERO OUTGOING TRANSFER ------------------------- shared_ptr MoneroOutgoingTransfer::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroOutgoingTransfer::copy(transfer) not implemented"); + return copy(static_pointer_cast(src), static_pointer_cast(tgt)); }; shared_ptr MoneroOutgoingTransfer::copy(const shared_ptr& src, const shared_ptr& tgt) const { @@ -391,13 +408,30 @@ namespace monero { // ----------------------- MONERO TRANSFER REQUEST -------------------------- shared_ptr MoneroTransferRequest::copy(const shared_ptr& src, const shared_ptr& tgt) const { - MTRACE("MoneroTransferRequest::copy(const shared_ptr& src, const shared_ptr& tgt"); - throw runtime_error("MoneroTransferRequest::copy(transfer) not implemented"); + return copy(static_pointer_cast(src), static_pointer_cast(tgt)); }; shared_ptr MoneroTransferRequest::copy(const shared_ptr& src, const shared_ptr& tgt) const { MTRACE("MoneroTransferRequest::copy(const shared_ptr& src, const shared_ptr& tgt)"); - throw runtime_error("MoneroTransferRequest::copy(request) not implemented"); + if (this != src.get()) throw runtime_error("this != src"); + + // copy base class + MoneroTransfer::copy(static_pointer_cast(src), static_pointer_cast(tgt)); + + // copy extensions + tgt->isIncoming = src->isIncoming; + tgt->address = src->address; + if (!src->addresses.empty()) tgt->addresses = vector(src->addresses); + tgt->subaddressIndex = src->subaddressIndex; + if (!src->subaddressIndices.empty()) tgt->subaddressIndices = vector(src->subaddressIndices); + if (!src->destinations.empty()) { + for (const shared_ptr& destination : src->destinations) { + tgt->destinations.push_back(destination->copy(destination, make_shared())); + } + } + tgt->hasDestinations = src->hasDestinations; + tgt->txRequest = src->txRequest; + return tgt; }; boost::optional MoneroTransferRequest::getIsIncoming() const { return isIncoming; } @@ -524,15 +558,17 @@ namespace monero { // ------------------------ MONERO OUTPUT REQUEST --------------------------- shared_ptr MoneroOutputRequest::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroOutputRequest::copy(output) not implemented"); + return MoneroOutputRequest::copy(static_pointer_cast(src), static_pointer_cast(tgt)); }; shared_ptr MoneroOutputRequest::copy(const shared_ptr& src, const shared_ptr& tgt) const { - throw runtime_error("MoneroOutputRequest::copy(outputWallet) not implemented"); + return MoneroOutputRequest::copy(static_pointer_cast(src), static_pointer_cast(tgt)); }; shared_ptr MoneroOutputRequest::copy(const shared_ptr& src, const shared_ptr& tgt) const { throw runtime_error("MoneroOutputRequest::copy(outputRequest) not implemented"); + if (this != src.get()) throw runtime_error("this != src"); + throw runtime_error("MoneroOutputRequest::copy() not implemented"); }; boost::property_tree::ptree MoneroOutputRequest::toPropertyTree() const { diff --git a/src/wallet/MoneroWalletModel.h b/src/wallet/MoneroWalletModel.h index 879f196..a5c885b 100644 --- a/src/wallet/MoneroWalletModel.h +++ b/src/wallet/MoneroWalletModel.h @@ -135,6 +135,7 @@ namespace monero { boost::optional address; boost::optional amount; + shared_ptr copy(const shared_ptr& src, const shared_ptr& tgt) const; boost::property_tree::ptree toPropertyTree() const; };