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

Minows #22

Merged
merged 4 commits into from
Aug 19, 2024
Merged

Minows #22

merged 4 commits into from
Aug 19, 2024

Conversation

ineiti
Copy link
Member

@ineiti ineiti commented Jul 2, 2024

This is the final PR for the 2024 Spring semester project from Zhe Xion working with the DEDIS lab at EPFL.
It adds a websocket implementation for mino using libp2p, which allows a simple change from websockets to other communication protocols.
The code has been benchmarked against the old minogrpc and tested in d-voting tests.

@ineiti ineiti force-pushed the minows branch 2 times, most recently from e977b67 to 2885f13 Compare July 2, 2024 14:43
@ineiti ineiti self-assigned this Jul 2, 2024
Copy link
Collaborator

@pierluca pierluca left a comment

Choose a reason for hiding this comment

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

Reviewed half-way, in particular low-hanging fruits.
More reviewing to follow... time permitting.

core/ordering/cosipbft/blockstore/disk.go Outdated Show resolved Hide resolved
mino/minogrpc/session/mod.go Outdated Show resolved Hide resolved
mino/minows/key/mod.go Show resolved Hide resolved

import (
"context"
"encoding/gob"
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are we using gob encoding everywhere instead of serde ? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

IIRC, the serde implementation used json, and as the first benchmarks were slow, it has been changed to a binary format. But in the end it turned out that the slowdown was due to another part of the implementation. So I think we can revert that, if you prefer to have serde everywhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

In fact he gob encodes the following structure:

type Packet struct {
	Source  []byte
	Payload []byte
}

And then uses serde to encode the payload.

Is it worth creating a serde abstraction for the Packet?

Copy link
Collaborator

Choose a reason for hiding this comment

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

To keep everything uniform, I'd say yes.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I looked at it, and I propose to keep the Packet as a gob-encoded structure, with the following reasoning:

  • to me it corresponds to the grpc-encoding found here, which is encoded using protobuf (if I got that right): overlayClient.Call
  • as it needs to interface with the Stream interface, I'll have to add a packet-size manually, so that the receiver knows how many bytes to receive

So, I would be implementing part of the gob interface myself. Which is why I propose to accept this as-is.

@pierluca what do you think?

mino/minows/mod.go Show resolved Hide resolved
test/cosidela_test.go Outdated Show resolved Hide resolved
test/cosidela_test.go Outdated Show resolved Hide resolved
mino/minows/key/mod.go Outdated Show resolved Hide resolved
Copy link
Member

@PascalinDe PascalinDe left a comment

Choose a reason for hiding this comment

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

reviewed 9/21 files, coming back later to it

@jbsv
Copy link
Collaborator

jbsv commented Jul 5, 2024

dela is now based on go 1.21. Is it possible to upgrade this PR to align it to 1.21 as well ?

@ineiti
Copy link
Member Author

ineiti commented Jul 5, 2024

dela is now based on go 1.21. Is it possible to upgrade this PR to align it to 1.21 as well ?

Good point. I'll try to rebase our dela fork on the dedis dela, and see if things break too hard :)

Co-authored-by: Zach Xion XioZ@users.noreply.github.com
Co-authored-by: Zach Xion XioZ@users.noreply.github.com

This commit implements a new Mino handler using libp2p with websockets.
Contrary to MinoGRPC it doesn't use any locks and uses a 1-level tree to handle messages.
It is at least as performant as the MinoGRPC implementation, and works with d-voting.
Co-authored-by: Zach Xion XioZ@users.noreply.github.com
@ineiti ineiti force-pushed the minows branch 13 times, most recently from 2e19446 to eb6b928 Compare July 5, 2024 08:50
@ineiti ineiti force-pushed the minows branch 3 times, most recently from 057263b to 85617df Compare July 5, 2024 09:36
@ineiti
Copy link
Member Author

ineiti commented Jul 5, 2024

dela is now based on go 1.21. Is it possible to upgrade this PR to align it to 1.21 as well ?

Good point. I'll try to rebase our dela fork on the dedis dela, and see if things break too hard :)

Great - 1.21 or the updates of the libp2p library triggers a Heisenbug. I hate it. And it doesn't even tell me where the bug is. Just something breaks.

@ineiti ineiti force-pushed the minows branch 9 times, most recently from 3eaef28 to 6653054 Compare July 5, 2024 13:21
Copy link
Collaborator

@pierluca pierluca left a comment

Choose a reason for hiding this comment

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

Finally finished the review.
I think some parts will be massively simplified by adopting serde.

@ineiti do you have any spare cycles for this or should DEDIS look into it ?

mino/minogrpc/controller/mod_test.go Outdated Show resolved Hide resolved
mino/minows/address.go Outdated Show resolved Hide resolved
mino/minows/address.go Show resolved Hide resolved
mino/minows/rpc.go Outdated Show resolved Hide resolved
mino/minows/rpc.go Outdated Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

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

here as well I'd try to get rid of gob and use serde, which can be easily injected wherever needed.

Comment on lines 154 to 175
src, err := p.myAddr.MarshalText()
if err != nil {
return xerrors.Errorf("could not marshal address: %v", err)
}
payload, err := msg.Serialize(p.rpc.context)
if err != nil {
return xerrors.Errorf("could not serialize message: %v", err)
}
dest, err := addr.MarshalText()
if err != nil {
return xerrors.Errorf("could not marshal address: %v", err)
}

// Send to orchestrator to relay to the destination participant
forward := Forward{
Packet: Packet{Source: src, Payload: payload},
Destination: dest,
}
err = p.out.Encode(&forward)
if err != nil {
return xerrors.Errorf("could not encode packet: %v", err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

this would be so much simpler with serde, and not mixed with the session code.

mino/minows/session.go Outdated Show resolved Hide resolved
Comment on lines 57 to 168
encoder, ok := o.outs[unwrapped.identity]
if !ok {
return xerrors.Errorf("%v: %v", ErrNotPlayer, addr)
}
src, err := o.myAddr.MarshalText()
if err != nil {
return xerrors.Errorf("could not marshal address: %v", err)
}
payload, err := msg.Serialize(o.rpc.context)
if err != nil {
return xerrors.Errorf("could not serialize message: %v", err)
}

err = encoder.Encode(&Packet{Source: src, Payload: payload})
if err != nil {
return xerrors.Errorf("could not encode packet: %v", err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

this would be so much simpler with serde, and not mixed with the session code.

mino/minows/session.go Show resolved Hide resolved
@ineiti
Copy link
Member Author

ineiti commented Aug 12, 2024

Great - 1.21 or the updates of the libp2p library triggers a Heisenbug. I hate it. And it doesn't even tell me where the bug is. Just something breaks.

OK, all should be good now, libp2p had a bug - will test this:

libp2p/go-libp2p#2867

@ineiti
Copy link
Member Author

ineiti commented Aug 14, 2024

Great - 1.21 or the updates of the libp2p library triggers a Heisenbug. I hate it. And it doesn't even tell me where the bug is. Just something breaks.

OK, all should be good now, libp2p had a bug - will test this:

libp2p/go-libp2p#2867

Auto-congratulation: this actually did the trick...

@ineiti ineiti force-pushed the minows branch 7 times, most recently from 8054787 to 16eadf9 Compare August 14, 2024 13:03
@ineiti
Copy link
Member Author

ineiti commented Aug 15, 2024

OK, this is my proposal for answering (most) of @pierluca 's comments:

  • small things implemented (don't export packet, avoid extensive indentation)
  • made the session.go simpler by merging orchestrator and participant into messageHandler
  • still not using serde :) But:
    • I'll need one gob anyway, to correctly pass the packet from serde.
    • messageHandler reduces further the encode/decode blocks
    • forward doesn't exist anymore, it's only packet now

The current PR has been added with some commits for the different things I did. For the final PR I'll merge them all into @Pierluca's comments.

Copy link
Collaborator

@pierluca pierluca left a comment

Choose a reason for hiding this comment

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

Looks much better to me.
I'm not 100% sure I follow why gob is necessary, but at this point it's highly maintainable and that's what matters ! 👍

@ineiti
Copy link
Member Author

ineiti commented Aug 15, 2024

Looks much better to me. I'm not 100% sure I follow why gob is necessary, but at this point it's highly maintainable and that's what matters ! 👍

At one point you need to encode the size of the message, so you know at the other end how many packets you need to read. In the minogrpc code, this is done by Google's grpc module. So the best one could do is to reduce the packet structure to Message []byte. Or you do it manually like it has been done in onet by first sending a 64-bit size field, followed by the raw bytes.

Here I cheat a bit by adding two other fields (one optional), so I don't have to wrap my head around how to implement the json-encoder/decoder.

- Adding new version of libp2p
- Re-enabling failing test and remove goverall
- Use peer.ID.Validate
- Don't export Packet and Forward
- Merging participant and orchestrator
@ineiti ineiti merged commit 8b3e267 into main Aug 19, 2024
5 checks passed
@ineiti ineiti deleted the minows branch August 19, 2024 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants