hidden-lightning-network
Use LDK to probe the lightning network for the detection of private channels.
We can look at public lightning node stats at places like 1ml.com. But "private channels are private". Except they are not, and we can figure it out.
Create our own lightning paths and guess channel IDs. If we guess correct, we know a node has a certain private channel based on error code. Then, we can even guess which node is on the other side of the path.
- Used LDK sample node as a starting point
- Connected it to our LND based polar instance
- Queried Routes to the destination target
- Figured out how to make fake lightning payments through a route
- Appended our guess route to the end of the path
- Sent our fake payment, interpreted the results
- Saved payment attempt state, can infer if our fake payment revealed a private channel
cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> <ldk_storage_directory_path> [<ldk-peer-listening-port>] [bitcoin-network] [announced-listen-addr announced-node-name]
source .env.local && cargo run $RPC_USER:$RPC_PASS@$RPC_HOST $STORAGE $LISTEN $NETWORK $NAME $ADDR
cargo run --bin scraper ./data/utxodump.csv ./data/iterate.txt
ALICE p2p
connectpeer 0258cc6d50ed15d05938261e209e5bee11948eda838d66b5481b3d6e839733cf87@127.0.0.1:9735
bob pubkey
sendfakepayment 0231014817072d627ef0772b5212e73a8f32190e1bad485418938e093f0f479768
correct channel id, correct pubkey
probeprivate 0258cc6d50ed15d05938261e209e5bee11948eda838d66b5481b3d6e839733cf87 03aa4f7f215d551f3bd6e852122d85d0da6b34753ebe03a94b2b7fc092694c6ff5 4460718673952768
wrong pubkey, correct channel id
probeprivate 0231014817072d627ef0772b5212e73a8f32190e1bad485418938e093f0f479768 030ac3e942e8407243c62423c7f0d68787ff112b7831c9cd2c7c1639c781591d94 645413325570048
wrong channel id, correct pubkey
probeprivate 0231014817072d627ef0772b5212e73a8f32190e1bad485418938e093f0f479768 03aa4f7f215d551f3bd6e852122d85d0da6b34753ebe03a94b2b7fc092694c6ff5 158329674465285
probeall
probeall assumptions data/nodes.json data/transactions
probeall assumptions all data/transactions
dump_results
dump_results data/results data/transactions
- Lightning Node
- Connects to another lightning node
- Needs gossip about the network
- Can create routes
- "query routes"
- "send to route"
- Send fake payments (with fake payment hash)
- Fork LDK
- Figure out the error code (16399)
- Handle unhandled error reason
- Interpret payment failure errors
- Open private channel between bob and carol
- Create special hops
- Detect difference (programatically) between when we use a real channel and not
- Write results to the DB
- Iterate over a list of UTXOs and see if any are a private channel
- Should get different error when channel_id is correct but pubkey is wrong (unknown_next_peer) should be PERM|10, instead we're getting PERM|15
- Only apply channel updates onto the channel it is meant for
- Resume where it left off
- Scrap a list of all public nodes
- Scrap a list of all public channels
- Filter out public channels from possible private channel list
- If it can't reach a target node, skip the rest of the probes to it
- Get a mainnet proxy node setup with a private channel with another node
- Update datasets
- Run on proxy node looking for a single private channel
- Run against some other targetted node
- Find out what % of public channels would fall into the assumption set
- Write up how combining parallel channel probing could work
- Retry payments if error is retriable and not what I'm looking for
- Work with multiple channels and multiple paths to increase speed
- Dump the results
- Run through found channels to find the other node
Sample node implementation using LDK.
git clone https://github.com/lightningdevkit/ldk-sample
cd ldk-sample
cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> <ldk_storage_directory_path> [<ldk-peer-listening-port>] [bitcoin-network] [announced-listen-addr announced-node-name]
bitcoind
's RPC username and password likely can be found through cat ~/.bitcoin/.cookie
.
bitcoin-network
: defaults to testnet
. Options: testnet
, regtest
, and signet
.
ldk-peer-listening-port
: defaults to 9735.
announced-listen-addr
and announced-node-name
: default to nothing, disabling any public announcements of this node.
announced-listen-addr
can be set to an IPv4 or IPv6 address to announce that as a publicly-connectable address for this node.
announced-node-name
can be any string up to 32 bytes in length, representing this node's alias.
Licensed under either:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.