Returns a gossip store file with the given channels in it, and a map of node labels -> ids
(channels, nodemap={})
| 511 | |
| 512 | |
| 513 | def generate_gossip_store(channels, nodemap={}): |
| 514 | """Returns a gossip store file with the given channels in it, and a map of node labels -> ids |
| 515 | """ |
| 516 | nodes = [] |
| 517 | |
| 518 | def write_bignum(outf, val): |
| 519 | if val < 253: |
| 520 | outf.write(val.to_bytes(1, byteorder='big')) |
| 521 | elif val <= 0xFFFF: |
| 522 | outf.write(b'\xFD') |
| 523 | outf.write(val.to_bytes(2, byteorder='big')) |
| 524 | elif val <= 0xFFFFFFFF: |
| 525 | outf.write(b'\xFE') |
| 526 | outf.write(val.to_bytes(4, byteorder='big')) |
| 527 | else: |
| 528 | outf.write(b'\xFF') |
| 529 | outf.write(val.to_bytes(8, byteorder='big')) |
| 530 | |
| 531 | def write_dumb_template(outf, channels, propname, illegalvals=[]): |
| 532 | """We don't bother uniquifing, just one entry per chan dir""" |
| 533 | # Template is simply all the values |
| 534 | write_bignum(outf, len(channels) * 2) |
| 535 | for c in channels: |
| 536 | for d in (0, 1): |
| 537 | v = getattr(c.half[d], propname) |
| 538 | assert v not in illegalvals |
| 539 | write_bignum(outf, v) |
| 540 | |
| 541 | # Now each entry for each channel half points into the values. |
| 542 | for i in range(0, len(channels) * 2): |
| 543 | write_bignum(outf, i) |
| 544 | |
| 545 | # First create nodes |
| 546 | for c in channels: |
| 547 | if c.node1 not in nodes: |
| 548 | nodes.append(c.node1) |
| 549 | if c.node2 not in nodes: |
| 550 | nodes.append(c.node2) |
| 551 | |
| 552 | cfile = tempfile.NamedTemporaryFile(prefix='gs-compressed-') |
| 553 | # <HEADER> := "GOSSMAP_COMPRESSv1\0" |
| 554 | cfile.write(b'GOSSMAP_COMPRESSv1\x00') |
| 555 | # <CHANNEL_ENDS> := {channel_count} {start_nodeidx}*{channel_count} {end_nodeidx}*{channel_count} |
| 556 | write_bignum(cfile, len(channels)) |
| 557 | for c in channels: |
| 558 | write_bignum(cfile, nodes.index(c.node1)) |
| 559 | for c in channels: |
| 560 | write_bignum(cfile, nodes.index(c.node2)) |
| 561 | |
| 562 | # <DISABLEDS> := <DISABLED>* {channel_count*2} |
| 563 | # <DISABLED> := {chanidx}*2+{direction} |
| 564 | for i, c in enumerate(channels): |
| 565 | for d in (0, 1): |
| 566 | if not c.half[d].enabled: |
| 567 | write_bignum(cfile, i * 2 + d) |
| 568 | write_bignum(cfile, len(channels) * 2) |
| 569 | |
| 570 | # <CAPACITIES> := <CAPACITY_TEMPLATES> {channel_count}*{capacity_idx} |