mirror of
https://github.com/monero-project/research-lab.git
synced 2025-03-12 09:37:25 +00:00
Block and blockchain working, computing fucking difficulty correctly finally
This commit is contained in:
parent
7c8aa16609
commit
f51f35669a
13 changed files with 6752 additions and 130 deletions
|
@ -51,9 +51,49 @@ class Blockchain(object):
|
||||||
elif tempCumDiff == maxCumDiff:
|
elif tempCumDiff == maxCumDiff:
|
||||||
self.miningIdents.append(ident)
|
self.miningIdents.append(ident)
|
||||||
#print("leaf ident = ", str(ident), ", and tempCumDiff = ", str(tempCumDiff), " and maxCumDiff = ", str(maxCumDiff))
|
#print("leaf ident = ", str(ident), ", and tempCumDiff = ", str(tempCumDiff), " and maxCumDiff = ", str(maxCumDiff))
|
||||||
|
assert len(self.miningIdents) > 0
|
||||||
|
|
||||||
class Test_Blockchain(unittest.TestCase):
|
class Test_Blockchain(unittest.TestCase):
|
||||||
|
def test_addBlock(self):
|
||||||
|
bill = Blockchain([], verbosity=True)
|
||||||
|
|
||||||
|
name = newIdent(0)
|
||||||
|
t = time.time()
|
||||||
|
s = t+random.random()
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
genesis = Block(params)
|
||||||
|
|
||||||
|
self.assertEqual(genesis.ident,name)
|
||||||
|
self.assertEqual(genesis.discoTimestamp,t)
|
||||||
|
self.assertEqual(genesis.arrivTimestamp,s)
|
||||||
|
self.assertTrue(genesis.parent is None)
|
||||||
|
self.assertEqual(genesis.diff,diff)
|
||||||
|
|
||||||
|
bill.addBlock(genesis)
|
||||||
|
|
||||||
|
self.assertTrue(genesis.ident in bill.blocks)
|
||||||
|
self.assertTrue(genesis.ident in bill.leaves)
|
||||||
|
self.assertEqual(len(bill.miningIdents),1)
|
||||||
|
self.assertEqual(genesis.ident, bill.miningIdents[0])
|
||||||
|
self.assertEqual(len(bill.blocks),1)
|
||||||
|
|
||||||
|
name = newIdent(1)
|
||||||
|
t = time.time()
|
||||||
|
s = t+random.random()
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":genesis.ident, "diff":diff}
|
||||||
|
blockA = Block(params)
|
||||||
|
bill.addBlock(blockA)
|
||||||
|
|
||||||
|
self.assertTrue(blockA.ident in bill.blocks)
|
||||||
|
self.assertTrue(blockA.ident in bill.leaves)
|
||||||
|
self.assertTrue(genesis.ident not in bill.leaves)
|
||||||
|
self.assertEqual(len(bill.miningIdents),1)
|
||||||
|
self.assertEqual(blockA.ident, bill.miningIdents[0])
|
||||||
|
self.assertEqual(len(bill.blocks),2)
|
||||||
|
|
||||||
|
|
||||||
def test_bc(self):
|
def test_bc(self):
|
||||||
bill = Blockchain([], verbosity=True)
|
bill = Blockchain([], verbosity=True)
|
||||||
|
|
||||||
|
@ -115,7 +155,7 @@ class Test_Blockchain(unittest.TestCase):
|
||||||
self.assertTrue(bill.blocks[genesis.ident].parent is None)
|
self.assertTrue(bill.blocks[genesis.ident].parent is None)
|
||||||
|
|
||||||
bill.whichLeaf()
|
bill.whichLeaf()
|
||||||
print(bill.miningIdents)
|
#print(bill.miningIdents)
|
||||||
|
|
||||||
self.assertEqual(type(bill.miningIdents), type([]))
|
self.assertEqual(type(bill.miningIdents), type([]))
|
||||||
self.assertTrue(len(bill.miningIdents), 2)
|
self.assertTrue(len(bill.miningIdents), 2)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from Blockchain import *
|
from Blockchain import *
|
||||||
|
import copy
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
'''
|
'''
|
||||||
|
@ -17,12 +18,9 @@ class Node(object):
|
||||||
self.edges = {}
|
self.edges = {}
|
||||||
|
|
||||||
def updateBlockchain(self, incBlocks, diffUpdateRate=1, mode="Nakamoto", targetRate=1.0/1209600.0):
|
def updateBlockchain(self, incBlocks, diffUpdateRate=1, mode="Nakamoto", targetRate=1.0/1209600.0):
|
||||||
# dataToUpdate shall be a dictionary of block identities (as keys) and their associated blocks (as values)
|
# incBlocks shall be a dictionary of block identities (as keys) and their associated blocks (as values)
|
||||||
# to be added to the local data. We assume difficulty scores have been reported honestly for now.
|
# to be added to the local data. We assume difficulty scores have been reported honestly for now.
|
||||||
|
|
||||||
# Stash a copy of incoming blocks so removing keys won't shrink the size of the dictionary over which
|
|
||||||
# we are looping.
|
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("\t\t Updating blockchain.")
|
print("\t\t Updating blockchain.")
|
||||||
|
|
||||||
|
@ -36,18 +34,19 @@ class Node(object):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("\t\t Now tempData has " + str(len(tempData)) + " entries.")
|
print("\t\t Now tempData has " + str(len(tempData)) + " entries.")
|
||||||
|
|
||||||
for key in incBlocks.blocks:
|
for key in incBlocks:
|
||||||
if key in self.data["blockchain"].blocks:
|
if key in self.data["blockchain"].blocks:
|
||||||
del tempData[key]
|
del tempData[key]
|
||||||
elif incBlocks.blocks[key].parent in self.data["blockchain"].blocks or incBlocks[key].parent is None:
|
elif incBlocks[key].parent in self.data["blockchain"].blocks or incBlocks[key].parent is None:
|
||||||
self.data["blockchain"].addBlock(incBlocks.blocks[key])
|
self.data["blockchain"].addBlock(incBlocks[key])
|
||||||
|
self.data["blockchain"].whichLeaf()
|
||||||
#if len(self.data["blockchain"]) % diffUpdateRate == 0:
|
#if len(self.data["blockchain"]) % diffUpdateRate == 0:
|
||||||
# self.updateDifficulty(mode, targetRate)
|
# self.updateDifficulty(mode, targetRate)
|
||||||
del tempData[key]
|
del tempData[key]
|
||||||
incBlocks = copy.deepcopy(tempData)
|
incBlocks = copy.deepcopy(tempData)
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("\t\t Now incBlocks has " + str(len(incBlocks.blocks)) + " entries.")
|
print("\t\t Now incBlocks has " + str(len(incBlocks)) + " entries.")
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("\t\tRemaining steps (while loop)")
|
print("\t\tRemaining steps (while loop)")
|
||||||
|
@ -58,8 +57,9 @@ class Node(object):
|
||||||
for key in incBlocks:
|
for key in incBlocks:
|
||||||
if key in self.data["blockchain"].blocks:
|
if key in self.data["blockchain"].blocks:
|
||||||
del tempData[key]
|
del tempData[key]
|
||||||
elif incBlocks.blocks[key].parent in self.data["blockchain"].blocks:
|
elif incBlocks[key].parent in self.data["blockchain"].blocks:
|
||||||
self.data["blockchain"].addBlock(incBlocks.blocks[key])
|
self.data["blockchain"].addBlock(incBlocks[key])
|
||||||
|
self.data["blockchain"].whichLeaf()
|
||||||
del tempData[key]
|
del tempData[key]
|
||||||
incBlocks = copy.deepcopy(tempData)
|
incBlocks = copy.deepcopy(tempData)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
|
@ -71,9 +71,15 @@ class Node(object):
|
||||||
# Note for default, targetRate = two weeks/period, seven days/week, 24 hours/day, 60 minutes/hour, 60 seconds/minute) = 1209600 seconds/period
|
# Note for default, targetRate = two weeks/period, seven days/week, 24 hours/day, 60 minutes/hour, 60 seconds/minute) = 1209600 seconds/period
|
||||||
if mode=="Nakamoto":
|
if mode=="Nakamoto":
|
||||||
# Use MLE estimate of poisson process, compare to targetRate, update by multiplying by resulting ratio.
|
# Use MLE estimate of poisson process, compare to targetRate, update by multiplying by resulting ratio.
|
||||||
|
if self.verbose:
|
||||||
|
print("Beginning update of difficulty with Nakamoto method")
|
||||||
count = 2016
|
count = 2016
|
||||||
bc = self.data["blockchain"]
|
bc = self.data["blockchain"]
|
||||||
ident = bc.miningIdent
|
if self.verbose:
|
||||||
|
print("Checking that blockchain is 2016*n blocks long and some mining identity has been set")
|
||||||
|
if len(bc.blocks) % 2016 == 0 and len(bc.miningIdents) > 0:
|
||||||
|
|
||||||
|
ident = random.choice(bc.miningIdents)
|
||||||
topTime = copy.deepcopy(bc.blocks[ident].discoTimestamp)
|
topTime = copy.deepcopy(bc.blocks[ident].discoTimestamp)
|
||||||
parent = bc.blocks[ident].parent
|
parent = bc.blocks[ident].parent
|
||||||
count = count - 1
|
count = count - 1
|
||||||
|
@ -89,11 +95,17 @@ class Node(object):
|
||||||
botTime = copy.deepcopy(bc.blocks[ident].discoTimestamp)
|
botTime = copy.deepcopy(bc.blocks[ident].discoTimestamp)
|
||||||
|
|
||||||
# Algebra is okay:
|
# Algebra is okay:
|
||||||
assert 0 <= 2016 - count and 2016 - count < 2017
|
|
||||||
assert topTime != botTime
|
assert topTime != botTime
|
||||||
|
|
||||||
# MLE estimate of arrivals per second:
|
# MLE estimate of arrivals per second:
|
||||||
mleDiscoRate = float(2016 - count)/float(topTime - botTime)
|
mleDiscoRate = float(2015)/float(topTime - botTime)
|
||||||
|
|
||||||
|
# Rates can't be negative, but this estimate could be (although it's highly unlikely given Bitcoin's standard choices
|
||||||
|
# of difficulty update rate, etc.
|
||||||
mleDiscoRate = abs(mleDiscoRate)
|
mleDiscoRate = abs(mleDiscoRate)
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
print("MLE disco rate = " + str(mleDiscoRate) + " and targetRate = " + str(targetRate))
|
||||||
# Rate must be positive... so the MLE for block arrival rate
|
# Rate must be positive... so the MLE for block arrival rate
|
||||||
# assuming a Poisson process _is not even well-defined_ as
|
# assuming a Poisson process _is not even well-defined_ as
|
||||||
# an estimate for block arrival rate assuming timestamps are
|
# an estimate for block arrival rate assuming timestamps are
|
||||||
|
@ -101,38 +113,66 @@ class Node(object):
|
||||||
|
|
||||||
# We use it nonetheless.
|
# We use it nonetheless.
|
||||||
|
|
||||||
# How much should difficulty change?
|
if self.verbose:
|
||||||
self.diff = self.diff*(mleDiscoRate/targetRate)
|
print("MLE discovery rate = " + str(mleDiscoRate))
|
||||||
|
print("Difficulty before adjustment = " + str(self.diff))
|
||||||
|
|
||||||
|
# Update difficulty multiplicatively
|
||||||
|
self.diff = self.diff*mleDiscoRate/targetRate
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
print("Difficulty after adjustment = ", str(self.diff))
|
||||||
|
|
||||||
elif mode=="vanSaberhagen":
|
elif mode=="vanSaberhagen":
|
||||||
# Similar to above, except use 1200 blocks, discard top 120 and bottom 120 after sorting.
|
# Similar to above, except use 1200 blocks, discard top 120 and bottom 120 after sorting.
|
||||||
# 4 minute blocks in the original cryptonote, I believe... targetRate = 1.0/
|
# 4 minute blocks in the original cryptonote, I believe... targetRate = 1.0/
|
||||||
# 4 minutes/period, 60 seconds/minute ~ 240 seconds/period
|
# 4 minutes/period, 60 seconds/minute ~ 240 seconds/period
|
||||||
assert targetRate==1.0/240.0
|
# assert targetRate==1.0/240.0
|
||||||
count = 1200
|
count = 1200
|
||||||
ident = self.data.miningIdent
|
bc = self.data["blockchain"]
|
||||||
|
bc.whichLeaf()
|
||||||
|
assert self.diff != 0.0
|
||||||
|
if len(bc.blocks) > 120:
|
||||||
|
assert type(bc.miningIdents)==type([])
|
||||||
|
assert len(bc.miningIdents) > 0
|
||||||
|
ident = random.choice(bc.miningIdents)
|
||||||
bl = []
|
bl = []
|
||||||
bl.append(copy.deepcopy(self.data.blocks[ident].discoTimestamp))
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
parent = self.data.blocks[ident].parent
|
parent = bc.blocks[ident].parent
|
||||||
count = count - 1
|
count = count - 1
|
||||||
while count > 0 and parent is not NOne:
|
while count > 0 and parent is not None:
|
||||||
ident = copy.deepcopy(parent)
|
ident = copy.deepcopy(parent)
|
||||||
bl.append(copy.deepcopy(self.data.blocks[ident].discoTimestamp))
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
parent = self.data.blocks[ident].parent
|
parent = bc.blocks[ident].parent
|
||||||
count = count-1
|
count = count-1
|
||||||
# sort
|
# sort
|
||||||
bl = sorted(bl)
|
bl = sorted(bl)
|
||||||
|
assert len(bl)<=1200
|
||||||
|
|
||||||
|
#print("Sample size = " + str(len(bl)))
|
||||||
|
# remove 10 and 90 %-iles
|
||||||
|
numOutliers = round(len(bl)/5)//2
|
||||||
|
assert numOutliers <= 120
|
||||||
|
#print("Number of outliers = " + str(numOutliers))
|
||||||
|
if numOutliers > 0:
|
||||||
|
bl = bl[numOutliers:-numOutliers]
|
||||||
|
#print("New Sample Size = " + str(len(bl)))
|
||||||
|
|
||||||
# remove outliers
|
|
||||||
bl = bl[120:-120]
|
|
||||||
|
|
||||||
# get topTime and botTime
|
# get topTime and botTime
|
||||||
|
if self.verbose:
|
||||||
|
print("bl[0] = " + str(bl[0]) + ",\tbl[-1] = " + str(bl[-1]))
|
||||||
topTime = bl[-1]
|
topTime = bl[-1]
|
||||||
botTime = bl[0]
|
botTime = bl[0]
|
||||||
|
if self.verbose:
|
||||||
|
print("list of timestamps = " + str(bl))
|
||||||
|
print("topTime = " + str(bl[-1]))
|
||||||
|
print("botTime = " + str(bl[0]))
|
||||||
|
|
||||||
# Assert algebra will work
|
# Assert algebra will work
|
||||||
assert 0 <= 960 - count and 960 - count < 961
|
# 1200 - 2*120 = 1200 - 240 = 960
|
||||||
assert topTime > botTime
|
assert 0 < len(bl) and len(bl) < 961
|
||||||
|
assert topTime - botTime >= 0.0
|
||||||
|
|
||||||
# Sort of the MLE: # blocks/difference in reported times
|
# Sort of the MLE: # blocks/difference in reported times
|
||||||
# But not the MLE, since the reported times may not be
|
# But not the MLE, since the reported times may not be
|
||||||
|
@ -158,20 +198,26 @@ class Node(object):
|
||||||
# lambda ~ (1.0/(stdev))*(2/skewness)**(1.0/3.0)
|
# lambda ~ (1.0/(stdev))*(2/skewness)**(1.0/3.0)
|
||||||
assert targetRate==1.0/120.0
|
assert targetRate==1.0/120.0
|
||||||
count = 1200
|
count = 1200
|
||||||
ident = self.data.miningIdent
|
bc = self.data["blockchain"]
|
||||||
|
if len(bc.miningIdents) > 0:
|
||||||
|
ident = random.choice(bc.miningIdents)
|
||||||
|
|
||||||
bl = []
|
bl = []
|
||||||
bl.append(copy.deepcopy(self.data.blocks[ident].discoTimestamp))
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
parent = self.data.blocks[ident].parent
|
parent = bc.blocks[ident].parent
|
||||||
count = count - 1
|
count = count - 1
|
||||||
while count > 0 and parent is not NOne:
|
while count > 0 and parent is not None:
|
||||||
ident = copy.deepcopy(parent)
|
ident = copy.deepcopy(parent)
|
||||||
bl.append(copy.deepcopy(self.data.blocks[ident].discoTimestamp))
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
parent = self.data.blocks[ident].parent
|
parent = bc.blocks[ident].parent
|
||||||
count = count-1
|
count = count-1
|
||||||
|
if len(bl) > 120:
|
||||||
sk = skew(bl)
|
sk = skew(bl)
|
||||||
va = var(bl)
|
va = var(bl)
|
||||||
stdv = sqrt(va)
|
stdv = sqrt(va)
|
||||||
lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
else:
|
||||||
|
lam = targetRate # we will not change difficulty unless we have at least 120 blocks of data (arbitrarily selected)
|
||||||
self.diff = self.diff*(lam/targetRate)
|
self.diff = self.diff*(lam/targetRate)
|
||||||
else:
|
else:
|
||||||
print("Error, invalid difficulty mode entered.")
|
print("Error, invalid difficulty mode entered.")
|
||||||
|
@ -193,77 +239,701 @@ class Node(object):
|
||||||
|
|
||||||
|
|
||||||
class Test_Node(unittest.TestCase):
|
class Test_Node(unittest.TestCase):
|
||||||
def test_node(self):
|
# TODO test each method separately
|
||||||
verbose = True
|
'''def test_nakamoto(self):
|
||||||
nellyIdent = newIdent(0)
|
print("Beginning test of Nakamoto difficulty adjustment")
|
||||||
bill = Blockchain([], verbosity=verbose)
|
print("Setting initial values")
|
||||||
|
target = 100.0 # rate = blocks/s
|
||||||
|
verbose = False
|
||||||
|
deltaT = 1.0/target # forced wait time
|
||||||
|
arrivalList = []
|
||||||
|
mode="Nakamoto"
|
||||||
|
|
||||||
|
print("Generating node")
|
||||||
|
nellyIdent = newIdent(0)
|
||||||
|
offset = random.random()
|
||||||
|
intensity = random.random()
|
||||||
|
|
||||||
|
print("Generating initial blockchain")
|
||||||
|
# Create a new initial blockchain object
|
||||||
|
bill = Blockchain([], verbosity=verbose)
|
||||||
name = newIdent(0)
|
name = newIdent(0)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t+1
|
t += offset
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = 1.0
|
||||||
|
oldDiff = copy.deepcopy(diff)
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
genesis = Block(params)
|
||||||
|
print("Adding block")
|
||||||
|
bill.addBlock(genesis)
|
||||||
|
bill.whichLeaf()
|
||||||
|
|
||||||
|
# Check that it consists only of the genesis block
|
||||||
|
self.assertTrue(len(bill.blocks)==1)
|
||||||
|
self.assertTrue(genesis.ident in bill.blocks)
|
||||||
|
self.assertTrue(genesis.parent is None)
|
||||||
|
|
||||||
|
print("Finish creating node")
|
||||||
|
# Create node with this blockchain.
|
||||||
|
nodeData = {"blockchain":bill, "intensity":intensity, "offset":offset}
|
||||||
|
params = {"ident":nellyIdent, "data":nodeData, "diff":diff, "verbose":verbose}
|
||||||
|
nelly = Node(params)
|
||||||
|
|
||||||
|
# Check node creation worked
|
||||||
|
self.assertEqual(nelly.ident, nellyIdent)
|
||||||
|
self.assertEqual(nelly.data["blockchain"], bill)
|
||||||
|
self.assertEqual(nelly.diff, diff)
|
||||||
|
self.assertEqual(nelly.data["intensity"], intensity)
|
||||||
|
self.assertEqual(nelly.data["offset"], offset)
|
||||||
|
|
||||||
|
# Sleep and add a block on top of genesis
|
||||||
|
if verbose:
|
||||||
|
print("sleeping")
|
||||||
|
time.sleep(deltaT)
|
||||||
|
|
||||||
|
print("Giving genesis block a child")
|
||||||
|
name = newIdent(1)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = oldDiff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":genesis.ident, "diff":diff}
|
||||||
|
blockA = Block(params)
|
||||||
|
nelly.updateBlockchain({blockA.ident:blockA})
|
||||||
|
oldIdent = blockA.ident
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),2)
|
||||||
|
self.assertTrue(blockA.ident in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertTrue(genesis.ident in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertEqual(genesis.ident, nelly.data["blockchain"].blocks[blockA.ident].parent)
|
||||||
|
|
||||||
|
print("Updating difficulty")
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With only two blocks, nothing should change.
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
|
||||||
|
# Print regardless of verbosity:
|
||||||
|
print("Now generating first difficulty adjustment period.")
|
||||||
|
|
||||||
|
# Now we are going to fast forward to right before the first difficulty adjustment.
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
while(N < 2015):
|
||||||
|
if N % 100 == 0:
|
||||||
|
print("\tN=" + str(N))
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = nelly.diff
|
||||||
|
oldDiff = diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
oldIdent = copy.deepcopy(name)
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 2016, nothing should change.
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
time.sleep(deltaT)
|
||||||
|
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = oldDiff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 2016, nothing should change.
|
||||||
|
# Note: 2016 blocks is 2015 block inter-arrival times.
|
||||||
|
expRatioNumerator = float(2015)/(arrivalList[-1] - arrivalList[-2016])
|
||||||
|
expRatio = expRatioNumerator/target
|
||||||
|
expDiff = oldDiff*expRatio
|
||||||
|
self.assertEqual(nelly.diff, expDiff)
|
||||||
|
|
||||||
|
# The following should fail, because our sample size is incorrect.
|
||||||
|
expRatioNumerator = float(2016)/(arrivalList[-1] - arrivalList[-2016])
|
||||||
|
expRatio = expRatioNumerator/target
|
||||||
|
expDiff = oldDiff*expRatio
|
||||||
|
self.assertFalse(nelly.diff - expDiff == 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
# Print regardless of verbosity:
|
||||||
|
print("Now generating second difficulty adjustment period.")
|
||||||
|
|
||||||
|
# Now we are going to fast forward to right before the next difficulty adjustment.
|
||||||
|
# This time, though, we are going to re-set the block inter-arrival time deltaT
|
||||||
|
# to half. This should drive difficulty up.
|
||||||
|
lastDifficultyScore = copy.deepcopy(nelly.diff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
while(N < 4031):
|
||||||
|
if N % 100 == 0:
|
||||||
|
print("\tN=" + str(N))
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = nelly.diff
|
||||||
|
oldDiff = diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
oldIdent = copy.deepcopy(name)
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 2016, nothing should change.
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
time.sleep(0.01*deltaT)
|
||||||
|
|
||||||
|
# Now if we add a single new block, we should trigger difficulty adjustment.
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
diff = oldDiff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score.
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target)
|
||||||
|
expRatioNumerator = float(2015)/(arrivalList[-1] - arrivalList[-2016])
|
||||||
|
expRatio = expRatioNumerator/target
|
||||||
|
expDiff = oldDiff*expRatio
|
||||||
|
print("expRatio = " + str(expRatio) + ", lastDifficultyScore = " + str(lastDifficultyScore) + ", new difficulty = " + str(nelly.diff))
|
||||||
|
self.assertEqual(nelly.diff, expDiff)
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_vs(self):
|
||||||
|
print("Beginning test of vanSaberhagen difficulty adjustment.")
|
||||||
|
print("Setting initial values")
|
||||||
|
target = 10.0 # 1.0/240.0 # rate = blocks/s
|
||||||
|
verbose = False
|
||||||
|
deltaT = 1.0/target # forced wait time
|
||||||
|
arrivalList = []
|
||||||
|
mode="vanSaberhagen"
|
||||||
|
|
||||||
|
print("Instantiating new node")
|
||||||
|
nellyIdent = newIdent(0)
|
||||||
|
offset = random.random()
|
||||||
|
intensity = random.random()
|
||||||
|
|
||||||
|
print("Creating new blockchain for new node")
|
||||||
|
# Create a new initial blockchain object
|
||||||
|
bill = Blockchain([], verbosity=verbose)
|
||||||
|
name = newIdent(0)
|
||||||
|
t = time.time()
|
||||||
|
t += offset
|
||||||
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
diff = 1.0
|
diff = 1.0
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
genesis = Block(params)
|
genesis = Block(params)
|
||||||
|
print("Adding genesis block")
|
||||||
bill.addBlock(genesis)
|
bill.addBlock(genesis)
|
||||||
|
bill.whichLeaf()
|
||||||
|
|
||||||
time.sleep(10)
|
# Check that it consists only of the genesis block
|
||||||
|
self.assertTrue(len(bill.blocks)==1)
|
||||||
|
self.assertTrue(genesis.ident in bill.blocks)
|
||||||
|
self.assertTrue(genesis.parent is None)
|
||||||
|
self.assertTrue(genesis.ident in bill.leaves)
|
||||||
|
|
||||||
|
print("Making node")
|
||||||
|
# Create node with this blockchain.
|
||||||
|
nodeData = {"blockchain":bill, "intensity":intensity, "offset":offset}
|
||||||
|
params = {"ident":nellyIdent, "data":nodeData, "diff":diff, "verbose":verbose}
|
||||||
|
nelly = Node(params)
|
||||||
|
|
||||||
|
# Check node creation worked
|
||||||
|
self.assertEqual(nelly.ident, nellyIdent)
|
||||||
|
self.assertEqual(nelly.data["blockchain"], bill)
|
||||||
|
self.assertEqual(nelly.diff, diff)
|
||||||
|
self.assertEqual(nelly.data["intensity"], intensity)
|
||||||
|
self.assertEqual(nelly.data["offset"], offset)
|
||||||
|
|
||||||
|
# Sleep and add a block on top of genesis
|
||||||
|
if verbose:
|
||||||
|
print("sleeping")
|
||||||
|
time.sleep(deltaT)
|
||||||
|
|
||||||
|
print("Give genesis a child")
|
||||||
name = newIdent(1)
|
name = newIdent(1)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t+1
|
t += nelly.data["offset"]
|
||||||
diff = 1.0
|
arrivalList.append(t)
|
||||||
|
s = t+random.random()
|
||||||
|
oldDiff = copy.deepcopy(diff)
|
||||||
|
diff = copy.deepcopy(nelly.diff)
|
||||||
|
assert diff != 0.0
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":genesis.ident, "diff":diff}
|
params = {"ident":name, "disco":t, "arriv":s, "parent":genesis.ident, "diff":diff}
|
||||||
blockA = Block(params)
|
blockA = Block(params)
|
||||||
bill.addBlock(blockA)
|
nelly.updateBlockchain({blockA.ident:blockA})
|
||||||
|
oldIdent = blockA.ident
|
||||||
|
|
||||||
# Nodes need an identity and a blockchain object and verbosity and difficulty
|
# Check this worked
|
||||||
nodeData = {"blockchain":bill, "intensity":random.random(), "offset":random.random()}
|
self.assertEqual(len(nelly.data["blockchain"].blocks),2)
|
||||||
params = {"ident":name, "data":nodeData, "diff":diff, "verbose":verbose}
|
self.assertTrue(blockA.ident in nelly.data["blockchain"].blocks)
|
||||||
nelly = Node(params)
|
self.assertTrue(genesis.ident in nelly.data["blockchain"].blocks)
|
||||||
nelly.updateDifficulty(mode="Nakamoto")
|
self.assertEqual(genesis.ident, nelly.data["blockchain"].blocks[blockA.ident].parent)
|
||||||
|
|
||||||
time.sleep(9)
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With only two blocks, nothing should change.
|
||||||
|
assert nelly.diff != 0.0
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
self.assertFalse(nelly.diff == -0.0)
|
||||||
|
|
||||||
name = newIdent(len(nelly.data))
|
# Print regardless of verbosity:
|
||||||
|
print("Now generating fulls sample size.")
|
||||||
|
|
||||||
|
# Now we are going to fast forward to a "full sample size" period of time.
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
while(N < 1200):
|
||||||
|
name = newIdent(N)
|
||||||
|
if N % 100 == 0:
|
||||||
|
print("\tNow adding block N=" + str(N))
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t + 1
|
t += nelly.data["offset"]
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":blockA.ident, "diff":diff}
|
arrivalList.append(t)
|
||||||
blockB = Block(params)
|
s = t+random.random()
|
||||||
nelly.updateBlockchain({blockB.ident:blockB})
|
oldDiff = copy.deepcopy(diff)
|
||||||
|
diff = copy.deepcopy(nelly.diff)
|
||||||
|
assert diff != 0.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
oldIdent = copy.deepcopy(name)
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
time.sleep(8)
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
name = newIdent(len(nelly.data))
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 100, nothing should change.
|
||||||
|
if N < 100:
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
time.sleep(0.5*deltaT)
|
||||||
|
|
||||||
|
print("Adding one more block")
|
||||||
|
name = newIdent(N)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t + 1
|
t += nelly.data["offset"]
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":blockA.ident, "diff":diff}
|
arrivalList.append(t)
|
||||||
blockC = Block(params)
|
s = t+random.random()
|
||||||
nelly.updateBlockchain({blockC.ident:blockC})
|
oldDiff = diff
|
||||||
|
diff = nelly.diff
|
||||||
|
assert diff != 0.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":nelly.diff}
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
time.sleep(1)
|
# Check this worked
|
||||||
name = newIdent(len(nelly.data))
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 2016, nothing should change.
|
||||||
|
# Note: 2016 blocks is 2015 block inter-arrival times.
|
||||||
|
print(str(arrivalList[-120]) + ", " + str(arrivalList[-1080]) + ", " + str(arrivalList[-120]-arrivalList[-1080]) + ", " + str(float(959)/(arrivalList[-120]-arrivalList[-1080]))+ ", " + str(float(float(959)/(arrivalList[-120]-arrivalList[-1080]))/float(target)))
|
||||||
|
expRatioNumerator = float(959)/(arrivalList[-120] - arrivalList[-1080])
|
||||||
|
expRatio = expRatioNumerator/target
|
||||||
|
print(expRatio)
|
||||||
|
expDiff = oldDiff*expRatio
|
||||||
|
print(expDiff)
|
||||||
|
print("expDiff = " + str(expDiff) + " and nelly.diff = " + str(nelly.diff))
|
||||||
|
self.assertEqual(nelly.diff, expDiff)
|
||||||
|
|
||||||
|
|
||||||
|
# Print regardless of verbosity:
|
||||||
|
print("Now fast forwarding past the tail end of the last period..")
|
||||||
|
# Now we are going to fast forward to right before the next difficulty adjustment.
|
||||||
|
# This time, though, we are going to re-set the block inter-arrival time deltaT
|
||||||
|
# to half. This should drive difficulty up.
|
||||||
|
lastDifficultyScore = copy.deepcopy(nelly.diff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
while(N < 1700):
|
||||||
|
name = newIdent(N)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t + 1
|
t += nelly.data["offset"]
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":blockC.ident, "diff":diff}
|
arrivalList.append(t)
|
||||||
blockD = Block(params)
|
s = t+random.random()
|
||||||
nelly.updateBlockchain({blockD.ident:blockD})
|
diff = nelly.diff
|
||||||
|
oldDiff = diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
oldIdent = copy.deepcopy(name)
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
time.sleep(7)
|
# Check this worked
|
||||||
name = newIdent(len(nelly.data))
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target) # With N < 2016, nothing should change.
|
||||||
|
self.assertEqual(nelly.diff, oldDiff)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
time.sleep(0.01*deltaT)
|
||||||
|
|
||||||
|
# Now if we add a single new block, we should trigger difficulty adjustment.
|
||||||
|
name = newIdent(N)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t + 1
|
t += nelly.data["offset"]
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":blockD.ident, "diff":diff}
|
arrivalList.append(t)
|
||||||
blockE = Block(params)
|
s = t+random.random()
|
||||||
nelly.updateBlockchain({blockE.ident:blockE})
|
diff = oldDiff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":oldIdent, "diff":diff}
|
||||||
|
block = Block(params)
|
||||||
|
nelly.updateBlockchain({block.ident:block})
|
||||||
|
|
||||||
|
# Check this worked
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks),N+1)
|
||||||
|
self.assertTrue(block.ident in nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update the difficulty score.
|
||||||
|
nelly.updateDifficulty(mode, targetRate = target)
|
||||||
|
expRatioNumerator = float(959)/(arrivalList[-120] - arrivalList[-1080])
|
||||||
|
expRatio = expRatioNumerator/target
|
||||||
|
expDiff = oldDiff*expRatio
|
||||||
|
print("expRatio = " + str(expRatio) + ", lastDifficultyScore = " + str(lastDifficultyScore) + ", new difficulty = " + str(nelly.diff))
|
||||||
|
self.assertEqual(nelly.diff, expDiff)
|
||||||
|
|
||||||
|
|
||||||
time.sleep(6)
|
|
||||||
name = newIdent(len(nelly.data))
|
def test_modexp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
'''# Check this worked
|
||||||
|
if mode == "Nakamoto":
|
||||||
|
# In this case we take simple MLE estimate
|
||||||
|
ratio = 1.0/abs(t1-t)
|
||||||
|
print("Nakamoto mle = " + str(ratio))
|
||||||
|
ratio = ratio/target
|
||||||
|
print("Normalized = " + str(ratio))
|
||||||
|
print("New diff = " + str(ratio*oldDiff))
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "vanSaberhagen":
|
||||||
|
# In this case, with only 2 blocks, we just use simple MLE again
|
||||||
|
ratio = 1.0/abs(t1-t)
|
||||||
|
ratio = ratio/target
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "MOM:expModGauss":
|
||||||
|
self.assertEqual(nelly.diff, 1.0)
|
||||||
|
# With at least 120 blocks of data...
|
||||||
|
#sk = skew(bl)
|
||||||
|
#va = var(bl)
|
||||||
|
#stdv = sqrt(va)
|
||||||
|
#lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
#self.diff = self.diff*(lam/targetRate)
|
||||||
|
# Otherwise, set to 1.0
|
||||||
|
else:
|
||||||
|
print("what world are you living in?")
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print("sleeping 1 seconds")
|
||||||
|
time.sleep(deltaT/5.0)
|
||||||
|
|
||||||
|
listOfTimes = [copy.deepcopy(t), copy.deepcopy(t1)]
|
||||||
|
listOfBlocks = []
|
||||||
|
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
lastIdent = blockA.ident
|
||||||
|
|
||||||
|
bail = False
|
||||||
|
while N < 10 and not bail:
|
||||||
|
# Generate new block
|
||||||
|
name = newIdent(N)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
s = t + 1
|
t += nelly.data["offset"]
|
||||||
params = {"ident":name, "disco":t, "arriv":s, "parent":blockE.ident, "diff":diff}
|
s = t+random.random()
|
||||||
blockF = Block(params)
|
oldDiff = copy.deepcopy(nelly.diff)
|
||||||
nelly.updateBlockchain({blockF.ident:blockF})
|
print("Current difficulty = ", oldDiff)
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":lastIdent, "diff":oldDiff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
|
||||||
|
# Append new block to running list along with creation time
|
||||||
|
listOfBlocks.append(newBlock)
|
||||||
|
listOfTimes.append(copy.deepcopy(t))
|
||||||
|
|
||||||
|
# Update nelly's blockchain with newBlock
|
||||||
|
nelly.updateBlockchain({newBlock.ident:newBlock})
|
||||||
|
lastIdent = name
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
self.assertTrue(name in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks), N+1)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update difficulty
|
||||||
|
nelly.updateDifficulty(mode, targetRate = 100.0)
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
if mode == "Nakamoto":
|
||||||
|
# In this case we take use top block and genesis block
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks) - 1)/(listOfTimes[-1] - listOfTimes[0])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
print("Hoped for difficulty = " + str(oldDiff*ratio) + ", and computed = " + str(nelly.diff))
|
||||||
|
elif mode == "vanSaberhagen":
|
||||||
|
# This case coincides with nakamoto until block 10
|
||||||
|
ratio = float( len(nelly.data["blockchain"].blocks) - 1)/(listOfTimes[-1] - listOfTimes[0])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "MOM:expModGauss":
|
||||||
|
self.assertEqual(nelly.diff, 1.0)
|
||||||
|
# With at least 120 blocks of data...
|
||||||
|
#sk = skew(bl)
|
||||||
|
#va = var(bl)
|
||||||
|
#stdv = sqrt(va)
|
||||||
|
#lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
#self.diff = self.diff*(lam/targetRate)
|
||||||
|
# Otherwise, set to 1.0
|
||||||
|
else:
|
||||||
|
print("what world are you living in?")
|
||||||
|
|
||||||
|
# Sleep a random time
|
||||||
|
print("Sleeping a random sub-second, working on block " + str(N))
|
||||||
|
deltaT = deltaT*ratio
|
||||||
|
time.sleep(deltaT/5.0)
|
||||||
|
|
||||||
|
while N < 120 and not bail:
|
||||||
|
# Generate new block
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
s = t+random.random()
|
||||||
|
oldDiff = copy.deepcopy(nelly.diff)
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":lastIdent, "diff":oldDiff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
|
||||||
|
# Append new block to running list along with creation time
|
||||||
|
listOfBlocks.append(newBlock)
|
||||||
|
listOfTimes.append(copy.deepcopy(t))
|
||||||
|
|
||||||
|
# Update nelly's blockchain with newBlock
|
||||||
|
nelly.updateBlockchain({newBlock.ident:newBlock})
|
||||||
|
lastIdent = name
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
self.assertTrue(name in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks), N+1)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update difficulty
|
||||||
|
nelly.updateDifficulty(mode, targetRate = 100.0)
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
if mode == "Nakamoto":
|
||||||
|
# In this case we take use top block and genesis block
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks)-1)/(listOfTimes[-1] - listOfTimes[0])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, oldDiff*ratio)
|
||||||
|
print("Hoped for difficulty = " + str(oldDiff*ratio) + ", and computed = " + str(nelly.diff))
|
||||||
|
elif mode == "vanSaberhagen":
|
||||||
|
# This case no longer coincides with Nakamoto...
|
||||||
|
numOutliers = len(nelly.data["blockchain"].blocks)//10
|
||||||
|
numOutliers = min(numOutliers, 120)
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks) - 2*numOutliers - 1)/(listOfTimes[-numOutliers] - listOfTimes[numOutliers])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, oldDiff*ratio)
|
||||||
|
elif mode == "MOM:expModGauss":
|
||||||
|
# With at least 120 blocks of data...
|
||||||
|
count = 1200
|
||||||
|
bl = []
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[lastIdent].discoTimestamp))
|
||||||
|
parent = bc.blocks[lastIdent].parent
|
||||||
|
count = count - 1
|
||||||
|
while count > 0 and parent is not None:
|
||||||
|
ident = copy.deepcopy(parent)
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
|
parent = bc.blocks[ident].parent
|
||||||
|
count = count-1
|
||||||
|
if len(bl) > 120:
|
||||||
|
sk = skew(bl)
|
||||||
|
va = var(bl)
|
||||||
|
stdv = sqrt(va)
|
||||||
|
lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
else:
|
||||||
|
lam = target
|
||||||
|
ratio = lam/target
|
||||||
|
self.assertEqual(nelly.diff, oldDiff*ratio)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("what world are you living in?")
|
||||||
|
|
||||||
|
# Sleep a random time
|
||||||
|
print("Sleeping a random sub-second, working on block " + str(N))
|
||||||
|
deltaT = deltaT*ratio
|
||||||
|
time.sleep(deltaT/5.0)
|
||||||
|
|
||||||
|
while N < 2400 and not bail:
|
||||||
|
# Generate new block
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
s = t+random.random()
|
||||||
|
oldDiff = copy.deepcopy(nelly.diff)
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":lastIdent, "diff":oldDiff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
|
||||||
|
# Append new block to running list along with creation time
|
||||||
|
listOfBlocks.append(newBlock)
|
||||||
|
listOfTimes.append(copy.deepcopy(t))
|
||||||
|
|
||||||
|
# Update nelly's blockchain with newBlock
|
||||||
|
nelly.updateBlockchain({newBlock.ident:newBlock})
|
||||||
|
lastIdent = name
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
self.assertTrue(name in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks), N+1)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update difficulty
|
||||||
|
nelly.updateDifficulty(mode, targetRate = 100.0)
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
if mode == "Nakamoto":
|
||||||
|
# In this case we take use top block and genesis block
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks)-1)/(listOfTimes[-1] - listOfTimes[0])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, oldDiff*ratio)
|
||||||
|
print("Hoped for difficulty = " + str(oldDiff*ratio) + ", and computed = " + str(nelly.diff))
|
||||||
|
elif mode == "vanSaberhagen":
|
||||||
|
# This case no longer coincides with Nakamoto...
|
||||||
|
numOutliers = len(nelly.data["blockchain"].blocks)//10
|
||||||
|
numOutliers = min(numOutliers, 120)
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks) - 2*numOutliers - 1)/(listOfTimes[-numOutliers] - listOfTimes[numOutliers])
|
||||||
|
ratio = ratio / target
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "MOM:expModGauss":
|
||||||
|
# With at least 120 blocks of data...
|
||||||
|
count = 1200
|
||||||
|
bl = []
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[lastIdent].discoTimestamp))
|
||||||
|
parent = bc.blocks[lastIdent].parent
|
||||||
|
count = count - 1
|
||||||
|
while count > 0 and parent is not None:
|
||||||
|
ident = copy.deepcopy(parent)
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
|
parent = bc.blocks[ident].parent
|
||||||
|
count = count-1
|
||||||
|
if len(bl) > 120:
|
||||||
|
sk = skew(bl)
|
||||||
|
va = var(bl)
|
||||||
|
stdv = sqrt(va)
|
||||||
|
lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
else:
|
||||||
|
lam = targetRate
|
||||||
|
ratio = lam/targetRate
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("what world are you living in?")
|
||||||
|
|
||||||
|
# Sleep a random time
|
||||||
|
print("Sleeping a random sub-second, working on block " + str(N))
|
||||||
|
deltaT = deltaT*ratio
|
||||||
|
time.sleep(deltaT/5.0)
|
||||||
|
|
||||||
|
|
||||||
|
while N < 3600 and not bail:
|
||||||
|
# Generate new block
|
||||||
|
name = newIdent(N)
|
||||||
|
t = time.time()
|
||||||
|
t += nelly.data["offset"]
|
||||||
|
s = t+random.random()
|
||||||
|
oldDiff = nelly.diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":lastIdent, "diff":oldDiff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
|
||||||
|
# Append new block to running list along with creation time
|
||||||
|
listOfBlocks.append(newBlock)
|
||||||
|
listOfTimes.append(copy.deepcopy(t))
|
||||||
|
|
||||||
|
# Update nelly's blockchain with newBlock
|
||||||
|
nelly.updateBlockchain({newBlock.ident:newBlock})
|
||||||
|
lastIdent = name
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
self.assertTrue(name in nelly.data["blockchain"].blocks)
|
||||||
|
self.assertEqual(len(nelly.data["blockchain"].blocks), N+1)
|
||||||
|
N = len(nelly.data["blockchain"].blocks)
|
||||||
|
|
||||||
|
# Update difficulty
|
||||||
|
nelly.updateDifficulty(mode, targetRate = 100.0)
|
||||||
|
|
||||||
|
# Quick check that this worked:
|
||||||
|
if mode == "Nakamoto":
|
||||||
|
# In this case we take use top block and genesis block
|
||||||
|
ratio = float(2400)/(listOfTimes[-1] - listOfTimes[-2400])
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "vanSaberhagen":
|
||||||
|
# This case no longer coincides with Nakamoto...
|
||||||
|
numOutliers = len(nelly.data["blockchain"].blocks)//10
|
||||||
|
numOutliers = min(numOutliers, 120)
|
||||||
|
ratio = float(len(nelly.data["blockchain"].blocks) - 2*numOutliers)/(listOfTimes[-numOutliers] - listOfTimes[numOutliers])
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
elif mode == "MOM:expModGauss":
|
||||||
|
# With at least 120 blocks of data...
|
||||||
|
count = 1200
|
||||||
|
bl = []
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[lastIdent].discoTimestamp))
|
||||||
|
parent = bc.blocks[lastIdent].parent
|
||||||
|
count = count - 1
|
||||||
|
while count > 0 and parent is not None:
|
||||||
|
ident = copy.deepcopy(parent)
|
||||||
|
bl.append(copy.deepcopy(bc.blocks[ident].discoTimestamp))
|
||||||
|
parent = bc.blocks[ident].parent
|
||||||
|
count = count-1
|
||||||
|
if len(bl) > 120:
|
||||||
|
sk = skew(bl)
|
||||||
|
va = var(bl)
|
||||||
|
stdv = sqrt(va)
|
||||||
|
lam = (1.0/stdv)*(2.0/sk)**(1.0/3.0)
|
||||||
|
else:
|
||||||
|
lam = targetRate
|
||||||
|
ratio = lam/targetRate
|
||||||
|
self.assertEqual(nelly.diff, ratio*oldDiff)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("what world are you living in?")
|
||||||
|
|
||||||
|
# Sleep a random time
|
||||||
|
print("Sleeping a random sub-second, working on block " + str(N))
|
||||||
|
deltaT = deltaT*ratio
|
||||||
|
time.sleep(deltaT/5.0)'''
|
||||||
|
|
||||||
|
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Node)
|
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Node)
|
||||||
|
|
46
source-code/Poisson-Graphs/new/Block.py
Normal file
46
source-code/Poisson-Graphs/new/Block.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import unittest, random, time
|
||||||
|
|
||||||
|
def newIdent(params):
|
||||||
|
nonce = params
|
||||||
|
# Generate new random identity.
|
||||||
|
return hash(str(nonce) + str(random.random()))
|
||||||
|
#### #### #### #### #### #### #### #### #### #### #### #### #### #### #### ####
|
||||||
|
class Block(object):
|
||||||
|
'''
|
||||||
|
Each block has: an identity, a timestamp of discovery (possibly false),
|
||||||
|
has a timestamp of arrival at the local node (possibly unnecessary), a
|
||||||
|
parent block's identity, and a difficulty score.
|
||||||
|
'''
|
||||||
|
def __init__(self, params={}):
|
||||||
|
self.ident = None
|
||||||
|
self.discoTimestamp = None
|
||||||
|
self.arrivTimestamp = None
|
||||||
|
self.parent = None
|
||||||
|
self.diff = None
|
||||||
|
try:
|
||||||
|
assert len(params)==5
|
||||||
|
except AssertionError:
|
||||||
|
print("Error in Block(): Tried to add a malformed block. We received params = " + str(params) + ", but should have had something of the form {\"ident\":ident, \"disco\":disco, \"arriv\":arriv, \"parent\":parent, \"diff\":diff}.")
|
||||||
|
self.ident = params["ident"]
|
||||||
|
self.discoTimestamp = params["disco"]
|
||||||
|
self.arrivTimestamp = params["arriv"]
|
||||||
|
self.parent = params["parent"]
|
||||||
|
self.diff = params["diff"]
|
||||||
|
|
||||||
|
class Test_Block(unittest.TestCase):
|
||||||
|
def test_b(self):
|
||||||
|
#bill = Block()
|
||||||
|
name = newIdent(0)
|
||||||
|
t = time.time()
|
||||||
|
s = t+1
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
bill = Block(params)
|
||||||
|
self.assertEqual(bill.ident,name)
|
||||||
|
self.assertEqual(bill.discoTimestamp,t)
|
||||||
|
self.assertEqual(bill.arrivTimestamp,t+1)
|
||||||
|
self.assertTrue(bill.parent is None)
|
||||||
|
self.assertEqual(bill.diff,diff)
|
||||||
|
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Block)
|
||||||
|
unittest.TextTestRunner(verbosity=1).run(suite)
|
46
source-code/Poisson-Graphs/new/Block.py~
Normal file
46
source-code/Poisson-Graphs/new/Block.py~
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import unittest, random, time
|
||||||
|
|
||||||
|
def newIdent(params):
|
||||||
|
nonce = params
|
||||||
|
# Generate new random identity.
|
||||||
|
return hash(str(nonce) + str(random.random()))
|
||||||
|
#### #### #### #### #### #### #### #### #### #### #### #### #### #### #### ####
|
||||||
|
class Block(object):
|
||||||
|
'''
|
||||||
|
Each block has: an identity, a timestamp of discovery (possibly false),
|
||||||
|
has a timestamp of arrival at the local node (possibly unnecessary), a
|
||||||
|
parent block's identity, and a difficulty score.
|
||||||
|
'''
|
||||||
|
def __init__(self, params={}):
|
||||||
|
self.ident = None
|
||||||
|
self.discoTimestamp = None
|
||||||
|
self.arrivTimestamp = None
|
||||||
|
self.parent = None
|
||||||
|
self.diff = None
|
||||||
|
try:
|
||||||
|
assert len(params)==5
|
||||||
|
except AssertionError:
|
||||||
|
print("Error in Block(): Tried to add a malformed block. We received params = " + str(params) + ", but should have had something of the form {\"ident\":ident, \"disco\":disco, \"arriv\":arriv, \"parent\":parent, \"diff\":diff}.")
|
||||||
|
self.ident = params["ident"]
|
||||||
|
self.discoTimestamp = params["disco"]
|
||||||
|
self.arrivTimestamp = params["arriv"]
|
||||||
|
self.parent = params["parent"]
|
||||||
|
self.diff = params["diff"]
|
||||||
|
|
||||||
|
class Test_Block(unittest.TestCase):
|
||||||
|
def test_b(self):
|
||||||
|
#bill = Block()
|
||||||
|
name = newIdent(0)
|
||||||
|
t = time.time()
|
||||||
|
s = t+1
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
bill = Block(params)
|
||||||
|
self.assertEqual(bill.ident,name)
|
||||||
|
self.assertEqual(bill.discoTimestamp,t)
|
||||||
|
self.assertEqual(bill.arrivTimestamp,t+1)
|
||||||
|
self.assertTrue(bill.parent is None)
|
||||||
|
self.assertEqual(bill.diff,diff)
|
||||||
|
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Block)
|
||||||
|
unittest.TextTestRunner(verbosity=1).run(suite)
|
1142
source-code/Poisson-Graphs/new/Blockchain.py
Normal file
1142
source-code/Poisson-Graphs/new/Blockchain.py
Normal file
File diff suppressed because it is too large
Load diff
1142
source-code/Poisson-Graphs/new/Blockchain.py~
Normal file
1142
source-code/Poisson-Graphs/new/Blockchain.py~
Normal file
File diff suppressed because it is too large
Load diff
116
source-code/Poisson-Graphs/new/Node.py
Normal file
116
source-code/Poisson-Graphs/new/Node.py
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
from Blockchain import *
|
||||||
|
|
||||||
|
class Node(object):
|
||||||
|
'''
|
||||||
|
Node object. params [identity, blockchain (data), verbosity, difficulty]
|
||||||
|
'''
|
||||||
|
def __init__(self, params={}):
|
||||||
|
try:
|
||||||
|
assert len(params)==5
|
||||||
|
except AssertionError:
|
||||||
|
print("Error, Tried to create malformed node.")
|
||||||
|
else:
|
||||||
|
self.ident = params["ident"]
|
||||||
|
self.data = params["data"]
|
||||||
|
self.verbose = params["verbose"]
|
||||||
|
self.edges = {}
|
||||||
|
self.mode = params["mode"]
|
||||||
|
self.targetRate = params["targetRate"]
|
||||||
|
|
||||||
|
def generateBlock(self, discoTime, nonce):
|
||||||
|
newName = newIdent(nonce)
|
||||||
|
t = discoTime
|
||||||
|
s = t+self.data["offset"]
|
||||||
|
diff = self.data["blockchain"].diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
self.data["blockchain"].addBlock(newBlock, mode, tr)
|
||||||
|
return newName
|
||||||
|
|
||||||
|
def updateBlockchain(self, incBlocks):
|
||||||
|
# incBlocks shall be a dictionary of block identities (as keys) and their associated blocks (as values)
|
||||||
|
# to be added to the local data. We assume difficulty scores have been reported honestly for now.
|
||||||
|
|
||||||
|
tempData = copy.deepcopy(incBlocks)
|
||||||
|
for key in incBlocks:
|
||||||
|
if key in self.data["blockchain"].blocks:
|
||||||
|
del tempData[key]
|
||||||
|
elif incBlocks[key].parent in self.data["blockchain"].blocks or incBlocks[key].parent is None:
|
||||||
|
self.data["blockchain"].addBlock(incBlocks[key], self.mode, self.targetRate)
|
||||||
|
del tempData[key]
|
||||||
|
incBlocks = copy.deepcopy(tempData)
|
||||||
|
while len(incBlocks)>0:
|
||||||
|
for key in incBlocks:
|
||||||
|
if key in self.data["blockchain"].blocks:
|
||||||
|
del tempData[key]
|
||||||
|
elif incBlocks[key].parent in self.data["blockchain"].blocks:
|
||||||
|
self.data["blockchain"].addBlock(incBlocks[key], self.mode, self.targetRate)
|
||||||
|
del tempData[key]
|
||||||
|
incBlocks = copy.deepcopy(tempData)
|
||||||
|
|
||||||
|
def propagate(self, timeOfProp, blockIdent):
|
||||||
|
for edgeIdent in self.edges:
|
||||||
|
edge = self.edges[edgeIdent]
|
||||||
|
length = e.data["length"]
|
||||||
|
timeOfArrival = timeOfProp + length
|
||||||
|
otherIdent = e.getNeighbor(self.ident)
|
||||||
|
other = e.nodes[otherIdent]
|
||||||
|
bc = other.data["blockchain"]
|
||||||
|
if blockIdent not in bc.blocks:
|
||||||
|
pB = e.data["pendingBlocks"]
|
||||||
|
pendingIdent = newIdent(len(pB))
|
||||||
|
mybc = self.data["blockchain"]
|
||||||
|
blockToProp = mybc.blocks[blockIdent]
|
||||||
|
pendingDat = {"timeOfArrival":timeOfArrival, "destIdent":otherIdent, "block":blockToProp}
|
||||||
|
pB.update({pendingIdent:pendingDat})
|
||||||
|
|
||||||
|
|
||||||
|
class Test_Node(unittest.TestCase):
|
||||||
|
# TODO test each method separately
|
||||||
|
def test_all(self):
|
||||||
|
bill = Blockchain([], verbosity=True)
|
||||||
|
mode="Nakamoto"
|
||||||
|
tr = 1.0/600000.0
|
||||||
|
deltaT = 600000.0
|
||||||
|
bill.targetRate = tr
|
||||||
|
|
||||||
|
name = newIdent(0)
|
||||||
|
t = 0.0
|
||||||
|
s = t
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
genesis = Block(params)
|
||||||
|
bill.addBlock(genesis, mode, tr)
|
||||||
|
|
||||||
|
parent = genesis.ident
|
||||||
|
|
||||||
|
nellyname = newIdent(time.time())
|
||||||
|
mode = "Nakamoto"
|
||||||
|
targetRate = 1.0/600000.0
|
||||||
|
params = {"ident":nellyname, "data":{"offset":0.0, "intensity":1.0, "blockchain":bill}, "verbose":True, "mode":mode, "targetRate":targetRate}
|
||||||
|
nelly = Node(params)
|
||||||
|
|
||||||
|
while len(nelly.data["blockchain"].blocks) < 2015:
|
||||||
|
name = newIdent(0)
|
||||||
|
diff = nelly.data["blockchain"].diff
|
||||||
|
t += deltaT*diff*(2.0*random.random()-1.0)
|
||||||
|
s = t
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":parent, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
bill.addBlock(newBlock, mode, tr)
|
||||||
|
parent = name
|
||||||
|
|
||||||
|
|
||||||
|
while len(nelly.data["blockchain"].blocks) < 5000:
|
||||||
|
name = newIdent(0)
|
||||||
|
diff = nelly.data["blockchain"].diff
|
||||||
|
t += deltaT*diff
|
||||||
|
s = t
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":parent, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
bill.addBlock(newBlock, mode, tr)
|
||||||
|
parent = name
|
||||||
|
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Node)
|
||||||
|
unittest.TextTestRunner(verbosity=1).run(suite)
|
||||||
|
|
116
source-code/Poisson-Graphs/new/Node.py~
Normal file
116
source-code/Poisson-Graphs/new/Node.py~
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
from Blockchain import *
|
||||||
|
|
||||||
|
class Node(object):
|
||||||
|
'''
|
||||||
|
Node object. params [identity, blockchain (data), verbosity, difficulty]
|
||||||
|
'''
|
||||||
|
def __init__(self, params={}):
|
||||||
|
try:
|
||||||
|
assert len(params)==5
|
||||||
|
except AssertionError:
|
||||||
|
print("Error, Tried to create malformed node.")
|
||||||
|
else:
|
||||||
|
self.ident = params["ident"]
|
||||||
|
self.data = params["data"]
|
||||||
|
self.verbose = params["verbose"]
|
||||||
|
self.edges = {}
|
||||||
|
self.mode = params["mode"]
|
||||||
|
self.targetRate = params["targetRate"]
|
||||||
|
|
||||||
|
def generateBlock(self, discoTime, nonce):
|
||||||
|
newName = newIdent(nonce)
|
||||||
|
t = discoTime
|
||||||
|
s = t+self.data["offset"]
|
||||||
|
diff = self.data["blockchain"].diff
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
self.data["blockchain"].addBlock(newBlock, mode, tr)
|
||||||
|
return newName
|
||||||
|
|
||||||
|
def updateBlockchain(self, incBlocks):
|
||||||
|
# incBlocks shall be a dictionary of block identities (as keys) and their associated blocks (as values)
|
||||||
|
# to be added to the local data. We assume difficulty scores have been reported honestly for now.
|
||||||
|
|
||||||
|
tempData = copy.deepcopy(incBlocks)
|
||||||
|
for key in incBlocks:
|
||||||
|
if key in self.data["blockchain"].blocks:
|
||||||
|
del tempData[key]
|
||||||
|
elif incBlocks[key].parent in self.data["blockchain"].blocks or incBlocks[key].parent is None:
|
||||||
|
self.data["blockchain"].addBlock(incBlocks[key], self.mode, self.targetRate)
|
||||||
|
del tempData[key]
|
||||||
|
incBlocks = copy.deepcopy(tempData)
|
||||||
|
while len(incBlocks)>0:
|
||||||
|
for key in incBlocks:
|
||||||
|
if key in self.data["blockchain"].blocks:
|
||||||
|
del tempData[key]
|
||||||
|
elif incBlocks[key].parent in self.data["blockchain"].blocks:
|
||||||
|
self.data["blockchain"].addBlock(incBlocks[key], self.mode, self.targetRate)
|
||||||
|
del tempData[key]
|
||||||
|
incBlocks = copy.deepcopy(tempData)
|
||||||
|
|
||||||
|
def propagate(self, timeOfProp, blockIdent):
|
||||||
|
for edgeIdent in self.edges:
|
||||||
|
edge = self.edges[edgeIdent]
|
||||||
|
length = e.data["length"]
|
||||||
|
timeOfArrival = timeOfProp + length
|
||||||
|
otherIdent = e.getNeighbor(self.ident)
|
||||||
|
other = e.nodes[otherIdent]
|
||||||
|
bc = other.data["blockchain"]
|
||||||
|
if blockIdent not in bc.blocks:
|
||||||
|
pB = e.data["pendingBlocks"]
|
||||||
|
pendingIdent = newIdent(len(pB))
|
||||||
|
mybc = self.data["blockchain"]
|
||||||
|
blockToProp = mybc.blocks[blockIdent]
|
||||||
|
pendingDat = {"timeOfArrival":timeOfArrival, "destIdent":otherIdent, "block":blockToProp}
|
||||||
|
pB.update({pendingIdent:pendingDat})
|
||||||
|
|
||||||
|
|
||||||
|
class Test_Node(unittest.TestCase):
|
||||||
|
# TODO test each method separately
|
||||||
|
def test_all(self):
|
||||||
|
bill = Blockchain([], verbosity=True)
|
||||||
|
mode="Nakamoto"
|
||||||
|
tr = 1.0/600000.0
|
||||||
|
deltaT = 600000.0
|
||||||
|
bill.targetRate = tr
|
||||||
|
|
||||||
|
name = newIdent(0)
|
||||||
|
t = 0.0
|
||||||
|
s = t
|
||||||
|
diff = 1.0
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":None, "diff":diff}
|
||||||
|
genesis = Block(params)
|
||||||
|
bill.addBlock(genesis, mode, tr)
|
||||||
|
|
||||||
|
parent = genesis.ident
|
||||||
|
|
||||||
|
nellyname = newIdent(time.time())
|
||||||
|
mode = "Nakamoto"
|
||||||
|
targetRate = 1.0/600000.0
|
||||||
|
params = {"ident":nellyname, "data":{"offset":0.0, "intensity":1.0, "blockchain":bill}, "verbose":True, "mode":mode, "targetRate":targetRate}
|
||||||
|
nelly = Node(params)
|
||||||
|
|
||||||
|
while len(nelly.data["blockchain"].blocks) < 2015:
|
||||||
|
name = newIdent(0)
|
||||||
|
diff = nelly.data["blockchain"].diff
|
||||||
|
t += deltaT*diff*(2.0*random.random()-1.0)
|
||||||
|
s = t
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":parent, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
bill.addBlock(newBlock, mode, tr)
|
||||||
|
parent = name
|
||||||
|
|
||||||
|
|
||||||
|
while len(nelly.data["blockchain"].blocks) < 5000:
|
||||||
|
name = newIdent(0)
|
||||||
|
diff = nelly.data["blockchain"].diff
|
||||||
|
t += deltaT*diff
|
||||||
|
s = t
|
||||||
|
params = {"ident":name, "disco":t, "arriv":s, "parent":parent, "diff":diff}
|
||||||
|
newBlock = Block(params)
|
||||||
|
bill.addBlock(newBlock, mode, tr)
|
||||||
|
parent = name
|
||||||
|
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(Test_Node)
|
||||||
|
unittest.TextTestRunner(verbosity=1).run(suite)
|
||||||
|
|
BIN
source-code/Poisson-Graphs/new/__pycache__/Block.cpython-35.pyc
Normal file
BIN
source-code/Poisson-Graphs/new/__pycache__/Block.cpython-35.pyc
Normal file
Binary file not shown.
Binary file not shown.
2501
source-code/Poisson-Graphs/new/output.txt
Normal file
2501
source-code/Poisson-Graphs/new/output.txt
Normal file
File diff suppressed because it is too large
Load diff
602
source-code/Poisson-Graphs/new/outputM.txt
Normal file
602
source-code/Poisson-Graphs/new/outputM.txt
Normal file
|
@ -0,0 +1,602 @@
|
||||||
|
time,rateConstant,difficulty
|
||||||
|
0.0,1.0,1.0
|
||||||
|
1.0,1.0,1.0
|
||||||
|
2.0,1.0,1.0
|
||||||
|
3.0,1.0,1.0
|
||||||
|
4.0,1.0,1.0
|
||||||
|
5.0,1.0,1.0
|
||||||
|
6.0,1.0,1.0
|
||||||
|
7.0,1.0,1.0
|
||||||
|
8.0,1.0,1.0
|
||||||
|
9.0,1.0,1.0
|
||||||
|
10.0,1.0,1.0
|
||||||
|
11.0,1.0,1.0
|
||||||
|
12.0,1.0,1.0
|
||||||
|
13.0,1.0,1.0
|
||||||
|
14.0,1.0,1.0
|
||||||
|
15.0,1.0,1.0
|
||||||
|
16.0,1.0,1.0
|
||||||
|
17.0,1.0,1.0
|
||||||
|
18.0,1.0,1.0
|
||||||
|
19.0,1.0,1.0
|
||||||
|
20.0,1.0,1.0
|
||||||
|
21.0,1.0,1.0
|
||||||
|
22.0,1.0,1.0
|
||||||
|
23.0,1.0,1.0
|
||||||
|
24.0,1.0,1.0
|
||||||
|
25.0,1.0,1.0
|
||||||
|
26.0,1.0,1.0
|
||||||
|
27.0,1.0,1.0
|
||||||
|
28.0,1.0,1.0
|
||||||
|
29.0,1.0,1.0
|
||||||
|
30.0,1.0,1.0
|
||||||
|
31.0,1.0,1.0
|
||||||
|
32.0,1.0,1.0
|
||||||
|
33.0,1.0,1.0
|
||||||
|
34.0,1.0,1.0
|
||||||
|
35.0,1.0,1.0
|
||||||
|
36.0,1.0,1.0
|
||||||
|
37.0,1.0,1.0
|
||||||
|
38.0,1.0,1.0
|
||||||
|
39.0,1.0,1.0
|
||||||
|
40.0,1.0,1.0
|
||||||
|
41.0,1.0,1.0
|
||||||
|
42.0,1.0,1.0
|
||||||
|
43.0,1.0,1.0
|
||||||
|
44.0,1.0,1.0
|
||||||
|
45.0,1.0,1.0
|
||||||
|
46.0,1.0,1.0
|
||||||
|
47.0,1.0,1.0
|
||||||
|
48.0,1.0,1.0
|
||||||
|
49.0,1.0,1.0
|
||||||
|
50.0,1.0,1.0
|
||||||
|
51.0,1.0,1.0
|
||||||
|
52.0,1.0,1.0
|
||||||
|
53.0,1.0,1.0
|
||||||
|
54.0,1.0,1.0
|
||||||
|
55.0,1.0,1.0
|
||||||
|
56.0,1.0,1.0
|
||||||
|
57.0,1.0,1.0
|
||||||
|
58.0,1.0,1.0
|
||||||
|
59.0,1.0,1.0
|
||||||
|
60.0,1.0,1.0
|
||||||
|
61.0,1.0,1.0
|
||||||
|
62.0,1.0,1.0
|
||||||
|
63.0,1.0,1.0
|
||||||
|
64.0,1.0,1.0
|
||||||
|
65.0,1.0,1.0
|
||||||
|
66.0,1.0,1.0
|
||||||
|
67.0,1.0,1.0
|
||||||
|
68.0,1.0,1.0
|
||||||
|
69.0,1.0,1.0
|
||||||
|
70.0,1.0,1.0
|
||||||
|
71.0,1.0,1.0
|
||||||
|
72.0,1.0,1.0
|
||||||
|
73.0,1.0,1.0
|
||||||
|
74.0,1.0,1.0
|
||||||
|
75.0,1.0,1.0
|
||||||
|
76.0,1.0,1.0
|
||||||
|
77.0,1.0,1.0
|
||||||
|
78.0,1.0,1.0
|
||||||
|
79.0,1.0,1.0
|
||||||
|
80.0,1.0,1.0
|
||||||
|
81.0,1.0,1.0
|
||||||
|
82.0,1.0,1.0
|
||||||
|
83.0,1.0,1.0
|
||||||
|
84.0,1.0,1.0
|
||||||
|
85.0,1.0,1.0
|
||||||
|
86.0,1.0,1.0
|
||||||
|
87.0,1.0,1.0
|
||||||
|
88.0,1.0,1.0
|
||||||
|
89.0,1.0,1.0
|
||||||
|
90.0,1.0,1.0
|
||||||
|
91.0,1.0,1.0
|
||||||
|
92.0,1.0,1.0
|
||||||
|
93.0,1.0,1.0
|
||||||
|
94.0,1.0,1.0
|
||||||
|
95.0,1.0,1.0
|
||||||
|
96.0,1.0,1.0
|
||||||
|
97.0,1.0,1.0
|
||||||
|
98.0,1.0,1.0
|
||||||
|
99.0,1.0,1.0
|
||||||
|
100.0,1.0,1.0
|
||||||
|
101.0,1.0,1.0
|
||||||
|
102.0,1.0,1.0
|
||||||
|
103.0,1.0,1.0
|
||||||
|
104.0,1.0,1.0
|
||||||
|
105.0,1.0,1.0
|
||||||
|
106.0,1.0,1.0
|
||||||
|
107.0,1.0,1.0
|
||||||
|
108.0,1.0,1.0
|
||||||
|
109.0,1.0,1.0
|
||||||
|
110.0,1.0,1.0
|
||||||
|
111.0,1.0,1.0
|
||||||
|
112.0,1.0,1.0
|
||||||
|
113.0,1.0,1.0
|
||||||
|
114.0,1.0,1.0
|
||||||
|
115.0,1.0,1.0
|
||||||
|
116.0,1.0,1.0
|
||||||
|
117.0,1.0,1.0
|
||||||
|
118.0,1.0,1.0
|
||||||
|
119.0,1.0,1.0
|
||||||
|
120.0,1.0,1.0
|
||||||
|
121.0,1.0,1.0
|
||||||
|
122.0,1.0,1.0
|
||||||
|
123.0,1.0,1.0
|
||||||
|
124.0,1.0,1.0
|
||||||
|
125.0,1.0,1.0
|
||||||
|
126.0,1.0,1.0
|
||||||
|
127.0,1.0,1.0
|
||||||
|
128.0,1.0,1.0
|
||||||
|
129.0,1.0,1.0
|
||||||
|
130.0,1.0,1.0
|
||||||
|
131.0,1.0,1.0
|
||||||
|
132.0,1.0,1.0
|
||||||
|
133.0,1.0,1.0
|
||||||
|
134.0,1.0,1.0
|
||||||
|
135.0,1.0,1.0
|
||||||
|
136.0,1.0,1.0
|
||||||
|
137.0,1.0,1.0
|
||||||
|
138.0,1.0,1.0
|
||||||
|
139.0,1.0,1.0
|
||||||
|
140.0,1.0,1.0
|
||||||
|
141.0,1.0,1.0
|
||||||
|
142.0,1.0,1.0
|
||||||
|
143.0,1.0,1.0
|
||||||
|
144.0,1.0,1.0
|
||||||
|
145.0,1.0,1.0
|
||||||
|
146.0,1.0,1.0
|
||||||
|
147.0,1.0,1.0
|
||||||
|
148.0,1.0,1.0
|
||||||
|
149.0,1.0,1.0
|
||||||
|
150.0,1.0,1.0
|
||||||
|
151.0,1.0,1.0
|
||||||
|
152.0,1.0,1.0
|
||||||
|
153.0,1.0,1.0
|
||||||
|
154.0,1.0,1.0
|
||||||
|
155.0,1.0,1.0
|
||||||
|
156.0,1.0,1.0
|
||||||
|
157.0,1.0,1.0
|
||||||
|
158.0,1.0,1.0
|
||||||
|
159.0,1.0,1.0
|
||||||
|
160.0,1.0,1.0
|
||||||
|
161.0,1.0,1.0
|
||||||
|
162.0,1.0,1.0
|
||||||
|
163.0,1.0,1.0
|
||||||
|
164.0,1.0,1.0
|
||||||
|
165.0,1.0,1.0
|
||||||
|
166.0,1.0,1.0
|
||||||
|
167.0,1.0,1.0
|
||||||
|
168.0,1.0,1.0
|
||||||
|
169.0,1.0,1.0
|
||||||
|
170.0,1.0,1.0
|
||||||
|
171.0,1.0,1.0
|
||||||
|
172.0,1.0,1.0
|
||||||
|
173.0,1.0,1.0
|
||||||
|
174.0,1.0,1.0
|
||||||
|
175.0,1.0,1.0
|
||||||
|
176.0,1.0,1.0
|
||||||
|
177.0,1.0,1.0
|
||||||
|
178.0,1.0,1.0
|
||||||
|
179.0,1.0,1.0
|
||||||
|
180.0,1.0,1.0
|
||||||
|
181.0,1.0,1.0
|
||||||
|
182.0,1.0,1.0
|
||||||
|
183.0,1.0,1.0
|
||||||
|
184.0,1.0,1.0
|
||||||
|
185.0,1.0,1.0
|
||||||
|
186.0,1.0,1.0
|
||||||
|
187.0,1.0,1.0
|
||||||
|
188.0,1.0,1.0
|
||||||
|
189.0,1.0,1.0
|
||||||
|
190.0,1.0,1.0
|
||||||
|
191.0,1.0,1.0
|
||||||
|
192.0,1.0,1.0
|
||||||
|
193.0,1.0,1.0
|
||||||
|
194.0,1.0,1.0
|
||||||
|
195.0,1.0,1.0
|
||||||
|
196.0,1.0,1.0
|
||||||
|
197.0,1.0,1.0
|
||||||
|
198.0,1.0,1.0
|
||||||
|
199.0,1.0,1.0
|
||||||
|
200.0,1.0,1.0
|
||||||
|
201.0,1.0,1.0
|
||||||
|
202.0,1.0,1.0
|
||||||
|
203.0,1.0,1.0
|
||||||
|
204.0,1.0,1.0
|
||||||
|
205.0,1.0,1.0
|
||||||
|
206.0,1.0,1.0
|
||||||
|
207.0,1.0,1.0
|
||||||
|
208.0,1.0,1.0
|
||||||
|
209.0,1.0,1.0
|
||||||
|
210.0,1.0,1.0
|
||||||
|
211.0,1.0,1.0
|
||||||
|
212.0,1.0,1.0
|
||||||
|
213.0,1.0,1.0
|
||||||
|
214.0,1.0,1.0
|
||||||
|
215.0,1.0,1.0
|
||||||
|
216.0,1.0,1.0
|
||||||
|
217.0,1.0,1.0
|
||||||
|
218.0,1.0,1.0
|
||||||
|
219.0,1.0,1.0
|
||||||
|
220.0,1.0,1.0
|
||||||
|
221.0,1.0,1.0
|
||||||
|
222.0,1.0,1.0
|
||||||
|
223.0,1.0,1.0
|
||||||
|
224.0,1.0,1.0
|
||||||
|
225.0,1.0,1.0
|
||||||
|
226.0,1.0,1.0
|
||||||
|
227.0,1.0,1.0
|
||||||
|
228.0,1.0,1.0
|
||||||
|
229.0,1.0,1.0
|
||||||
|
230.0,1.0,1.0
|
||||||
|
231.0,1.0,1.0
|
||||||
|
232.0,1.0,1.0
|
||||||
|
233.0,1.0,1.0
|
||||||
|
234.0,1.0,1.0
|
||||||
|
235.0,1.0,1.0
|
||||||
|
236.0,1.0,1.0
|
||||||
|
237.0,1.0,1.0
|
||||||
|
238.0,1.0,1.0
|
||||||
|
239.0,1.0,1.0
|
||||||
|
240.0,1.0,1.0
|
||||||
|
241.0,1.0,1.0
|
||||||
|
242.0,1.0,1.0
|
||||||
|
243.0,1.0,1.0
|
||||||
|
244.0,1.0,1.0
|
||||||
|
245.0,1.0,1.0
|
||||||
|
246.0,1.0,1.0
|
||||||
|
247.0,1.0,1.0
|
||||||
|
248.0,1.0,1.0
|
||||||
|
249.0,1.0,1.0
|
||||||
|
250.0,1.0,1.0
|
||||||
|
251.0,1.0,1.0
|
||||||
|
252.0,1.0,1.0
|
||||||
|
253.0,1.0,1.0
|
||||||
|
254.0,1.0,1.0
|
||||||
|
255.0,1.0,1.0
|
||||||
|
256.0,1.0,1.0
|
||||||
|
257.0,1.0,1.0
|
||||||
|
258.0,1.0,1.0
|
||||||
|
259.0,1.0,1.0
|
||||||
|
260.0,1.0,1.0
|
||||||
|
261.0,1.0,1.0
|
||||||
|
262.0,1.0,1.0
|
||||||
|
263.0,1.0,1.0
|
||||||
|
264.0,1.0,1.0
|
||||||
|
265.0,1.0,1.0
|
||||||
|
266.0,1.0,1.0
|
||||||
|
267.0,1.0,1.0
|
||||||
|
268.0,1.0,1.0
|
||||||
|
269.0,1.0,1.0
|
||||||
|
270.0,1.0,1.0
|
||||||
|
271.0,1.0,1.0
|
||||||
|
272.0,1.0,1.0
|
||||||
|
273.0,1.0,1.0
|
||||||
|
274.0,1.0,1.0
|
||||||
|
275.0,1.0,1.0
|
||||||
|
276.0,1.0,1.0
|
||||||
|
277.0,1.0,1.0
|
||||||
|
278.0,1.0,1.0
|
||||||
|
279.0,1.0,1.0
|
||||||
|
280.0,1.0,1.0
|
||||||
|
281.0,1.0,1.0
|
||||||
|
282.0,1.0,1.0
|
||||||
|
283.0,1.0,1.0
|
||||||
|
284.0,1.0,1.0
|
||||||
|
285.0,1.0,1.0
|
||||||
|
286.0,1.0,1.0
|
||||||
|
287.0,1.0,1.0
|
||||||
|
288.0,1.0,1.0
|
||||||
|
289.0,1.0,1.0
|
||||||
|
290.0,1.0,1.0
|
||||||
|
291.0,1.0,1.0
|
||||||
|
292.0,1.0,1.0
|
||||||
|
293.0,1.0,1.0
|
||||||
|
294.0,1.0,1.0
|
||||||
|
295.0,1.0,1.0
|
||||||
|
296.0,1.0,1.0
|
||||||
|
297.0,1.0,1.0
|
||||||
|
298.0,1.0,1.0
|
||||||
|
299.0,1.0,1.0
|
||||||
|
300.0,1.0,1.0
|
||||||
|
301.0,1.0,1.0
|
||||||
|
302.0,1.0,1.0
|
||||||
|
303.0,1.0,1.0
|
||||||
|
304.0,1.0,1.0
|
||||||
|
305.0,1.0,1.0
|
||||||
|
306.0,1.0,1.0
|
||||||
|
307.0,1.0,1.0
|
||||||
|
308.0,1.0,1.0
|
||||||
|
309.0,1.0,1.0
|
||||||
|
310.0,1.0,1.0
|
||||||
|
311.0,1.0,1.0
|
||||||
|
312.0,1.0,1.0
|
||||||
|
313.0,1.0,1.0
|
||||||
|
314.0,1.0,1.0
|
||||||
|
315.0,1.0,1.0
|
||||||
|
316.0,1.0,1.0
|
||||||
|
317.0,1.0,1.0
|
||||||
|
318.0,1.0,1.0
|
||||||
|
319.0,1.0,1.0
|
||||||
|
320.0,1.0,1.0
|
||||||
|
321.0,1.0,1.0
|
||||||
|
322.0,1.0,1.0
|
||||||
|
323.0,1.0,1.0
|
||||||
|
324.0,1.0,1.0
|
||||||
|
325.0,1.0,1.0
|
||||||
|
326.0,1.0,1.0
|
||||||
|
327.0,1.0,1.0
|
||||||
|
328.0,1.0,1.0
|
||||||
|
329.0,1.0,1.0
|
||||||
|
330.0,1.0,1.0
|
||||||
|
331.0,1.0,1.0
|
||||||
|
332.0,1.0,1.0
|
||||||
|
333.0,1.0,1.0
|
||||||
|
334.0,1.0,1.0
|
||||||
|
335.0,1.0,1.0
|
||||||
|
336.0,1.0,1.0
|
||||||
|
337.0,1.0,1.0
|
||||||
|
338.0,1.0,1.0
|
||||||
|
339.0,1.0,1.0
|
||||||
|
340.0,1.0,1.0
|
||||||
|
341.0,1.0,1.0
|
||||||
|
342.0,1.0,1.0
|
||||||
|
343.0,1.0,1.0
|
||||||
|
344.0,1.0,1.0
|
||||||
|
345.0,1.0,1.0
|
||||||
|
346.0,1.0,1.0
|
||||||
|
347.0,1.0,1.0
|
||||||
|
348.0,1.0,1.0
|
||||||
|
349.0,1.0,1.0
|
||||||
|
350.0,1.0,1.0
|
||||||
|
351.0,1.0,1.0
|
||||||
|
352.0,1.0,1.0
|
||||||
|
353.0,1.0,1.0
|
||||||
|
354.0,1.0,1.0
|
||||||
|
355.0,1.0,1.0
|
||||||
|
356.0,1.0,1.0
|
||||||
|
357.0,1.0,1.0
|
||||||
|
358.0,1.0,1.0
|
||||||
|
359.0,1.0,1.0
|
||||||
|
360.0,1.0,1.0
|
||||||
|
361.0,1.0,1.0
|
||||||
|
362.0,1.0,1.0
|
||||||
|
363.0,1.0,1.0
|
||||||
|
364.0,1.0,1.0
|
||||||
|
365.0,1.0,1.0
|
||||||
|
366.0,1.0,1.0
|
||||||
|
367.0,1.0,1.0
|
||||||
|
368.0,1.0,1.0
|
||||||
|
369.0,1.0,1.0
|
||||||
|
370.0,1.0,1.0
|
||||||
|
371.0,1.0,1.0
|
||||||
|
372.0,1.0,1.0
|
||||||
|
373.0,1.0,1.0
|
||||||
|
374.0,1.0,1.0
|
||||||
|
375.0,1.0,1.0
|
||||||
|
376.0,1.0,1.0
|
||||||
|
377.0,1.0,1.0
|
||||||
|
378.0,1.0,1.0
|
||||||
|
379.0,1.0,1.0
|
||||||
|
380.0,1.0,1.0
|
||||||
|
381.0,1.0,1.0
|
||||||
|
382.0,1.0,1.0
|
||||||
|
383.0,1.0,1.0
|
||||||
|
384.0,1.0,1.0
|
||||||
|
385.0,1.0,1.0
|
||||||
|
386.0,1.0,1.0
|
||||||
|
387.0,1.0,1.0
|
||||||
|
388.0,1.0,1.0
|
||||||
|
389.0,1.0,1.0
|
||||||
|
390.0,1.0,1.0
|
||||||
|
391.0,1.0,1.0
|
||||||
|
392.0,1.0,1.0
|
||||||
|
393.0,1.0,1.0
|
||||||
|
394.0,1.0,1.0
|
||||||
|
395.0,1.0,1.0
|
||||||
|
396.0,1.0,1.0
|
||||||
|
397.0,1.0,1.0
|
||||||
|
398.0,1.0,1.0
|
||||||
|
399.0,1.0,1.0
|
||||||
|
400.0,1.0,1.0
|
||||||
|
401.0,1.0,1.0
|
||||||
|
402.0,1.0,1.0
|
||||||
|
403.0,1.0,1.0
|
||||||
|
404.0,1.0,1.0
|
||||||
|
405.0,1.0,1.0
|
||||||
|
406.0,1.0,1.0
|
||||||
|
407.0,1.0,1.0
|
||||||
|
408.0,1.0,1.0
|
||||||
|
409.0,1.0,1.0
|
||||||
|
410.0,1.0,1.0
|
||||||
|
411.0,1.0,1.0
|
||||||
|
412.0,1.0,1.0
|
||||||
|
413.0,1.0,1.0
|
||||||
|
414.0,1.0,1.0
|
||||||
|
415.0,1.0,1.0
|
||||||
|
416.0,1.0,1.0
|
||||||
|
417.0,1.0,1.0
|
||||||
|
418.0,1.0,1.0
|
||||||
|
419.0,1.0,1.0
|
||||||
|
420.0,1.0,1.0
|
||||||
|
421.0,1.0,1.0
|
||||||
|
422.0,1.0,1.0
|
||||||
|
423.0,1.0,1.0
|
||||||
|
424.0,1.0,1.0
|
||||||
|
425.0,1.0,1.0
|
||||||
|
426.0,1.0,1.0
|
||||||
|
427.0,1.0,1.0
|
||||||
|
428.0,1.0,1.0
|
||||||
|
429.0,1.0,1.0
|
||||||
|
430.0,1.0,1.0
|
||||||
|
431.0,1.0,1.0
|
||||||
|
432.0,1.0,1.0
|
||||||
|
433.0,1.0,1.0
|
||||||
|
434.0,1.0,1.0
|
||||||
|
435.0,1.0,1.0
|
||||||
|
436.0,1.0,1.0
|
||||||
|
437.0,1.0,1.0
|
||||||
|
438.0,1.0,1.0
|
||||||
|
439.0,1.0,1.0
|
||||||
|
440.0,1.0,1.0
|
||||||
|
441.0,1.0,1.0
|
||||||
|
442.0,1.0,1.0
|
||||||
|
443.0,1.0,1.0
|
||||||
|
444.0,1.0,1.0
|
||||||
|
445.0,1.0,1.0
|
||||||
|
446.0,1.0,1.0
|
||||||
|
447.0,1.0,1.0
|
||||||
|
448.0,1.0,1.0
|
||||||
|
449.0,1.0,1.0
|
||||||
|
450.0,1.0,1.0
|
||||||
|
451.0,1.0,1.0
|
||||||
|
452.0,1.0,1.0
|
||||||
|
453.0,1.0,1.0
|
||||||
|
454.0,1.0,1.0
|
||||||
|
455.0,1.0,1.0
|
||||||
|
456.0,1.0,1.0
|
||||||
|
457.0,1.0,1.0
|
||||||
|
458.0,1.0,1.0
|
||||||
|
459.0,1.0,1.0
|
||||||
|
460.0,1.0,1.0
|
||||||
|
461.0,1.0,1.0
|
||||||
|
462.0,1.0,1.0
|
||||||
|
463.0,1.0,1.0
|
||||||
|
464.0,1.0,1.0
|
||||||
|
465.0,1.0,1.0
|
||||||
|
466.0,1.0,1.0
|
||||||
|
467.0,1.0,1.0
|
||||||
|
468.0,1.0,1.0
|
||||||
|
469.0,1.0,1.0
|
||||||
|
470.0,1.0,1.0
|
||||||
|
471.0,1.0,1.0
|
||||||
|
472.0,1.0,1.0
|
||||||
|
473.0,1.0,1.0
|
||||||
|
474.0,1.0,1.0
|
||||||
|
475.0,1.0,1.0
|
||||||
|
476.0,1.0,1.0
|
||||||
|
477.0,1.0,1.0
|
||||||
|
478.0,1.0,1.0
|
||||||
|
479.0,1.0,1.0
|
||||||
|
480.0,1.0,1.0
|
||||||
|
481.0,1.0,1.0
|
||||||
|
482.0,1.0,1.0
|
||||||
|
483.0,1.0,1.0
|
||||||
|
484.0,1.0,1.0
|
||||||
|
485.0,1.0,1.0
|
||||||
|
486.0,1.0,1.0
|
||||||
|
487.0,1.0,1.0
|
||||||
|
488.0,1.0,1.0
|
||||||
|
489.0,1.0,1.0
|
||||||
|
490.0,1.0,1.0
|
||||||
|
491.0,1.0,1.0
|
||||||
|
492.0,1.0,1.0
|
||||||
|
493.0,1.0,1.0
|
||||||
|
494.0,1.0,1.0
|
||||||
|
495.0,1.0,1.0
|
||||||
|
496.0,1.0,1.0
|
||||||
|
497.0,1.0,1.0
|
||||||
|
498.0,1.0,1.0
|
||||||
|
499.0,1.0,1.0
|
||||||
|
500.0,1.0,1.0
|
||||||
|
501.0,1.0,1.0
|
||||||
|
502.0,1.0,1.0
|
||||||
|
503.0,1.0,1.0
|
||||||
|
504.0,1.0,1.0
|
||||||
|
505.0,1.0,1.0
|
||||||
|
506.0,1.0,1.0
|
||||||
|
507.0,1.0,1.0
|
||||||
|
508.0,1.0,1.0
|
||||||
|
509.0,1.0,1.0
|
||||||
|
510.0,1.0,1.0
|
||||||
|
511.0,1.0,1.0
|
||||||
|
512.0,1.0,1.0
|
||||||
|
513.0,1.0,1.0
|
||||||
|
514.0,1.0,1.0
|
||||||
|
515.0,1.0,1.0
|
||||||
|
516.0,1.0,1.0
|
||||||
|
517.0,1.0,1.0
|
||||||
|
518.0,1.0,1.0
|
||||||
|
519.0,1.0,1.0
|
||||||
|
520.0,1.0,1.0
|
||||||
|
521.0,1.0,1.0
|
||||||
|
522.0,1.0,1.0
|
||||||
|
523.0,1.0,1.0
|
||||||
|
524.0,1.0,1.0
|
||||||
|
525.0,1.0,1.0
|
||||||
|
526.0,1.0,1.0
|
||||||
|
527.0,1.0,1.0
|
||||||
|
528.0,1.0,1.0
|
||||||
|
529.0,1.0,1.0
|
||||||
|
530.0,1.0,1.0
|
||||||
|
531.0,1.0,1.0
|
||||||
|
532.0,1.0,1.0
|
||||||
|
533.0,1.0,1.0
|
||||||
|
534.0,1.0,1.0
|
||||||
|
535.0,1.0,1.0
|
||||||
|
536.0,1.0,1.0
|
||||||
|
537.0,1.0,1.0
|
||||||
|
538.0,1.0,1.0
|
||||||
|
539.0,1.0,1.0
|
||||||
|
540.0,1.0,1.0
|
||||||
|
541.0,1.0,1.0
|
||||||
|
542.0,1.0,1.0
|
||||||
|
543.0,1.0,1.0
|
||||||
|
544.0,1.0,1.0
|
||||||
|
545.0,1.0,1.0
|
||||||
|
546.0,1.0,1.0
|
||||||
|
547.0,1.0,1.0
|
||||||
|
548.0,1.0,1.0
|
||||||
|
549.0,1.0,1.0
|
||||||
|
550.0,1.0,1.0
|
||||||
|
551.0,1.0,1.0
|
||||||
|
552.0,1.0,1.0
|
||||||
|
553.0,1.0,1.0
|
||||||
|
554.0,1.0,1.0
|
||||||
|
555.0,1.0,1.0
|
||||||
|
556.0,1.0,1.0
|
||||||
|
557.0,1.0,1.0
|
||||||
|
558.0,1.0,1.0
|
||||||
|
559.0,1.0,1.0
|
||||||
|
560.0,1.0,1.0
|
||||||
|
561.0,1.0,1.0
|
||||||
|
562.0,1.0,1.0
|
||||||
|
563.0,1.0,1.0
|
||||||
|
564.0,1.0,1.0
|
||||||
|
565.0,1.0,1.0
|
||||||
|
566.0,1.0,1.0
|
||||||
|
567.0,1.0,1.0
|
||||||
|
568.0,1.0,1.0
|
||||||
|
569.0,1.0,1.0
|
||||||
|
570.0,1.0,1.0
|
||||||
|
571.0,1.0,1.0
|
||||||
|
572.0,1.0,1.0
|
||||||
|
573.0,1.0,1.0
|
||||||
|
574.0,1.0,1.0
|
||||||
|
575.0,1.0,1.0
|
||||||
|
576.0,1.0,1.0
|
||||||
|
577.0,1.0,1.0
|
||||||
|
578.0,1.0,1.0
|
||||||
|
579.0,1.0,1.0
|
||||||
|
580.0,1.0,1.0
|
||||||
|
581.0,1.0,1.0
|
||||||
|
582.0,1.0,1.0
|
||||||
|
583.0,1.0,1.0
|
||||||
|
584.0,1.0,1.0
|
||||||
|
585.0,1.0,1.0
|
||||||
|
586.0,1.0,1.0
|
||||||
|
587.0,1.0,1.0
|
||||||
|
588.0,1.0,1.0
|
||||||
|
589.0,1.0,1.0
|
||||||
|
590.0,1.0,1.0
|
||||||
|
591.0,1.0,1.0
|
||||||
|
592.0,1.0,1.0
|
||||||
|
593.0,1.0,1.0
|
||||||
|
594.0,1.0,1.0
|
||||||
|
595.0,1.0,1.0
|
||||||
|
596.0,1.0,1.0
|
||||||
|
597.0,1.0,1.0
|
||||||
|
598.0,1.0,1.0
|
||||||
|
599.0,1.0,1.0
|
||||||
|
600.0,1.0,1.0
|
201
source-code/Poisson-Graphs/new/outputM.txt~
Normal file
201
source-code/Poisson-Graphs/new/outputM.txt~
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
time,rateConstant,difficulty
|
||||||
|
0.0,1.0,1.0
|
||||||
|
120458.46590012926,1.0,1.0
|
||||||
|
240605.33373578714,1.0,1.0
|
||||||
|
360287.44233708055,1.0,1.0
|
||||||
|
480034.84471731156,1.0,1.0
|
||||||
|
601021.4072874074,1.0,1.0
|
||||||
|
720155.9397105722,1.0,1.0
|
||||||
|
840557.1097845419,1.0,1.0
|
||||||
|
960142.4715273783,1.0,1.0
|
||||||
|
1080326.4196690398,1.0,1.0
|
||||||
|
1200228.3567496322,1.0,1.0
|
||||||
|
1321393.1769845556,1.0,1.0
|
||||||
|
1442403.7637959223,1.0,1.0
|
||||||
|
1563312.6884154421,1.0,1.0
|
||||||
|
1683650.3562759135,1.0,1.0
|
||||||
|
1804242.0878089573,1.0,1.0
|
||||||
|
1923957.6270508477,1.0,1.0
|
||||||
|
2043603.5193920576,1.0,1.0
|
||||||
|
2162815.4440224506,1.0,1.0
|
||||||
|
2282288.929005547,1.0,1.0
|
||||||
|
2402114.705755926,1.0,1.0
|
||||||
|
2522303.585101224,1.0,1.0
|
||||||
|
2643267.2988593285,1.0,1.0
|
||||||
|
2762617.5338163865,1.0,1.0
|
||||||
|
2882563.380726947,1.0,1.0
|
||||||
|
3003489.532699132,1.0,1.0
|
||||||
|
3124641.562256374,1.0,1.0
|
||||||
|
3245100.9215427977,1.0,1.0
|
||||||
|
3365536.420458877,1.0,1.0
|
||||||
|
3484337.996609595,1.0,1.0
|
||||||
|
3604694.7847104715,1.0,1.0
|
||||||
|
3724951.576782264,1.0,1.0
|
||||||
|
3846026.69613723,1.0,1.0
|
||||||
|
3967024.7982774274,1.0,1.0
|
||||||
|
4085911.063711746,1.0,1.0
|
||||||
|
4205815.028144305,1.0,1.0
|
||||||
|
4325421.232620401,1.0,1.0
|
||||||
|
4444827.052513202,1.0,1.0
|
||||||
|
4565099.154304211,1.0,1.0
|
||||||
|
4686236.387124661,1.0,1.0
|
||||||
|
4806734.051850467,1.0,1.0
|
||||||
|
4926566.647937627,1.0,1.0
|
||||||
|
5045488.866484466,1.0,1.0
|
||||||
|
5166502.755345808,1.0,1.0
|
||||||
|
5287233.653263695,1.0,1.0
|
||||||
|
5407908.334559678,1.0,1.0
|
||||||
|
5528786.366282915,1.0,1.0
|
||||||
|
5647678.3122160155,1.0,1.0
|
||||||
|
5767244.089580304,1.0,1.0
|
||||||
|
5886473.651601109,1.0,1.0
|
||||||
|
6006435.897878854,1.0,1.0
|
||||||
|
6125341.27352921,1.0,1.0
|
||||||
|
6245479.785253891,1.0,1.0
|
||||||
|
6365523.236878065,1.0,1.0
|
||||||
|
6485749.795878896,1.0,1.0
|
||||||
|
6605240.444894265,1.0,1.0
|
||||||
|
6724686.210446132,1.0,1.0
|
||||||
|
6844155.218750592,1.0,1.0
|
||||||
|
6963341.181369955,1.0,1.0
|
||||||
|
7082695.6923123505,1.0,1.0
|
||||||
|
7203655.141225615,1.0,1.0
|
||||||
|
7322627.204840391,1.0,1.0
|
||||||
|
7441799.159546731,1.0,1.0
|
||||||
|
7562822.49932097,1.0,1.0
|
||||||
|
7683323.524066307,1.0,1.0
|
||||||
|
7804477.48899398,1.0,1.0
|
||||||
|
7923457.857637024,1.0,1.0
|
||||||
|
8043898.249303401,1.0,1.0
|
||||||
|
8164187.296374614,1.0,1.0
|
||||||
|
8283469.107294493,1.0,1.0
|
||||||
|
8402627.723784521,1.0,1.0
|
||||||
|
8523745.89200794,1.0,1.0
|
||||||
|
8643778.9729813,1.0,1.0
|
||||||
|
8764635.624631569,1.0,1.0
|
||||||
|
8885538.059417976,1.0,1.0
|
||||||
|
9006433.79263568,1.0,1.0
|
||||||
|
9127489.588015186,1.0,1.0
|
||||||
|
9247569.28782317,1.0,1.0
|
||||||
|
9367958.084440755,1.0,1.0
|
||||||
|
9487586.29442678,1.0,1.0
|
||||||
|
9606427.886281481,1.0,1.0
|
||||||
|
9725872.946140163,1.0,1.0
|
||||||
|
9846820.596317865,1.0,1.0
|
||||||
|
9966080.313457007,1.0,1.0
|
||||||
|
10085765.108573573,1.0,1.0
|
||||||
|
10206008.374459436,1.0,1.0
|
||||||
|
10326807.845790997,1.0,1.0
|
||||||
|
10447513.423168132,1.0,1.0
|
||||||
|
10566795.347145824,1.0,1.0
|
||||||
|
10686179.997466285,1.0,1.0
|
||||||
|
10805522.808373246,1.0,1.0
|
||||||
|
10925591.945700001,1.0,1.0
|
||||||
|
11045387.795286857,1.0,1.0
|
||||||
|
11165651.717103494,1.0,1.0
|
||||||
|
11286830.098064246,1.0,1.0
|
||||||
|
11406728.71699933,1.0,1.0
|
||||||
|
11525922.789870113,1.0,1.0
|
||||||
|
11646476.03903497,1.0,1.0
|
||||||
|
11766081.434268286,1.0,1.0
|
||||||
|
11886554.737807736,1.0,1.0
|
||||||
|
12006591.066234503,1.0,1.0
|
||||||
|
12125475.542528223,1.0,1.0
|
||||||
|
12245282.608027933,1.0,1.0
|
||||||
|
12364566.337023206,1.0,1.0
|
||||||
|
12484001.537563423,1.0,1.0
|
||||||
|
12604914.58673975,1.0,1.0
|
||||||
|
12725797.319719713,1.0,1.0
|
||||||
|
12844665.121160349,1.0,1.0
|
||||||
|
12964577.111847764,1.0,1.0
|
||||||
|
13083664.372389417,1.0,1.0
|
||||||
|
13204397.122438395,1.0,1.0
|
||||||
|
13324189.80038166,1.0,1.0
|
||||||
|
13445349.787586372,1.0,1.0
|
||||||
|
13564667.751049513,1.0,1.0
|
||||||
|
13684270.141374838,1.0,1.0
|
||||||
|
13804933.175467426,1.0,1.0
|
||||||
|
13926075.032552686,1.0,1.0
|
||||||
|
14045914.739095576,1.0,1.0
|
||||||
|
14166631.90042476,1.0,1.0
|
||||||
|
14286319.61550191,1.0,1.0
|
||||||
|
14406521.722056692,1.0,0.434741782576
|
||||||
|
14527069.972553544,1.0,0.19008730551
|
||||||
|
14647876.788742132,1.0,0.0840528337448
|
||||||
|
14766882.452974409,1.0,0.037302520528
|
||||||
|
14886464.10335911,1.0,0.0165590754676
|
||||||
|
15006383.983595744,1.0,0.00734675515331
|
||||||
|
15125494.942906044,1.0,0.00323569454228
|
||||||
|
15246686.831929097,1.0,0.00142738653296
|
||||||
|
15365567.953963466,1.0,0.000625305203658
|
||||||
|
15485210.071059253,1.0,0.00027137099116
|
||||||
|
15605744.64157258,1.0,0.00011715461834
|
||||||
|
15726806.733151415,1.0,5.07010986398e-05
|
||||||
|
15847473.63409661,1.0,2.20995440742e-05
|
||||||
|
15967616.71119521,1.0,9.7101015984e-06
|
||||||
|
16087483.017800437,1.0,4.29503052419e-06
|
||||||
|
16208328.180223988,1.0,1.92536966438e-06
|
||||||
|
16328269.772618307,1.0,8.74191715802e-07
|
||||||
|
16448898.77254663,1.0,4.04296324402e-07
|
||||||
|
16569068.683560552,1.0,1.90818902578e-07
|
||||||
|
16689986.260285133,1.0,9.28633545485e-08
|
||||||
|
16810906.032656457,1.0,4.72143204458e-08
|
||||||
|
16930289.120968327,1.0,2.49711320542e-08
|
||||||
|
17050753.779718515,1.0,1.3892256413e-08
|
||||||
|
17170600.427019596,1.0,8.15844774794e-09
|
||||||
|
17289713.01359109,1.0,4.99225078962e-09
|
||||||
|
17410383.421790008,1.0,3.25190780354e-09
|
||||||
|
17530744.28431112,1.0,2.30869255122e-09
|
||||||
|
17649863.36025036,1.0,1.75633116174e-09
|
||||||
|
17771007.11205409,1.0,1.56057621444e-09
|
||||||
|
17891565.791564044,1.0,2.04725172611e-09
|
||||||
|
18010728.55130284,1.0,3.28303372549e-09
|
||||||
|
18131143.8843602,1.0,3.25496154055e-09
|
||||||
|
18251685.45446652,1.0,2.60736708269e-09
|
||||||
|
18371507.007102486,1.0,1.85630105501e-09
|
||||||
|
18491403.948076807,1.0,1.21928659457e-09
|
||||||
|
18611553.039604228,1.0,7.49792394597e-10
|
||||||
|
18730744.251551468,1.0,4.45186327526e-10
|
||||||
|
18849856.685056694,1.0,2.61385070862e-10
|
||||||
|
18968926.062500622,1.0,1.55149613051e-10
|
||||||
|
19088067.33909847,1.0,9.51850841053e-11
|
||||||
|
19207594.13354391,1.0,6.1434055957e-11
|
||||||
|
19328017.11208744,1.0,4.14815251504e-11
|
||||||
|
19448814.951942917,1.0,2.86357848006e-11
|
||||||
|
19567841.28162038,1.0,2.11150220091e-11
|
||||||
|
19688388.179414563,1.0,1.6406642243e-11
|
||||||
|
19807627.873820234,1.0,1.43187359575e-11
|
||||||
|
19928483.04169874,1.0,1.35913238196e-11
|
||||||
|
20048557.76424465,1.0,1.4331290576e-11
|
||||||
|
20167664.74191137,1.0,2.37342192382e-11
|
||||||
|
20287610.467802733,1.0,3.14063325262e-11
|
||||||
|
20408382.62417472,1.0,3.36556321046e-11
|
||||||
|
20527817.08243184,1.0,3.00938650991e-11
|
||||||
|
20646637.59478427,1.0,2.24650389033e-11
|
||||||
|
20766577.880066067,1.0,1.49080962166e-11
|
||||||
|
20885785.934438772,1.0,8.89077367161e-12
|
||||||
|
21005536.07104386,1.0,4.87060433801e-12
|
||||||
|
21124902.305172637,1.0,2.47052077112e-12
|
||||||
|
21244885.7076036,1.0,1.17786853388e-12
|
||||||
|
21364581.43746038,1.0,5.31532928098e-13
|
||||||
|
21484493.676516064,1.0,2.28757375026e-13
|
||||||
|
21603916.644479226,1.0,9.40324531004e-14
|
||||||
|
21723733.860411238,1.0,3.70938898759e-14
|
||||||
|
21844771.38186735,1.0,1.42162474893e-14
|
||||||
|
21964794.368862327,1.0,5.30817642226e-15
|
||||||
|
22085627.151319932,1.0,1.94525471916e-15
|
||||||
|
22205153.52382764,1.0,6.9852514309e-16
|
||||||
|
22324878.40351138,1.0,2.45757880538e-16
|
||||||
|
22444702.60558849,1.0,8.47565473955e-17
|
||||||
|
22564133.40356277,1.0,2.8611824903e-17
|
||||||
|
22684916.550748322,1.0,9.50429614301e-18
|
||||||
|
22804924.811821572,1.0,3.10972949853e-18
|
||||||
|
22924555.89776567,1.0,1.00142181128e-18
|
||||||
|
23044673.155832924,1.0,3.17850639386e-19
|
||||||
|
23164255.219417505,1.0,9.93453168398e-20
|
||||||
|
23283874.042637054,1.0,3.05585142432e-20
|
||||||
|
23403159.90787814,1.0,9.23510334381e-21
|
||||||
|
23522146.490881946,1.0,2.7354446299e-21
|
||||||
|
23641985.23572208,1.0,7.94854774163e-22
|
||||||
|
23760806.412928328,1.0,2.26044417743e-22
|
||||||
|
23881715.30956635,1.0,6.31881915952e-23
|
Loading…
Reference in a new issue