Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifications to enable Offline Signing in monero-gui and possible... #9492

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

DiosDelRayo
Copy link

… other projects via UR or other mediums of exchange.

This PR is part of the CCS Monero Signer Resurrection (milestone 4). The modifications are needed to get the blobs of the offline signing data exchange without writing and reading from disk. To merge UR additions to monero-gui, this needs to be merged first.

   Added the following signatures in the mention files:

   wallet/wallet2.h
   +    std::string export_key_images_string(bool all = false) const;
   +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);
   M    bool wallet2::export_key_images(const std::string &filename, bool all) const

   wallet/api/pending_transaction.h
   +    std::string commit_string() override;

   wallet/api/unsigned_transaction.h
   +    std::string signAsString() override;

   wallet/api/wallet.h:
   +    bool submitTransactionFromString(const std::string &fileName) override;
   +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override;
   +    std::string exportKeyImagesAsString(bool all = false) override;
   +    bool importKeyImagesFromString(const std::string &data) override;
   +    std::string exportOutputsAsString(bool all = false) override;
   +    bool importOutputsFromString(const std::string &data) override;

   wallet/api/wallet2_api.h
   +    virtual std::string commit_string() = 0;
   +    virtual std::string signAsString() = 0;
   +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0;
   +    virtual bool submitTransactionFromString(const std::string &fileName) = 0;
   +    virtual bool importKeyImagesFromString(const std::string &data) = 0;
   +    virtual std::string exportOutputsAsString(bool all = false) = 0;
   +    virtual bool importOutputsFromString(const std::string &data) = 0;
   +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);

   And the implementations in:

   wallet/wallet2.cpp
   wallet/api/pending_transaction.cpp
   wallet/api/unsigned_transaction.cpp
   wallet/api/wallet.cpp

   The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to
   use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file.
   IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or
   use a std::string for the actual payload instead of a file path.

   One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up.

   This modifications was done to get all the necessary data for offline signing via UR or any other channel not
   using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is.

who asks? and others added 15 commits July 17, 2024 20:09
…ther projects via UR or other mediums of

       exchange.

       Added the following signatures in the mention files:

       wallet/wallet2.h
       +    std::string export_key_images_string(bool all = false) const;
       +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);
       M    bool wallet2::export_key_images(const std::string &filename, bool all) const

       wallet/api/pending_transaction.h
       +    std::string commit_string() override;

       wallet/api/unsigned_transaction.h
       +    std::string signAsString() override;

       wallet/api/wallet.h:
       +    bool submitTransactionFromString(const std::string &fileName) override;
       +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override;
       +    std::string exportKeyImagesAsString(bool all = false) override;
       +    bool importKeyImagesFromString(const std::string &data) override;
       +    std::string exportOutputsAsString(bool all = false) override;
       +    bool importOutputsFromString(const std::string &data) override;

       wallet/api/wallet2_api.h
       +    virtual std::string commit_string() = 0;
       +    virtual std::string signAsString() = 0;
       +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0;
       +    virtual bool submitTransactionFromString(const std::string &fileName) = 0;
       +    virtual bool importKeyImagesFromString(const std::string &data) = 0;
       +    virtual std::string exportOutputsAsString(bool all = false) = 0;
       +    virtual bool importOutputsFromString(const std::string &data) = 0;
       +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);

       And the implementations in:

       wallet/wallet2.cpp
       wallet/api/pending_transaction.cpp
       wallet/api/unsigned_transaction.cpp
       wallet/api/wallet.cpp

       The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to
       use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file.
       IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or
       use a std::string for the actual payload instead of a file path.

       One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up.

       This modifications was done to get all the necessary data for offline signing via UR or any other channel not
       using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is.
…ther projects via UR or other mediums of exchange.

       Added the following signatures in the mention files:

       wallet/wallet2.h
       +    std::string export_key_images_string(bool all = false) const;
       +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);
       M    bool wallet2::export_key_images(const std::string &filename, bool all) const

       wallet/api/pending_transaction.h
       +    std::string commit_string() override;

       wallet/api/unsigned_transaction.h
       +    std::string signAsString() override;

       wallet/api/wallet.h:
       +    bool submitTransactionFromString(const std::string &fileName) override;
       +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override;
       +    std::string exportKeyImagesAsString(bool all = false) override;
       +    bool importKeyImagesFromString(const std::string &data) override;
       +    std::string exportOutputsAsString(bool all = false) override;
       +    bool importOutputsFromString(const std::string &data) override;

       wallet/api/wallet2_api.h
       +    virtual std::string commit_string() = 0;
       +    virtual std::string signAsString() = 0;
       +    virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0;
       +    virtual bool submitTransactionFromString(const std::string &fileName) = 0;
       +    virtual bool importKeyImagesFromString(const std::string &data) = 0;
       +    virtual std::string exportOutputsAsString(bool all = false) = 0;
       +    virtual bool importOutputsFromString(const std::string &data) = 0;
       +    uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);

       And the implementations in:

       wallet/wallet2.cpp
       wallet/api/pending_transaction.cpp
       wallet/api/unsigned_transaction.cpp
       wallet/api/wallet.cpp

       The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to
       use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file.
       IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or
       use a std::string for the actual payload instead of a file path.

       One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up.

       This modifications was done to get all the necessary data for offline signing via UR or any other channel not
       using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is.
DiosDelRayo pushed a commit to DiosDelRayo/monero-gui that referenced this pull request Sep 27, 2024
	and needs to get enabled with `WITH_OTS_UR` to compile with UR.

	This update depends on [monero
	PR](monero-project/monero#9492).
	It cannot work without modifications on monero core!

	@tobtoht also mentions that build with static Qt5 will not
	work. I compiled and tested exclusively with ubuntu 24.04
	in Qt Creator with Qt 5.15.2
Copy link
Contributor

@sneurlax sneurlax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK and the code changes LGTM for the most part. Functions are separated, errors are handled well, and documentation via inline comments is in-line with the status quo. You could add more comments in areas, but the context around your changes also lacks comments, so they're in the established style in those cases--but could nevertheless be commented and I think in that case breaking convention/style would be justified. Unit tests could also be added, although this could be a good first issue for a subsequent contributor after this is merged.

Copy link

@SNeedlewoods SNeedlewoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran out of time for a full review today, but for the first pass it's looking mostly good, left a few comments in case you want to look into things already before I finish the review.

Thanks for your contribution.

src/wallet/api/pending_transaction.cpp Outdated Show resolved Hide resolved
src/wallet/api/pending_transaction.cpp Outdated Show resolved Hide resolved
LOG_ERROR(m_errorString);
m_status = Status_Error;
}
m_wallet.startRefresh();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think this is needed.

@@ -1134,6 +1134,27 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}

UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &data) {
clearStatus();
UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminds me of this issue: #9461

src/wallet/wallet2.cpp Show resolved Hide resolved
Copy link

@SNeedlewoods SNeedlewoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2, review complete.
From this round the only relevant change for code flow is setStatus() to setStatusError().
Other things may be more subjective and/or only style related.

src/wallet/api/wallet.cpp Outdated Show resolved Hide resolved
src/wallet/api/wallet.cpp Show resolved Hide resolved
src/wallet/api/wallet.cpp Outdated Show resolved Hide resolved
src/wallet/api/wallet.h Outdated Show resolved Hide resolved
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keyword virtual should be used in the interface file wallet2_api.h only. (I know this is violated already in several places in the current API.)

And parameter name unsigned_filename should be data.

src/wallet/api/wallet2_api.h Outdated Show resolved Hide resolved
src/wallet/api/wallet2_api.h Outdated Show resolved Hide resolved
src/wallet/api/wallet2_api.h Outdated Show resolved Hide resolved
SNeedlewoods pushed a commit to SNeedlewoods/seraphis_wallet that referenced this pull request Oct 21, 2024
(Method name: reason)
signTxToStr: gets added in monero-project#9492 as `signAsString()`
loadTx: not needed, all it does is `loadFromFile()` and `parseTxFromStr()`
estimateBacklog(min_tx_weight, max_tx_weight, fees): not needed, calls `estimateBacklog(fee_levels)`
SNeedlewoods pushed a commit to SNeedlewoods/seraphis_wallet that referenced this pull request Oct 31, 2024
(Method name: reason)
signTxToStr: gets added in monero-project#9492 as `signAsString()`
loadTx: not needed, all it does is `loadFromFile()` and `parseTxFromStr()`
estimateBacklog(min_tx_weight, max_tx_weight, fees): not needed, calls `estimateBacklog(fee_levels)`
Copy link

@SNeedlewoods SNeedlewoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from what I wrote you on Matrix, here are two more minor things I found on this round of the review.
Will take another look later, but so far this is looking good, thanks for your work.


bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL);
if (!r) {
setStatusError(Status_Ok, tr("Failed to load transaction from string"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
setStatusError(Status_Ok, tr("Failed to load transaction from string"));
setStatusError(tr("Failed to load transaction from string"));

virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &data) override;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &data) override;
UnsignedTransaction * loadUnsignedTxFromString(const std::string &data) override;

@MrCyjaneK
Copy link

https://github.com/MrCyjaneK/monero_c/blob/master/patches/monero/0012-WIP-UR-functions.patch <- with functions that export UR strings redy to be displayed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants