diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2023-03-21 14:44:27 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2023-03-21 21:05:53 +0000 |
commit | 7a4a03d9d3413258b00122d56675d3a029b52013 (patch) | |
tree | a7297f0bd08f2a0a7dcdcc7b5eb828e934b57600 | |
parent | Merge pull request #8775 (diff) | |
download | monero-7a4a03d9d3413258b00122d56675d3a029b52013.tar.xz |
wallet2: do not commit transactions more than once
Fixes #8793
-rw-r--r-- | src/wallet/wallet2.cpp | 18 | ||||
-rwxr-xr-x | tests/functional_tests/transfer.py | 34 |
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() |