bumped min python version to 3.7, added upload sessions to use in preventing infinite upload fails
This commit is contained in:
parent
376b2cc2d6
commit
4b8fe7eeb3
@ -24,7 +24,8 @@ import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as p
|
||||
from . import onlinepeers, uploadqueue
|
||||
from communicatorutils import servicecreator, onionrcommunicatortimers
|
||||
from communicatorutils import downloadblocks, lookupblocks, lookupadders
|
||||
from communicatorutils import servicecreator, connectnewpeers, uploadblocks
|
||||
from communicatorutils import servicecreator, connectnewpeers
|
||||
from communicatorutils import uploadblocks
|
||||
from communicatorutils import daemonqueuehandler, announcenode, deniableinserts
|
||||
from communicatorutils import cooldownpeer, housekeeping, netcheck
|
||||
from onionrutils import localcommand, epoch
|
||||
@ -50,6 +51,7 @@ class OnionrCommunicatorDaemon:
|
||||
# initialize core with Tor socks port being 3rd argument
|
||||
self.proxyPort = shared_state.get(NetController).socksPort
|
||||
|
||||
# Upload information, list of blocks to upload
|
||||
self.blocksToUpload = []
|
||||
|
||||
# loop time.sleep delay in seconds
|
||||
@ -241,11 +243,6 @@ class OnionrCommunicatorDaemon:
|
||||
logger.debug('Heartbeat. Node running for %s.' % humanreadabletime.human_readable_time(self.getUptime()))
|
||||
self.decrementThreadCount('heartbeat')
|
||||
|
||||
def announce(self, peer):
|
||||
'''Announce to peers our address'''
|
||||
if announcenode.announce_node(self) == False:
|
||||
logger.warn('Could not introduce node.', terminal=True)
|
||||
|
||||
def runCheck(self):
|
||||
if run_file_exists(self):
|
||||
logger.debug('Status check; looks good.')
|
||||
|
@ -1,9 +1,9 @@
|
||||
'''
|
||||
"""
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
Class to remember blocks that need to be uploaded and not shared on startup/shutdown
|
||||
'''
|
||||
'''
|
||||
"""
|
||||
"""
|
||||
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
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
"""
|
||||
|
||||
import atexit
|
||||
import json
|
||||
@ -33,14 +33,14 @@ def _add_to_hidden_blocks(cache):
|
||||
localcommand.local_command('waitforshare/' + bl, post=True)
|
||||
|
||||
class UploadQueue:
|
||||
'''
|
||||
"""
|
||||
Saves and loads block upload info from json file
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self, communicator: 'OnionrCommunicatorDaemon'):
|
||||
'''Start the UploadQueue object, loading left over uploads into queue
|
||||
"""Start the UploadQueue object, loading left over uploads into queue
|
||||
and registering save shutdown function
|
||||
'''
|
||||
"""
|
||||
self.communicator = communicator
|
||||
cache = deadsimplekv.DeadSimpleKV(UPLOAD_MEMORY_FILE)
|
||||
self.store_obj = cache
|
||||
@ -54,7 +54,7 @@ class UploadQueue:
|
||||
atexit.register(self.save)
|
||||
|
||||
def save(self):
|
||||
'''Saves to disk on shutdown or if called manually'''
|
||||
"""Saves to disk on shutdown or if called manually"""
|
||||
bl: list = self.communicator.blocksToUpload
|
||||
self.store_obj.put('uploads', bl)
|
||||
self.store_obj.flush()
|
||||
|
@ -24,6 +24,9 @@ import onionrblockapi as block
|
||||
from onionrutils import localcommand, stringvalidators, basicrequests
|
||||
from communicator import onlinepeers
|
||||
import onionrcrypto
|
||||
|
||||
from . import session
|
||||
|
||||
def upload_blocks_from_communicator(comm_inst):
|
||||
# when inserting a block, we try to upload it to a few peers to add some deniability
|
||||
TIMER_NAME = "upload_blocks_from_communicator"
|
||||
@ -42,7 +45,7 @@ def upload_blocks_from_communicator(comm_inst):
|
||||
if peer in triedPeers:
|
||||
continue
|
||||
triedPeers.append(peer)
|
||||
url = 'http://' + peer + '/upload'
|
||||
url = 'http://%s/upload' % (peer,)
|
||||
try:
|
||||
#data = {'block': block.Block(bl).getRaw()}
|
||||
data = block.Block(bl).getRaw()
|
51
onionr/communicatorutils/uploadblocks/session.py
Normal file
51
onionr/communicatorutils/uploadblocks/session.py
Normal file
@ -0,0 +1,51 @@
|
||||
"""
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
Virtual upload "sessions" for blocks
|
||||
"""
|
||||
"""
|
||||
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/>.
|
||||
"""
|
||||
from typing import Union
|
||||
|
||||
from onionrutils import stringvalidators
|
||||
from onionrutils import bytesconverter
|
||||
from onionrutils import epoch
|
||||
from utils import reconstructhash
|
||||
|
||||
class UploadSession:
|
||||
"""Manages statistics for an Onionr block upload session
|
||||
|
||||
accepting a block hash (incl. unpadded) as an argument"""
|
||||
def __init__(self, block_hash: Union[str, bytes]):
|
||||
block_hash = bytesconverter.bytes_to_str(block_hash)
|
||||
block_hash = reconstructhash.reconstruct_hash(block_hash)
|
||||
if not stringvalidators.validate_hash(block_hash): raise ValueError
|
||||
|
||||
self.block_hash = reconstructhash.deconstruct_hash(block_hash)
|
||||
self.total_fail_count: int = 0
|
||||
self.total_success_count: int = 0
|
||||
self.peer_fails = {}
|
||||
|
||||
def fail_peer(self, peer):
|
||||
try:
|
||||
self.peer_fails[peer] += 1
|
||||
except KeyError:
|
||||
self.peer_fails[peer] = 0
|
||||
|
||||
def fail(self):
|
||||
self.total_fail_count += 1
|
||||
|
||||
def success(self):
|
||||
self.total_success_count += 1
|
@ -24,7 +24,7 @@ ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
|
||||
ONIONR_VERSION = '0.0.0' # for debugging and stuff
|
||||
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
|
||||
API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
|
||||
MIN_PY_VERSION = 6
|
||||
MIN_PY_VERSION = 7
|
||||
DEVELOPMENT_MODE = True
|
||||
MAX_BLOCK_TYPE_LENGTH = 15
|
||||
MAX_BLOCK_CLOCK_SKEW = 120
|
||||
|
@ -52,7 +52,7 @@ class TestPeerProfiles(unittest.TestCase):
|
||||
p.addScore(1)
|
||||
self.assertEqual(p.score, keydb.transportinfo.get_address_info(p.address, 'success'))
|
||||
|
||||
def test_inc_score_with_sync_Delay(self):
|
||||
def test_inc_score_with_sync_delay(self):
|
||||
p = peerprofiles.PeerProfiles(test_peers.pop())
|
||||
s = 0
|
||||
for x in range(2):
|
||||
|
36
tests/test_upload_session.py
Normal file
36
tests/test_upload_session.py
Normal file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys, os
|
||||
sys.path.append(".")
|
||||
sys.path.append("onionr/")
|
||||
import unittest, uuid
|
||||
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
|
||||
print("Test directory:", TEST_DIR)
|
||||
os.environ["ONIONR_HOME"] = TEST_DIR
|
||||
import hashlib
|
||||
from communicatorutils import uploadblocks
|
||||
|
||||
def hash_generator():
|
||||
hasher = hashlib.sha3_256()
|
||||
hasher.update(os.urandom(15))
|
||||
return hasher.hexdigest()
|
||||
|
||||
test_hashes = []
|
||||
for x in range(100): test_hashes.append(hash_generator())
|
||||
|
||||
class UploadSessionTest(unittest.TestCase):
|
||||
def test_init_fail(self):
|
||||
s = test_hashes.pop()
|
||||
s = uploadblocks.session.UploadSession(s)
|
||||
self.assertEqual(s.total_fail_count, 0)
|
||||
|
||||
def test_init_success(self):
|
||||
s = test_hashes.pop()
|
||||
s = uploadblocks.session.UploadSession(s)
|
||||
self.assertEqual(s.total_success_count, 0)
|
||||
|
||||
def test_invalid(self):
|
||||
invalid = [None, 1, -1, 0, 'ab43c5b8c7b9b037d4f02fa6bc77dbb522bfcbcd7e8ea2953bf2252c6e9232a8b', lambda: None, True, False]
|
||||
for x in invalid:
|
||||
self.assertRaises((ValueError, AttributeError), uploadblocks.session.UploadSession, x)
|
||||
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user