diff --git a/lntopo/__main__.py b/lntopo/__main__.py index 7530e45..6077f6b 100644 --- a/lntopo/__main__.py +++ b/lntopo/__main__.py @@ -1,6 +1,7 @@ import json import click from lntopo.timemachine import timemachine +from lntopo.reforme import reforme from lntopo.common import GossipStore from lntopo import common from binascii import unhexlify @@ -13,6 +14,7 @@ def cli(): cli.add_command(timemachine) +cli.add_command(reforme) @cli.group() def nodes(): diff --git a/lntopo/parser.py b/lntopo/parser.py index ca23fa8..f196d93 100644 --- a/lntopo/parser.py +++ b/lntopo/parser.py @@ -80,6 +80,7 @@ def __json__(self): 'fee_base_msat': self.fee_base_msat, 'fee_proportional_millionths': self.fee_proportional_millionths, 'htlc_maximum_msat': self.htlc_maximum_msat, + 'disabled': bool(self.disable), 'chain_hash': hexlify(self.chain_hash).decode('ASCII'), } @@ -96,6 +97,11 @@ def direction(self): (b,) = struct.unpack("!B", self.channel_flags) return b & 0x01 + @property + def disable(self): + (b,) = struct.unpack("!B", self.channel_flags) + return (b >> 1) & 0x01 + def serialize(self): raise ValueError() @@ -286,6 +292,8 @@ def parse_address(b): return a # https://github.com/alexbosworth/bolt07/blob/519c94a7837e687bf7478a74779d5ea493a76a44/addresses/encode_base32.js + + def to_base_32(addr): alphabet = 'abcdefghijklmnopqrstuvwxyz234567' byte = 8 @@ -305,9 +313,10 @@ def to_base_32(addr): if bits > 0: base32 += alphabet[(value << (word - bits)) & lastIndex] - + return base32 + def parse_node_announcement(b): if not isinstance(b, io.BytesIO): b = io.BytesIO(b) diff --git a/lntopo/reforme.py b/lntopo/reforme.py new file mode 100644 index 0000000..6e9caa4 --- /dev/null +++ b/lntopo/reforme.py @@ -0,0 +1,57 @@ +from .common import DatasetFile +import click +from .parser import ChannelAnnouncement, ChannelUpdate +from tqdm import tqdm +from datetime import datetime +import csv +import os + + +def append_csv(rows, path): + header = not os.path.exists(path) + + with open(path, mode='a', newline='') as file: + writer = csv.writer(file) + + # Write the header if the file is new + if header: + writer.writerow(rows[0].keys()) + + # Write the rows + for row in rows: + writer.writerow(row.values()) + + +@click.group() +def reforme(): + pass + + +@reforme.command() +@click.argument("dataset", type=DatasetFile()) +def reforme(dataset): + ''' + reforme data set for tvalgoteam + ''' + if not os.path.exists("data/channels/"): + os.makedirs('data/channels/') + for m in tqdm(dataset, desc="Replaying gossip messages"): + if isinstance(m, ChannelAnnouncement): + node1 = min(m.node_ids[0].hex(), m.node_ids[1].hex()) + node2 = max(m.node_ids[0].hex(), m.node_ids[1].hex()) + row = [{'channelId': m.num_short_channel_id, + 'node1Pub': node1, 'node2Pub': node2}] + append_csv(row, 'data/dictionary.csv') + if isinstance(m, ChannelUpdate): + row = [{ + 'lastUpdate': m.timestamp, + 'direction': m.direction+1, + 'timeLockDelta': m.cltv_expiry_delta, + 'minHtlc': m.htlc_minimum_msat, + 'feeRateMilliMsat': m.fee_proportional_millionths, + 'feeBaseMsat': m.fee_base_msat, + 'disabled': m.disable, + 'maxHtlcMsat': m.htlc_maximum_msat + + }] + append_csv(row, f'data/channels/{m.num_short_channel_id}.csv') diff --git a/lntopo/timemachine.py b/lntopo/timemachine.py index 120587f..63c7063 100644 --- a/lntopo/timemachine.py +++ b/lntopo/timemachine.py @@ -29,7 +29,7 @@ def restore(dataset, timestamp=None, fmt='dot'): """ if timestamp is None: - timestamp = time.time() + timestamp = time.time() cutoff = timestamp - 2 * 7 * 24 * 3600 channels = {} @@ -84,6 +84,7 @@ def restore(dataset, timestamp=None, fmt='dot'): if m.htlc_maximum_msat: chan["htlc_maximum_msat"] = m.htlc_maximum_msat chan["cltv_expiry_delta"] = m.cltv_expiry_delta + chan["disabled"] = m.disable elif isinstance(m, NodeAnnouncement): node_id = m.node_id.hex() @@ -123,7 +124,8 @@ def restore(dataset, timestamp=None, fmt='dot'): for scid in todelete: del channels[scid] - nodes = [n for n in nodes.values() if n["in_degree"] > 0 or n['out_degree'] > 0] + nodes = [n for n in nodes.values() if n["in_degree"] > + 0 or n['out_degree'] > 0] if len(channels) == 0: print(