ui: Add option to remove expired offers and bids.
This commit is contained in:
		
							parent
							
								
									1dcd750fea
								
							
						
					
					
						commit
						cbb3d0ac02
					
				@ -145,6 +145,7 @@ from .basicswap_util import (
 | 
				
			|||||||
    NotificationTypes as NT,
 | 
					    NotificationTypes as NT,
 | 
				
			||||||
    AutomationOverrideOptions,
 | 
					    AutomationOverrideOptions,
 | 
				
			||||||
    VisibilityOverrideOptions,
 | 
					    VisibilityOverrideOptions,
 | 
				
			||||||
 | 
					    inactive_states,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -6109,6 +6110,12 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            session.remove()
 | 
					            session.remove()
 | 
				
			||||||
            self.mxDB.release()
 | 
					            self.mxDB.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def activeBidsQueryStr(self, now: int, offer_table: str = 'offers', bids_table: str = 'bids'):
 | 
				
			||||||
 | 
					        offers_inset = f' AND {offer_table}.expire_at > {now}' if offer_table != '' else ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inactive_states_str = ', '.join([str(int(s)) for s in inactive_states])
 | 
				
			||||||
 | 
					        return f' ({bids_table}.state NOT IN ({inactive_states_str}) AND ({bids_table}.state > {BidStates.BID_RECEIVED} OR ({bids_table}.expire_at > {now}{offers_inset}))) '
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def listBids(self, sent=False, offer_id=None, for_html=False, filters={}):
 | 
					    def listBids(self, sent=False, offer_id=None, for_html=False, filters={}):
 | 
				
			||||||
        self.mxDB.acquire()
 | 
					        self.mxDB.acquire()
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@ -6139,7 +6146,7 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            with_available_or_active = filters.get('with_available_or_active', False)
 | 
					            with_available_or_active = filters.get('with_available_or_active', False)
 | 
				
			||||||
            with_expired = filters.get('with_expired', True)
 | 
					            with_expired = filters.get('with_expired', True)
 | 
				
			||||||
            if with_available_or_active:
 | 
					            if with_available_or_active:
 | 
				
			||||||
                query_str += 'AND (bids.state NOT IN ({}, {}, {}, {}, {}) AND (bids.state > {} OR (bids.expire_at > {} AND offers.expire_at > {}))) '.format(BidStates.SWAP_COMPLETED, BidStates.BID_ERROR, BidStates.BID_REJECTED, BidStates.SWAP_TIMEDOUT, BidStates.BID_ABANDONED, BidStates.BID_RECEIVED, now, now)
 | 
					                query_str += ' AND ' + self.activeBidsQueryStr(now)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if with_expired is not True:
 | 
					                if with_expired is not True:
 | 
				
			||||||
                    query_str += 'AND bids.expire_at > {} AND offers.expire_at > {} '.format(now, now)
 | 
					                    query_str += 'AND bids.expire_at > {} AND offers.expire_at > {} '.format(now, now)
 | 
				
			||||||
 | 
				
			|||||||
@ -506,3 +506,6 @@ def strSwapDesc(swap_type):
 | 
				
			|||||||
    if swap_type == SwapTypes.XMR_SWAP:
 | 
					    if swap_type == SwapTypes.XMR_SWAP:
 | 
				
			||||||
        return 'Adaptor Sig'
 | 
					        return 'Adaptor Sig'
 | 
				
			||||||
    return None
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inactive_states = [BidStates.SWAP_COMPLETED, BidStates.BID_ERROR, BidStates.BID_REJECTED, BidStates.SWAP_TIMEDOUT, BidStates.BID_ABANDONED]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										54
									
								
								basicswap/db_util.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								basicswap/db_util.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copyright (c) 2023 The BSX Developers
 | 
				
			||||||
 | 
					# Distributed under the MIT software license, see the accompanying
 | 
				
			||||||
 | 
					# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .db import (
 | 
				
			||||||
 | 
					    Concepts,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def remove_expired_data(self):
 | 
				
			||||||
 | 
					    self.log.warning('Removing expired data')
 | 
				
			||||||
 | 
					    now: int = self.getTime()
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        session = self.openSession()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        active_bids_insert = self.activeBidsQueryStr(now, '', 'b2')
 | 
				
			||||||
 | 
					        query_str = f'''
 | 
				
			||||||
 | 
					                    SELECT o.offer_id FROM offers o
 | 
				
			||||||
 | 
					                    WHERE o.expire_at <= :now AND 0 = (SELECT COUNT(*) FROM bids b2 WHERE b2.offer_id = o.offer_id AND {active_bids_insert})
 | 
				
			||||||
 | 
					                    '''
 | 
				
			||||||
 | 
					        num_offers = 0
 | 
				
			||||||
 | 
					        num_bids = 0
 | 
				
			||||||
 | 
					        offer_rows = session.execute(query_str, {'now': now})
 | 
				
			||||||
 | 
					        for offer_row in offer_rows:
 | 
				
			||||||
 | 
					            num_offers += 1
 | 
				
			||||||
 | 
					            bid_rows = session.execute('SELECT bids.bid_id FROM bids WHERE bids.offer_id = :offer_id', {'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            for bid_row in bid_rows:
 | 
				
			||||||
 | 
					                num_bids += 1
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM transactions WHERE transactions.bid_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM eventlog WHERE eventlog.linked_type = :type_ind AND eventlog.linked_id = :bid_id', {'type_ind': int(Concepts.BID), 'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM automationlinks WHERE automationlinks.linked_type = :type_ind AND automationlinks.linked_id = :bid_id', {'type_ind': int(Concepts.BID), 'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM prefunded_transactions WHERE prefunded_transactions.linked_type = :type_ind AND prefunded_transactions.linked_id = :bid_id', {'type_ind': int(Concepts.BID), 'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM history WHERE history.concept_type = :type_ind AND history.concept_id = :bid_id', {'type_ind': int(Concepts.BID), 'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM xmr_swaps WHERE xmr_swaps.bid_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM actions WHERE actions.linked_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM addresspool WHERE addresspool.bid_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM xmr_split_data WHERE xmr_split_data.bid_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					                session.execute('DELETE FROM bids WHERE bids.bid_id = :bid_id', {'bid_id': bid_row[0]})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM eventlog WHERE eventlog.linked_type = :type_ind AND eventlog.linked_id = :offer_id', {'type_ind': int(Concepts.OFFER), 'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM automationlinks WHERE automationlinks.linked_type = :type_ind AND automationlinks.linked_id = :offer_id', {'type_ind': int(Concepts.OFFER), 'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM prefunded_transactions WHERE prefunded_transactions.linked_type = :type_ind AND prefunded_transactions.linked_id = :offer_id', {'type_ind': int(Concepts.OFFER), 'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM history WHERE history.concept_type = :type_ind AND history.concept_id = :offer_id', {'type_ind': int(Concepts.OFFER), 'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM xmr_offers WHERE xmr_offers.offer_id = :offer_id', {'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM sentoffers WHERE sentoffers.offer_id = :offer_id', {'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM actions WHERE actions.linked_id = :offer_id', {'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					            session.execute('DELETE FROM offers WHERE offers.offer_id = :offer_id', {'offer_id': offer_row[0]})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.log.warning(f'Removed data for {num_offers} expired offers and {num_bids} bids.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    finally:
 | 
				
			||||||
 | 
					        self.closeSession(session)
 | 
				
			||||||
@ -38,7 +38,6 @@ from .ui.util import (
 | 
				
			|||||||
    getCoinName,
 | 
					    getCoinName,
 | 
				
			||||||
    get_data_entry,
 | 
					    get_data_entry,
 | 
				
			||||||
    get_data_entry_or,
 | 
					    get_data_entry_or,
 | 
				
			||||||
    have_data_entry,
 | 
					 | 
				
			||||||
    listAvailableCoins,
 | 
					    listAvailableCoins,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .ui.page_automation import (
 | 
					from .ui.page_automation import (
 | 
				
			||||||
@ -55,6 +54,7 @@ from .ui.page_settings import page_settings
 | 
				
			|||||||
from .ui.page_encryption import page_changepassword, page_unlock, page_lock
 | 
					from .ui.page_encryption import page_changepassword, page_unlock, page_lock
 | 
				
			||||||
from .ui.page_identity import page_identity
 | 
					from .ui.page_identity import page_identity
 | 
				
			||||||
from .ui.page_smsgaddresses import page_smsgaddresses
 | 
					from .ui.page_smsgaddresses import page_smsgaddresses
 | 
				
			||||||
 | 
					from .ui.page_debug import page_debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
env = Environment(loader=PackageLoader('basicswap', 'templates'))
 | 
					env = Environment(loader=PackageLoader('basicswap', 'templates'))
 | 
				
			||||||
env.filters['formatts'] = format_timestamp
 | 
					env.filters['formatts'] = format_timestamp
 | 
				
			||||||
@ -333,31 +333,6 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
            'summary': summary,
 | 
					            'summary': summary,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def page_debug(self, url_split, post_string):
 | 
					 | 
				
			||||||
        swap_client = self.server.swap_client
 | 
					 | 
				
			||||||
        swap_client.checkSystemStatus()
 | 
					 | 
				
			||||||
        summary = swap_client.getSummary()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        result = None
 | 
					 | 
				
			||||||
        messages = []
 | 
					 | 
				
			||||||
        err_messages = []
 | 
					 | 
				
			||||||
        form_data = self.checkForm(post_string, 'wallets', err_messages)
 | 
					 | 
				
			||||||
        if form_data:
 | 
					 | 
				
			||||||
            if have_data_entry(form_data, 'reinit_xmr'):
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    swap_client.initialiseWallet(Coins.XMR)
 | 
					 | 
				
			||||||
                    messages.append('Done.')
 | 
					 | 
				
			||||||
                except Exception as a:
 | 
					 | 
				
			||||||
                    err_messages.append('Failed.')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        template = env.get_template('debug.html')
 | 
					 | 
				
			||||||
        return self.render_template(template, {
 | 
					 | 
				
			||||||
            'messages': messages,
 | 
					 | 
				
			||||||
            'err_messages': err_messages,
 | 
					 | 
				
			||||||
            'result': result,
 | 
					 | 
				
			||||||
            'summary': summary,
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def page_active(self, url_split, post_string):
 | 
					    def page_active(self, url_split, post_string):
 | 
				
			||||||
        swap_client = self.server.swap_client
 | 
					        swap_client = self.server.swap_client
 | 
				
			||||||
        swap_client.checkSystemStatus()
 | 
					        swap_client.checkSystemStatus()
 | 
				
			||||||
@ -502,7 +477,7 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
                if page == 'rpc':
 | 
					                if page == 'rpc':
 | 
				
			||||||
                    return self.page_rpc(url_split, post_string)
 | 
					                    return self.page_rpc(url_split, post_string)
 | 
				
			||||||
                if page == 'debug':
 | 
					                if page == 'debug':
 | 
				
			||||||
                    return self.page_debug(url_split, post_string)
 | 
					                    return page_debug(self, url_split, post_string)
 | 
				
			||||||
                if page == 'explorers':
 | 
					                if page == 'explorers':
 | 
				
			||||||
                    return self.page_explorers(url_split, post_string)
 | 
					                    return self.page_explorers(url_split, post_string)
 | 
				
			||||||
                if page == 'offer':
 | 
					                if page == 'offer':
 | 
				
			||||||
 | 
				
			|||||||
@ -67,6 +67,13 @@
 | 
				
			|||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
           </thead>
 | 
					           </thead>
 | 
				
			||||||
           <form method="post">
 | 
					           <form method="post">
 | 
				
			||||||
 | 
					            <tr class="opacity-100 text-gray-500 dark:text-gray-100">
 | 
				
			||||||
 | 
					             <td class="py-3 px-6 bold">Remove expired offers and bids</td>
 | 
				
			||||||
 | 
					             <td td class="py-3 px-6 ">
 | 
				
			||||||
 | 
					              <button name="remove_expired" type="submit" value="Yes" class="flex flex-wrap justify-center py-2 px-4 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none" onclick="return confirmRemoveExpired();">
 | 
				
			||||||
 | 
					              Yes - Remove Data</button>
 | 
				
			||||||
 | 
					             </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
            <tr class="opacity-100 text-gray-500 dark:text-gray-100">
 | 
					            <tr class="opacity-100 text-gray-500 dark:text-gray-100">
 | 
				
			||||||
             <td class="py-3 px-6 bold">Reinitialise XMR wallet</td>
 | 
					             <td class="py-3 px-6 bold">Reinitialise XMR wallet</td>
 | 
				
			||||||
             <td td class="py-3 px-6 ">
 | 
					             <td td class="py-3 px-6 ">
 | 
				
			||||||
@ -82,8 +89,8 @@
 | 
				
			|||||||
                </g>
 | 
					                </g>
 | 
				
			||||||
               </svg>Yes - Start Process</button>
 | 
					               </svg>Yes - Start Process</button>
 | 
				
			||||||
             </td>
 | 
					             </td>
 | 
				
			||||||
             <input type="hidden" name="formid" value="{{ form_id }}">
 | 
					 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <input type="hidden" name="formid" value="{{ form_id }}">
 | 
				
			||||||
           </form>
 | 
					           </form>
 | 
				
			||||||
          </table>
 | 
					          </table>
 | 
				
			||||||
         </div>
 | 
					         </div>
 | 
				
			||||||
@ -121,4 +128,9 @@
 | 
				
			|||||||
{% include 'footer.html' %}
 | 
					{% include 'footer.html' %}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					function confirmRemoveExpired() {
 | 
				
			||||||
 | 
					  return confirm("This will remove all expired offers and bids from the database - Are you sure?");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
@ -142,15 +142,7 @@
 | 
				
			|||||||
     {% endif %}
 | 
					     {% endif %}
 | 
				
			||||||
     {% endif %}
 | 
					     {% endif %}
 | 
				
			||||||
     <!-- havedata -->
 | 
					     <!-- havedata -->
 | 
				
			||||||
    </div> {% endfor %} <script>
 | 
					    </div> {% endfor %}
 | 
				
			||||||
     function confirmReseed() {
 | 
					 | 
				
			||||||
      return confirm("Are you sure?\nBackup your wallet before and after.\nWon't detect used keys.\nShould only be used for new wallets.");
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     function confirmWithdrawal() {
 | 
					 | 
				
			||||||
      return confirm("Are you sure?");
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
   </div>
 | 
					   </div>
 | 
				
			||||||
 </section>
 | 
					 </section>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										54
									
								
								basicswap/ui/page_debug.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								basicswap/ui/page_debug.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copyright (c) 2023 The BSX Developers
 | 
				
			||||||
 | 
					# Distributed under the MIT software license, see the accompanying
 | 
				
			||||||
 | 
					# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import traceback
 | 
				
			||||||
 | 
					from .util import (
 | 
				
			||||||
 | 
					    have_data_entry,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from basicswap.chainparams import (
 | 
				
			||||||
 | 
					    Coins,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from basicswap.db_util import (
 | 
				
			||||||
 | 
					    remove_expired_data,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def page_debug(self, url_split, post_string):
 | 
				
			||||||
 | 
					    server = self.server
 | 
				
			||||||
 | 
					    swap_client = server.swap_client
 | 
				
			||||||
 | 
					    swap_client.checkSystemStatus()
 | 
				
			||||||
 | 
					    summary = swap_client.getSummary()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result = None
 | 
				
			||||||
 | 
					    messages = []
 | 
				
			||||||
 | 
					    err_messages = []
 | 
				
			||||||
 | 
					    form_data = self.checkForm(post_string, 'wallets', err_messages)
 | 
				
			||||||
 | 
					    if form_data:
 | 
				
			||||||
 | 
					        if have_data_entry(form_data, 'reinit_xmr'):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                swap_client.initialiseWallet(Coins.XMR)
 | 
				
			||||||
 | 
					                messages.append('Done.')
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                err_messages.append('Failed.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if have_data_entry(form_data, 'remove_expired'):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                remove_expired_data(swap_client)
 | 
				
			||||||
 | 
					                messages.append('Done.')
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                if swap_client.debug is True:
 | 
				
			||||||
 | 
					                    swap_client.log.error(traceback.format_exc())
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    swap_client.log.error(f'remove_expired_data: {e}')
 | 
				
			||||||
 | 
					                err_messages.append('Failed.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template = server.env.get_template('debug.html')
 | 
				
			||||||
 | 
					    return self.render_template(template, {
 | 
				
			||||||
 | 
					        'messages': messages,
 | 
				
			||||||
 | 
					        'err_messages': err_messages,
 | 
				
			||||||
 | 
					        'result': result,
 | 
				
			||||||
 | 
					        'summary': summary,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
@ -3,6 +3,7 @@
 | 
				
			|||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- cores: Raised Particl and Monero daemon version.
 | 
					- cores: Raised Particl and Monero daemon version.
 | 
				
			||||||
 | 
					- ui: Add debug option to remove expired offers, bids and transactions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
0.0.62
 | 
					0.0.62
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user