def __init__(self, name, genesis: Block, weight): self.name = name self.weight = weight self.tree = CompressedTree(genesis) self.justification = set() self.latest_messages = dict() self.own_message_at_height = dict()
def test_inserting_on_genesis(): genesis = Block(None) tree = CompressedTree(genesis) block = Block(genesis) node = tree.add_new_latest_block(block, 0) assert tree.size == 2 assert tree.root.block == genesis assert tree.root.children.pop() == node
def test_inserting_on_leaf(): genesis = Block(None) tree = CompressedTree(genesis) block_1 = Block(genesis) _ = tree.add_new_latest_block(block_1, 0) block_2 = Block(block_1) node_2 = tree.add_new_latest_block(block_2, 0) assert tree.size == 2 assert tree.root.block == genesis assert tree.root.children.pop() == node_2
def test_vals_add_on_other_blocks(): genesis = Block(None) tree = CompressedTree(genesis) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) val_0_block = tree.latest_block_nodes[0].block for i in range(3): block = Block(val_0_block) _ = tree.add_new_latest_block(block, i) assert tree.size == 5
def test_add_not_on_root(): genesis = Block(None) tree = CompressedTree(genesis) block = Block(None) node = tree.add_new_latest_block(block, 0) assert node is None block = Block(genesis) node = tree.add_new_latest_block(block, 0) assert tree.root.children.pop() == node assert node.block == block
def test_inserting_on_intermediate(): genesis = Block(None) tree = CompressedTree(genesis) block_1 = Block(genesis) _ = tree.add_new_latest_block(block_1, 0) block_2 = Block(block_1) _ = tree.add_new_latest_block(block_2, 0) on_inter_block = Block(block_1) on_inter_node = tree.add_new_latest_block(on_inter_block, 1) assert tree.size == 4 assert tree.root == on_inter_node.parent.parent
class Validator: def __init__(self, name, genesis: Block, weight): self.name = name self.weight = weight self.tree = CompressedTree(genesis) self.justification = set() self.latest_messages = dict() self.own_message_at_height = dict() def see_message(self, message: Message) -> None: for val in message.latest_messages: prev_message = message.latest_messages[val] if prev_message not in self.justification: self.see_message(prev_message) self.justification.add(message) new_latest = False if message.sender not in self.latest_messages: self.latest_messages[message.sender] = message new_latest = True else: if message.message_height > self.latest_messages[ message.sender].message_height: self.latest_messages[message.sender] = message new_latest = True # only add the message to the reduced tree if it is a new later message if new_latest: self.tree.add_new_latest_block(message.block, message.sender) def forkchoice(self) -> Block: return self.tree.find_head(self.weight).block def make_new_message(self) -> Message: block = Block(self.forkchoice()) prev_message = self.latest_messages.get(self.name, None) message = Message(self.name, block, self.latest_messages, prev_message=prev_message) self.latest_messages[self.name] = message self.own_message_at_height[message.message_height] = message return message
def test_path_block_to_child_node(): genesis = Block(None) tree = CompressedTree(genesis) block_1 = Block(genesis) node_1 = tree.add_new_latest_block(block_1, 0) assert tree.path_block_to_child_node[block_1] == node_1 assert len(tree.path_block_to_child_node) == 1 block_2 = Block(block_1) node_2 = tree.add_new_latest_block(block_2, 0) assert tree.path_block_to_child_node[block_1] == node_2 assert len(tree.path_block_to_child_node) == 1 on_inter_block = Block(block_1) on_inter_node = tree.add_new_latest_block(on_inter_block, 1) assert tree.path_block_to_child_node[ block_1].block == block_1 # node_1 was deleted, so it's a dif node assert tree.path_block_to_child_node[block_2] == node_2 assert tree.path_block_to_child_node[on_inter_block] == on_inter_node assert len(tree.path_block_to_child_node) == 3
def test_find_prev_in_tree(): genesis = Block(None) tree = CompressedTree(genesis) block = Block(None) assert None is tree.find_prev_node_in_tree(block) block = Block(genesis) assert tree.root is tree.find_prev_node_in_tree(block) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) block_1 = Block(tree.latest_block_nodes[2].block) assert block_1.parent_block == tree.find_prev_node_in_tree(block_1).block tree.add_new_latest_block(block_1, 2) assert block_1 == tree.latest_block_nodes[2].block block_2 = Block(tree.latest_block_nodes[2].block) assert block_2.parent_block == tree.find_prev_node_in_tree(block_2).block
def test_random(): genesis = Block(None) tree = CompressedTree(genesis) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) new_block = Block(tree.latest_block_nodes[1].block) tree.add_new_latest_block(new_block, 1) new_block = Block(tree.latest_block_nodes[1].block) tree.add_new_latest_block(new_block, 1)
def extract_tree(c_tree: CompressedTree) -> nx.Graph: G = nx.Graph() connections = list() nodes = c_tree.all_nodes() for node in nodes: name = node.block.name p_name = node.parent.block.name if node.parent is not None and node.parent != '' else 0 if node.parent is None: continue if node.block.name == node.parent.block.name: continue connections.append(((name, p_name))) print(connections) G.add_edges_from(connections) return G
def test_massive_tree(): genesis = Block(None) tree = CompressedTree(genesis) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) for i in range(1000): print(i) prev_val = random.randint(0, 2) new_block = Block(tree.latest_block_nodes[prev_val].block) new_val = random.randint(0, 2) tree.add_new_latest_block(new_block, new_val) assert tree.size <= 6 block = tree.latest_block_nodes[2].block assert tree.find_head({ block: 1 }).block.prev_at_height(block.height) == block
def test_ghost(): # Setup genesis = Block(None) tree = CompressedTree(genesis) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) val_0_block = tree.latest_block_nodes[0].block for i in range(3): block = Block(val_0_block) _ = tree.add_new_latest_block(block, i) val_0_block = tree.latest_block_nodes[0].block # Giving this block more weight, gives GHOST determanism b = Block(val_0_block) head_node = tree.add_new_latest_block(b, 0) weight = {b: 2} assert head_node == tree.find_head(weight)
def test_new_finalised_node_pruning(): # Setup genesis = Block(None) tree = CompressedTree(genesis) for i in range(3): block = Block(genesis) _ = tree.add_new_latest_block(block, i) val_0_block = tree.latest_block_nodes[0].block for i in range(3): block = Block(val_0_block) _ = tree.add_new_latest_block(block, i) assert tree.size == 5 # Test Pruning new_root = tree.node_with_block[val_0_block] tree.prune(new_root) assert tree.size == 4
def test_delete_with_child(): genesis = Block(None) tree = CompressedTree(genesis) block_1_val_0 = Block(genesis) _ = tree.add_new_latest_block(block_1_val_0, 0) block_2_val_0 = Block(block_1_val_0) _ = tree.add_new_latest_block(block_2_val_0, 0) block_1_val_1 = Block(block_1_val_0) _ = tree.add_new_latest_block(block_1_val_1, 1) block_1_val_2 = Block(genesis) _ = tree.add_new_latest_block(block_1_val_2, 2) block_3_val_0 = Block(block_1_val_2) _ = tree.add_new_latest_block(block_3_val_0, 0) assert tree.size == 4 assert len(tree.root.children) == 2 assert tree.latest_block_nodes[1] in tree.root.children assert tree.latest_block_nodes[2] in tree.root.children assert tree.latest_block_nodes[0] not in tree.root.children
block.name = name if block.parent_block is None: continue if block.parent_block.name == block.name: continue adding = (block.name, block.parent_block.name) connections.append((block.name, block.parent_block.name)) print(connections) G.add_edges_from(connections) return G if __name__ == '__main__': genesis = Block(None) genesis.name = 1 tree = CompressedTree(genesis) blocks = [] for i in range(5): block = Block(genesis) blocks.append(block) _ = tree.add_new_latest_block(block, i) for i in range(25): prev_val = random.randint(0, 4) new_block = Block(tree.latest_block_nodes[prev_val].block) new_val = random.randint(0, 4) blocks.append(new_block) tree.add_new_latest_block(new_block, new_val) assert tree.size <= 10 print("RUNNING {}".format(i))