convert drand proto to message protocol

pull/569/head
Minh Doan 6 years ago committed by Minh Doan
parent d5bfa934f6
commit 51f04a1c43
  1. 11
      drand/drand.go
  2. 22
      drand/drand_leader.go
  3. 19
      drand/drand_leader_msg.go
  4. 12
      drand/drand_leader_msg_test.go
  5. 20
      drand/drand_test.go
  6. 21
      drand/drand_validator.go
  7. 24
      drand/drand_validator_msg.go
  8. 10
      drand/drand_validator_msg_test.go

@ -9,7 +9,7 @@ import (
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
drand_proto "github.com/harmony-one/harmony/api/drand" msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/crypto/vrf" "github.com/harmony-one/harmony/crypto/vrf"
@ -149,9 +149,8 @@ func (dRand *DRand) AddPeers(peers []*p2p.Peer) int {
} }
// Sign on the drand message signature field. // Sign on the drand message signature field.
func (dRand *DRand) signDRandMessage(message *drand_proto.Message) error { func (dRand *DRand) signDRandMessage(message *msg_pb.Message) error {
message.Signature = nil message.Signature = nil
// TODO: use custom serialization method rather than protobuf
marshaledMessage, err := protobuf.Marshal(message) marshaledMessage, err := protobuf.Marshal(message)
if err != nil { if err != nil {
return err return err
@ -165,7 +164,7 @@ func (dRand *DRand) signDRandMessage(message *drand_proto.Message) error {
} }
// Signs the drand message and returns the marshaled message. // Signs the drand message and returns the marshaled message.
func (dRand *DRand) signAndMarshalDRandMessage(message *drand_proto.Message) ([]byte, error) { func (dRand *DRand) signAndMarshalDRandMessage(message *msg_pb.Message) ([]byte, error) {
err := dRand.signDRandMessage(message) err := dRand.signDRandMessage(message)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@ -199,10 +198,10 @@ func (dRand *DRand) GetValidatorPeers() []p2p.Peer {
} }
// Verify the signature of the message are valid from the signer's public key. // Verify the signature of the message are valid from the signer's public key.
func verifyMessageSig(signerPubKey *bls.PublicKey, message drand_proto.Message) error { func verifyMessageSig(signerPubKey *bls.PublicKey, message *msg_pb.Message) error {
signature := message.Signature signature := message.Signature
message.Signature = nil message.Signature = nil
messageBytes, err := protobuf.Marshal(&message) messageBytes, err := protobuf.Marshal(message)
if err != nil { if err != nil {
return err return err
} }

@ -6,6 +6,7 @@ import (
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
drand_proto "github.com/harmony-one/harmony/api/drand" drand_proto "github.com/harmony-one/harmony/api/drand"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/crypto/vdf" "github.com/harmony-one/harmony/crypto/vdf"
@ -80,15 +81,15 @@ func (dRand *DRand) init(epochBlock *types.Block) {
// ProcessMessageLeader dispatches messages for the leader to corresponding processors. // ProcessMessageLeader dispatches messages for the leader to corresponding processors.
func (dRand *DRand) ProcessMessageLeader(payload []byte) { func (dRand *DRand) ProcessMessageLeader(payload []byte) {
message := drand_proto.Message{} message := &msg_pb.Message{}
err := protobuf.Unmarshal(payload, &message) err := protobuf.Unmarshal(payload, message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand) utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand)
} }
switch message.Type { switch message.Type {
case drand_proto.MessageType_COMMIT: case msg_pb.MessageType_COMMIT:
dRand.processCommitMessage(message) dRand.processCommitMessage(message)
default: default:
utils.GetLogInstance().Error("Unexpected message type", "msgType", message.Type, "dRand", dRand) utils.GetLogInstance().Error("Unexpected message type", "msgType", message.Type, "dRand", dRand)
@ -96,8 +97,8 @@ func (dRand *DRand) ProcessMessageLeader(payload []byte) {
} }
// ProcessMessageValidator dispatches validator's consensus message. // ProcessMessageValidator dispatches validator's consensus message.
func (dRand *DRand) processCommitMessage(message drand_proto.Message) { func (dRand *DRand) processCommitMessage(message *msg_pb.Message) {
if message.Type != drand_proto.MessageType_COMMIT { if message.Type != msg_pb.MessageType_DRAND_COMMIT {
utils.GetLogInstance().Error("Wrong message type received", "expected", drand_proto.MessageType_COMMIT, "got", message.Type) utils.GetLogInstance().Error("Wrong message type received", "expected", drand_proto.MessageType_COMMIT, "got", message.Type)
return return
} }
@ -105,7 +106,8 @@ func (dRand *DRand) processCommitMessage(message drand_proto.Message) {
dRand.mutex.Lock() dRand.mutex.Lock()
defer dRand.mutex.Unlock() defer dRand.mutex.Unlock()
validatorID := message.SenderId drandMsg := message.GetDrand()
validatorID := drandMsg.SenderId
validatorPeer := dRand.getValidatorPeerByID(validatorID) validatorPeer := dRand.getValidatorPeerByID(validatorID)
vrfs := dRand.vrfs vrfs := dRand.vrfs
if len((*vrfs)) >= ((len(dRand.PublicKeys))/3 + 1) { if len((*vrfs)) >= ((len(dRand.PublicKeys))/3 + 1) {
@ -120,9 +122,9 @@ func (dRand *DRand) processCommitMessage(message drand_proto.Message) {
return return
} }
rand := message.Payload[:32] rand := drandMsg.Payload[:32]
proof := message.Payload[32 : len(message.Payload)-64] proof := drandMsg.Payload[32 : len(drandMsg.Payload)-64]
pubKeyBytes := message.Payload[len(message.Payload)-64:] pubKeyBytes := drandMsg.Payload[len(drandMsg.Payload)-64:]
_, pubKey := p256.GenerateKey() _, pubKey := p256.GenerateKey()
pubKey.Deserialize(pubKeyBytes) pubKey.Deserialize(pubKeyBytes)
@ -135,7 +137,7 @@ func (dRand *DRand) processCommitMessage(message drand_proto.Message) {
utils.GetLogInstance().Debug("Received new VRF commit", "numReceivedSoFar", len((*vrfs)), "validatorID", validatorID, "PublicKeys", len(dRand.PublicKeys)) utils.GetLogInstance().Debug("Received new VRF commit", "numReceivedSoFar", len((*vrfs)), "validatorID", validatorID, "PublicKeys", len(dRand.PublicKeys))
(*vrfs)[validatorID] = message.Payload (*vrfs)[validatorID] = drandMsg.Payload
dRand.bitmap.SetKey(validatorPeer.ConsensusPubKey, true) // Set the bitmap indicating that this validator signed. dRand.bitmap.SetKey(validatorPeer.ConsensusPubKey, true) // Set the bitmap indicating that this validator signed.
if len((*vrfs)) >= ((len(dRand.PublicKeys))/3 + 1) { if len((*vrfs)) >= ((len(dRand.PublicKeys))/3 + 1) {

@ -1,20 +1,27 @@
package drand package drand
import ( import (
drand_proto "github.com/harmony-one/harmony/api/drand"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
) )
// Constructs the init message // Constructs the init message
func (dRand *DRand) constructInitMessage() []byte { func (dRand *DRand) constructInitMessage() []byte {
message := drand_proto.Message{} message := &msg_pb.Message{
message.Type = drand_proto.MessageType_INIT ReceiverType: msg_pb.ReceiverType_VALIDATOR,
message.SenderId = dRand.nodeID ServiceType: msg_pb.ServiceType_DRAND,
Type: msg_pb.MessageType_DRAND_INIT,
Request: &msg_pb.Message_Drand{
Drand: &msg_pb.DrandRequest{},
},
}
message.BlockHash = dRand.blockHash[:] drandMsg := message.GetDrand()
drandMsg.SenderId = dRand.nodeID
drandMsg.BlockHash = dRand.blockHash[:]
// Don't need the payload in init message // Don't need the payload in init message
marshaledMessage, err := dRand.signAndMarshalDRandMessage(&message) marshaledMessage, err := dRand.signAndMarshalDRandMessage(message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("Failed to sign and marshal the init message", "error", err) utils.GetLogInstance().Error("Failed to sign and marshal the init message", "error", err)
} }

@ -4,8 +4,8 @@ import (
"testing" "testing"
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
drand_proto "github.com/harmony-one/harmony/api/drand"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/p2pimpl" "github.com/harmony-one/harmony/p2p/p2pimpl"
@ -25,8 +25,8 @@ func TestConstructInitMessage(test *testing.T) {
msgPayload, _ := proto.GetDRandMessagePayload(msg) msgPayload, _ := proto.GetDRandMessagePayload(msg)
message := drand_proto.Message{} message := &msg_pb.Message{}
err = protobuf.Unmarshal(msgPayload, &message) err = protobuf.Unmarshal(msgPayload, message)
if err != nil { if err != nil {
test.Error("Error in extracting Init message from payload", err) test.Error("Error in extracting Init message from payload", err)
@ -47,12 +47,10 @@ func TestProcessCommitMessage(test *testing.T) {
msgPayload, _ := proto.GetDRandMessagePayload(msg) msgPayload, _ := proto.GetDRandMessagePayload(msg)
message := drand_proto.Message{} message := &msg_pb.Message{}
err = protobuf.Unmarshal(msgPayload, &message) err = protobuf.Unmarshal(msgPayload, message)
if err != nil { if err != nil {
test.Error("Error in extracting Commit message from payload", err) test.Error("Error in extracting Commit message from payload", err)
} }
dRand.ProcessMessageLeader(msgPayload)
} }

@ -7,7 +7,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
drand_proto "github.com/harmony-one/harmony/api/drand" msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
@ -167,12 +167,20 @@ func TestVerifyMessageSig(test *testing.T) {
test.Fatalf("newhost failure: %v", err) test.Fatalf("newhost failure: %v", err)
} }
dRand := New(host, "0", []p2p.Peer{leader, validator}, leader, nil, true) dRand := New(host, "0", []p2p.Peer{leader, validator}, leader, nil, true)
message := drand_proto.Message{}
message.Type = drand_proto.MessageType_INIT
message.SenderId = dRand.nodeID
message.BlockHash = dRand.blockHash[:] message := &msg_pb.Message{
dRand.signDRandMessage(&message) ReceiverType: msg_pb.ReceiverType_VALIDATOR,
ServiceType: msg_pb.ServiceType_DRAND,
Type: msg_pb.MessageType_DRAND_INIT,
Request: &msg_pb.Message_Drand{
Drand: &msg_pb.DrandRequest{},
},
}
drandMsg := message.GetDrand()
drandMsg.SenderId = dRand.nodeID
drandMsg.BlockHash = dRand.blockHash[:]
dRand.signDRandMessage(message)
if verifyMessageSig(dRand.pubKey, message) != nil { if verifyMessageSig(dRand.pubKey, message) != nil {
test.Error("Failed to verify the signature") test.Error("Failed to verify the signature")

@ -3,6 +3,7 @@ package drand
import ( import (
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
drand_proto "github.com/harmony-one/harmony/api/drand" drand_proto "github.com/harmony-one/harmony/api/drand"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/host" "github.com/harmony-one/harmony/p2p/host"
@ -10,31 +11,28 @@ import (
// ProcessMessageValidator dispatches messages for the validator to corresponding processors. // ProcessMessageValidator dispatches messages for the validator to corresponding processors.
func (dRand *DRand) ProcessMessageValidator(payload []byte) { func (dRand *DRand) ProcessMessageValidator(payload []byte) {
message := drand_proto.Message{} message := &msg_pb.Message{}
err := protobuf.Unmarshal(payload, &message) err := protobuf.Unmarshal(payload, message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand) utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand)
} }
switch message.Type { if message.Type == msg_pb.MessageType_DRAND_INIT {
case drand_proto.MessageType_INIT:
dRand.processInitMessage(message) dRand.processInitMessage(message)
case drand_proto.MessageType_COMMIT: } else {
// do nothing on the COMMIT message, as it is intended to send to leader
default:
utils.GetLogInstance().Error("Unexpected message type", "msgType", message.Type, "dRand", dRand) utils.GetLogInstance().Error("Unexpected message type", "msgType", message.Type, "dRand", dRand)
} }
} }
// ProcessMessageValidator dispatches validator's consensus message. // ProcessMessageValidator dispatches validator's consensus message.
func (dRand *DRand) processInitMessage(message drand_proto.Message) { func (dRand *DRand) processInitMessage(message *msg_pb.Message) {
if message.Type != drand_proto.MessageType_INIT { if message.Type != msg_pb.MessageType_DRAND_INIT {
utils.GetLogInstance().Error("Wrong message type received", "expected", drand_proto.MessageType_INIT, "got", message.Type) utils.GetLogInstance().Error("Wrong message type received", "expected", drand_proto.MessageType_COMMIT, "got", message.Type)
return return
} }
blockHash := message.BlockHash drandMsg := message.GetDrand()
// Verify message signature // Verify message signature
err := verifyMessageSig(dRand.leader.ConsensusPubKey, message) err := verifyMessageSig(dRand.leader.ConsensusPubKey, message)
@ -45,6 +43,7 @@ func (dRand *DRand) processInitMessage(message drand_proto.Message) {
utils.GetLogInstance().Debug("[DRG] verify the message signature Succeeded") utils.GetLogInstance().Debug("[DRG] verify the message signature Succeeded")
// TODO: check the blockHash is the block hash of last block of last epoch. // TODO: check the blockHash is the block hash of last block of last epoch.
blockHash := drandMsg.BlockHash
copy(dRand.blockHash[:], blockHash[:]) copy(dRand.blockHash[:], blockHash[:])
rand, proof := dRand.vrf(dRand.blockHash) rand, proof := dRand.vrf(dRand.blockHash)

@ -1,23 +1,31 @@
package drand package drand
import ( import (
drand_proto "github.com/harmony-one/harmony/api/drand"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
) )
// Constructs the init message // Constructs the init message
func (dRand *DRand) constructCommitMessage(vrf [32]byte, proof []byte) []byte { func (dRand *DRand) constructCommitMessage(vrf [32]byte, proof []byte) []byte {
message := drand_proto.Message{} message := &msg_pb.Message{
message.Type = drand_proto.MessageType_COMMIT ReceiverType: msg_pb.ReceiverType_LEADER,
message.SenderId = dRand.nodeID ServiceType: msg_pb.ServiceType_DRAND,
Type: msg_pb.MessageType_DRAND_COMMIT,
Request: &msg_pb.Message_Drand{
Drand: &msg_pb.DrandRequest{},
},
}
message.BlockHash = dRand.blockHash[:] drandMsg := message.GetDrand()
message.Payload = append(vrf[:], proof...) drandMsg.SenderId = dRand.nodeID
drandMsg.BlockHash = dRand.blockHash[:]
drandMsg.BlockHash = dRand.blockHash[:]
drandMsg.Payload = append(vrf[:], proof...)
// Adding the public key into payload so leader can verify the vrf // Adding the public key into payload so leader can verify the vrf
// TODO: change the curve to follow the same curve with consensus, so the public key doesn't need to be attached. // TODO: change the curve to follow the same curve with consensus, so the public key doesn't need to be attached.
message.Payload = append(message.Payload, (*dRand.vrfPubKey).Serialize()...) drandMsg.Payload = append(drandMsg.Payload, (*dRand.vrfPubKey).Serialize()...)
marshaledMessage, err := dRand.signAndMarshalDRandMessage(&message) marshaledMessage, err := dRand.signAndMarshalDRandMessage(message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("Failed to sign and marshal the commit message", "error", err) utils.GetLogInstance().Error("Failed to sign and marshal the commit message", "error", err)
} }

@ -4,8 +4,8 @@ import (
"testing" "testing"
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
drand_proto "github.com/harmony-one/harmony/api/drand"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/p2pimpl" "github.com/harmony-one/harmony/p2p/p2pimpl"
@ -24,8 +24,8 @@ func TestConstructCommitMessage(test *testing.T) {
msg := dRand.constructCommitMessage([32]byte{}, []byte{}) msg := dRand.constructCommitMessage([32]byte{}, []byte{})
msgPayload, _ := proto.GetDRandMessagePayload(msg) msgPayload, _ := proto.GetDRandMessagePayload(msg)
message := drand_proto.Message{} message := &msg_pb.Message{}
err = protobuf.Unmarshal(msgPayload, &message) err = protobuf.Unmarshal(msgPayload, message)
if err != nil { if err != nil {
test.Error("Error in extracting Commit message from payload", err) test.Error("Error in extracting Commit message from payload", err)
@ -46,8 +46,8 @@ func TestProcessInitMessage(test *testing.T) {
msgPayload, _ := proto.GetDRandMessagePayload(msg) msgPayload, _ := proto.GetDRandMessagePayload(msg)
message := drand_proto.Message{} message := &msg_pb.Message{}
err = protobuf.Unmarshal(msgPayload, &message) err = protobuf.Unmarshal(msgPayload, message)
if err != nil { if err != nil {
test.Error("Error in extracting Init message from payload", err) test.Error("Error in extracting Init message from payload", err)

Loading…
Cancel
Save