From 463d8f35e28640d5d58c21b1ec19aa40a726cbb4 Mon Sep 17 00:00:00 2001 From: b-g-goodell Date: Tue, 12 Dec 2017 11:18:22 -0700 Subject: [PATCH] Rem. dep. file --- source-code/Spectre/BlockDAG.py | 227 -------------------------------- 1 file changed, 227 deletions(-) delete mode 100644 source-code/Spectre/BlockDAG.py diff --git a/source-code/Spectre/BlockDAG.py b/source-code/Spectre/BlockDAG.py deleted file mode 100644 index 3f89be0..0000000 --- a/source-code/Spectre/BlockDAG.py +++ /dev/null @@ -1,227 +0,0 @@ -from Block import * - #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### -class BlockDAG(object): - """ Collection of >=1 block. """ - def __init__(self, params=None): - self.genesis = Block() - self.genesis.id = "0" - self.blocks = {self.genesis.id:self.genesis} - self.leaves = {self.genesis.id:self.genesis} - - # Blocks from top-down antichain subsets covering >= 1/2 of blockDAG - self.votBlocks = {self.genesis.id:self.genesis} - # Blocks from top-down antichain subsets "non-negl" likely to re-org - self.ordBlocks = {self.genesis.id:self.genesis} - - if params is not None: - self.security = params - else: - self.security = 10 - self.vote = {} - self.pending = {} - for blockZ in self.votBlocks: - for blockX in self.ordBlocks: - for blockY in self.ordBlocks: - self.vote.update({(blockZ,blockX,blockY):0}) - self.pending.update({(blockZ,blockX,blockY):0}) - - def computeVote(self, dagIn): - (canopy, fullCanopy) = self.pick(dagIn) - for layer in fullCanopy: - for blockZ in layer: - if blockZ not in dagIn.votBlocks: - continue - else: - for blockX in layer: - if blockX not in dagIn.ordBlocks: - continue - else: - for blockY in layer: - if blockY not in dagIn.ordBlocks: - continue - else: - if self.inPast(dagIn,blockY,blockZ) and self.inPast(dagIn,blockX,blockZ): - # then Z votes recursively - if blockZ not in dagIn.seenPasts: - dagIn.seenPasts.update({blockZ:dagIn.getPast(blockZ)}) - dagIn.seenVotes.update({blockZ:dagIn.vote(dagIn.seenPasts[blockZ])}) - dagIn.vote.update({(blockZ,blockX,blockY):dagIn.seenVotes[blockZ][(blockX,blockY)], (blockZ,blockY,blockX):dagIn.seenVotes[blockZ][(blockY,blockX)], (blockZ,blockX,blockZ):1, (blockZ, blockZ, blockX):-1, (blockZ, blockY, blockZ):1, (blockZ, blockZ, blockY):-1}) - elif self.inPast(dagIn, blockY, blockZ) and not self.inPast(dagIn, blockX, blockZ): - dagIn.vote.update({(blockZ,blockX,blockY):-1, (blockZ,blockY,blockX):1, (blockZ,blockX,blockZ):-1, (blockZ,blockZ,blockX):1, (blockZ,blockZ,blockY):-1, (blockZ,blockY,blockZ):1}) # Then Z votes Y < Z < X - elif not self.inPast(dagIn, blockY, blockZ) and self.inPast(dagIn, blockX, blockZ): - dagIn.vote.update({(blockZ,blockX,blockY):1, (blockZ,blockY,blockX):-1, (blockZ,blockX,blockZ):1, (blockZ,blockZ,blockX):-1, (blockZ,blockZ,blockY):1, (blockZ,blockY,blockZ):-1}) # Then Z votes X < Z < Y - else: - if dagIn.pending[(blockZ,blockX,blockY)] > 0: - dagIn.vote.update({(blockZ,blockX,blockY):1, (blockZ,blockY,blockX):-1, (blockZ, blockX, blockZ):-1, (blockZ, blockZ, blockX):1, (blockZ, blockY, blockZ):-1, (blockZ, blockZ, blockY):1}) - elif dagIn.pending[(blockZ,blockX,blockY)] < 0: - dagIn.vote.update({(blockZ,blockX,blockY):-1, (blockZ,blockY,blockX):1, (blockZ, blockX, blockZ):-1, (blockZ, blockZ, blockX):1, (blockZ, blockY, blockZ):-1, (blockZ, blockZ, blockY):1}) - else: - dagIn.vote.update({(blockZ,blockX,blockY):0, (blockZ,blockY,blockX):0, (blockZ, blockX, blockZ):-1, (blockZ, blockZ, blockX):1, (blockZ, blockY, blockZ):-1, (blockZ, blockZ, blockY):1}) - q = deque() - for p in dagIn.blocks[blockZ].parents: - if p in dagIn.votBlocks: - q.append(p) - while(len(q)>0): - nextBlock = q.popleft() - if (nextBlock, blockX, blockY) not in dagIn.pending: - dagIn.pending.update({(nextBlock, blockX,blockY):0}) - if (nextBlock, blockY, blockX) not in dagIn.pending: - dagIn.pending.update({(nextBlock, blockY,blockX):0}) - if dagIn.vote[(blockZ,blockX,blockY)] > 0: - dagIn.pending[(nextBlock,blockX,blockY)] += 1 - dagIn.pending[(nextBlock,blockY,blockX)] -= 1 - elif dagIn.vote[(blockZ,blockX,blockY)] < 0: - dagIn.pending[(nextBlock,blockX,blockY)] -= 1 - dagIn.pending[(nextBlock,blockY,blockX)] += 1 - for p in dagIn.blocks[nextBlock].parents: - if p in dagIn.votBlocks: - q.append(p) - totalVote = {} - for blockX in dagIn.ordBlocks: - for blockY in dagIn.ordBlocks: - if (blockX, blockY) not in totalVote: - totalVote.update({(blockX,blockY):0, (blockY,blockX):0}) - for blockZ in dagIn.votBlocks: - if dagIn.vote[(blockZ,blockX,blockY)] > 0: - totalVote[(blockX,blockY)] += 1 - elif dagIn.vote[(blockZ,blockX,blockY)] < 0: - totalVote[(blockX,blockY)] -= 1 - if totalVote[(blockX,blockY)] > 0: - totalVote[(blockX,blockY)] = 1 - elif totalVote[(blockX,blockY)] < 0: - totalVote[(blockX,blockY)] = -1 - return totalVote - - def pick(self, dagIn): - """ Pick voting blocks and orderable blocks """ - (canopy, fullCanopy) = self.antichain(dagIn) - dagIn.votBlocks = {} - dagIn.ordBlocks = {} - idx = 0 - count = len(canopy[idx]) - for block in canopy[idx]: - dagIn.votBlocks.update({block:dagIn.blocks[block]}) - dagIn.ordBlocks.update({blcok:dagIn.blocks[block]}) - numVoters = 1 - ((-len(dagIn.blocks))//2) - while(count < numVoters): - idx += 1 - count += len(canopy[idx]) - for block in canopy[idx]: - dagIn.votBlocks.update({block:dagIn.blocks[block]}) - if idx < self.security: - dagIn.ordBlocks.update({block:dagIn.blocks[block]}) - return (canopy, fullCanopy) - - - def makeBlock(self, idIn, parentsIn): - assert idIn not in self.blocks - newBlock = Block() - newBlock.id = idIn - newBlock.addParents(parentsIn) - self.blocks.update({newBlock.id:newBlock}) - for parent in parentsIn: - if parent in self.leaves: - del self.leaves[parent] - self.blocks[parent].addChild(newBlock) - self.leaves.update({newBlock.id:newBlock}) - - def pruneLeaves(self, dagIn): - result = BlockDAG() - result.genesis.id = dagIn.genesis.id - q = deque() - for child in dagIn.genesis.children: - if child not in dagIn.leaves: - q.append(child) - while(len(q)>0): - nextBlock = q.popleft() - result.makeBlock(nextBlock, dagIn.blocks[nextBlock].parents) - for child in dagIn.blocks[nextBlock].children: - if child not in dagIn.leaves: - q.append(child) - return result - - def antichain(self, dagIn): - canopy = [] - fullCanopy = [] - nextDag = dagIn - canopy.append(nextDag.leaves) - fullCanopy.append(nextDag.leaves) - while(len(nextDag.blocks)>1): - nextDag = dagIn.pruneLeaves(dagIn) - canopy.append(nextDag.leaves) - fullCanopy.append(fullCanopy[-1]) - for leaf in nextDag.leaves: - fullCanopy[-1].append(leaf) - nextDag = self.pruneLeaves(dagIn) - return (canopy, fullCanopy) - - def inPast(self, dagIn, y, x): - """ self.inPast(dag, y,x) if and only if y is in the past of x in dag """ - found = False - if y in dagIn.blocks[x].parents: - found = True - else: - q = deque() - for parent in dagIn.blocks[x].parents: - q.append(parent) - while(len(q)>0): - nextBlock = q.popleft() - if y in dagIn.blocks[nextBlock].parents: - found = True - break - else: - for parent in dagIn.blocks[nextBlock].parents: - q.append(parent) - return found - - def getPast(self, dagIn, block): - subdag = BlockDAG() - subdag.genesis = dagIn.genesis - q = deque() - for child in dagIn.genesis.children: - if self.inPast(dagIn,child,block): - q.append(child) - while len(q) > 0: - nextBlock = q.popleft() - subdag.makeBlock(dagIn.blocks[nextBlock]) - for child in dagIn.blocks[nextBlock].children: - if self.inPast(dagIn,child,block): - q.append(child) - return subdag - - -class Test_BlockDAG(unittest.TestCase): - def test_BlockDAG(self): - dag = BlockDAG() - self.assertTrue("0" in dag.blocks) - self.assertTrue("0" in dag.leaves) - self.assertTrue(len(dag.blocks)==1) - self.assertTrue(len(dag.leaves)==1) - b0 = dag.genesis - - dag.makeBlock("1",{"0":b0}) - b1 = dag.blocks["1"] - self.assertTrue("1" in dag.blocks) - self.assertTrue("1" in dag.leaves) - self.assertTrue("0" not in dag.leaves) - self.assertTrue(len(dag.blocks)==2) - self.assertTrue(len(dag.leaves)==1) - self.assertTrue("1" in b0.children) - self.assertTrue("1" in dag.genesis.children) - self.assertTrue("1" in dag.blocks[dag.genesis.id].children) - - dag.makeBlock("2", {"0":b0}) - b2 = dag.blocks["2"] - - dag.makeBlock("3", {"1":b1, "2":b2}) - b3 = dag.blocks["3"] - - dag.makeBlock("4", {"2":b2}) - b4 = dag.blocks["4"] - - print(dag.computeVote(dag)) - - - -suite = unittest.TestLoader().loadTestsFromTestCase(Test_BlockDAG) -unittest.TextTestRunner(verbosity=1).run(suite)