Skip to content

Commit

Permalink
Broadcast sign power (#4683)
Browse files Browse the repository at this point in the history
  • Loading branch information
Frozen authored Jul 23, 2024
1 parent 900529d commit 0e74201
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 174 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,6 @@ debug_external: clean

build_localnet_validator:
bash test/build-localnet-validator.sh

generate:
bash ./scripts/gogenerate.sh
413 changes: 270 additions & 143 deletions api/proto/message/message.pb.go

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions api/proto/message/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum MessageType {
DRAND_INIT = 10 [deprecated=true];
DRAND_COMMIT = 11 [deprecated=true];
LOTTERY_REQUEST = 12 [deprecated=true]; // it should be either ENTER or GETPLAYERS but it will be removed later.
LAST_SIGN_POWER = 13;
}

// This is universal message for all communication protocols.
Expand All @@ -47,6 +48,7 @@ message Message {
ViewChangeRequest viewchange = 7;
// Refactor this later after demo.
LotteryRequest lottery_request = 8 [deprecated=true];
LastSignPowerRequest last_sign_power = 9;
}
}

Expand Down Expand Up @@ -98,6 +100,14 @@ message DrandRequest {
bytes payload = 4 [deprecated=true];
}

message LastSignPowerRequest {
int64 prepare = 1;
int64 commit = 2;
int64 change = 3;
bytes sender_pubkey = 4;
uint32 shard_id = 5;
}

message ViewChangeRequest {
uint64 view_id = 1;
uint64 block_num = 2;
Expand Down
15 changes: 15 additions & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ type Consensus struct {
// Both flags only for initialization state.
start bool
isInitialLeader bool

// value receives from
lastKnownSignPower int64
}

// Blockchain returns the blockchain.
Expand Down Expand Up @@ -399,6 +402,18 @@ func (consensus *Consensus) InitConsensusWithValidators() (err error) {
return nil
}

func (consensus *Consensus) SetLastKnownSignPower(i int64) {
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
consensus.lastKnownSignPower = i
}

func (consensus *Consensus) GetLastKnownSignPower() int64 {
consensus.mutex.RLock()
defer consensus.mutex.RUnlock()
return consensus.lastKnownSignPower
}

type downloadAsync struct {
}

Expand Down
46 changes: 46 additions & 0 deletions consensus/consensus_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ethereum/go-ethereum/common"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/quorum"
Expand All @@ -17,8 +18,10 @@ import (
bls_cosi "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/internal/chain"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/shard/committee"
"github.com/harmony-one/harmony/webhooks"
Expand Down Expand Up @@ -153,13 +156,56 @@ func (consensus *Consensus) updateBitmaps() {

}

func (consensus *Consensus) sendLastSignPower() {
if consensus.isLeader() {
k, err := consensus.getLeaderPrivateKey(consensus.LeaderPubKey.Object)
if err != nil {
consensus.getLogger().Err(err).Msg("Leader not found in the committee")
return
}
comm, _ := consensus.decider.CurrentTotalPower(quorum.Commit)
prep, _ := consensus.decider.CurrentTotalPower(quorum.Prepare)
view, _ := consensus.decider.CurrentTotalPower(quorum.ViewChange)
msg := &msg_pb.Message{
ServiceType: msg_pb.ServiceType_CONSENSUS,
Type: msg_pb.MessageType_LAST_SIGN_POWER,
Request: &msg_pb.Message_LastSignPower{
LastSignPower: &msg_pb.LastSignPowerRequest{
Prepare: getOrZero(prep),
Commit: getOrZero(comm),
Change: getOrZero(view),
SenderPubkey: k.Pub.Bytes[:],
ShardId: consensus.ShardID,
},
},
}
marshaledMessage, err := consensus.signAndMarshalConsensusMessage(msg, k.Pri)
if err != nil {
consensus.getLogger().Err(err).
Msg("[constructNewViewMessage] failed to sign and marshal the new view message")
return
}
msgToSend := proto.ConstructConsensusMessage(marshaledMessage)
if err := consensus.msgSender.SendWithoutRetry(
[]nodeconfig.GroupID{
nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID))},
p2p.ConstructMessage(msgToSend),
); err != nil {
consensus.getLogger().Err(err).
Msg("[LastSignPower] could not send out the ViewChange message")
}
}
}

// ResetState resets the state of the consensus
func (consensus *Consensus) resetState() {
consensus.switchPhase("ResetState", FBFTAnnounce)

consensus.blockHash = [32]byte{}
consensus.block = []byte{}
consensus.decider.ResetPrepareAndCommitVotes()
consensus.sendLastSignPower()

if consensus.prepareBitmap != nil {
consensus.prepareBitmap.Clear()
}
Expand Down
10 changes: 10 additions & 0 deletions consensus/consensus_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
vrf_bls "github.com/harmony-one/harmony/crypto/vrf/bls"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/vdf/src/vdf_go"
Expand Down Expand Up @@ -90,6 +91,8 @@ func (consensus *Consensus) HandleMessageUpdate(ctx context.Context, peer libp2p
case t == msg_pb.MessageType_NEWVIEW:
members := consensus.decider.Participants()
fbftMsg, err = ParseNewViewMessage(msg, members)
case t == msg_pb.MessageType_LAST_SIGN_POWER:
return nil
default:
fbftMsg, err = consensus.parseFBFTMessage(msg)
}
Expand Down Expand Up @@ -971,3 +974,10 @@ func (consensus *Consensus) DeleteMessagesLessThan(number uint64) {
defer consensus.mutex.Unlock()
consensus.fBFTLog.deleteMessagesLessThan(number)
}

func getOrZero(n *numeric.Dec) int64 {
if n == nil {
return 0
}
return (*n).Mul(numeric.NewDec(100)).TruncateInt64()
}
1 change: 1 addition & 0 deletions consensus/fbft_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type FBFTMessage struct {
M3AggSig *bls_core.Sign
M3Bitmap *bls_cosi.Mask
Verified bool
LastVotePower int64
}

func (m *FBFTMessage) Hash() []byte {
Expand Down
26 changes: 2 additions & 24 deletions node/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package node

import (
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/consensus/votepower"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/eth/rpc"
"github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/internal/tikv"
Expand Down Expand Up @@ -181,27 +179,7 @@ func (node *Node) GetLastSigningPower() (float64, error) {
}

func (node *Node) GetLastSigningPower2() (float64, error) {
bc := node.Consensus.Blockchain()
cur := bc.CurrentBlock()
ss, err := bc.ReadShardState(cur.Epoch())
if err != nil {
return 0, err
}
roster, err := votepower.Compute(&ss.Shards[bc.ShardID()], cur.Epoch())
if err != nil {
return 0, err
}
blsPubKeys, err := ss.Shards[bc.ShardID()].BLSPublicKeys()
if err != nil {
return 0, err
}

mask := bls.NewMask(blsPubKeys)
err = mask.SetMask(cur.Header().LastCommitBitmap())
if err != nil {
return 0, err
}
power := roster.VotePowerByMask(mask)
round := float64(power.MulInt64(10000).RoundInt64()) / 10000
p := node.Consensus.GetLastKnownSignPower()
round := float64(p) / 10000
return round, nil
}
28 changes: 21 additions & 7 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,14 @@ func (node *Node) validateNodeMessage(ctx context.Context, payload []byte) (
return payload[p2pNodeMsgPrefixSize:], msgType, nil
}

type ignore = bool

// validateShardBoundMessage validate consensus message
// validate shardID
// validate public key size
// verify message signature
func validateShardBoundMessage(consensus *consensus.Consensus, peer libp2p_peer.ID, nodeConfig *nodeconfig.ConfigType, payload []byte,
) (*msg_pb.Message, *bls.SerializedPublicKey, bool, error) {
) (*msg_pb.Message, *bls.SerializedPublicKey, ignore, error) {
var (
m msg_pb.Message
//consensus = registry.GetConsensus()
Expand Down Expand Up @@ -528,11 +530,16 @@ func validateShardBoundMessage(consensus *consensus.Consensus, peer libp2p_peer.
}
}

maybeCon, maybeVC := m.GetConsensus(), m.GetViewchange()
senderKey := []byte{}
senderBitmap := []byte{}
var (
maybeCon = m.GetConsensus()
maybeVC = m.GetViewchange()
maybeSP = m.GetLastSignPower()
senderKey []byte
senderBitmap []byte
)

if maybeCon != nil {
switch {
case maybeCon != nil:
if maybeCon.ShardId != consensus.ShardID {
nodeConsensusMessageCounterVec.With(prometheus.Labels{"type": "invalid_shard"}).Inc()
return nil, nil, true, errors.WithStack(errWrongShardID)
Expand All @@ -546,7 +553,7 @@ func validateShardBoundMessage(consensus *consensus.Consensus, peer libp2p_peer.
if maybeCon.ViewId+5 < consensus.GetCurBlockViewID() {
return nil, nil, true, errors.WithStack(errViewIDTooOld)
}
} else if maybeVC != nil {
case maybeVC != nil:
if maybeVC.ShardId != consensus.ShardID {
nodeConsensusMessageCounterVec.With(prometheus.Labels{"type": "invalid_shard"}).Inc()
return nil, nil, true, errors.WithStack(errWrongShardID)
Expand All @@ -556,7 +563,14 @@ func validateShardBoundMessage(consensus *consensus.Consensus, peer libp2p_peer.
if maybeVC.ViewId+5 < consensus.GetViewChangingID() {
return nil, nil, true, errors.WithStack(errViewIDTooOld)
}
} else {
case maybeSP != nil:
if maybeSP.ShardId != consensus.ShardID {
nodeConsensusMessageCounterVec.With(prometheus.Labels{"type": "invalid_shard"}).Inc()
return nil, nil, true, errors.WithStack(errWrongShardID)
}
senderKey = maybeSP.SenderPubkey
consensus.SetLastKnownSignPower(maybeSP.Commit)
default:
nodeConsensusMessageCounterVec.With(prometheus.Labels{"type": "invalid"}).Inc()
return nil, nil, true, errors.WithStack(errNoSenderPubKey)
}
Expand Down

0 comments on commit 0e74201

Please sign in to comment.