remove POW for annoncements

This commit is contained in:
Kevin Froman 2020-01-19 21:02:04 -06:00
parent 1c6893e297
commit 7db8193bf6
6 changed files with 67 additions and 97 deletions

View File

@ -52,56 +52,26 @@ def announce_node(daemon):
except onionrexceptions.OnlinePeerNeeded: except onionrexceptions.OnlinePeerNeeded:
peer = "" peer = ""
for _ in range(1): try:
try: ourID = gettransports.get()[0]
ourID = gettransports.get()[0] if not peer:
if not peer: raise onionrexceptions.OnlinePeerNeeded
raise onionrexceptions.OnlinePeerNeeded except (IndexError, onionrexceptions.OnlinePeerNeeded):
except (IndexError, onionrexceptions.OnlinePeerNeeded): pass
break else:
url = 'http://' + peer + '/announce' url = 'http://' + peer + '/announce'
data = {'node': ourID} data = {'node': ourID}
combinedNodes = ourID + peer logger.info('Announcing node to ' + url)
if ourID != 1: if basicrequests.do_post_request(
existingRand = bytesconverter.bytes_to_str( url,
keydb.transportinfo.get_address_info(peer, 'powValue')) data,
# Reset existingRand if it no longer meets the minimum POW port=daemon.shared_state.get(NetController).socksPort)\
if isinstance(existingRand, type(None)) or \ == 'Success':
not existingRand.endswith( logger.info('Successfully introduced node to ' + peer,
'0' * onionrvalues.ANNOUNCE_POW): terminal=True)
existingRand = '' ret_data = True
keydb.transportinfo.set_address_info(peer, 'introduced', 1)
if peer in daemon.announceCache:
data['random'] = daemon.announceCache[peer]
elif len(existingRand) > 0:
data['random'] = existingRand
else:
daemon.announceProgress[peer] = True
proof = onionrproofs.DataPOW(
combinedNodes, minDifficulty=onionrvalues.ANNOUNCE_POW)
del daemon.announceProgress[peer]
try:
data['random'] = base64.b64encode(proof.waitForResult()[1])
except TypeError:
# Happens when we failed to produce a proof
logger.error(f"Failed to produce a pow for {peer} annce")
announce_fail = True
else:
daemon.announceCache[peer] = data['random']
if not announce_fail:
logger.info('Announcing node to ' + url)
if basicrequests.do_post_request(
url,
data,
port=daemon.shared_state.get(NetController).socksPort)\
== 'Success':
logger.info('Successfully introduced node to ' + peer,
terminal=True)
ret_data = True
keydb.transportinfo.set_address_info(peer, 'introduced', 1)
keydb.transportinfo.set_address_info(peer, 'powValue',
data['random'])
daemon.decrementThreadCount('announce_node') daemon.decrementThreadCount('announce_node')
return ret_data return ret_data

View File

@ -44,6 +44,10 @@ DATABASE_LOCK_TIMEOUT = 60
# Block creation anonymization requirements # Block creation anonymization requirements
MIN_BLOCK_UPLOAD_PEER_PERCENT = 0.1 MIN_BLOCK_UPLOAD_PEER_PERCENT = 0.1
WSGI_SERVER_REQUEST_TIMEOUT_SECS = 120
MAX_NEW_PEER_QUEUE = 1000
# Begin OnionrValues migrated values # Begin OnionrValues migrated values
"""Make announce take a few seconds (on average) to compute to discourage excessive node announcements""" """Make announce take a few seconds (on average) to compute to discourage excessive node announcements"""
ANNOUNCE_POW = 6 ANNOUNCE_POW = 6

View File

@ -1,9 +1,16 @@
''' """Onionr - Private P2P Communication.
Onionr - Private P2P Communication
Handle announcements to the public API server Handle announcements to the public API server
''' """
''' from flask import Response, g
import deadsimplekv
import logger
from etc import onionrvalues
from onionrutils import stringvalidators, bytesconverter
import filepaths
from communicator import OnionrCommunicatorDaemon
"""
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,60 +23,39 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' """
import base64
from flask import Response, g
import deadsimplekv
import logger
from etc import onionrvalues
from onionrutils import stringvalidators, bytesconverter
from utils import gettransports
import onionrcrypto as crypto, filepaths
from communicator import OnionrCommunicatorDaemon
def handle_announce(request): def handle_announce(request):
''' """accept announcement posts, validating POW
accept announcement posts, validating POW
clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request
''' """
resp = 'failure' resp = 'failure'
powHash = ''
randomData = ''
newNode = '' newNode = ''
try: try:
newNode = request.form['node'].encode() newNode = request.form['node'].encode()
except KeyError: except KeyError:
logger.warn('No node specified for upload') logger.warn('No node specified for upload')
pass
else: else:
try: newNode = bytesconverter.bytes_to_str(newNode)
randomData = request.form['random'] announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
randomData = base64.b64decode(randomData) announce_queue_list = announce_queue.get('new_peers')
except KeyError: if announce_queue_list is None:
logger.warn('No random data specified for upload') announce_queue_list = []
else: else:
nodes = newNode + bytesconverter.str_to_bytes(gettransports.get()[0]) if len(announce_queue_list) >= onionrvalues.MAX_NEW_PEER_QUEUE:
nodes = crypto.hashers.blake2b_hash(nodes) newNode = ''
powHash = crypto.hashers.blake2b_hash(randomData + nodes)
try: if stringvalidators.validate_transport(newNode) and \
powHash = powHash.decode() newNode not in announce_queue_list:
except AttributeError: g.shared_state.get(
pass OnionrCommunicatorDaemon).newPeers.append(newNode)
if powHash.startswith('0' * onionrvalues.ANNOUNCE_POW): announce_queue.put('new_peers',
newNode = bytesconverter.bytes_to_str(newNode) announce_queue_list.append(newNode))
announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache) announce_queue.flush()
announce_queue_list = announce_queue.get('new_peers') resp = 'Success'
if announce_queue_list is None:
announce_queue_list = []
if stringvalidators.validate_transport(newNode) and not newNode in announce_queue_list:
#clientAPI.onionrInst.communicatorInst.newPeers.append(newNode)
g.shared_state.get(OnionrCommunicatorDaemon).newPeers.append(newNode)
announce_queue.put('new_peers', announce_queue_list.append(newNode))
announce_queue.flush()
resp = 'Success'
else:
logger.warn(newNode.decode() + ' failed to meet POW: ' + powHash)
resp = Response(resp) resp = Response(resp)
if resp == 'failure': if resp == 'failure':
return resp, 406 return resp, 406

View File

@ -120,7 +120,6 @@ function appendMessages(msg, blockHash, beforeHash, channel) {
} }
} }
} }
} }
@ -228,7 +227,7 @@ newPostForm.onsubmit = function(){
"token": webpass "token": webpass
} }
}) })
.then((resp) => resp.text()) // Transform the data into text .then((resp) => resp.text())
.then(function(data) { .then(function(data) {
newPostForm.style.display = 'block' newPostForm.style.display = 'block'
if (data == 'failure due to duplicate insert'){ if (data == 'failure due to duplicate insert'){

View File

@ -176,6 +176,11 @@
</div> </div>
</div> </div>
<h6>Session Connections</h6> <h6>Session Connections</h6>
<div class="columns">
<div class="column">
<a class="button is-info" id="torToggle">Tor Info</a>
</div>
</div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
Last Received: <span id="lastIncoming">None since start</span> Last Received: <span id="lastIncoming">None since start</span>

View File

@ -71,7 +71,13 @@ if (sec_description_str !== 'normal'){
function getStats(){ function getStats(){
stats = JSON.parse(httpGet('getstats', webpass)) stats = JSON.parse(httpGet('getstats', webpass))
uptimeDisplay.innerText = seconds2time(stats['uptime']) uptimeDisplay.innerText = seconds2time(stats['uptime'])
connectedDisplay.innerText = stats['connectedNodes'] connectedNodes = stats['connectedNodes'].split('\n')
connectedDisplay.innerText = ''
for (x = 0; x < connectedNodes.length; x++){
if (! connectedDisplay.innerText.includes(connectedNodes[x])){
connectedDisplay.innerText += '🧅 ' + connectedNodes[x] + '\n'
}
}
storedBlockDisplay.innerText = stats['blockCount'] storedBlockDisplay.innerText = stats['blockCount']
queuedBlockDisplay.innerText = stats['blockQueueCount'] queuedBlockDisplay.innerText = stats['blockQueueCount']
securityLevel.innerText = sec_description_str securityLevel.innerText = sec_description_str