Merge branch 'mergenick' into mergenickmaster
This commit is contained in:
commit
b47da779cb
@ -44,12 +44,6 @@ if sys.version_info[0] == 2 or sys.version_info[1] < onionrvalues.MIN_PY_VERSION
|
||||
sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (onionrvalues.MIN_PY_VERSION,))
|
||||
sys.exit(1)
|
||||
|
||||
# Ensure Python interpreter is not optimized TODO: Remove asserts and replace with ifs
|
||||
from utils import detectoptimization
|
||||
if detectoptimization.detect_optimization():
|
||||
sys.stderr.write('Error, Onionr cannot be run with an optimized Python interpreter\n')
|
||||
sys.exit(2)
|
||||
|
||||
# Create Onionr data directories, must be done before most imports
|
||||
from utils import createdirs
|
||||
createdirs.create_dirs()
|
||||
|
@ -65,7 +65,7 @@ def announce_node(daemon):
|
||||
data['random'] = existingRand
|
||||
else:
|
||||
daemon.announceProgress[peer] = True
|
||||
proof = onionrproofs.DataPOW(combinedNodes, forceDifficulty=onionrvalues.ANNOUNCE_POW)
|
||||
proof = onionrproofs.DataPOW(combinedNodes, minDifficulty=onionrvalues.ANNOUNCE_POW)
|
||||
del daemon.announceProgress[peer]
|
||||
try:
|
||||
data['random'] = base64.b64encode(proof.waitForResult()[1])
|
||||
|
@ -19,7 +19,7 @@ def verify_POW(blockContent):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
difficulty = onionrproofs.getDifficultyForNewBlock(blockContent, ourBlock=False)
|
||||
difficulty = onionrproofs.getDifficultyForNewBlock(blockContent)
|
||||
|
||||
if difficulty < int(config.get('general.minimum_block_pow')):
|
||||
difficulty = int(config.get('general.minimum_block_pow'))
|
||||
|
@ -17,91 +17,64 @@
|
||||
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 multiprocessing, nacl.encoding, nacl.hash, nacl.utils, time, math, threading, binascii, sys, json
|
||||
import multiprocessing, nacl.encoding, nacl.hash, nacl.utils, time, math, threading, binascii, sys, json, sys
|
||||
import config, logger, onionrblockapi, storagecounter
|
||||
from onionrutils import bytesconverter
|
||||
from onionrcrypto import hashers
|
||||
config.reload()
|
||||
|
||||
def getDifficultyModifier():
|
||||
'''returns the difficulty modifier for block storage based
|
||||
on a variety of factors, currently only disk use.
|
||||
'''
|
||||
retData = 0
|
||||
useFunc = storagecounter.StorageCounter().get_percent
|
||||
percentUse = storagecounter.StorageCounter().getPercent()
|
||||
difficultyIncrease = math.floor(4 * percentUse) # difficulty increase is a step function
|
||||
|
||||
percentUse = useFunc()
|
||||
return difficultyIncrease
|
||||
|
||||
if percentUse >= 0.50:
|
||||
retData += 1
|
||||
elif percentUse >= 0.75:
|
||||
retData += 2
|
||||
elif percentUse >= 0.95:
|
||||
retData += 3
|
||||
|
||||
return retData
|
||||
|
||||
def getDifficultyForNewBlock(data, ourBlock=True):
|
||||
def getDifficultyForNewBlock(data):
|
||||
'''
|
||||
Get difficulty for block. Accepts size in integer, Block instance, or str/bytes full block contents
|
||||
'''
|
||||
retData = 0
|
||||
dataSize = 0
|
||||
if isinstance(data, onionrblockapi.Block):
|
||||
dataSize = len(data.getRaw().encode('utf-8'))
|
||||
dataSizeInBytes = len(bytesconverter.str_to_bytes(data.getRaw()))
|
||||
else:
|
||||
dataSize = len(bytesconverter.str_to_bytes(data))
|
||||
dataSizeInBytes = len(bytesconverter.str_to_bytes(data))
|
||||
|
||||
if ourBlock:
|
||||
minDifficulty = config.get('general.minimum_send_pow', 4)
|
||||
else:
|
||||
minDifficulty = config.get('general.minimum_block_pow', 4)
|
||||
totalDifficulty = max(minDifficulty, math.floor(dataSizeInBytes / 1000000.0)) + getDifficultyModifier()
|
||||
|
||||
retData = max(minDifficulty, math.floor(dataSize / 100000)) + getDifficultyModifier()
|
||||
return totalDifficulty
|
||||
|
||||
return retData
|
||||
|
||||
def getHashDifficulty(h: str):
|
||||
'''
|
||||
Return the amount of leading zeroes in a hex hash string (h)
|
||||
Return the amount of leading zeroes in a hex hash string (hexHash)
|
||||
'''
|
||||
difficulty = 0
|
||||
for character in h:
|
||||
if character == '0':
|
||||
difficulty += 1
|
||||
else:
|
||||
break
|
||||
return difficulty
|
||||
return len(h) - len(h.lstrip('0'))
|
||||
|
||||
def hashMeetsDifficulty(h):
|
||||
def hashMeetsDifficulty(hexHash):
|
||||
'''
|
||||
Return bool for a hash string to see if it meets pow difficulty defined in config
|
||||
'''
|
||||
hashDifficulty = getHashDifficulty(h)
|
||||
hashDifficulty = getHashDifficulty(hexHash)
|
||||
|
||||
try:
|
||||
expected = int(config.get('general.minimum_block_pow'))
|
||||
except TypeError:
|
||||
raise ValueError('Missing general.minimum_block_pow config')
|
||||
if hashDifficulty >= expected:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
return hashDifficulty >= expected
|
||||
|
||||
class DataPOW:
|
||||
def __init__(self, data, forceDifficulty=0, threadCount = 1):
|
||||
self.foundHash = False
|
||||
self.difficulty = 0
|
||||
def __init__(self, data, minDifficulty = 0, threadCount = 1):
|
||||
self.data = data
|
||||
self.threadCount = threadCount
|
||||
self.difficulty = max(minDifficulty, getDifficultyForNewBlock(data))
|
||||
self.rounds = 0
|
||||
self.hashing = False
|
||||
|
||||
if forceDifficulty == 0:
|
||||
dataLen = sys.getsizeof(data)
|
||||
self.difficulty = math.floor(dataLen / 1000000)
|
||||
if self.difficulty <= 2:
|
||||
self.difficulty = 4
|
||||
else:
|
||||
self.difficulty = forceDifficulty
|
||||
self.foundHash = False
|
||||
|
||||
try:
|
||||
self.data = self.data.encode()
|
||||
@ -124,9 +97,6 @@ class DataPOW:
|
||||
self.hashing = True
|
||||
self.reporting = reporting
|
||||
iFound = False # if current thread is the one that found the answer
|
||||
answer = ''
|
||||
heartbeat = 200000
|
||||
hbCount = 0
|
||||
|
||||
while self.hashing:
|
||||
rand = nacl.utils.random()
|
||||
@ -183,7 +153,7 @@ class DataPOW:
|
||||
return result
|
||||
|
||||
class POW:
|
||||
def __init__(self, metadata, data, threadCount = 1, forceDifficulty=0):
|
||||
def __init__(self, metadata, data, threadCount = 1, minDifficulty=0):
|
||||
self.foundHash = False
|
||||
self.difficulty = 0
|
||||
self.data = data
|
||||
@ -198,8 +168,8 @@ class POW:
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if forceDifficulty > 0:
|
||||
self.difficulty = forceDifficulty
|
||||
if minDifficulty > 0:
|
||||
self.difficulty = minDifficulty
|
||||
else:
|
||||
# Calculate difficulty. Dumb for now, may use good algorithm in the future.
|
||||
self.difficulty = getDifficultyForNewBlock(bytes(json_metadata + b'\n' + self.data))
|
||||
@ -218,10 +188,7 @@ class POW:
|
||||
self.hashing = True
|
||||
self.reporting = reporting
|
||||
iFound = False # if current thread is the one that found the answer
|
||||
answer = ''
|
||||
hbCount = 0
|
||||
nonce = int(binascii.hexlify(nacl.utils.random(2)), 16)
|
||||
startNonce = nonce
|
||||
nonce = int(binascii.hexlify(nacl.utils.random(64)), 16)
|
||||
while self.hashing:
|
||||
#token = nacl.hash.blake2b(rand + self.data).decode()
|
||||
self.metadata['pow'] = nonce
|
||||
|
@ -1,27 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
Detect if Python is being run in optimized mode or not, which has security considerations for assert statements
|
||||
'''
|
||||
'''
|
||||
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/>.
|
||||
'''
|
||||
|
||||
def detect_optimization():
|
||||
'''Returns true if Python is run in optimized mode (-o), based on optimization ignoring assert statements'''
|
||||
try:
|
||||
assert True is False
|
||||
except AssertionError:
|
||||
return False
|
||||
return True
|
@ -1,6 +1,4 @@
|
||||
import netcontroller
|
||||
|
||||
def has_tor():
|
||||
if netcontroller.tor_binary() is None:
|
||||
return False
|
||||
return True
|
||||
return netcontroller.tor_binary() is not None
|
Loading…
Reference in New Issue
Block a user