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

Chunking large Identify responses with Signed Records #958

Merged
merged 5 commits into from
Jun 3, 2020

Conversation

aarshkshah1992
Copy link
Contributor

p2p/protocol/identify/id.go Outdated Show resolved Hide resolved
p2p/protocol/identify/id.go Outdated Show resolved Hide resolved
p2p/protocol/identify/id.go Outdated Show resolved Hide resolved
p2p/protocol/identify/pb/identify.proto Outdated Show resolved Hide resolved
p2p/protocol/identify/pb/identify.proto Outdated Show resolved Hide resolved
p2p/protocol/identify/id.go Outdated Show resolved Hide resolved
}

// then write just the signed record
m := &pb.Identify{SignedPeerRecord: sr}
Copy link
Member

Choose a reason for hiding this comment

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

Can't the signed peer record be nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@raulk We already check for that at

if sr == nil || proto.Size(mes) <= legacyIDSize {
.

@aarshkshah1992 aarshkshah1992 changed the title [WIP] Chunking large Identify responses with Signed Records Chunking large Identify responses with Signed Records Jun 2, 2020
mes := pb.Identify{}
if err := r.ReadMsg(&mes); err != nil {
log.Warning("error reading identify message: ", err)
s.Reset()
return
}

if mes.More {
m := &pb.Identify{}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to make a new message here, just reuse the existing one and merge in the new fields.

Copy link
Contributor

Choose a reason for hiding this comment

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

This should be done just by reading in the existing message.

Copy link
Member

Choose a reason for hiding this comment

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

This will also generalize this code to merge protocols, addresses, etc. We can write this as:

func mergeMessages(r ggio.Reader, m proto.Message) error {
	for i := 0; i < maxMessages; i++ {
	  	switch err := r.ReadMsg(mes); err {
	    default:
		case io.EOF:
        	return nil
	    case nil:
			log.Warning("error reading identify message: ", err)
			s.Reset()
			return
		}
	}
    return fmt.Errorf("too many parts")
}

Copy link
Contributor Author

@aarshkshah1992 aarshkshah1992 Jun 3, 2020

Choose a reason for hiding this comment

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

@Stebalien

Had to use proto.Merge(dst, src) here after calling the gogo reader because the gogo varint reader uses proto.Unmarshal under the hood which resets(clears) the existing proto message before reading the new one into it.

Other than that, works well.

// more is set to true by a peer to indicate to the receiver that the signed record is absent in the current message
// and the peer should read the next message from the stream to fetch it.
// This is done because messages with signed records can exceed the legacy message size of 2K bytes.
optional bool more = 9 [(gogoproto.nullable) = false];
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this nullable thing? I would advise against using gogo specific stuff in the protobuf decls, as there are other implementations in different languages that want to use the same protobuf file.

Copy link
Member

Choose a reason for hiding this comment

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

This is just an annotation to tell gogo how to generate the go code for this protobuf. Other protobuf implementations will ignore annotations they don't understand.

mes := pb.Identify{}
if err := r.ReadMsg(&mes); err != nil {
log.Warning("error reading identify message: ", err)
s.Reset()
return
}

if mes.More {
m := &pb.Identify{}
Copy link
Member

Choose a reason for hiding this comment

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

This will also generalize this code to merge protocols, addresses, etc. We can write this as:

func mergeMessages(r ggio.Reader, m proto.Message) error {
	for i := 0; i < maxMessages; i++ {
	  	switch err := r.ReadMsg(mes); err {
	    default:
		case io.EOF:
        	return nil
	    case nil:
			log.Warning("error reading identify message: ", err)
			s.Reset()
			return
		}
	}
    return fmt.Errorf("too many parts")
}

mes := pb.Identify{}
if err := r.ReadMsg(&mes); err != nil {
log.Warning("error reading identify message: ", err)
s.Reset()
return
}

if mes.More {
Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure we don't need "more". We can just read till the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has been removed now since merging the messages works well.

Copy link
Member

Choose a reason for hiding this comment

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

We can remove the more field now, correct? I've gone ahead and done that but I'd like to double check with you (we can revert and add it back if you left it there for a reason).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Stebalien Yes, we can remove it. Sorry, I forgot this bit.

@aarshkshah1992
Copy link
Contributor Author

aarshkshah1992 commented Jun 3, 2020

@Stebalien @vyzo Have made the changes. Please take a look.

One test is failing in the Pull request build:

--- FAIL: TestHostProtoPreference (0.05s)
    basic_host_test.go:339: should have connected on  /testing

But, I'm not being able to reproduce it locally. Could one of you try and see if it fails for you to after merging with master ?

@vyzo
Copy link
Contributor

vyzo commented Jun 3, 2020

flaky tests on travis is nothing new unfortunately, I restarted the build to see if it persists.

go.mod Outdated
@@ -25,7 +25,7 @@ require (
github.com/libp2p/go-libp2p-netutil v0.1.0
github.com/libp2p/go-libp2p-peerstore v0.2.4
github.com/libp2p/go-libp2p-secio v0.2.2
github.com/libp2p/go-libp2p-swarm v0.2.4
github.com/libp2p/go-libp2p-swarm v0.2.6-0.20200602101559-2b4925e207f2
Copy link
Contributor

Choose a reason for hiding this comment

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

we'll need to update to release swarm before merging this.

@Stebalien Stebalien force-pushed the feat/signed-records-chunking branch from ed43042 to 513e13d Compare June 3, 2020 22:27
We no longer need it now that we keep reading till the stream closes.
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.

4 participants