Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds a short section to the readme on how to interpret multiaddrs. I think this is the unifying principle of how we use multiaddrs in practice and could guide how we use them in the future. I don't think anything here is controversial and it fits with the "encapsulation" ideas presented originally. This is really just a clarification of what I think is the original intent.
This is a PR so that it's easier to discuss the changes line by line.
All but one of our constructions fit this principle. The uncommon
p2p-circuit
with a defined relay path does not fit this principle as thep2p-circuit
component is currently defined, but I think we can make some small changes to make it fit. e.g./ip4/1.2.3.4/tcp/1234/p2p/qmR/p2p-circuit/ip4/4.3.2.1/tcp/54321/p2p/qmA
doesn't cleanly fit this model. We could add a new via protocol that takes in a single parameter of data, parses it as a multiaddr, and passes it to the underlying protocol as avia
parameter. This would look like/ip4/1.2.3.4/tcp/1234/p2p/qmR/p2p-circuit/via/bracketenc/[ip4/4.3.2.1/tcp/54321]/p2p/qmA
. What's nice is the could also describe (though we don't currently support) multiple hops in the circuit:/ip4/1.2.3.4/tcp/1234/p2p/qmR/p2p-circuit/via/bracketenc/[ip4/4.3.2.1/tcp/54321/p2p/QmR2/p2p-circuit/via/bracketenc/[/ip4/2.2.2.2/tcp/1234]]/p2p/qmA
.Example
As an example, here's how you would parse the string and interpret
/ip4/1.2.3.4/tcp/1234/p2p/qmR/p2p-circuit/via/bracketenc/[ip4/4.3.2.1/tcp/54321/p2p/QmR2/p2p-circuit/via/bracketenc/[/ip4/2.2.2.2/tcp/1234]]/p2p/qmA
. Remember that parsing the binary representation is easy since we either know the size of the data for a protocol (fixed size) or the data is length prefixed.Parsing the string into a multiaddr, left to right:
/ip4/...
We see ip4 and call ip4's string to byte to consume the string up to/tcp/...
.tcp
and call tcp's string to byte to consum up to/p2p/...
.via
, via doesn't take a value, so we continue tobracketenc/...
bracketenc
parses the rest of the string until it finds a matching closing bracket]
. This logic is defined by this encoding. The parsed string is kept as the value forbracketenc
.p2p
and parse the following peer id.Interpreting the multiaddr, right to left:
p2p
component takes its peer ID value and passes it to the next component as the parameterpeer=QmA
.bracketenc
component takes its value and passes it to the next component as parameterdata=ip4/4.3.2.1/tcp/54321/p2p/QmR2/p2p-circuit/via/bracketenc/[/ip4/2.2.2.2/tcp/1234]
. It also forwards any other parameter it was given (i.e.peer=QmA
).via
component takes the data parameter and parses the multiaddr (similar to our parsing the string into a multiaddr example above). It passes this to the next component as parametervia=<parsedMultiaddr>
. It also forwards any other parameter it was given (i.e.peer=QmA
).p2p-circuit
component now has the parametersvia=<parsedMultiaddr>
andpeer=QmA
. Thep2p-circuit
transport can now dial the relayQmR
defined by the rest of the multiaddr (/ip4/1.2.3.4/tcp/1234/p2p/qmR/
), and can tell that relay to connect to peerQmA
via the pathvia=<parsedMultiaddr>
.Why now?
This came up as I was fixing WSS in go-libp2p and realized I needed to keep the hostname around for the SNI (e.g. I needed
/ip4/1.2.3.4/tls/sni/example.com/ws
).We also need this to:
Related threads
multiformats/multiformats#55. It's worth reviewing the
proposals/multipath.md
file first.I think this is the minimal change that gets multiaddrs able to fulfill the goals of multipath. Key differences here are that we don't have a way to let the codec define the binary output directly (we always prefix it with a varint of byte length). We may want to change this and default it to varint prefix, but allow other ways to write and parse the binary. This would allow us to make the
p2p-circuit
fit the model in a backwards compatible way.Questions
Changes this would require
p2p-circuit/via
orp2p-circuit/route
option (as demonstrated above)./
instead it should parse the multiaddr from the left to the right. This should be backwards compatible, but new multiaddr constructions will not work on older clients. e.g./ip4/.../http/path/lenprefixencode/20_somepath/tosomething
wouldn't work on older clients, but this also wouldn't work because of the missing codec.What this enables/unlocks
If we agree on this we can unblock the following tricky issues:
This principle unblocks some previously tricky issues:
We unlock the ability to handle parameters in a simple way. And we unlock the ability to support nested paths (via an encoding like:
/ip6/.../p2p/QmR1/p2p-circuit-path/lenprefixencode/33_/ip6/.../QmR2/p2p-circuit/p2p/QmA
)Tagging folks I know have opinions here, forgive me if I miss you:
@Stebalien
@marten-seemann
@mxinden
@elenaf9