Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bolt07: Adding P2P routing gossiping #1

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions 07-routing-gossip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# BOLT #7: P2P Node and Channel Discovery

This specification describes a simple initial node and channel discovery mechanism that does not rely on a third-party to disseminate the information.

Node and channel discovery serve two different purposes:

- Channel discovery allows the creation and maintenance of a local view of the network's topology such that the node can discover routes to desired destination.
- Node discovery allows nodes to broadcast their ID, host and port, such that other nodes can open connections and establish payment channels.

Peers in the network exchange `route_announcement` messages that contain information about a node and about its outgoing channels.
The node creating an announcement is referred to as the _announcing node_.
Announcements MUST have at least one associated channel whose existence can be proven by inspection of the blockchain, i.e., the anchor transaction creating the channel MUST have been confirmed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean that the transaction should have reached min_conf right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we might just set this at 6 confirmations, which should be safe. Keep in mind though that the endpoints of the channel may have completely different policies, some accepting 0-conf anchors for channels and some being pedantic and waiting for 120 confirmations for example. It should be safe to just a lower bound enforced by nodes.

Copy link
Collaborator

@pm47 pm47 Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 confirmations seems fine. My point was that if we just wait for one confirmation (which is what the spec seems to be saying) we might have issues with some nodes not having received the new block yet and discarding the announcement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I'll add the 6 confirmations to the spec.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw I just realized that 0-conf anchors are not possible with ids based on block height 😁


Nodes receiving an announcement verify that this is the latest update from the announcing node by comparing the included timestamp and update their local view of the network's topology accordingly.
The receiving node removes all channels that are signaled to be removed or are no longer included in the announcement, adds any new channels and adjusts the parameters of the existing channels.
Notice that this specification does not include any mechanism for differential announcements, i.e., every announcement ships the entire final state for that node.

Once the announcement has been processed it is added to a list of outgoing announcements to the processing node's peers, which will be flushed at regular intervals.
This store and delayed forward broadcast is called a _staggered broadcast_

Notice that each announcement will only announce a single direction of the channel, i.e., the outgoing direction from the point of view of the announcing node.
The other direction will be announced by the other endpoint of the channel.
This reflects the willingness of the announcing node to forward payments over the announced channel.

## Message Format

This specification defines one message type with identifier 256 (`0x00000100`), called a `MSG_ROUTING_UPDATE`.
It comprises both the sending node's identity and contact information as well as all of its outgoing channels.

```
[4:timestamp]
[33:node_id]
[16:ipv6]
[2:port]
[3:rgb_color]
[var:alias]
[4+X*46:channels]
[64:signature]
```

The timestamp is required to be monotonically increasing from one update to another, it MAY correspond to unix timestamp when the sending node created the announcement.
The node ID is a 33 byte compressed public key that uniquely identifies the node in the network and matches the signature.
The IPv6 field is used for both IPv4 and IPv6 addresses, using the IPv4-Mapped IPv6 Address format defined in [RFC 4291 section 2.5.5.2](https://tools.ietf.org/html/rfc4291#section-2.5.5.2):

```
| 80 bits | 16 | 32 bits |
+--------------------------------------+--------------------------+
|0000..............................0000|FFFF| IPv4 address |
+--------------------------------------+----+---------------------+
```

The alias is a length prefixed UTF-8 encoded string.
The UTF-8 encoded string is prefixed by a 4 byte unsigned int in network byte order, defining the length of the string.
The RGB color and alias MAY be used by the node operator to customize their node's appearance in maps and graphs, and MAY be used to reference nodes in interfaces.
Notice however that there is no collision protection for aliases, hence the node ID MUST be verified before initiating any transfer.

The `channels` field comprises a 4 byte unsigned int count of channels that follow.
Each channel has the following format:

```
[33:destination]
[4:blockheight]
[4:blockindex]
[1:expiry]
[2:fee_base]
[2:fee_proportional]
```

The `destination` field is the node ID of the remote node from the point of view of the announcing node.
Thus the `node_id` from the enclosing announcement and the `destination` identify the two endpoints of the channel.
The `blockheight` and `blockindex` MAY be combined to form a globally unique `channel_id` that MAY be used to identify the channel in future.
The remaining fields determine the minimum timelock difference that HTLCs have to respect (`expiry`) and the fees that the announcing node expected when routing a payment through the announced channel from `node_id` to `destination`.

## Creation and Processing of Announcements

The announcing node creates the message with the node's information and all its channels.
Normal removal of a channel is done by omitting the channel in the `channels` field.
Notice that this does not allow removing a channel if no active channels are left open, since an announcement requires at least one channel in the `channels` field to be valid.
Copy link
Collaborator

@pm47 pm47 Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just allow messages with no channels?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is not so much accepting messages without channels the problem is that we'd have to forward them as well, flooding the network with messages that are basically free to create.

An attacker can just generate any number of node IDs and announce its existence. And we can't just drop empty announces for which we don't know the corresponding node, because other nodes may know it and require the removal message.

If we require a channel, even a closed one, he must at least make a bitcoin transaction, which makes the attack non-free. I agree that signaling via the expiry is a bit wonky, but keep in mind that this is voluntary signaling, we can still remove channels if the anchor TX gets spent (modulo effort of tracking those).

An explicit removal of all channel MAY be signaled by creating an announcement that includes only one last channel to be closed, and setting the `expiry` field of that channel to `0xFF`.

The announcing node serializes the message omitting the `signature` field, and computes the signature on the partial serialized message using the private key matching the `node_id` in the message.
The signature is then serialized and appended to the message, completing the message.

The announcing peer then sends the announcement to its peers, initiating the broadcast.

Upon receiving an announcement the nodes verifies the validity of the announcement.
In order to be valid the following conditions MUST be satisfied:

- The timestamp MUST be larger than the last valid announcement from the announcing node.
- The anchor transactions for each channel, identified by the (`blockheight`, `blockindex`)-tuple must have reached at least a minimum number of 6 confirmations. The node MAY require more confirmations before processing and/or forwarding the announcement.
- The signature in the announcement MUST be a valid signature from the public key in the `node_id` field for the message up to the signature itself.
- The announcement MUST have at least on valid channel. The validity of the channel can be verified by inspecting the anchor transaction specified in the announcement.
- If the `expiry` field of any channel is set to `0xFF` then it MUST be the only channel in the announcement.

If an announcement is not valid, it MUST be discarded, otherwise the node applies it to its local view of the topology:
the receiving node removes all channels from its local view that match the `node_id` as the origin of the channel, i.e., all channels that have been previously announced by that node, and adds all channels in the announcement unless they have an `expiry` field of `0xFF`.

If, after applying the changes from the announcement, there are no channels associated with the announcing node, then the receiving node MAY purge the announcing node from the set of known nodes.
Otherwise the receiving node updates the metadata and stores the signature associated with the announcement.
This will later allow the receiving node to rebuild the announcement for its peers.

After processing the announcement the receiving node adds the announcement to a list of outgoing announcements.
The list of outgoing announcement MUST NOT contain multiple announcements with the same `node_id`, duplicates MUST be removed and announcements with lower `timestamp` fields MUST be replaced.
This list of outgoing announcements is flushed once every 60 seconds, independently of the arrival times of announcements, resulting in a staggered announcement and deduplication of announcements.

Nodes MAY re-announce their channels regularly, however this is discouraged in order to keep the resource requirements low.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a basic dos protection, shouldn't we just not propagate re-announcements?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I had a heartbeat in mind, allowing nodes to purge channels and nodes that it hasn't seen for a long time (24h?), but it might cause a lot of traffic.

We require timestamps to increase, so that re-announcements actually have to start from the announcing node. But dropping identical re-announcements is not hard, on the other hand it is trivial for the announcing node to slightly modify its announcement making it count as new.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we will probably need some kind of rate limiting logic and blacklisting then, à la bitcoind.

In order to bootstrap nodes that were not online at the time of the broadcast nodes will announce all known nodes and their associated channels at the time of connection establishment.
The individual announcements can be reconstructed from the set of known nodes, containing the metadata and signatures for the announcements, and the routing table, containing the channel information.
The broadcast is stopped after the first hop since the peers of the newly joined node already have the announcement and the timestamp check will fail.

## References

- [RFC 4291](https://tools.ietf.org/html/rfc4291)