Introduce basic network Identity package - #82
Conversation
rargulati
left a comment
There was a problem hiding this comment.
Should the implementation be in a file in net rather than identity? I'm leaning towards yes.
| } | ||
|
|
||
| func pubKeyToID(pub ci.PubKey) peer.ID { | ||
| // From go-libp2p-peer: PKI-based identities for libp2p |
|
|
||
| func (pi PeerIdentity) addIdentityToStore() (pstore.Peerstore, error) { | ||
| ps := pstore.NewPeerstore() | ||
| // HACK: see github.com/rargulati/go-libp2p-crypto for fix |
There was a problem hiding this comment.
no longer true, remove
|
Hmm… Not sure I follow putting it into a |
|
So you're saying rather than make this an |
|
I just realized I actually misread your comment earlier. Like, really really badly misread. Don't know what I was thinking. I was saying if we've got an I don't think the implementation should be in |
| } | ||
|
|
||
| // An ID corresponds to the identification of a member in a peer-to-peer network. | ||
| type ID peer.ID |
There was a problem hiding this comment.
Rule of thumb: if we're importing libp2p into the net package, we're leaking our transport layer.
I think this needs to be some variation of what my branch calls ClientIdentifier (which is a bad name). Let me try and get that branch up so we can talk more concretely.
There was a problem hiding this comment.
This could have been a string or interface{}, but I really, really hated the idea of adding more conversion code. I get that I have to do that though ha.
| // member will generate or provide a keypair, which will correspond to a network | ||
| // ID. Consumers of the net package require an ID to register with protocol level | ||
| // ID's, as well as a public key for authentication. | ||
| type Identity interface { |
There was a problem hiding this comment.
I do think this will need to be out here. The form may be slightly different.
There was a problem hiding this comment.
Not convinced we need this as an exported thing now that we have net.TransportIdentifier. The question might end up being about consumers though: who calls ID and PubKeyFromID and what do they do with it? I think it might be best to move this into libp2p.go until we see a need for pulling it out.
| } | ||
|
|
||
| type PeerIdentity struct { | ||
| type peerIdentity struct { |
There was a problem hiding this comment.
👏 to making this unexported.
|
Should I move all of the code to |
|
Assuming we still mean |
Shadowfiend
left a comment
There was a problem hiding this comment.
Other than the question about Identity, I feel like this is ready to be merged and iterated on. Some things will become clearer as we start actually writing the code that connects to libp2p and opens/joins a broadcast channel.
| // member will generate or provide a keypair, which will correspond to a network | ||
| // ID. Consumers of the net package require an ID to register with protocol level | ||
| // ID's, as well as a public key for authentication. | ||
| type Identity interface { |
There was a problem hiding this comment.
Not convinced we need this as an exported thing now that we have net.TransportIdentifier. The question might end up being about consumers though: who calls ID and PubKeyFromID and what do they do with it? I think it might be best to move this into libp2p.go until we see a need for pulling it out.
|
|
||
| // LoadOrGenerateIdentity allows a client to provide or generate an Identity that | ||
| // will be used to reference the client in the peer-to-peer network. | ||
| func LoadOrGenerateIdentity(randseed int64, filePath string) (net.Identity, error) { |
There was a problem hiding this comment.
I would see if this and AddIdentityToStore can be unexported (might not be the case).
The goal behind `net.Identity` is to expose a minimal subset of network level identifiers for external consumption (ie, in registering the association between a network and protocol identifiers). We identifiy peers within the libp2p network by their peer.ID and ed25519 public keys. These public keys are generated from the corresponding private keys.
The interface now resides in net/interfaces.go (along with other net interfaces).
The identity package is the local implementation of net.Identity. This is expressed as `peerIdentity`. This allows consumers to generate a `identity.peerIdentity` which implements `net.Identity` and gives the client access to adding an identity to a store as well as all the functionality of `net.Identity`.
Simple tests for the local implementation of the interface.
Currently we use go-libp2p-crypto as our underlying PKI lib. This may change in the future as the application becomes more fleshed out.
Prove that we can store and retrieve an identity from an addressbook/store (in this case, go-libp2p-peerstore), and that we can generate a valid public/private key pair that can sign and verify a signature over a message.
Rather than having a separate identity package for the nework, collapse this abstraction directly into the network (as part of the p2p package). Our libp2p implementation will be contained directly within the p2p abstraction (which is a network level abstraction). Our libp2p identity can now be hidden behind this abstraction.
In an effort to ensure our interfaces don't leak information about the underlying transport, we consolidate the implementation under the p2p package with a simpler interface implementation. Furthermore, we remove unnecessary abstractions (intermediate PubKey and ID types) and opt to use strings/[]byte where appropriate as most interfaces will accept, return, or trivial convert between native types.
The Identity interface is no longer needed as it's unnecessary to expose to external consumers. Rather we rely on TransportIdentifier. We modify this interface to have an ID() method which exposes a string.
Refactor the implementation to implement the TransportIdentifier interface as well as modifying methods to use said interface (as well as unexporting methods). Remove the need for net.TransportIdentifier.ID().
|
Removed the Identity interface. The casting of the internal type is meh, but the alternative (ie. adding an |
Shadowfiend
left a comment
There was a problem hiding this comment.
Haven't taken a deep look at the tests yet, but left some notes and questions.
| ) | ||
|
|
||
| // Implementation of the TransportIdentifier interface | ||
| type networkID peer.ID |
There was a problem hiding this comment.
Not sure we need to alias this. The main point of net.TransportIdentifier is that internally we can refer to our type exactly as it is, and when it crosses an interface boundary it can be referenced as a net.TransportIdentifier.
There was a problem hiding this comment.
You can't define new methods on a non-local types. Redefining external interfaces in terms of a new interface in a different package is considered illegal:
func (ni peer.ID) ProviderName() string {
return "libp2p"
}
does not compile
There was a problem hiding this comment.
Ah yes, of course… < slaps forehead >
| @@ -0,0 +1,102 @@ | |||
| package net | |||
There was a problem hiding this comment.
This should be in package libp2p, under net/.
There was a problem hiding this comment.
Hm, I wish you told me this when it was net/p2p/ to just rename to libp2p ;-P
| // Implementation of the TransportIdentifier interface | ||
| type networkID peer.ID | ||
|
|
||
| func (ni networkID) ProviderName() string { |
There was a problem hiding this comment.
Thoughts on making this *peer.ID (or *networkID if we choose to keep the alias)?
There was a problem hiding this comment.
Can make this *networkID, but can't do peer.ID as that would be redefining an interface and type out of its own package.
| // member will generate or provide a keypair, which will correspond to a network | ||
| // ID. Consumers of the net package require an ID to register with protocol level | ||
| // ID's, as well as a public key for authentication. | ||
| type peerIdentity struct { |
There was a problem hiding this comment.
Confused… What's the difference between this and peer.ID?
There was a problem hiding this comment.
This is our internal means of referencing this stuff. I guess I haven't been clear in how this stuff will be used.
There was a problem hiding this comment.
My 2¢: if we've got a bundle of things that can produce a peer.ID, we might as well use that as the TransportIdentifier implementor. The code that interacts with TransportIdentifier won't care, as it won't interact with the internals.
| return pid | ||
| } | ||
|
|
||
| func (pi *peerIdentity) PubKeyFromID(id TransportIdentifier) (ci.PubKey, error) { |
There was a problem hiding this comment.
Is this something we expect someone to invoke outside of the libp2p package?
|
|
||
| // loadOrGenerateIdentity allows a client to provide or generate an Identity that | ||
| // will be used to reference the client in the peer-to-peer network. | ||
| func loadOrGenerateIdentity(randseed int64, filePath string) (*peerIdentity, error) { |
There was a problem hiding this comment.
I think I asked this earlier, but it feels like we should make this decision as far removed from here as possible. Probably in the Connect function or whatever will be bootstrapping the network connection. Having a loadOrGenerateIdentity function that in turn actually can do one of three things (load, generate deterministically, and generate cryptographically secure) is not ideal.
Since there's no code other than tests consuming this, I think we can just lose this function and implement the tests by calling the generate* functions directly.
| } | ||
|
|
||
| // generateIdentity generates a public/private-key pair | ||
| // (using the libp2p/crypto wrapper for golang/crypto) provided a reader. |
There was a problem hiding this comment.
Not really “provided a reader” anymore, right?
|
|
||
| // generateIdentity generates a public/private-key pair | ||
| // (using the libp2p/crypto wrapper for golang/crypto) provided a reader. | ||
| // Use randseed for deterministic IDs, otherwise we'll use cryptographically secure psuedorandomness. |
There was a problem hiding this comment.
pseudo*, but I think this whole line is no longer valid.
|
I think we're kind of on the same page, but not really. There's been quite a bit of churn on this concept over two PRs. The goal here is to make small slices, and open PRs that consume these concepts, but I see that a lot of context is lost for the reviewer (as I have the context in my head). I'll need to take a different approach. It will be best if I close this PR. I'll wait for your PRs to get merged in, and then introduce a larger PR that shows all of these concepts as a single unit. |
|
Let's focus on merging #83 at the start of tomorrow, as that's the last PR that touches the network interface in a significant way (there's another branch that adds |
More at https://en.wikipedia.org/wiki/My_Name_Is
The goal behind
net.Identityis to expose a minimal subset of networklevel identifiers for external consumption (ie, in registering the
association between a network and protocol identifiers).
We identifiy peers within the libp2p network by their peer.ID and
ed25519 public keys. These public keys are generated from the
corresponding private keys.
This PR attempts to focus the work started in #69
TODO: