* Major core refactoring

* renamed clandestine to esoteric
This commit is contained in:
Kevin Froman 2019-06-22 16:16:12 -05:00
parent 5cee375b02
commit 50e93f46e4
20 changed files with 472 additions and 366 deletions

View file

@ -0,0 +1 @@
from . import keydb, blockmetadb, daemonqueue

View file

@ -0,0 +1,58 @@
import sqlite3
from . import expiredblocks, updateblockinfo
def get_block_list(core_inst, dateRec = None, unsaved = False):
'''
Get list of our blocks
'''
if dateRec == None:
dateRec = 0
conn = sqlite3.connect(core_inst.blockDB, timeout=30)
c = conn.cursor()
execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;'
args = (dateRec,)
rows = list()
for row in c.execute(execute, args):
for i in row:
rows.append(i)
conn.close()
return rows
def get_block_date(core_inst, blockHash):
'''
Returns the date a block was received
'''
conn = sqlite3.connect(core_inst.blockDB, timeout=30)
c = conn.cursor()
execute = 'SELECT dateReceived FROM hashes WHERE hash=?;'
args = (blockHash,)
for row in c.execute(execute, args):
for i in row:
return int(i)
conn.close()
return None
def get_blocks_by_type(core_inst, blockType, orderDate=True):
'''
Returns a list of blocks by the type
'''
conn = sqlite3.connect(core_inst.blockDB, timeout=30)
c = conn.cursor()
if orderDate:
execute = 'SELECT hash FROM hashes WHERE dataType=? ORDER BY dateReceived;'
else:
execute = 'SELECT hash FROM hashes WHERE dataType=?;'
args = (blockType,)
rows = list()
for row in c.execute(execute, args):
for i in row:
rows.append(i)
conn.close()
return rows

View file

@ -0,0 +1,15 @@
import sqlite3
def get_expired_blocks(core_inst):
'''Returns a list of expired blocks'''
conn = sqlite3.connect(core_inst.blockDB, timeout=30)
c = conn.cursor()
date = int(core_inst._utils.getEpoch())
execute = 'SELECT hash FROM hashes WHERE expire <= %s ORDER BY dateReceived;' % (date,)
rows = list()
for row in c.execute(execute):
for i in row:
rows.append(i)
conn.close()
return rows

View file

@ -0,0 +1,13 @@
import sqlite3
def update_block_info(core_inst, hash, key, data):
if key not in ('dateReceived', 'decrypted', 'dataType', 'dataFound', 'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'):
return False
conn = sqlite3.connect(core_inst.blockDB, timeout=30)
c = conn.cursor()
args = (data, hash)
c.execute("UPDATE hashes SET " + key + " = ? where hash = ?;", args)
conn.commit()
conn.close()
return True

View file

@ -0,0 +1,75 @@
import sqlite3, os
import onionrevents as events
def daemon_queue(core_inst):
'''
Gives commands to the communication proccess/daemon by reading an sqlite3 database
This function intended to be used by the client. Queue to exchange data between "client" and server.
'''
retData = False
if not os.path.exists(core_inst.queueDB):
core_inst.dbCreate.createDaemonDB()
else:
conn = sqlite3.connect(core_inst.queueDB, timeout=30)
c = conn.cursor()
try:
for row in c.execute('SELECT command, data, date, min(ID), responseID FROM commands group by id'):
retData = row
break
except sqlite3.OperationalError:
core_inst.dbCreate.createDaemonDB()
else:
if retData != False:
c.execute('DELETE FROM commands WHERE id=?;', (retData[3],))
conn.commit()
conn.close()
events.event('queue_pop', data = {'data': retData}, onionr = core_inst.onionrInst)
return retData
def daemon_queue_add(core_inst, command, data='', responseID=''):
'''
Add a command to the daemon queue, used by the communication daemon (communicator.py)
'''
retData = True
date = core_inst._utils.getEpoch()
conn = sqlite3.connect(core_inst.queueDB, timeout=30)
c = conn.cursor()
t = (command, data, date, responseID)
try:
c.execute('INSERT INTO commands (command, data, date, responseID) VALUES(?, ?, ?, ?)', t)
conn.commit()
except sqlite3.OperationalError:
retData = False
core_inst.daemonQueue()
events.event('queue_push', data = {'command': command, 'data': data}, onionr = core_inst.onionrInst)
conn.close()
return retData
def daemon_queue_get_response(core_inst, responseID=''):
'''
Get a response sent by communicator to the API, by requesting to the API
'''
assert len(responseID) > 0
resp = core_inst._utils.localCommand('queueResponse/' + responseID)
return resp
def clear_daemon_queue(core_inst):
'''
Clear the daemon queue (somewhat dangerous)
'''
conn = sqlite3.connect(core_inst.queueDB, timeout=30)
c = conn.cursor()
try:
c.execute('DELETE FROM commands;')
conn.commit()
except:
pass
conn.close()
events.event('queue_clear', onionr = core_inst.onionrInst)

View file

@ -0,0 +1 @@
from . import addkeys, listkeys, removekeys, userinfo, transportinfo

View file

@ -0,0 +1,70 @@
import sqlite3
import onionrevents as events, config
def add_peer(core_inst, peerID, name=''):
'''
Adds a public key to the key database (misleading function name)
'''
if peerID in core_inst.listPeers() or peerID == core_inst._crypto.pubKey:
raise ValueError("specified id is already known")
# This function simply adds a peer to the DB
if not core_inst._utils.validatePubKey(peerID):
return False
events.event('pubkey_add', data = {'key': peerID}, onionr = core_inst.onionrInst)
conn = sqlite3.connect(core_inst.peerDB, timeout=30)
hashID = core_inst._crypto.pubKeyHashID(peerID)
c = conn.cursor()
t = (peerID, name, 'unknown', hashID, 0)
for i in c.execute("SELECT * FROM peers WHERE id = ?;", (peerID,)):
try:
if i[0] == peerID:
conn.close()
return False
except ValueError:
pass
except IndexError:
pass
c.execute('INSERT INTO peers (id, name, dateSeen, hashID, trust) VALUES(?, ?, ?, ?, ?);', t)
conn.commit()
conn.close()
return True
def add_address(core_inst, address):
'''
Add an address to the address database (only tor currently)
'''
if type(address) is None or len(address) == 0:
return False
if core_inst._utils.validateID(address):
if address == config.get('i2p.ownAddr', None) or address == core_inst.hsAddress:
return False
conn = sqlite3.connect(core_inst.addressDB, timeout=30)
c = conn.cursor()
# check if address is in database
# this is safe to do because the address is validated above, but we strip some chars here too just in case
address = address.replace('\'', '').replace(';', '').replace('"', '').replace('\\', '')
for i in c.execute("SELECT * FROM adders WHERE address = ?;", (address,)):
try:
if i[0] == address:
conn.close()
return False
except ValueError:
pass
except IndexError:
pass
t = (address, 1)
c.execute('INSERT INTO adders (address, type) VALUES(?, ?);', t)
conn.commit()
conn.close()
events.event('address_add', data = {'address': address}, onionr = core_inst.onionrInst)
return True
else:
return False

View file

@ -0,0 +1,63 @@
import sqlite3
import logger
def list_peers(core_inst, randomOrder=True, getPow=False, trust=0):
'''
Return a list of public keys (misleading function name)
randomOrder determines if the list should be in a random order
trust sets the minimum trust to list
'''
conn = sqlite3.connect(core_inst.peerDB, timeout=30)
c = conn.cursor()
payload = ''
if trust not in (0, 1, 2):
logger.error('Tried to select invalid trust.')
return
if randomOrder:
payload = 'SELECT * FROM peers WHERE trust >= ? ORDER BY RANDOM();'
else:
payload = 'SELECT * FROM peers WHERE trust >= ?;'
peerList = []
for i in c.execute(payload, (trust,)):
try:
if len(i[0]) != 0:
if getPow:
peerList.append(i[0] + '-' + i[1])
else:
peerList.append(i[0])
except TypeError:
pass
conn.close()
return peerList
def list_adders(core_inst, randomOrder=True, i2p=True, recent=0):
'''
Return a list of transport addresses
'''
conn = sqlite3.connect(core_inst.addressDB, timeout=30)
c = conn.cursor()
if randomOrder:
addresses = c.execute('SELECT * FROM adders ORDER BY RANDOM();')
else:
addresses = c.execute('SELECT * FROM adders;')
addressList = []
for i in addresses:
if len(i[0].strip()) == 0:
continue
addressList.append(i[0])
conn.close()
testList = list(addressList) # create new list to iterate
for address in testList:
try:
if recent > 0 and (core_inst._utils.getEpoch() - core_inst.getAddressInfo(address, 'lastConnect')) > recent:
raise TypeError # If there is no last-connected date or it was too long ago, don't add peer to list if recent is not 0
except TypeError:
addressList.remove(address)
return addressList

View file

@ -0,0 +1,19 @@
import sqlite3
import onionrevents as events
def remove_address(core_inst, address):
'''
Remove an address from the address database
'''
if core_inst._utils.validateID(address):
conn = sqlite3.connect(core_inst.addressDB, timeout=30)
c = conn.cursor()
t = (address,)
c.execute('Delete from adders where address=?;', t)
conn.commit()
conn.close()
events.event('address_remove', data = {'address': address}, onionr = core_inst.onionrInst)
return True
else:
return False

View file

@ -0,0 +1,53 @@
import sqlite3
def get_address_info(core_inst, address, info):
'''
Get info about an address from its database entry
address text, 0
type int, 1
knownPeer text, 2
speed int, 3
success int, 4
powValue 5
failure int 6
lastConnect 7
trust 8
introduced 9
'''
conn = sqlite3.connect(core_inst.addressDB, timeout=30)
c = conn.cursor()
command = (address,)
infoNumbers = {'address': 0, 'type': 1, 'knownPeer': 2, 'speed': 3, 'success': 4, 'powValue': 5, 'failure': 6, 'lastConnect': 7, 'trust': 8, 'introduced': 9}
info = infoNumbers[info]
iterCount = 0
retVal = ''
for row in c.execute('SELECT * FROM adders WHERE address=?;', command):
for i in row:
if iterCount == info:
retVal = i
break
else:
iterCount += 1
conn.close()
return retVal
def set_address_info(core_inst, address, key, data):
'''
Update an address for a key
'''
conn = sqlite3.connect(core_inst.addressDB, timeout=30)
c = conn.cursor()
command = (data, address)
if key not in ('address', 'type', 'knownPeer', 'speed', 'success', 'failure', 'powValue', 'lastConnect', 'lastConnectAttempt', 'trust', 'introduced'):
raise Exception("Got invalid database key when setting address info")
else:
c.execute('UPDATE adders SET ' + key + ' = ? WHERE address=?', command)
conn.commit()
conn.close()

View file

@ -0,0 +1,50 @@
import sqlite3
def get_user_info(core_inst, peer, info):
'''
Get info about a peer from their database entry
id text 0
name text, 1
adders text, 2
dateSeen not null, 3
trust int 4
hashID text 5
'''
conn = sqlite3.connect(core_inst.peerDB, timeout=30)
c = conn.cursor()
command = (peer,)
infoNumbers = {'id': 0, 'name': 1, 'adders': 2, 'dateSeen': 3, 'trust': 4, 'hashID': 5}
info = infoNumbers[info]
iterCount = 0
retVal = ''
for row in c.execute('SELECT * FROM peers WHERE id=?;', command):
for i in row:
if iterCount == info:
retVal = i
break
else:
iterCount += 1
conn.close()
return retVal
def set_peer_info(core_inst, peer, key, data):
'''
Update a peer for a key
'''
conn = sqlite3.connect(core_inst.peerDB, timeout=30)
c = conn.cursor()
command = (data, peer)
# TODO: validate key on whitelist
if key not in ('id', 'name', 'pubkey', 'forwardKey', 'dateSeen', 'trust'):
raise Exception("Got invalid database key when setting peer info")
c.execute('UPDATE peers SET ' + key + ' = ? WHERE id=?', command)
conn.commit()
conn.close()