2020-03-04 06:59:29 +00:00
|
|
|
"""Onionr - Private P2P Communication.
|
2019-06-13 06:58:17 +00:00
|
|
|
|
2020-03-04 06:59:29 +00:00
|
|
|
Cleanup old Onionr blocks and forward secrecy keys using the communicator.
|
|
|
|
Ran from a communicator timer usually
|
|
|
|
"""
|
|
|
|
import sqlite3
|
2020-07-27 00:02:39 +00:00
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from deadsimplekv import DeadSimpleKV
|
2020-07-07 13:37:23 +00:00
|
|
|
|
2020-03-04 06:59:29 +00:00
|
|
|
import logger
|
|
|
|
from onionrusers import onionrusers
|
|
|
|
from onionrutils import epoch
|
|
|
|
from coredb import blockmetadb, dbfiles
|
|
|
|
import onionrstorage
|
|
|
|
from onionrstorage import removeblock
|
|
|
|
from onionrblocks import onionrblacklist
|
2020-07-24 08:24:41 +00:00
|
|
|
from onionrblocks.storagecounter import StorageCounter
|
2020-08-17 00:52:50 +00:00
|
|
|
from etc.onionrvalues import DATABASE_LOCK_TIMEOUT
|
2020-12-03 02:46:36 +00:00
|
|
|
from onionrproofs import hashMeetsDifficulty
|
2020-03-04 06:59:29 +00:00
|
|
|
"""
|
2019-06-13 06:58:17 +00:00
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2020-03-04 06:59:29 +00:00
|
|
|
"""
|
|
|
|
|
2020-07-24 08:24:41 +00:00
|
|
|
storage_counter = StorageCounter()
|
|
|
|
|
2019-08-26 02:18:09 +00:00
|
|
|
|
2020-11-15 18:26:25 +00:00
|
|
|
def __remove_from_upload(shared_state, block_hash: str):
|
|
|
|
kv: "DeadSimpleKV" = shared_state.get_by_string("DeadSimpleKV")
|
2019-08-26 02:18:09 +00:00
|
|
|
try:
|
2020-07-27 00:02:39 +00:00
|
|
|
kv.get('blocksToUpload').remove(block_hash)
|
2019-08-26 02:18:09 +00:00
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
|
2020-03-04 06:59:29 +00:00
|
|
|
|
2020-12-03 02:46:36 +00:00
|
|
|
def __purge_block(shared_state, block_hash, add_to_blacklist = True):
|
|
|
|
blacklist = None
|
|
|
|
|
|
|
|
removeblock.remove_block(block_hash)
|
|
|
|
onionrstorage.deleteBlock(block_hash)
|
|
|
|
__remove_from_upload(shared_state, block_hash)
|
|
|
|
|
|
|
|
if add_to_blacklist:
|
|
|
|
blacklist = onionrblacklist.OnionrBlackList()
|
|
|
|
blacklist.addToDB(block_hash)
|
|
|
|
|
|
|
|
|
2020-11-15 18:26:25 +00:00
|
|
|
def clean_old_blocks(shared_state):
|
2020-03-04 06:59:29 +00:00
|
|
|
"""Delete expired blocks + old blocks if disk allocation is near full"""
|
2019-07-28 05:33:26 +00:00
|
|
|
blacklist = onionrblacklist.OnionrBlackList()
|
2019-06-13 06:58:17 +00:00
|
|
|
# Delete expired blocks
|
2019-07-20 06:02:30 +00:00
|
|
|
for bHash in blockmetadb.expiredblocks.get_expired_blocks():
|
2020-12-03 02:46:36 +00:00
|
|
|
__purge_block(shared_state, bHash, add_to_blacklist=True)
|
|
|
|
logger.info('Deleted expired block: %s' % (bHash,))
|
2019-06-13 06:58:17 +00:00
|
|
|
|
2020-07-24 08:24:41 +00:00
|
|
|
while storage_counter.is_full():
|
2020-03-03 11:55:50 +00:00
|
|
|
try:
|
|
|
|
oldest = blockmetadb.get_block_list()[0]
|
|
|
|
except IndexError:
|
|
|
|
break
|
2020-03-20 08:50:48 +00:00
|
|
|
else:
|
2020-12-03 02:46:36 +00:00
|
|
|
__purge_block(shared_state, bHash, add_to_blacklist=True)
|
|
|
|
logger.info('Deleted block because of full storage: %s' % (oldest,))
|
2019-06-13 06:58:17 +00:00
|
|
|
|
2020-03-04 06:59:29 +00:00
|
|
|
|
2020-11-21 05:31:19 +00:00
|
|
|
def clean_keys():
|
2020-03-04 06:59:29 +00:00
|
|
|
"""Delete expired forward secrecy keys"""
|
2020-08-17 00:52:50 +00:00
|
|
|
conn = sqlite3.connect(dbfiles.user_id_info_db,
|
|
|
|
timeout=DATABASE_LOCK_TIMEOUT)
|
2019-06-13 06:58:17 +00:00
|
|
|
c = conn.cursor()
|
2019-06-25 23:07:35 +00:00
|
|
|
time = epoch.get_epoch()
|
2019-06-13 06:58:17 +00:00
|
|
|
deleteKeys = []
|
|
|
|
|
2020-07-07 13:37:23 +00:00
|
|
|
for entry in c.execute(
|
|
|
|
"SELECT * FROM forwardKeys WHERE expire <= ?", (time,)):
|
2019-06-13 06:58:17 +00:00
|
|
|
logger.debug('Forward key: %s' % entry[1])
|
|
|
|
deleteKeys.append(entry[1])
|
|
|
|
|
|
|
|
for key in deleteKeys:
|
|
|
|
logger.debug('Deleting forward key %s' % key)
|
|
|
|
c.execute("DELETE from forwardKeys where forwardKey = ?", (key,))
|
|
|
|
conn.commit()
|
|
|
|
conn.close()
|
|
|
|
|
2019-07-20 06:02:30 +00:00
|
|
|
onionrusers.deleteExpiredKeys()
|
2020-12-03 02:46:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
def clean_blocks_not_meeting_pow(shared_state):
|
|
|
|
"""Clean blocks not meeting min send/rec pow. Used if config.json POW changes"""
|
|
|
|
block_list = blockmetadb.get_block_list()
|
|
|
|
for block in block_list:
|
|
|
|
if not hashMeetsDifficulty(block):
|
|
|
|
logger.warn(
|
|
|
|
f"Deleting block {block} because it was stored" +
|
|
|
|
"with a POW level smaller than current.", terminal=True)
|
|
|
|
__purge_block(shared_state, block)
|