def sync(self, pk, payload):
        """Update hg and return new event ids in topological order."""

        info = crypto_sign(dumps({c: self.height[h]
                for c, h in self.can_see[self.head].items()}), self.sk)
        msg = crypto_sign_open(self.network[pk](self.pk, info), pk)

        remote_head, remote_hg = loads(msg)
        new = tuple(toposort(remote_hg.keys() - self.hg.keys(),
                       lambda u: remote_hg[u].p))

        for h in new:
            ev = remote_hg[h]
            if self.is_valid_event(h, ev):
                self.add_event(h, ev)


        if self.is_valid_event(remote_head, remote_hg[remote_head]):
            h, ev = self.new_event(payload, (self.head, remote_head))
            # this really shouldn't fail, let's check it to be sure
            assert self.is_valid_event(h, ev)
            self.add_event(h, ev)
            self.head = h

        return new + (h,)
Example #2
0
def longest_path_in_dag(g: AdjList, w: EdgeWeight, start: Hashable,
                        goal: Hashable) -> Tuple[int, Path]:
    """
    >>> g = {0: [1, 2], 1: [4], 2: [3], 3: [4]}
    >>> w = {(0, 1): 7, (0, 2): 4, (2, 3): 2, (1, 4): 1, (3, 4): 3}
    >>> longest_path_in_dag(g, w, 0, 4)
    (9, [0, 2, 3, 4])
    """
    g_pred = collections.defaultdict(list)
    for x, preds in g.items():
        for pred in preds:
            g_pred[pred].append(x)

    vs = toposort(g)
    dp = collections.defaultdict(lambda: -1000000)
    pred = dict()
    dp[start] = 0
    for v in vs:
        if v == start:
            continue
        for v_prev in g_pred.get(v, []):
            if dp[v] < (newmax := dp[v_prev] + w[v_prev, v]):
                dp[v] = newmax
                pred[v] = v_prev