Skip to content

Introduce basic network Identity package - #82

Closed
rargulati wants to merge 10 commits into
protocally-identicalfrom
my-name-is
Closed

Introduce basic network Identity package#82
rargulati wants to merge 10 commits into
protocally-identicalfrom
my-name-is

Conversation

@rargulati

@rargulati rargulati commented Apr 24, 2018

Copy link
Copy Markdown
Contributor

"My Name Is" is a song by American rapper Eminem from his major-label debut album The Slim Shady LP (1999). The song samples Labi Siffre's 1975 track "I Got The...". The song was ranked at #26 on "VH1's 100 Greatest Songs of the '90s".[2] "My Name Is" was also ranked #6 on Q Magazine's "1001 Best Songs Ever". [3] The song was placed at number 39 by Rolling Stone on their list of "100 Greatest Hip-Hop songs of all time" in April 2016.[4] The recording garnered Eminem his first Grammy Award for Best Rap Solo Performance at the 42nd Grammy Awards in 2000.

More at https://en.wikipedia.org/wiki/My_Name_Is

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.

This PR attempts to focus the work started in #69

TODO:

  • Tests
  • Address any review

@rargulati rargulati left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should the implementation be in a file in net rather than identity? I'm leaning towards yes.

Comment thread pkg/net/identity/identity.go Outdated
}

func pubKeyToID(pub ci.PubKey) peer.ID {
// From go-libp2p-peer: PKI-based identities for libp2p

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

remove

Comment thread pkg/net/identity/identity.go Outdated

func (pi PeerIdentity) addIdentityToStore() (pstore.Peerstore, error) {
ps := pstore.NewPeerstore()
// HACK: see github.com/rargulati/go-libp2p-crypto for fix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no longer true, remove

@Shadowfiend

Copy link
Copy Markdown
Contributor

Hmm… Not sure I follow putting it into a net.go file?I think the base interfaces/structures/functions live in a packagename/packagename.go file (we actually need to move net/interface.go to net/net.go), and if there's additional functionality that makes sense to break out we put it in named files under packagename/. For an example of my thinking, see https://github.com/keep-network/keep-core/tree/6c1f05c49bccbd33c1f5118c4e126bd9f2bbe0c6/pkg/beacon/relay/dkg, with dkg.go implementing the main DKG functionality, and sibling files like message.go and marshaling.go dealing with supporting functionality.

@rargulati

rargulati commented Apr 25, 2018

Copy link
Copy Markdown
Contributor Author

So you're saying rather than make this an identity package just do this as net/identity.go?

@Shadowfiend

Copy link
Copy Markdown
Contributor

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 identity package, the file should probably be identity/identity.go---which is where it is hehe.

I don't think the implementation should be in net, but rather in net/libp2p.

Comment thread pkg/net/interface.go Outdated
}

// An ID corresponds to the identification of a member in a peer-to-peer network.
type ID peer.ID

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@rargulati rargulati Apr 25, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR is up @ #83.

Comment thread pkg/net/interface.go Outdated
// 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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I do think this will need to be out here. The form may be slightly different.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👏 to making this unexported.

@rargulati
rargulati changed the base branch from master to protocally-identical April 27, 2018 01:04
@rargulati

Copy link
Copy Markdown
Contributor Author

Should I move all of the code to net/libp2p.go or just the implementation of id.ProviderName() in net/libp2p.go and leave the rest in identity/. Basically figuring out if I need to nuke the identity package and move the stuff in there to net and net/libp2p.go.

@Shadowfiend

Copy link
Copy Markdown
Contributor

Assuming we still mean net/libp2p/*, I think if you're wondering it's safest to start by sticking it all the libp2p package. If we see that the identity stuff is big enough to be its own thing, it can graduate to a separate package, probably under libp2p/. Right now I don't really see the need to expose identity outside of libp2p-land, because I'm not seeing any other consumers quite yet (this may change).

@Shadowfiend Shadowfiend left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread pkg/net/interface.go Outdated
// 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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread pkg/net/p2p/libp2p.go Outdated

// 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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would see if this and AddIdentityToStore can be unexported (might not be the case).

Raghav Gulati and others added 9 commits April 30, 2018 13:44
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().
@rargulati

Copy link
Copy Markdown
Contributor Author

Removed the Identity interface.

The casting of the internal type is meh, but the alternative (ie. adding an ID() string method to net.TransportIdentifier) doesn't necessarily make anything better.

@Shadowfiend Shadowfiend left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Haven't taken a deep look at the tests yet, but left some notes and questions.

Comment thread pkg/net/libp2p.go
)

// Implementation of the TransportIdentifier interface
type networkID peer.ID

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah yes, of course… < slaps forehead >

Comment thread pkg/net/libp2p.go
@@ -0,0 +1,102 @@
package net

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be in package libp2p, under net/.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hm, I wish you told me this when it was net/p2p/ to just rename to libp2p ;-P

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

<_<

Comment thread pkg/net/libp2p.go
// Implementation of the TransportIdentifier interface
type networkID peer.ID

func (ni networkID) ProviderName() string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thoughts on making this *peer.ID (or *networkID if we choose to keep the alias)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can make this *networkID, but can't do peer.ID as that would be redefining an interface and type out of its own package.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yep yep.

Comment thread pkg/net/libp2p.go
// 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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Confused… What's the difference between this and peer.ID?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is our internal means of referencing this stuff. I guess I haven't been clear in how this stuff will be used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread pkg/net/libp2p.go
return pid
}

func (pi *peerIdentity) PubKeyFromID(id TransportIdentifier) (ci.PubKey, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this something we expect someone to invoke outside of the libp2p package?

Comment thread pkg/net/libp2p.go

// 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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread pkg/net/libp2p.go
}

// generateIdentity generates a public/private-key pair
// (using the libp2p/crypto wrapper for golang/crypto) provided a reader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not really “provided a reader” anymore, right?

Comment thread pkg/net/libp2p.go

// 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pseudo*, but I think this whole line is no longer valid.

@rargulati

Copy link
Copy Markdown
Contributor Author

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.

@rargulati rargulati closed this May 1, 2018
@Shadowfiend

Copy link
Copy Markdown
Contributor

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 net.Provider, but that's not crucial right now I think, and you can always steal those commits for your PR if you'd like).

@rargulati
rargulati deleted the my-name-is branch May 25, 2018 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants