def construct_suffix_tree(inputstr, printstuff=False): global _printstuff, maxLength, timers, total_recursive _printstuff = printstuff # assumes inputstr converted to integer alphabet, takes O(n) to do anyway inputstr = append_unique_char(inputstr) if len(inputstr) - 1 == 0: root = Node(aId='root') root.add_child(Node(aId=1, aStrLength=1)) root.update_leaf_list() return root if len(inputstr) - 1 == 1: # inputstr was just a single char before we appended the unique_char root = Node(aId='root') root.add_child(Node(aId=1, aStrLength=2)) root.add_child(Node(aId=2, aStrLength=1)) root.update_leaf_list() return root t_odd = T_odd(inputstr) t_even = T_even(t_odd, inputstr) t_overmerged = overmerge(t_even, t_odd, inputstr) compute_lcp_tree(t_overmerged) adjust_overmerge(t_overmerged, t_even, t_odd, inputstr) cleanup_tree(t_overmerged) return t_overmerged
def merge(): # Takes every child in merge list, adds a new node with # these children as children to the new node inner = Node(node.str_length + 1, "inner") for cm in current_merg: inner.add_child(cm) children_list.append(inner)
def createTreeTwo(): rootNode = Node(aStrLength=0, aId="root") inner1 = Node(aId="inner1") inner2 = Node(aId="inner2") rootNode.add_child(inner1) rootNode.add_child(inner2) nodes = [] nodes.append(Node(aId=1)) nodes.append(Node(aId=2)) nodes.append(Node(aId=3)) nodes.append(Node(aId=4)) nodes.append(Node(aId=5)) nodes.append(Node(aId=6)) inner1.add_child(nodes[0]) inner1.add_child(nodes[1]) nodes.append(inner1) nodes.append(inner2) inner2_1 = Node(aId="inner2_1") inner2.add_child(nodes[2]) inner2.add_child(nodes[3]) inner2.add_child(inner2_1) nodes.append(inner2_1) inner2_1.add_child(nodes[4]) inner2_1.add_child(nodes[5]) return rootNode, nodes
def test_get_ancestors(self): """ Test that all ancestors can be retrieved """ child = Node('test_get_ancestors_child') grand_child = Node('test_get_descendants_grand_child') child.add_child(grand_child) self.root_node.add_child(child) result = grand_child.get_ancestors() assert (all(p in result for p in [child, self.root_node]))
def test_get_descendants(self): """ Test that all descendants can be retrieved """ child = Node('test_get_descendants_child') grand_child = Node('test_get_descendants_grand_child') child.add_child(grand_child) self.root_node.add_child(child) result = self.root_node.get_descendants() assert (all(c in result for c in [child, grand_child]))
def slowscan(u, v, S): global jump # searches for string v starting in node u # create a node for v if necessary and return it curr_node = u remaining = v if S[remaining[0]] in curr_node.charDict: child = curr_node.charDict[S[remaining[0]]] leafID = child.leaflist[0].id - 1 edge = (leafID + child.parent.str_length, leafID + child.str_length) curr_lcp = lcp(remaining, edge, S) if curr_lcp: if string_length(curr_lcp) == string_length(edge): # remaining contains more than curr_lcp; we need to look # further down the tree return slowscan(child, (remaining[0]+string_length(curr_lcp), remaining[1]), S) # make new internal node internal = Node(aId='inner') internal.charDict = dict() # internal.str = curr_node.str + curr_lcp # internal.edge = curr_lcp internal.leaflist = child.leaflist internal.str_length = curr_node.str_length + string_length(curr_lcp) # Remove child childLeafId = child.leaflist[0].id-1 childChar = S[childLeafId + child.parent.str_length] del curr_node.charDict[childChar] curr_node.remove_child(child) # Add internal node curr_node.add_child(internal) internalLeafId = internal.leaflist[0].id-1 internalChar = S[internalLeafId + internal.parent.str_length] curr_node.charDict[internalChar] = internal curr_node.charDict # Add child internal.add_child(child) childChar = S[childLeafId + child.parent.str_length] internal.charDict[childChar] = child remaining = (remaining[0]+string_length(curr_lcp), remaining[1]) return internal, remaining return curr_node, remaining
def test_remove_node_cascading(self): """ Test removal of a node and every descendant of that node """ node_to_remove = Node('test_remove_node') self.root_node.add_child(node_to_remove) dummy_children = [] for i in range(5): c = Node(str(i)) dummy_children.append(c) node_to_remove.add_child(c) self.root_node.remove_node(node_to_remove, True) assert (node_to_remove not in self.root_node.children) assert (all(c.content not in self.root_node for c in dummy_children))
def createTreeOne(): rootNode = Node(aStrLength=0, aId="root") n1_l = Node( aId="inner1", aStrLength=1, ) n1_r = Node(aId="inner2", aStrLength=1) rootNode.add_child(n1_l) rootNode.add_child(n1_r) n2_1_l = Node(aId=1, aStrLength=2) n2_1_r = Node(aId=2, aStrLength=2) n1_l.add_child(n2_1_l) n1_l.add_child(n2_1_r) n2_2_l = Node(aId=3, aStrLength=2) n2_2_r = Node(aId=4, aStrLength=2) n1_r.add_child(n2_2_l) n1_r.add_child(n2_2_r) return rootNode, [n2_1_l, n2_1_r, n2_2_l, n2_2_r, n1_l, n1_r]
def tree_search(self, current_state, last_action, parent=None, depth=0): # (self, name, state, reward = 0, parent = None, parent_action = None, best_q_value = None): if parent is None: parent = Node("level_{}_action_{}".format(depth, None), current_state.detach().cpu().numpy()) next_states, actions = self.get_next_states(current_state) actions = (actions == 1).nonzero()[:, 1] # print(actions) # print(next_states) # expand best_q = -maxsize best_a = None best_child = None # print(next_states.size(), actions.size()) if depth < self.max_depth: # if depth != 0: # tqdm.disable() for ns, a in tqdm(zip(next_states, actions), disable=os.environ.get("DISABLE_TQDM", depth != 0), total=len(actions)): # if (last_action == 2 and a.item() == 3) or (last_action == 3 and a.item() == 2): # continue action_name = ACTION_DICT_REVERSE[a.item()] child = Node("level_{}_action_{}".format(depth + 1, a), ns.detach().cpu().numpy(), parent=parent, action_name=action_name) best_q_value, _, _ = self.tree_search(ns, a, parent=child, depth=depth + 1) parent.add_child(child) best_q_value += self.reward_func() # if depth == 0: # print(best_q_value, best_action) if (last_action == 2 and a.item() == 3) or (last_action == 3 and a.item() == 2): continue if best_q_value > best_q: best_q = best_q_value best_a = a.item() best_child = child # print(last_action, best_a) best_q_value, a = self.eval_finish_action(ns) # if depth == 0: # print(best_q_value, best_action) if best_q_value > best_q: best_q = best_q_value best_a = a # if depth == 1: # print("finish", best_q_value) # print("best", best_q) else: best_a, q_value = self.dqn_model.predict(current_state) best_q = q_value.max(0)[0] # print(best_a, best_q) parent.best_q_value = best_q parent.best_child = best_child parent.best_action = best_a # print(last_action, best_a) # print(best_a) return best_q, best_a, parent
def merger_helper(current, even, odd): global _overmerge even_children = even.children odd_children = odd.children e = 0 o = 0 while (e < len(even_children) or o < len(odd_children)): e_child = None e_char = None o_child = None o_char = None if (e < len(even_children)): e_child = even_children[e] if e_child.is_leaf(): leaf_id = e_child.id else: leaf_descendant = e_child.leaflist[0] leaf_id = leaf_descendant.id e_char = S[leaf_id + e_child.parent.str_length - 1] if (o < len(odd_children)): o_child = odd_children[o] if o_child.is_leaf(): leaf_id = o_child.id else: leaf_descendant = o_child.leaflist[0] leaf_id = leaf_descendant.id o_char = S[leaf_id + o_child.parent.str_length - 1] if (e_child is None): o += 1 o_child.old_parent = o_child.parent current.add_child(o_child) # prepare the LCA nodepair thingy during the overmerge if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca'): if o_child.is_leaf(): current.lca_odd = o_child else: current.lca_odd = o_child.leaflist[0] if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca') and hasattr( current, 'lca_odd'): if hasattr(e_child, 'lca_even'): current.lca_even = e_child.lca_even continue if (o_child is None): e += 1 e_child.old_parent = e_child.parent current.add_child(e_child) # prepare the LCA nodepair thingy during the overmerge if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca'): if e_child.is_leaf(): current.lca_even = e_child else: current.lca_even = e_child.leaflist[0] # continue if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca') and hasattr( current, 'lca_even'): if hasattr(e_child, 'lca_odd'): current.lca_odd = e_child.lca_odd continue if (o_char != e_char): # Case 1 # If the first char of the two parentEdges doesnt match, insert # the the first char (by lexicographic order), and insert. # Count that up to preceed to next child in child list if (o_char < e_char): # t_overmerged.update_leaf_list() o_child.old_parent = o_child.parent current.add_child(o_child) o += 1 # prepare the LCA nodepair thingy during the overmerge if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca'): if o_child.is_leaf(): current.lca_odd = o_child else: current.lca_odd = o_child.leaflist[0] if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca') and hasattr( current, 'lca_odd'): if hasattr(o_child, 'lca_even'): current.lca_even = o_child.lca_even else: e_child.old_parent = e_child.parent current.add_child(e_child) e += 1 # prepare the LCA nodepair thingy during the overmerge if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca'): if e_child.is_leaf(): current.lca_even = e_child else: current.lca_even = e_child.leaflist[0] if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca'): if hasattr(e_child, 'lca_odd'): current.lca_odd = e_child.lca_odd else: # Even and odd have same first char in parent edge e_parentEdge_len = e_child.str_length - current.str_length o_parentEdge_len = o_child.str_length - current.str_length if (e_parentEdge_len != o_parentEdge_len): # Case 3 # If the two parentEdge's start with the same char, and is # not of equal length # We will then decide which node has the longest parent # edge, insert this into our current merge tree # we will then call recursively on this edge, and on the # child with the longer edge. We do this be introducing # an substitue node, which only purpose is to make the # recursive call possible. short_child = o_child long_child = e_child swapped = False if e_parentEdge_len < o_parentEdge_len: swapped = True short_child = e_child long_child = o_child short_child.old_parent = short_child.parent long_child.old_parent = long_child.parent inner_node = Node(short_child.str_length, short_child.id) current.add_child(inner_node) # subtrees added for reference in adjust_overmerge inner_node.even_subtree = e_child inner_node.odd_subtree = o_child short_child_sub = Node(short_child.str_length, aId="sub_" + str(short_child.id)) short_child_sub.add_child(long_child) if not short_child.children: # prepare the LCA nodepair thingy in case short_child # is a leaf node itself and is overmerged to have some # subtree containing another heterogenous leaf node if swapped: inner_node.lca_even = short_child else: inner_node.lca_odd = short_child if swapped: # short_child originates in even_tree merger_helper(inner_node, short_child, short_child_sub) else: # short_child originates in odd_tree merger_helper(inner_node, short_child_sub, short_child) had_lca_even_too = False overwrote = False if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca'): if hasattr(inner_node, 'lca_even'): current.lca_even = inner_node.lca_even had_lca_even_too = True if hasattr(current, 'overwrite_lca'): overwrote = True if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca') and not overwrote: if hasattr(inner_node, 'lca_odd'): current.lca_odd = inner_node.lca_odd if had_lca_even_too: # we cached both lca_even and lca_odd from same # child, mark this so one can be overwritten by # whatever leafnode we may see next in another # subtree current.overwrite_lca = True else: # Case 2 # If two parent edge's start with the same char, and are of # equal length, we will ad an internal node, and call our # merger_helper recursively with the two sub trees. # SPECIAL CASE: # if one of either e_child or o_child does not have any children, # then it is a leaf node itself. This means, that we are not # creating and merging into a new inner, but rather into this # particular leaf node, creating a leaf node with a subtree # being the subtree of the other node # Note, that both e_child and o_child cannot have empty children # lists, as that would mean they were both leaf nodes. But as # we have already made sure that their string lengths are equal, # there would be two suffixes in the tree of equal length, # which is impossible # W.r.t. LCA nodepairs, this current node should never be LCA # of any odd/even nodepair as a result of this merge, as every # odd/even node in the merge will be child of 'inner', which is # current's child, so the nodepairs should instead have 'inner' # as LCA. It may still be LCA of some nodepair, but this is a # result of one of the other overmerge cases e_parentEdge_len = o_child.str_length inner_id = 'inner' inner = Node(e_parentEdge_len, inner_id) if not e_child.children: inner.id = e_child.id inner.lca_even = e_child if not o_child.children: inner.id = o_child.id inner.lca_odd = o_child current.add_child(inner) inner.even_subtree = e_child inner.odd_subtree = o_child merger_helper(inner, e_child, o_child) # t_overmerged.update_leaf_list() had_lca_even_too = False overwrote = False if not hasattr(current, 'lca_even') or hasattr( current, 'overwrite_lca'): if hasattr(inner, 'lca_even'): current.lca_even = inner.lca_even had_lca_even_too = True if hasattr(current, 'overwrite_lca'): overwrote = True if not hasattr(current, 'lca_odd') or hasattr( current, 'overwrite_lca') and not overwrote: if hasattr(inner, 'lca_odd'): current.lca_odd = inner.lca_odd if had_lca_even_too: current.overwrite_lca = True o += 1 e += 1
def T_even(t_odd, inputstr): global _even_calls S = inputstr n = len(S) # (i) # find the lexicographical ordering of the even suffixes leaflist = [] def get_leafs(node): nonlocal leaflist if node.is_leaf(): leaflist.append(node) t_odd.dfs(get_leafs) odd_suffix_ordering = [node.id for node in leaflist] # t_odd.leaflist] # even_suffixes is a list of tuples (x[2i], suffix[2i + 1]) to radix sort even_suffixes = [(int(S[node - 2]), node) for node in odd_suffix_ordering if node != 1] radixsort.sort(even_suffixes, 0) even_suffixes = [tup[1] - 1 for tup in even_suffixes] # in case S is of even length, n % 2 == 0, the even suffix at pos n # is the last one in the sorted list, as it starts with character '$' # which, by definition, is ranked as |alphabet| + 1, i.e. last character # We need to add this one specifically, as it is not found by counting # all odd suffixes down by one # e.g.: if the inputstr is of length 4, then odd suffixes are 1 and 3 # if we only count even suffixes as odd suffixes prefixed with # a character, we will never capture 4, as 5 is not an odd suffix # hence why we need to manually add it as the last one as it is '$' if n % 2 == 0: even_suffixes.append(n) # (ii) # compute lcp for adjacent even suffixes lca_f = fast_lca.LCA() lca_f.preprocess(t_odd) id2node = [] t_odd.traverse(lambda n: id2node.append((n.id, n)) if 'inner' not in str(n.id) else 'do nothing') id2node = dict(id2node) lcp = {} for idx in range(0, len(even_suffixes) - 1): i = even_suffixes[idx] j = even_suffixes[idx + 1] curr_lcp = 0 if (S[i - 1] == S[j - 1] and i < n and j < n): if j + 1 in id2node and i + 1 in id2node: lca_parent = lca_f.query(id2node[i + 1], id2node[j + 1]) curr_lcp = lca_parent.str_length + 1 else: curr_lcp = 1 lcp[(even_suffixes[idx], even_suffixes[idx + 1])] = curr_lcp # (iii) # construct T_even using information from (i) and (ii) root = Node(aId='root') fst_suf = even_suffixes[0] fst_suf_len = n - fst_suf + 1 # S[fst_suf - 1:] node_fst_suf = Node(fst_suf_len, fst_suf) root.add_child(node_fst_suf) id2node = {fst_suf: node_fst_suf} currLoopTime = 0 updatingLeafList = 0 for i in range(1, len(even_suffixes)): prev_suf = even_suffixes[i - 1] curr_suf = even_suffixes[i] curr_lcp = lcp[(prev_suf, curr_suf)] prev_lcp = None if i > 1: prevprev_suf = even_suffixes[i - 2] prev_lcp = lcp[(prevprev_suf, prev_suf)] if curr_lcp == 0: curr_suf_len = n - curr_suf + 1 new_node = Node(curr_suf_len, curr_suf) root.add_child(new_node) id2node[curr_suf] = new_node else: if prev_lcp: prev_node = id2node[prev_suf] # we need to append the new node to somewhere on the # path from root to the parent of the prev_node. # This might involve following a lot of nodes' # parentEdges to find the spot # TODO: is it O(n)??? remaining_until_insertion = prev_lcp - curr_lcp possible_insertion_node = prev_node.parent while remaining_until_insertion > 0: # run up through parentEdges until # remaining_until_insertion is 0 len_of_edge = possible_insertion_node.str_length - possible_insertion_node.parent.str_length remaining_until_insertion -= len_of_edge possible_insertion_node = possible_insertion_node.parent # possible_insertion_node is now the spot at which we # should place curr_suf # we need to pop the rightmost child of the # possible_insertion_node as we need to insert an inner # node with this child and our new_node as children in # place of this rightmost child, if # remaining_until_insertion is negative and not exactly # 0, in which case we can just add_child(new_node) if remaining_until_insertion == 0: len_newnode = n - curr_suf + 1 new_node = Node(len_newnode, curr_suf) id2node[curr_suf] = new_node possible_insertion_node.add_child(new_node) else: child_of_insertion_node = possible_insertion_node.children.pop( ) split_idx = abs(remaining_until_insertion) inner_parentEdge_len = child_of_insertion_node.parent.str_length + split_idx innernode = Node(inner_parentEdge_len, 'inner') len_newnode = n - curr_suf + 1 new_node = Node(len_newnode, curr_suf) possible_insertion_node.add_child(innernode) innernode.add_child(child_of_insertion_node) innernode.add_child(new_node) id2node[curr_suf] = new_node else: innernode_len = curr_lcp innernode = Node(innernode_len, 'inner') new_node_len = n - curr_suf + 1 new_node = Node(new_node_len, curr_suf) id2node[curr_suf] = new_node prev_node = id2node[prev_suf] # update prev_node by removing lcp from its parentEdge # as it has been assigned a new parent who's parentEdge # is exactly lcp # prev_node.parentEdge = prev_node.parentEdge[len(str_curr_lcp):] prev_node.parent.children[-1] = innernode innernode.parent = prev_node.parent # important! prev_node must be added before new_node to # keep lexicographic ordering of children innernode.add_child(prev_node) innernode.add_child(new_node) t_even = root t_even.update_leaf_list() del S, n, leaflist, odd_suffix_ordering, even_suffixes, lca_f, id2node return t_even
class DDosChain(Blockchain): def __init__(self, version: float, send_queue: Queue, gui_queue: Queue) -> None: super(DDosChain, self).__init__(version, send_queue, gui_queue) self.tree = Node('Root') self.tree.add_child( Node( str("ab2a248087095ef9e84a900337fac41cf2d588e9017b345f1c90a4bb0844ed28" .encode('utf-8')))) self.blocked_ips: Dict[str, Node] = {} def get_ips(self): return list(self.blocked_ips.keys()) def save_ips_to_file(self): with open(IP_LIST_FILE_NAME, 'w') as f: f.writelines(self.blocked_ips.keys()) def load_chain(self): if os.path.exists('ddos_bc_file.txt') and \ os.stat('ddos_bc_file.txt').st_size != 0 and \ Path('ddos_bc_file.txt').is_file(): print_debug_info('Load existing blockchain from file') with open('ddos_bc_file.txt', 'r') as bc_file: self.chain = serializer.deserialize(bc_file.read()) else: self.chain[DDosHeader(0, 0, 768894480, 0, 0)] = [] def save_chain(self): """ Save the current chain to the hard drive. """ pprint('saving to file named bc_file.txt') with open('ddos_bc_file.txt', 'w') as output: output.write(serializer.serialize(self.chain)) def process_transaction(self, transaction: DDosTransaction): # INVITE if transaction.data.type == 'i': new_node = Node(str(transaction.data.data)) parent = self.tree.get_node_by_content(str(transaction.sender)) parent.add_child(new_node) # UNINVITE elif transaction.data.type == 'ui': node_to_remove = self.tree.get_node_by_content( str(transaction.data.data)) self.tree.remove_node(node_to_remove, False) # BLOCK IP elif transaction.data.type == 'b': if transaction.data.data in self.blocked_ips: ancestors = self.blocked_ips[transaction.data.data].\ get_ancestors() if str(transaction.sender) in [a.content for a in ancestors]: # Escalate blocked-IP to ancestor for a in ancestors: if a.content == str(transaction.sender): self.blocked_ips[transaction.data.data] = a break else: self.blocked_ips[transaction.data.data] =\ self.tree.get_node_by_content( str(transaction.sender)) # UNBLOCK IP elif transaction.data.type == 'ub': del (self.blocked_ips[transaction.data.data]) # PURGE elif transaction.data.type == 'p': node_to_remove = self.tree.get_node_by_content( str(transaction.data.data)) self.tree.remove_node(node_to_remove, False) index_list = [] # Remove all ips blocked from this client for i, t in self.blocked_ips.items(): blocker = t if blocker.content == node_to_remove.content: index_list.append(i) for index in index_list: del (self.blocked_ips[index]) if self.gui_ready: self.gui_queue.put(('operation', transaction, 'local')) def valid_operation(self, transaction: DDosTransaction): # Invite if transaction.data.type == 'i': if str(transaction.data.data) in self.tree: print_debug_info('Client is already invited!') return False # Uninvite / Purge elif transaction.data.type == 'ui' or transaction.data.type == 'p': if str(transaction.data.data) not in self.tree: print_debug_info('Client could not be found!') return False node_to_remove = self.tree.get_node_by_content( str(transaction.data.data)) sender_node = self.tree.get_node_by_content(str( transaction.sender)) if node_to_remove.content not in sender_node: print_debug_info('No permission to delete this node!') return False # Block IP-Address elif transaction.data.type == 'b': if transaction.data.data in self.blocked_ips: ancestors = self.blocked_ips[transaction.data.data].\ get_ancestors() if not str( transaction.sender) in [a.content for a in ancestors]: print_debug_info('IP was already blocked') return False # Unblock IP-Address elif transaction.data.type == 'ub': if transaction.data.data in self.blocked_ips: if str(transaction.sender) ==\ self.blocked_ips[transaction.data.data].content: return True ancestors = self.blocked_ips[transaction.data.data].\ get_ancestors() if str(transaction.sender) in [a.content for a in ancestors]: # IP blocked from descendant return True print_debug_info('IP was already blocked') return False else: print_debug_info('Trying to unblock IP that was not blocked') return False return True def new_transaction(self, transaction: DDosTransaction): if not self.validate_transaction(transaction): print_debug_info('Invalid transaction') return for pool_transaction in self.transaction_pool: if transaction == pool_transaction: print_debug_info('Transaction already in pool') return if transaction.data == pool_transaction.data: print_debug_info('This operation is already in the pool') return self.transaction_pool.append(transaction) self.send_queue.put(('new_transaction', transaction, 'broadcast')) if self.gui_ready: self.gui_queue.put(('new_transaction', transaction, 'local')) if len(self.transaction_pool) >= 5: self.create_m_blocks() def process_block(self, block: Block): for transaction in block.transactions: self.process_transaction(transaction) # Remove from pool try: self.transaction_pool.remove(transaction) except ValueError: pass def new_block(self, block: Block): # Main chain if self.validate_block(block, self.latest_block()): self.process_block(block) self.chain[block.header] = block.transactions self.send_queue.put(('new_block', block, 'broadcast')) if self.gui_ready: self.gui_queue.put(('new_block', block, 'local')) else: print_debug_info('Block not for main chain') self.check_new_chain(block) def validate_block(self, block: Block, last_block: Block, new_chain: bool = False) -> bool: if not super().validate_block(block, last_block, new_chain): return False return all(self.validate_transaction(t) for t in block.transactions) def validate_transaction(self, transaction: DDosTransaction): if not str(transaction.sender) in self.tree: print_debug_info('Sender could not be found in invited clients.') return False if not self.valid_operation(transaction): return False try: verify_key = nacl.signing.VerifyKey( transaction.sender, encoder=nacl.encoding.HexEncoder) transaction_hash = verify_key.verify( transaction.signature).decode() hash_str = (str(transaction.sender) + str(transaction.data) + str(transaction.timestamp)) validate_hash = self.hash(hash_str) if validate_hash == transaction_hash: print_debug_info('Signature OK') return True print_debug_info('Wrong Hash') return False except BadSignatureError: print_debug_info('Bad Signature, Validation Failed') return False def create_m_blocks(self): t_amount = len(self.transaction_pool) for i in range(0, t_amount, 5): if i + 5 > t_amount: break header = DDosHeader( self.version, len(self.chain), time(), self.latest_block().header.root_hash, self.create_merkle_root(self.transaction_pool[i:i + 5])) block = Block(header, list(self.transaction_pool[i:i + 5])) self.new_block(block) def create_block(self, proof: Any) -> Block: header = DDosHeader(self.version, len(self.chain), time(), self.latest_block().header.root_hash, self.create_merkle_root(self.transaction_pool)) block = Block(header, list(self.transaction_pool)) return block def create_proof(self, miner_key: bytes) -> Any: return 0 def process_message(self, message: Tuple[str, Any, Address]): """ Create processor for incoming blockchain messages. Returns: Processor (function) that processes blockchain messages. """ msg_type, msg_data, msg_address = message if msg_type == 'get_ips': if msg_address == 'local': pprint(self.get_ips()) elif msg_address == 'daemon': self.save_ips_to_file() else: return elif msg_type == 'show_children': node = self.tree.get_node_by_content(str(msg_data)) if msg_address == 'local': if node: node.print() else: print('Your key has not been invited to this blockchain!') print( 'If you were invited, please contact the person who invited you!' ) elif msg_address == 'gui': self.gui_queue.put(('tree', node, 'local')) else: super(DDosChain, self).process_message(message)
def banana_test(): # banana # 123232 inputstr = farach.str2int('123232') root = Node(aId="root") root.add_child(Node(7, 1)) inner = Node(1, "inner") root.add_child(inner) inner2 = Node(3, "inner") inner2.add_child(Node(6, 2)) inner2.add_child(Node(4, 4)) inner.add_child(inner2) inner.add_child(Node(2, 6)) inner = Node(2, "inner") inner.add_child(Node(5, 3)) inner.add_child(Node(3, 5)) root.add_child(inner) root.add_child(Node(1, 7)) constructed_tree = farach.construct_suffix_tree(inputstr) root.update_leaf_list() # print(constructed_tree.fancyprint(inputstr)) # print(root.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == root.fancyprint(inputstr)
def createExampleToReport(): nodes = [] rootNode = Node(aId="root") inner_2 = Node(aId="inner2") inner_8 = Node(aId="inner8") rootNode.add_child(inner_2) nodes.append(Node(aId=3)) inner_2.add_child(nodes[0]) inner_4 = Node(aId="inner4") inner_2.add_child(inner_4) nodes.append(Node(aId=5)) nodes.append(Node(aId=6)) nodes.append(Node(aId=7)) inner_4.add_child(nodes[1]) inner_4.add_child(nodes[2]) inner_4.add_child(nodes[3]) rootNode.add_child(inner_8) nodes.append(Node(aId=9)) nodes.append(Node(aId=10)) inner_8.add_child(nodes[4]) inner_8.add_child(nodes[5]) lca_al = lca.LCA() lca_al.preprocess(rootNode) print(rootNode.fancyprintLCA())
class TestNodes(object): """ Test class for the functionality of the node class""" def setup_method(self): """ Setup root node. """ self.root_node = Node('Test') def test_contains(self): """ Test the contains functionality of the node. """ result = 'Test' in self.root_node assert (result is True) def test_add_child(self): """ Test adding of a new child node. """ new_node = Node('test_add_child') self.root_node.add_child(new_node) assert (new_node in self.root_node.children) assert (new_node.parent is self.root_node) def test_set_parent(self): """ Test setting of a parent for a node. """ new_node = Node('test_set_parent') new_node.set_parent(self.root_node) assert (new_node in self.root_node.children) assert (new_node.parent is self.root_node) def test_nested_contains(self): """ Test that contains works with descendants """ child = Node('test_nested_contains') self.root_node.add_child(child) result = 'test_nested_contains' in self.root_node assert (result is True) def test_get_node_by_content(self): """ Test finding of nodes via content """ child = Node('test_get_node_by_content') self.root_node.add_child(child) result = self.root_node.get_node_by_content('test_get_node_by_content') assert (result is child) def test_get_descendants(self): """ Test that all descendants can be retrieved """ child = Node('test_get_descendants_child') grand_child = Node('test_get_descendants_grand_child') child.add_child(grand_child) self.root_node.add_child(child) result = self.root_node.get_descendants() assert (all(c in result for c in [child, grand_child])) def test_get_ancestors(self): """ Test that all ancestors can be retrieved """ child = Node('test_get_ancestors_child') grand_child = Node('test_get_descendants_grand_child') child.add_child(grand_child) self.root_node.add_child(child) result = grand_child.get_ancestors() assert (all(p in result for p in [child, self.root_node])) def test_remove_node(self): """ Test removal of a node """ node_to_remove = Node('test_remove_node') self.root_node.add_child(node_to_remove) self.root_node.remove_node(node_to_remove, False) assert (node_to_remove not in self.root_node.children) def test_remove_node_cascading(self): """ Test removal of a node and every descendant of that node """ node_to_remove = Node('test_remove_node') self.root_node.add_child(node_to_remove) dummy_children = [] for i in range(5): c = Node(str(i)) dummy_children.append(c) node_to_remove.add_child(c) self.root_node.remove_node(node_to_remove, True) assert (node_to_remove not in self.root_node.children) assert (all(c.content not in self.root_node for c in dummy_children))
def construct_suffix_tree(inputstr, printstuff=False): S = append_unique_char(inputstr) n = len(S) root = Node(aId='root') root.charDict = dict() fst_child = Node(aId=1, aStrLength=n) fst_child.charDict = dict() fst_child.leaflist = [fst_child] root.charDict[S[0]] = fst_child root.add_child(fst_child) root.leaflist = [fst_child] for i in range(1, n): suff = (i, n) # S[i:n] suff_id = i + 1 suff_node = Node(aId=suff_id, aStrLength=n - i) suff_node.charDict = dict() suff_node.leaflist = [suff_node] remaining = suff parent = root searching = True child_to_merge = None lcp_with_child = '' while searching: continue_loop = False if S[remaining[0]] in parent.charDict: c = parent.charDict[S[remaining[0]]] c_parentEdge = c.getParentEdge() curr_lcp = lcp(c_parentEdge, remaining, S) if string_length(curr_lcp) == string_length(c_parentEdge): # continue with c as parent parent = c remaining = (remaining[0] + string_length(curr_lcp), remaining[1]) #remaining[len(curr_lcp):] # loop; test children of new parent, c continue_loop = True else: # found our parent, break out child_to_merge = c lcp_with_child = curr_lcp searching = False if not continue_loop: # no children shared lcp; either it is to be appended to root # or to whatever parent was left from last iteration. # Either case will have the correct node saved in 'parent' searching = False break if child_to_merge: internal_strlength = parent.str_length + string_length(lcp_with_child) internal = Node(aId='inner', aStrLength=internal_strlength) internal.charDict = dict() internal.leaflist = suff_node.leaflist childToMergeChar = S[child_to_merge.getParentEdge()[0]] del parent.charDict[childToMergeChar] parent.remove_child(child_to_merge) parent.add_child(internal) internalChar = S[internal.getParentEdge()[0]] parent.charDict[internalChar] = internal internal.add_child(suff_node) suff_nodeChar = S[suff_node.getParentEdge()[0]] internal.charDict[suff_nodeChar] = suff_node internal.add_child(child_to_merge) child_to_merge_Char = S[child_to_merge.getParentEdge()[0]] internal.charDict[child_to_merge_Char] = child_to_merge else: parent.add_child(suff_node) suff_nodeChar = S[suff_node.getParentEdge()[0]] parent.charDict[suff_nodeChar] = suff_node return root
def current_test(): inputstr = farach.str2int('1222') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') inner1 = Node(aId='inner', aStrLength=[2]) inner2 = Node(aId='inner', aStrLength=[2]) leaf1 = Node(aId=1, aStrLength=[1, 2, 2, 2, 3]) leaf2 = Node(aId=2, aStrLength=[2, 3]) leaf3 = Node(aId=3, aStrLength=[3]) leaf4 = Node(aId=4, aStrLength=[3]) leaf5 = Node(aId=5, aStrLength=[3]) expected_result.add_child(leaf1) expected_result.add_child(inner1) expected_result.add_child(leaf5) inner1.add_child(inner2) inner1.add_child(leaf4) inner2.add_child(leaf2) inner2.add_child(leaf3) # print('-'*80) # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint(inputstr)) # print('actual:') # print(constructed_tree.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)
def construct_suffix_tree(inputstr, printstuff=False): timers["fastscan"] = 0 S = append_unique_char(inputstr) alphabet = {} count = 1 for c in S: if c not in alphabet: alphabet[c] = count count += 1 n = len(S) id2node = {} root = Node(aId='root') root.charDict = dict() root.str = root.edge = [] root.suffix_link = root fst_child = Node(aId=1, aStrLength=n) fst_child.charDict = dict() fst_child.str_length = n fst_child.leaflist = [fst_child] root.charDict[S[0]] = fst_child root.add_child(fst_child) root.leaflist = [fst_child] id2node[1] = fst_child head_i = root tail_i = (0, n) for i in range(1, n): if head_i == root: tail_i = (tail_i[0]+1, tail_i[1]) head_i, remaining = slowscan(root, tail_i, S) leaf_iplus1 = Node(aId=i + 1) leaf_iplus1.charDict = dict() leaf_iplus1.str_length = n - i leaf_iplus1.leaflist = [leaf_iplus1] head_i.add_child(leaf_iplus1) leaf_iplusLeafID = i leaf_iplusChar = S[i + leaf_iplus1.parent.str_length] head_i.charDict[leaf_iplusChar] = leaf_iplus1 tail_i = (tail_i[0] + head_i.str_length, tail_i[1]) continue u = head_i.parent leafID = head_i.leaflist[0].id - 1 v = (leafID + head_i.parent.str_length, leafID + head_i.str_length) if u != root: w, remaining = fastscan(u.suffix_link, v, S) if w is None: w = root else: w, remaining = fastscan(root, (v[0]+1, v[1]), S) if w is None: w = root if string_length(remaining) > 0: # "w is an edge" parent = w.parent leaf = w w = Node(aId='inner') w.charDict = dict() w.str_length = leaf.str_length - string_length(remaining) leafID = leaf.leaflist[0].id - 1 leafChar = S[leaf.parent.str_length + leafID] del parent.charDict[leafChar] parent.remove_child(leaf) w.leaflist = leaf.leaflist parent.add_child(w) wID = w.leaflist[0].id - 1 wChar = S[w.parent.str_length + wID] parent.charDict[wChar] = w w.add_child(leaf) leafID = leaf.leaflist[0].id - 1 leafChar = S[leaf.parent.str_length + leafID] w.charDict[leafChar] = leaf head_i.suffix_link = w head_i = w new_leaf = Node(aId=i + 1) new_leaf.charDict = dict() new_leaf.leaflist = [new_leaf] new_leaf.str_length = n - i w.add_child(new_leaf) new_leafID = new_leaf.leaflist[0].id - 1 new_leafChar = S[new_leaf.parent.str_length + new_leafID] w.charDict[new_leafChar] = new_leaf else: head_i.suffix_link = w head_i, remaining = slowscan(w, tail_i, S) leaf_iplus1 = Node(aId=i + 1) leaf_iplus1.charDict = dict() leaf_iplus1.str_length = n - i leaf_iplus1.leaflist = [leaf_iplus1] head_i.add_child(leaf_iplus1) leaf_iplus1ID = leaf_iplus1.leaflist[0].id - 1 leaf_iplus1Char = S[leaf_iplus1.parent.str_length + leaf_iplus1ID] head_i.charDict[leaf_iplus1Char] = leaf_iplus1 tail_i = (i + head_i.str_length, n) return root
def run_tests(): inputstr = farach.str2int('1') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') expected_result.add_child(Node(aId=1, aStrLength=2)) expected_result.add_child(Node(aId=2, aStrLength=1)) constructed_tree.update_leaf_list() expected_result.update_leaf_list() # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint()) # print('actual:') # print(constructed_tree.fancyprint()) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) inputstr = farach.str2int('12') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') expected_result.add_child(Node(aId=1, aStrLength=3)) expected_result.add_child(Node(aId=2, aStrLength=2)) expected_result.add_child(Node(aId=3, aStrLength=1)) constructed_tree.update_leaf_list() expected_result.update_leaf_list() # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint(inputstr)) # print('actual:') # print(constructed_tree.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) inputstr = farach.str2int('11') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') innernode = Node(aId='inner', aStrLength=1) expected_result.add_child(innernode) innernode.add_child(Node(aId=1, aStrLength=3)) innernode.add_child(Node(aId=2, aStrLength=2)) expected_result.add_child(Node(aId=3, aStrLength=1)) constructed_tree.update_leaf_list() expected_result.update_leaf_list() # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint(inputstr)) # print('actual:') # print(constructed_tree.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) inputstr = farach.str2int('111') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') inner1 = Node(aId='inner', aStrLength=1) inner2 = Node(aId='inner', aStrLength=2) leaf1 = Node(aId=1, aStrLength=4) leaf2 = Node(aId=2, aStrLength=3) leaf3 = Node(aId=3, aStrLength=2) leaf4 = Node(aId=4, aStrLength=1) expected_result.add_child(inner1) expected_result.add_child(leaf4) inner1.add_child(inner2) inner1.add_child(leaf3) inner2.add_child(leaf1) inner2.add_child(leaf2) constructed_tree.update_leaf_list() expected_result.update_leaf_list() # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint(inputstr)) # print('actual:') # print(constructed_tree.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) # inputstr = farach.str2int('122') # constructed_tree = farach.construct_suffix_tree(inputstr) # expected_result = Node(aId='root') # expected_result.add_child(Node(aId=1, aStrLength=[12])) # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) inputstr = farach.str2int('1222') constructed_tree = farach.construct_suffix_tree(inputstr) expected_result = Node(aId='root') inner1 = Node(aId='inner', aStrLength=1) inner2 = Node(aId='inner', aStrLength=2) leaf1 = Node(aId=1, aStrLength=5) leaf2 = Node(aId=2, aStrLength=4) leaf3 = Node(aId=3, aStrLength=3) leaf4 = Node(aId=4, aStrLength=2) leaf5 = Node(aId=5, aStrLength=1) expected_result.add_child(leaf1) expected_result.add_child(inner1) expected_result.add_child(leaf5) inner1.add_child(inner2) inner1.add_child(leaf4) inner2.add_child(leaf2) inner2.add_child(leaf3) expected_result.update_leaf_list() # print('inputstr: %s' % inputstr) # print('expected:') # print(expected_result.fancyprint(inputstr)) # print('actual:') # print(constructed_tree.fancyprint(inputstr)) assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) # inputstr = farach.str2int('1221') # constructed_tree = farach.construct_suffix_tree(inputstr) # expected_result = Node(aId='root') # expected_result.add_child(Node(aId=1, aStrLength=[12])) # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) # inputstr = farach.str2int('2221') # constructed_tree = farach.construct_suffix_tree(inputstr) # expected_result = Node(aId='root') # expected_result.add_child(Node(aId=1, aStrLength=[12])) # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr) banana_test() print('tests succeeded!')
def str12121(): string = '12121' string = str2int(string) constructed_tree = farach.construct_suffix_tree(string) actual_tree = Node(aId='root') inner1 = Node(1, 'inner') inner2 = Node(2, 'inner') inner3 = Node(3, 'inner') leaf1 = Node(6, 1) leaf2 = Node(5, 2) leaf3 = Node(4, 3) leaf4 = Node(3, 4) leaf5 = Node(2, 5) leaf6 = Node(1, 6) actual_tree.add_child(inner1) actual_tree.add_child(inner2) actual_tree.add_child(leaf6) inner1.add_child(inner3) inner1.add_child(leaf5) inner3.add_child(leaf1) inner3.add_child(leaf3) inner2.add_child(leaf2) inner2.add_child(leaf4) actual_tree.update_leaf_list() # print(actual_tree.fancyprint(string)) # print(constructed_tree.fancyprint(string)) check_correctness(constructed_tree, string) assert constructed_tree.fancyprint(string) == actual_tree.fancyprint( string)