def _transact(graph: nx.MultiGraph, src: int, tgt: int, amount: int, new_node: int, info: dict): from more_itertools import pairwise path, weights, fees = find_route(graph, src, tgt, amount) # no path found if path is None: info['no_path'] += 1 return for (node, neighbour) in pairwise(path): channel_trans_amt = weights[neighbour] channel_policy = graph.get_policy(node, neighbour) # channel cannot handle transaction if channel_policy.balance < channel_trans_amt: info['channel_imbalance'] += 1 if node == new_node or neighbour == new_node: info['failure'][node, neighbour] += 1 raise Exception('Adversary channel imbalance') return # record successful transaction info['total_success'] += 1 total_amt = 0 # move amount between nodes in path for (node, neighbour) in pairwise(path): if neighbour is None: # remove total amount from src graph.nodes[path[0]]['data'].capacity -= total_amt # add amount to tgt graph.nodes[node]['data'].capacity += weights[node] break channel_trans_amt = weights[neighbour] channel_policy = graph.get_policy(node, neighbour) # pay channel fees to node graph.nodes[node]['data'].capacity += fees[node] total_amt += fees[node] # shift channel balance channel_policy.balance -= channel_trans_amt graph.get_policy(neighbour, node).balance += channel_trans_amt # record profit for adversary if node == new_node or neighbour == new_node: info['success'][node, neighbour] += 1 info['profit'][node, neighbour] += fees[node]
def reward(g: nx.MultiGraph, edge: Tuple[int, int], const_amt: int, fee_type: str, fee: int = None) -> int: # debugging # print_flag = fee is not None u, v = edge if fee is not None: g.update_fee(u, v, fee, fee_type) else: fee = getattr(g.get_policy(u, v), fee_type) ebc = edge_betweenness(g, const_amt)[edge] # debugging # if print_flag: # print('({:>3d}, {:>3d}) fee {:>9d} ebc {:>9f} '.format( # u, v, fee, ebc), end='') return fee * ebc