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

Adds a first simple DKG implementations #41

Merged
merged 24 commits into from
May 14, 2020
Merged

Adds a first simple DKG implementations #41

merged 24 commits into from
May 14, 2020

Conversation

nkcr
Copy link
Contributor

@nkcr nkcr commented Apr 27, 2020

Adds a first DKG/Pedersen implementation and improves minogrpc.

  • Defines a DKG interface in dkg/
  • Implements Pedersen in dkg/pedersen
  • Updates minogrpc to only use Enveloppe
  • Updates and fixes the tree routing protocol
  • Fixes some race conditions with minogrpc
  • Updates minogrpc/traffic to display a more accurate representation

More extensive testing will follow.

@nkcr nkcr self-assigned this Apr 27, 2020
@nkcr nkcr marked this pull request as draft April 27, 2020 14:04
@nkcr nkcr marked this pull request as ready for review May 12, 2020 09:35
@nkcr nkcr requested a review from Gilthoniel May 12, 2020 09:39
@nkcr
Copy link
Contributor Author

nkcr commented May 12, 2020

For the record, here is an update of the networking flow diagram for the TestRPC_MultipleRingMesh_Stream test where messages flow as:

CLIENT -> NODE1 -> NODE2 -> ... NODE9 -> CLIENT

tree height is set to 4.

graph

@nkcr nkcr added mod/mino About the Mino module R4M 🚀 The PR is ready to be reviewed and merged labels May 12, 2020
dkg/mod.go Outdated
)

// Factory defines the DKG Starter's factory
type Factory interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

I usually defines a factory if I have to decode a Protobuf message into its implementation. In that case, using a factory is very limiting in the way you instantiate the DKG. For instance, if you want a dummy one that won't need keys, you still have to provide something (sure, that can be nil, but it's for the example). It's ok if each implementation provide its constructor like skipchain or byzcoin is doing.

dkg/mod.go Outdated
}

// Starter defines the primitive to start a DKG protocol
type Starter interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

For Blockchain and Ledger, I used this abstraction of an actor so that the main interface is called DKG and you have a Listen function that will create a DKGActor. If that makes sense to you, I would prefer keeping the same logic to be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm always for keeping consistency. And yes, it makes sense!
Like so?

// DKG defines the primitive to start a DKG protocol
type DKG interface {
	Listen(players mino.Players, threshold uint32) (DKG, error)
}

// Actor defines the primitives to use a DKG protocol
type Actor interface {
	Encrypt(message []byte) (K, C kyber.Point, remainder []byte, err error)
	Decrypt(K, C kyber.Point) ([]byte, error)
	Reshare() error
}

type Handler struct {
mino.UnsupportedHandler
sync.RWMutex
af mino.AddressFactory
Copy link
Contributor

Choose a reason for hiding this comment

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

addressFactory for a struct attribute.

}
h.RUnlock()

errs := out.Send(decryptReply, from)
Copy link
Contributor

Choose a reason for hiding this comment

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

err = <-out.Send(...) as you're listening to one error anyway, so either it's nil or something went wrong.

// received our start signal. In this case we will collect the Deals
// while waiting for the start signal.
deals := []*Deal{msg}
for {
Copy link
Contributor

Choose a reason for hiding this comment

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

You're essentially doing the same thing so you can probably for loop the whole select and remove this one.

Copy link
Contributor

Choose a reason for hiding this comment

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

You just need to handle the Decrypt if it hasn't started but you have to do it anyway.

@@ -143,3 +147,10 @@ func (m Minogrpc) MakeRPC(name string, h mino.Handler) (mino.RPC, error) {

return rpc, nil
}

// AddNeighbours fills the neighbours map of the server
func (m Minogrpc) AddNeighbours(minoGrpcs ...*Minogrpc) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll have to change this anyway when going to real world, so maybe it's the right time to make an API to pass the certificate?

clientStream.Send(&OverlayMsg{Message: overlayMsg.Message})
clientStream.Send(&Envelope{
From: o.addr.String(),
PhysicalFrom: o.addr.String(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use something more meaningful like LastHop or Relay. Now, is it really necessary ? You're supposed to know the mesh.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMO it can't be more explicit than that. LastHop is already speaking at a logical level, where here I want to know who sent me this message, regardless its content.
It is hard to know for a node who sent a message because the listen function receive messages from the orchestrator and the children of a node.

Message: envelope.Message,
})

// TODO: think how we can make all the node set the routing then start
Copy link
Contributor

Choose a reason for hiding this comment

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

It should be impossible to receive a message before the routing message, because the relay will open the connection and then directly send the routing message before relaying anything.

@@ -400,6 +401,15 @@ func (srv *Server) Serve() error {
return nil
}

func (srv *Server) addNeighbour(servers ...*Server) {
for _, server := range servers {
srv.neighbours[server.addr.String()] = Peer{
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned earlier, at some point you will need to be able to extract the server certificate (to a file for instance), transmit it to a peer and then populate the peer server with it. From what I see, it shouldn't hard to adapt but as soon as it's done, you won't get more surprises.

return xerrors.Errorf("couldn't marshal envelope: %v", err)
player, ok := playerItf.(overlayStream)
if !ok {
fabric.Logger.Fatal().Msg("not ok")
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't believe I'm the one saying an error message is too short ! But it should slightly more detailed. Why would that happen ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh, you're so right! I forgot to update this one.... : /

@Gilthoniel
Copy link
Contributor

When you implement the tests, if you're using minogrpc, it would be nice to make it real in the sense that you don't have access to other servers. I do that with minoch because that's the purpose but a few integration tests with minogrpc are definitely nice.

@nkcr
Copy link
Contributor Author

nkcr commented May 13, 2020

it would be nice to make it real in the sense that you don't have access to other servers

Yes that's is already the case in the server_test.go except when I can specify a dynamic number of servers (which happens once).

@nkcr nkcr requested a review from Gilthoniel May 14, 2020 07:37
@Gilthoniel Gilthoniel merged commit 7ea2c0c into master May 14, 2020
@Gilthoniel Gilthoniel deleted the dkg-pedersen branch May 14, 2020 13:11
bbjubjub2494 pushed a commit to bbjubjub2494/dela that referenced this pull request Aug 3, 2024
Adds a first simple DKG implementations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mod/mino About the Mino module R4M 🚀 The PR is ready to be reviewed and merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants