udpate ffs again

This commit is contained in:
Brandon Goodell 2017-12-12 15:33:24 -07:00
parent cdaeb98d1d
commit ba5049ddcc
2 changed files with 81 additions and 206 deletions

View file

@ -16,18 +16,15 @@ class Block(object):
and updates parents to include. and updates parents to include.
_recomputeIdent : recomputes identity _recomputeIdent : recomputes identity
Usage: Usage:
b0 = Block() b0 = Block(dataIn = stuff, parentsIn = None)
b0.data = ... b1 = Block(dataIn = otherStuff, parentsIn = { b0.ident : b0 })
b1 = Block()
b1.data = ...
b1.addParents({b0.ident:b0})
""" """
def __init__(self): def __init__(self, dataIn=None, parentsIn=None):
# Initialize with empty payload, no identity, and empty parents. # Initialize with empty payload, no identity, and empty parents.
self.data = None self.data = dataIn
self.ident = hash(str(0)) self.ident = hash(str(0))
self.parents = None self.parents = parentsIn
self.addParents({}) self.addParents({})
def addParents(self, parentsIn): # dict of parents def addParents(self, parentsIn): # dict of parents

View file

@ -13,7 +13,7 @@ from Block import *
class BlockHandler(object): class BlockHandler(object):
def __init__(self): def __init__(self):
print("Initializing") #print("Initializing")
# Initialize a BlockHandler object. # Initialize a BlockHandler object.
self.data = None self.data = None
self.blocks = {} # Set of blocks (which track parents) self.blocks = {} # Set of blocks (which track parents)
@ -32,214 +32,92 @@ class BlockHandler(object):
self._addBlock(blocksIn[b]) self._addBlock(blocksIn[b])
def _addBlock(self, b): def _addBlock(self, b):
print("Adding block") #print("Adding block")
# Take a single block b and add to self.blocks, record family # Take a single block b and add to self.blocks, record family
# relations, update leaf monitor, update root monitor if nec- # relations, update leaf monitor, update root monitor if nec-
# essary # essary
diffDict = {b.ident:b}
diffDict = {copy.deepcopy(b.ident):copy.deepcopy(b)}
try:
assert b.ident not in self.blocks
except AssertionError:
print("Woops, tried to add a block with ident in self.blocks, overwriting old block")
self.blocks.update(diffDict) self.blocks.update(diffDict)
self.family.update({b.ident:{}})
self.family[b.ident].update({"parents":b.parents, "children":{}})
for parentIdent in b.parents:
if parentIdent not in self.family:
self.family.update({parentIdent:{}})
if "parents" not in self.family[parentIdent]:
self.family[parentIdent].update({"parents":{}})
if "children" not in self.family[parentIdent]:
self.family[parentIdent].update({"children":{}})
self.family[parentIdent]["parents"].update(b.parents)
self.family[parentIdent]["children"].update(diffDict)
if parentIdent in self.leaves:
del self.leaves[parentIdent]
if len(b.parents)==0 and b.ident not in self.roots:
self.roots.update(diffDict)
self.leaves.update(diffDict)
def inPast(self, x, y): try:
print("Testing if in past") assert b.ident not in self.leaves
# Return true if y is an ancestor of x except AssertionError:
q = deque() print("Woops, tried to add a block to leaf set that is already in the leafset, aborting.")
for pid in self.blocks[x].parents: self.leaves.update(diffDict) # New block is always a leaf
if pid==y:
return True
break
q.append(pid)
while(len(q)>0):
nxtIdent = q.popleft()
if len(self.blocks[nxtIdent].parents) > 0:
for pid in self.blocks[nxtIdent].parents:
if pid==y:
return True
break
q.append(pid)
return False
try:
assert b.ident not in self.family
except AssertionError:
print("woops, tried to add a block that already has a recorded family history, aborting.")
self.family.update({b.ident:{"parents":b.parents, "children":{}}}) # Add fam history fam
def vote(self): # Now update each parent's family history to reflect the new child
print("Voting") if len(b.parents)>0:
# Compute partial spectre vote for top several layers of for parentIdent in b.parents:
# the dag. if parentIdent not in self.family:
(U, vids) = self.leafBackAntichain() # This should never occur.
self.votes = {} print("Hey, what? confusedTravolta.gif... parentIdent not in self.family, parent not correct somehow.")
self.family.update({parentIdent:{}})
q = deque() if "parents" not in self.family[parentIdent]:
self.pendingVotes = {} # This should never occur.
for i in range(len(U)): print("Hey, what? confusedTravolta.gif... family history of parent lacks sub-dict for parentage, parent not correct somehow")
for leafId in U[i]: self.family[parentIdent].update({"parents":{}})
if i > 0:
self.sumPendingVotes(leafId, vids)
for x in U[i]: if "children" not in self.family[parentIdent]:
if x != leafId: # This should never occur.
q.append(x) print("Hey, what? confusedTravolta.gif... family history of parent lacks sub-dict for children, parent not correct somehow")
while(len(q)>0): self.family[parentIdent].update({"children":{}})
x = q.popleft()
if (leafId, leafId, x) not in self.votes:
self.votes.update({(leafId, leafId, x):1})
else:
try:
assert self.votes[(leafId, leafId, x)]==1
except AssertionError:
print("Woops, we found (leafId, leafId, x) as a key in self.votes while running vote(), and it should be +1, but it isn't:\n\n", (leafId, leafId, x), self.votes[(leafId, leafId, x)], "\n\n")
if (leafId, x, leafId) not in self.votes:
self.votes.update({(leafId, x, leafId):-1})
else:
try:
assert self.votes[(leafId,x,leafId)]==-1
except AssertionError:
print("Woops, we found (leafId, x, leafId) as a key in self.votes while running vote(), and it should be +1, but it isn't:\n\n", (leafId, x, leafId), self.votes[(leafId, x, leafId)], "\n\n")
self.transmitVote(leafId, leafId, x)
for pid in self.blocks[x].parents:
if not self.inPast(leafId, pid) and pid in vids and pid != leafId:
q.append(pid)
print(self.votes)
def sumPendingVotes(self, blockId, vulnIds): # Make sure grandparents are stored correctly (does nothing if already stored correctly)
print("Summing pending votes") self.family[parentIdent]["parents"].update(self.blocks[parentIdent].parents)
# For a blockId, take all pending votes for vulnerable IDs (x,y)
# if the net is positive vote 1, if the net is negative vote -1
# otherwise vote 0.
for x in vulnIds:
for y in vulnIds:
if (blockId, x, y) in self.pendingVotes:
if self.pendingVotes[(blockId, x, y)] > 0:
if (blockId, x, y) not in self.votes:
self.votes.update({(blockId, x, y):1})
else:
try:
assert self.votes[(blockId,x,y)]==1
except AssertionError:
print("Woops, we found (blockId, x, y) as a key in self.votes, and it should be +1, but it isn't:\n\n", (blockId, x, y), self.votes[(blockId, x,y)], "\n\n")
if (blockId, y, x) not in self.votes:
self.votes.update({(blockId, y, x):-1})
else:
try:
assert self.votes[(blockId,y,x)]==-1
except AssertionError:
print("Woops, we found (blockId, y, x) as a key in self.votes, and it should be -1, but it isn't:\n\n", (blockId, y, x), self.votes[(blockId, y,x)], "\n\n")
self.transmitVote(blockId, x, y)
elif self.pendingVotes[(blockId, x, y)] < 0:
if (blockId, x, y) not in self.votes:
self.votes.update({(blockId, x, y):-1})
else:
try:
assert self.votes[(blockId,x,y)]==-1
except AssertionError:
print("Woops, we found (blockId, x, y) as a key in self.votes, and it should be -1, but it isn't:\n\n", (blockId, x, y), self.votes[(blockId, x,y)], "\n\n")
if (blockId, y, x) not in self.votes: # Update "children" sub-dict of family history of parent
self.votes.update({(blockId, y, x):1}) self.family[parentIdent]["children"].update(diffDict)
else:
try:
assert self.votes[(blockId,y,x)]==1
except AssertionError:
print("Woops, we found (blockId, y, x) as a key in self.votes, and it should be +1, but it isn't:\n\n", (blockId, x, y), self.votes[(blockId, x,y)], "\n\n")
self.transmitVote(blockId, y, x)
else:
if (blockId, x, y) not in self.votes:
self.votes.update({(blockId, x, y):0})
else:
try:
assert self.votes[(blockId,x,y)]==0
except AssertionError:
print("Woops, we found (blockId, x, y) as a key in self.votes, and it should be 0, but it isn't:\n\n", (blockId, x, y), self.votes[(blockId, x,y)], "\n\n")
if (blockId, y, x) not in self.votes:
self.votes.update({(blockId, y, x):0})
else:
try:
assert self.votes[(blockId,y,x)]==0
except AssertionError:
print("Woops, we found (blockId, y, x) as a key in self.votes, and it should be 0, but it isn't:\n\n", (blockId, y, x), self.votes[(blockId, y,x)], "\n\n")
# If the parent was previously a leaf, it is no longer
if parentIdent in self.leaves:
del self.leaves[parentIdent]
else:
if b.ident not in self.roots:
self.roots.update(diffDict)
self.leaves.update(diffDict)
self.family.update({b.ident:{"parents":{}, "children":{}}})
def transmitVote(self, v, x, y):
print("Transmitting votes")
q = deque()
for pid in self.blocks[v].parents:
q.append(pid)
while(len(q)>0):
print("Length of queue = ", len(q))
nxtPid = q.popleft()
if (nxtPid, x, y) not in self.pendingVotes:
self.pendingVotes.update({(nxtPid,x,y):1})
self.pendingVotes.update({(nxtPid,y,x):-1})
else:
self.pendingVotes[(nxtPid,x,y)] += 1
self.pendingVotes[(nxtPid,y,x)] -= 1
if len(self.blocks[nxtPid].parents) > 0:
for pid in self.blocks[nxtPid].parents:
if pid != nxtPid:
q.append(pid)
def leafBackAntichain(self):
print("Computing antichain")
temp = copy.deepcopy(self)
decomposition = []
vulnIdents = None
decomposition.append(temp.leaves)
vulnIdents = decomposition[-1]
temp = temp.pruneLeaves()
while(len(temp.blocks)>0 and len(decomposition) < self.antichainCutoff):
decomposition.append(temp.leaves)
for xid in decomposition[-1]:
if xid not in vulnIdents:
vulnIdents.update({xid:decomposition[-1][xid]})
temp = temp.pruneLeaves()
return decomposition, vulnIdents
def pruneLeaves(self):
print("Pruning leaves")
out = BlockHandler()
q = deque()
for rootIdent in self.roots:
q.append(rootIdent)
while(len(q)>0):
thisIdent = q.popleft()
if thisIdent not in self.leaves:
out._addBlock(self.blocks[thisIdent])
for chIdent in self.family[thisIdent]["children"]:
q.append(chIdent)
return out
class Test_RoBlock(unittest.TestCase): class Test_RoBlock(unittest.TestCase):
def test_BlockHandler(self): def test_BlockHandler(self):
R = BlockHandler() R = BlockHandler()
b = Block() b = Block(dataIn="zirconium encrusted tweezers", parentsIn={})
b.data = "zirconium encrusted tweezers"
b._recomputeIdent()
R._addBlock(b) R._addBlock(b)
diffDict = {copy.deepcopy(b.ident) : copy.deepcopy(b)}
b = Block() #print("Differential ", diffDict)
b.data = "brontosaurus slippers cannot exist" b = Block(dataIn="brontosaurus slippers do not exist", parentsIn=copy.deepcopy(diffDict))
b.addParents(R.leaves)
R._addBlock(b) R._addBlock(b)
#print("Blocks ", R.blocks)
#print("Family ", R.family)
#print("Leaves ", R.leaves)
self.assertEqual(len(R.blocks),2)
self.assertEqual(len(R.family),2)
self.assertEqual(len(R.leaves),1)
#print("Differential ", diffDict)
key, value = diffDict.popitem()
#print("Differential ", diffDict)
#print("Outputted values ", key, value)
#print("b.ident should = leaf.ident", b.ident)
self.assertTrue(key in R.blocks)
self.assertTrue(b.ident in R.blocks)
self.assertTrue(key in R.family[b.ident]["parents"])
self.assertTrue(b.ident in R.family[key]["children"])
R.vote()
suite = unittest.TestLoader().loadTestsFromTestCase(Test_RoBlock) suite = unittest.TestLoader().loadTestsFromTestCase(Test_RoBlock)
unittest.TextTestRunner(verbosity=1).run(suite) unittest.TextTestRunner(verbosity=1).run(suite)