8

Sorry for the dumb question, but I'm not very good in lightning network... So I have two daemons: c-lightning and LND.

Channels from the c-lightning comes like this 505580x1917x1; Channels from the LND comes like this 556369376388317185;

Is it possible to bring them to a single format? For example c-lightning convert to simple integer like LND in order to find same channels from both daemons?

1
  • 1
    In the spec meeting in November it was agreed to make the format of the short channel Id part of the protocol. In future implementations should use the clightning format with x as a separator instead of : while colon was very readable the short channel ids that use x as a separator are doubleclickable. Commented Mar 23, 2019 at 9:29

3 Answers 3

8

The specification of the short_channel_id describes the format as follows:

The short_channel_id is the unique description of the funding transaction. It is constructed as follows:

  1. the most significant 3 bytes: indicating the block height
  2. the next 3 bytes: indicating the transaction index within the block
  3. the least significant 2 bytes: indicating the output index that pays to the channel.

Hence to convert between the two formats you can use the following python snippets:

def lnd_to_cl_scid(s):
    block = s >> 40
    tx = s >> 16 & 0xFFFFFF
    output = s  & 0xFFFF
    return (block, tx, output)

def cl_to_lnd_scid(s):
    s = [int(i) for i in s.split('x')]
    return (s[0] << 40) | (s[1] << 16) | s[2]

The reason we (c-lightning) use the dotted format is because it allows us to look up the funding TX without having to do a conversion (and it usually is shorter than the u64 representation)

2

https://github.com/lightningnetwork/lnd/blob/8379bbaa9b259544c2c8591782a78d7384680b2a/lnwire/short_channel_id.go#L25-L43

// NewShortChanIDFromInt returns a new ShortChannelID which is the decoded
// version of the compact channel ID encoded within the uint64. The format of
// the compact channel ID is as follows: 3 bytes for the block height, 3 bytes
// for the transaction index, and 2 bytes for the output index.
func NewShortChanIDFromInt(chanID uint64) ShortChannelID {
    return ShortChannelID{
        BlockHeight: uint32(chanID >> 40),
        TxIndex:     uint32(chanID>>16) & 0xFFFFFF,
        TxPosition:  uint16(chanID),
    }
}

// ToUint64 converts the ShortChannelID into a compact format encoded within a
// uint64 (8 bytes).
func (c ShortChannelID) ToUint64() uint64 {
    // TODO(roasbeef): explicit error on overflow?
    return ((uint64(c.BlockHeight) << 40) | (uint64(c.TxIndex) << 16) |
        (uint64(c.TxPosition)))
}
0

I have the following function definition in my Bash profile:

scid() {
    local -i scid
    if (( ${#} )) ; then
        for scid ; do
            echo "$((scid >> 40))x$((scid >> 16 & 0xFFFFFF))x$((scid & 0xFFFF))"
        done
    else
        while read -r scid ; do
            scid "${scid}"
        done
    fi
}

This lets me conveniently convert those ugly LND-style short channel IDs into the standards-compliant format, either by passing them to the scid function as arguments or by piping them in, one per line:

$ scid 556369376388317185
506015x904x1
$ echo 556369376388317185 | scid
506015x904x1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.