aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2023-03-21 14:44:27 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2023-03-21 21:05:53 +0000
commit7a4a03d9d3413258b00122d56675d3a029b52013 (patch)
treea7297f0bd08f2a0a7dcdcc7b5eb828e934b57600
parentMerge pull request #8775 (diff)
downloadmonero-7a4a03d9d3413258b00122d56675d3a029b52013.tar.xz
wallet2: do not commit transactions more than once
Fixes #8793
-rw-r--r--src/wallet/wallet2.cpp18
-rwxr-xr-xtests/functional_tests/transfer.py34
2 files changed, 52 insertions, 0 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index e61bfa9f0..227ea19bd 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -6745,6 +6745,24 @@ void wallet2::commit_tx(pending_tx& ptx)
crypto::hash txid;
txid = get_transaction_hash(ptx.tx);
+
+ // if it's already processed, bail
+ if (std::find_if(m_transfers.begin(), m_transfers.end(), [&txid](const transfer_details &td) { return td.m_txid == txid; }) != m_transfers.end())
+ {
+ MDEBUG("Transaction " << txid << " already processed");
+ return;
+ }
+ if (m_unconfirmed_txs.find(txid) != m_unconfirmed_txs.end())
+ {
+ MDEBUG("Transaction " << txid << " already processed");
+ return;
+ }
+ if (m_confirmed_txs.find(txid) != m_confirmed_txs.end())
+ {
+ MDEBUG("Transaction " << txid << " already processed");
+ return;
+ }
+
crypto::hash payment_id = crypto::null_hash;
std::vector<cryptonote::tx_destination_entry> dests;
uint64_t amount_in = 0;
diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py
index dd15369d3..fc3906f7e 100755
--- a/tests/functional_tests/transfer.py
+++ b/tests/functional_tests/transfer.py
@@ -52,6 +52,7 @@ class TransferTest():
self.check_tx_notes()
self.check_rescan()
self.check_is_key_image_spent()
+ self.check_multiple_submissions()
def reset(self):
print('Resetting blockchain')
@@ -829,6 +830,39 @@ class TransferTest():
res = daemon.is_key_image_spent(ki)
assert res.spent_status == expected
+ def check_multiple_submissions(self):
+ daemon = Daemon()
+
+ print('Testing multiple submissions')
+
+ dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
+
+ self.wallet[0].refresh()
+ res = self.wallet[0].get_balance()
+ balance = res.balance
+
+ res = self.wallet[0].transfer([dst], ring_size = 16, get_tx_key = False, get_tx_hex = False, get_tx_metadata = True)
+ tx_hex = res.tx_metadata
+ tx_fee = res.fee
+ res = self.wallet[0].relay_tx(tx_hex)
+
+ # submit again before mined
+ res = self.wallet[0].relay_tx(tx_hex)
+ daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1)
+
+ self.wallet[0].refresh()
+ res = self.wallet[0].get_balance()
+ assert res.balance == balance - tx_fee
+
+ balance = res.balance
+
+ # submit again after mined
+ res = self.wallet[0].relay_tx(tx_hex)
+ daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1)
+
+ self.wallet[0].refresh()
+ res = self.wallet[0].get_balance()
+ assert res.balance == balance
if __name__ == '__main__':
TransferTest().run_test()