-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,6 +162,44 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) | |
return m_status == Status_Ok; | ||
} | ||
|
||
std::string PendingTransactionImpl::commit_string() | ||
{ | ||
|
||
std::string tx; | ||
LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size()); | ||
|
||
try { | ||
tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx); | ||
m_status = Status_Ok; | ||
} catch (const tools::error::daemon_busy&) { | ||
// TODO: make it translatable with "tr"? | ||
m_errorString = tr("daemon is busy. Please try again later."); | ||
m_status = Status_Error; | ||
} catch (const tools::error::no_connection_to_daemon&) { | ||
m_errorString = tr("no connection to daemon. Please make sure daemon is running."); | ||
m_status = Status_Error; | ||
} catch (const tools::error::tx_rejected& e) { | ||
std::ostringstream writer(m_errorString); | ||
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); | ||
std::string reason = e.reason(); | ||
m_status = Status_Error; | ||
m_errorString = writer.str(); | ||
if (!reason.empty()) | ||
m_errorString += string(tr(". Reason: ")) + reason; | ||
} catch (const std::exception &e) { | ||
m_errorString = string(tr("Unknown exception: ")) + e.what(); | ||
m_status = Status_Error; | ||
} catch (...) { | ||
m_errorString = tr("Unhandled exception"); | ||
LOG_ERROR(m_errorString); | ||
m_status = Status_Error; | ||
} | ||
Comment on lines
+174
to
+196
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems these |
||
m_wallet.startRefresh(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't think this is needed. |
||
if (m_status != Status_Ok) | ||
return ""; | ||
return tx; | ||
} | ||
|
||
uint64_t PendingTransactionImpl::amount() const | ||
{ | ||
uint64_t result = 0; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reminds me of this issue: #9461 |
||
if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){ | ||
setStatusError(tr("Failed to load unsigned transactions")); | ||
transaction->m_status = UnsignedTransaction::Status::Status_Error; | ||
transaction->m_errorString = errorString(); | ||
|
||
return transaction; | ||
} | ||
|
||
// Check tx data and construct confirmation message | ||
std::string extra_message; | ||
if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty()) | ||
extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str(); | ||
transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message); | ||
setStatus(transaction->status(), transaction->errorString()); | ||
|
||
return transaction; | ||
} | ||
|
||
bool WalletImpl::submitTransaction(const string &fileName) { | ||
clearStatus(); | ||
if (checkBackgroundSync("cannot submit tx")) | ||
|
@@ -1154,6 +1175,48 @@ bool WalletImpl::submitTransaction(const string &fileName) { | |
return true; | ||
} | ||
|
||
bool WalletImpl::submitTransactionFromString(const string &data) { | ||
clearStatus(); | ||
if (checkBackgroundSync("cannot submit tx")) | ||
return false; | ||
std::unique_ptr<PendingTransactionImpl> transaction(new PendingTransactionImpl(*this)); | ||
|
||
bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL); | ||
if (!r) { | ||
setStatus(Status_Ok, tr("Failed to load transaction from string")); | ||
DiosDelRayo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return false; | ||
} | ||
|
||
if(!transaction->commit()) { | ||
setStatusError(transaction->m_errorString); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
std::string WalletImpl::exportKeyImagesAsString(bool all) | ||
{ | ||
if (m_wallet->watch_only()) | ||
{ | ||
setStatusError(tr("Wallet is view only")); | ||
return ""; | ||
} | ||
if (checkBackgroundSync("cannot export key images")) | ||
return ""; | ||
|
||
try | ||
{ | ||
return m_wallet->export_key_images_string(all); | ||
DiosDelRayo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
catch (const std::exception &e) | ||
{ | ||
LOG_ERROR("Error exporting key images: " << e.what()); | ||
setStatusError(e.what()); | ||
return ""; | ||
} | ||
} | ||
|
||
bool WalletImpl::exportKeyImages(const string &filename, bool all) | ||
{ | ||
if (m_wallet->watch_only()) | ||
|
@@ -1181,6 +1244,31 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) | |
return true; | ||
} | ||
|
||
bool WalletImpl::importKeyImagesFromString(const std::string &data) | ||
{ | ||
if (checkBackgroundSync("cannot import key images")) | ||
return false; | ||
if (!trustedDaemon()) { | ||
setStatusError(tr("Key images can only be imported with a trusted daemon")); | ||
return false; | ||
} | ||
try | ||
{ | ||
uint64_t spent = 0, unspent = 0; | ||
uint64_t height = m_wallet->import_key_images_string(data, spent, unspent); | ||
LOG_PRINT_L2("Signed key images imported to height " << height << ", " | ||
<< print_money(spent) << " spent, " << print_money(unspent) << " unspent"); | ||
} | ||
catch (const std::exception &e) | ||
{ | ||
LOG_ERROR("Error exporting key images: " << e.what()); | ||
setStatusError(string(tr("Failed to import key images: ")) + e.what()); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
DiosDelRayo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
bool WalletImpl::importKeyImages(const string &filename) | ||
{ | ||
if (checkBackgroundSync("cannot import key images")) | ||
|
@@ -1206,6 +1294,29 @@ bool WalletImpl::importKeyImages(const string &filename) | |
return true; | ||
} | ||
|
||
std::string WalletImpl::exportOutputsAsString(bool all) | ||
{ | ||
if (checkBackgroundSync("cannot export outputs")) | ||
return ""; | ||
if (m_wallet->key_on_device()) | ||
{ | ||
setStatusError(string(tr("Not supported on HW wallets."))); | ||
return ""; | ||
} | ||
|
||
try | ||
{ | ||
return m_wallet->export_outputs_to_str(all); | ||
} | ||
catch (const std::exception &e) | ||
{ | ||
LOG_ERROR("Error exporting outputs: " << e.what()); | ||
setStatusError(string(tr("Error exporting outputs: ")) + e.what()); | ||
return ""; | ||
} | ||
return ""; | ||
} | ||
|
||
bool WalletImpl::exportOutputs(const string &filename, bool all) | ||
{ | ||
if (checkBackgroundSync("cannot export outputs")) | ||
|
@@ -1238,6 +1349,32 @@ bool WalletImpl::exportOutputs(const string &filename, bool all) | |
return true; | ||
} | ||
|
||
bool WalletImpl::importOutputsFromString(const std::string &data) | ||
{ | ||
if (checkBackgroundSync("cannot import outputs")) | ||
return false; | ||
if (m_wallet->key_on_device()) | ||
{ | ||
setStatusError(string(tr("Not supported on HW wallets."))); | ||
return false; | ||
} | ||
|
||
|
||
try | ||
{ | ||
size_t n_outputs = m_wallet->import_outputs_from_str(data); | ||
LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported"); | ||
} | ||
catch (const std::exception &e) | ||
{ | ||
LOG_ERROR("Failed to import outputs: " << e.what()); | ||
setStatusError(string(tr("Failed to import outputs: ")) + e.what()); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool WalletImpl::importOutputs(const string &filename) | ||
{ | ||
if (checkBackgroundSync("cannot import outputs")) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,8 @@ struct PendingTransaction | |
virtual ~PendingTransaction() = 0; | ||
virtual int status() const = 0; | ||
virtual std::string errorString() const = 0; | ||
// return string of transaction gives the same content which would be saved to file with commit(filename) | ||
virtual std::string commit_string() = 0; | ||
// commit transaction or save to file if filename is provided. | ||
virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; | ||
virtual uint64_t amount() const = 0; | ||
|
@@ -161,6 +163,11 @@ struct UnsignedTransaction | |
* return - true on success | ||
*/ | ||
virtual bool sign(const std::string &signedFileName) = 0; | ||
/*! | ||
* @brief sign - Sign txs and return as string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: |
||
* return - true on success | ||
*/ | ||
virtual std::string signAsString() = 0; | ||
}; | ||
|
||
/** | ||
|
@@ -895,11 +902,24 @@ struct Wallet | |
*/ | ||
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; | ||
|
||
/*! | ||
* \brief loadUnsignedTxFromString - creates transaction from unsigned tx string | ||
* \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() | ||
* after object returned | ||
*/ | ||
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; | ||
DiosDelRayo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/*! | ||
* \brief submitTransaction - submits transaction in signed tx file | ||
* \return - true on success | ||
*/ | ||
virtual bool submitTransaction(const std::string &fileName) = 0; | ||
|
||
/*! | ||
* \brief submitTransactionFromString - submits transaction in signed tx file | ||
* \return - true on success | ||
*/ | ||
virtual bool submitTransactionFromString(const std::string &fileName) = 0; | ||
DiosDelRayo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
/*! | ||
|
@@ -916,13 +936,27 @@ struct Wallet | |
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations, | ||
PendingTransaction::Priority priority) const = 0; | ||
|
||
/*! | ||
* \brief exportKeyImages - exports key images as string | ||
* \param all - export all key images or only those that have not yet been exported | ||
* \return - key images as std::string | ||
*/ | ||
virtual std::string exportKeyImagesAsString(bool all = false) = 0; | ||
|
||
/*! | ||
* \brief exportKeyImages - exports key images to file | ||
* \param filename | ||
* \param all - export all key images or only those that have not yet been exported | ||
* \return - true on success | ||
*/ | ||
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; | ||
|
||
/*! | ||
* \brief importKeyImagesFromString - imports key images from string for UR use. | ||
* \param data | ||
* \return - true on success | ||
*/ | ||
virtual bool importKeyImagesFromString(const std::string &data) = 0; | ||
|
||
/*! | ||
* \brief importKeyImages - imports key images from file | ||
|
@@ -932,12 +966,25 @@ struct Wallet | |
virtual bool importKeyImages(const std::string &filename) = 0; | ||
|
||
/*! | ||
* \brief importOutputs - exports outputs to file | ||
* \brief exportOutputsAsString - exports outputs to a string for UR | ||
* \return - true on success | ||
*/ | ||
virtual std::string exportOutputsAsString(bool all = false) = 0; | ||
|
||
/*! | ||
* \brief exportOutputs - exports outputs to file | ||
* \param filename | ||
* \return - true on success | ||
*/ | ||
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0; | ||
|
||
/*! | ||
* \brief importOutputsFromString - imports outputs from string for UR | ||
* \param filename | ||
* \return - true on success | ||
*/ | ||
virtual bool importOutputsFromString(const std::string &data) = 0; | ||
|
||
/*! | ||
* \brief importOutputs - imports outputs from file | ||
* \param filename | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other methods in this file (and in the wallet API in general) are written in camelCase instead of snake_case.
And I would suggest a name closer to the wallet2 origin like
dumpTxToStr()
.