diff --git a/consensus/consensus.go b/consensus/consensus.go index b62a25077..126490f09 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -121,6 +121,14 @@ type Consensus struct { BlockPeriod time.Duration // The time due for next block proposal NextBlockDue time.Time + // Temporary flag to control whether multi-sig signing is enabled + MultiSig bool + + // TODO (leo): an new metrics system to keep track of the consensus/viewchange + // finality of previous consensus in the unit of milliseconds + finality int64 + // finalityCounter keep tracks of the finality time + finalityCounter int64 } // SetCommitDelay sets the commit message delay. If set to non-zero, diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 044985471..447b6367a 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -535,3 +535,19 @@ func (consensus *Consensus) SetCurViewID(viewID uint64) { func (consensus *Consensus) SetViewChangingID(viewID uint64) { consensus.current.SetViewChangingID(viewID) } + +// StartFinalityCount set the finality counter to current time +func (consensus *Consensus) StartFinalityCount() { + consensus.finalityCounter = time.Now().UnixNano() +} + +// FinishFinalityCount calculate the current finality +func (consensus *Consensus) FinishFinalityCount() { + d := time.Now().UnixNano() + consensus.finality = (d - consensus.finalityCounter) / 1000000 +} + +// GetFinality returns the finality time in milliseconds of previous consensus +func (consensus *Consensus) GetFinality() int64 { + return consensus.finality +} diff --git a/consensus/debug.go b/consensus/debug.go index 4045bd90c..b4a23ccb3 100644 --- a/consensus/debug.go +++ b/consensus/debug.go @@ -19,3 +19,8 @@ func (c *Consensus) GetCurViewID() uint64 { func (c *Consensus) GetViewChangingID() uint64 { return c.current.GetViewChangingID() } + +// GetBlockNum return the current blockNum of the consensus struct +func (c *Consensus) GetBlockNum() uint64 { + return c.blockNum +} diff --git a/consensus/validator.go b/consensus/validator.go index fde5ab253..97ae6d21c 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -54,6 +54,7 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { } return } + consensus.StartFinalityCount() consensus.prepare() } diff --git a/go.mod b/go.mod index 6fc8a106a..4cd9a9795 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/common v0.4.1 // indirect github.com/prometheus/procfs v0.0.3 // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 github.com/rjeczalik/notify v0.9.2 github.com/rs/cors v1.7.0 // indirect github.com/rs/zerolog v1.18.0 diff --git a/hmy/hmy.go b/hmy/hmy.go index 61c209804..e760f590f 100644 --- a/hmy/hmy.go +++ b/hmy/hmy.go @@ -93,6 +93,8 @@ type NodeAPI interface { ListTopic() []string ListBlockedPeer() []peer.ID + GetConsensusInternal() commonRPC.ConsensusInternal + // debug API GetConsensusMode() string GetConsensusPhase() string @@ -176,6 +178,8 @@ func (hmy *Harmony) GetNodeMetadata() commonRPC.NodeMetadata { c := commonRPC.C{} c.TotalKnownPeers, c.Connected, c.NotConnected = hmy.NodeAPI.PeerConnectivity() + consensusInternal := hmy.NodeAPI.GetConsensusInternal() + return commonRPC.NodeMetadata{ BLSPublicKey: blsKeys, Version: nodeconfig.GetVersion(), @@ -190,6 +194,7 @@ func (hmy *Harmony) GetNodeMetadata() commonRPC.NodeMetadata { Archival: cfg.GetArchival(), NodeBootTime: hmy.NodeAPI.GetNodeBootTime(), PeerID: nodeconfig.GetPeerID(), + Consensus: consensusInternal, C: c, } } diff --git a/node/api.go b/node/api.go index e01d2146b..a298f0f3e 100644 --- a/node/api.go +++ b/node/api.go @@ -6,6 +6,7 @@ import ( "github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/rosetta" hmy_rpc "github.com/harmony-one/harmony/rpc" + rpc_common "github.com/harmony-one/harmony/rpc/common" "github.com/harmony-one/harmony/rpc/filters" "github.com/libp2p/go-libp2p-core/peer" ) @@ -126,3 +127,20 @@ func (node *Node) GetConsensusViewChangingID() uint64 { func (node *Node) GetConsensusCurViewID() uint64 { return node.Consensus.GetCurViewID() } + +// GetConsensusBlockNum returns the current block number of the consensus +func (node *Node) GetConsensusBlockNum() uint64 { + return node.Consensus.GetBlockNum() +} + +// GetConsensusInternal returns consensus internal data +func (node *Node) GetConsensusInternal() rpc_common.ConsensusInternal { + return rpc_common.ConsensusInternal{ + ViewID: node.GetConsensusCurViewID(), + ViewChangeID: node.GetConsensusViewChangingID(), + Mode: node.GetConsensusMode(), + Phase: node.GetConsensusPhase(), + BlockNum: node.GetConsensusBlockNum(), + ConsensusTime: node.Consensus.GetFinality(), + } +} diff --git a/node/node.go b/node/node.go index 721e76838..930064680 100644 --- a/node/node.go +++ b/node/node.go @@ -43,6 +43,8 @@ import ( libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/pkg/errors" "golang.org/x/sync/semaphore" + + "github.com/rcrowley/go-metrics" ) const ( @@ -119,6 +121,9 @@ type Node struct { deciderCache *lru.Cache committeeCache *lru.Cache + + Metrics metrics.Registry + // metrics of p2p messages NumP2PMessages uint32 NumTotalMessages uint32 diff --git a/node/node_handler.go b/node/node_handler.go index bf03e8751..4013bc1a4 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -369,6 +369,8 @@ func (node *Node) PostConsensusProcessing( Str("hash", newBlock.Header().Hash().Hex()). Msg("Added New Block to Blockchain!!!") + node.Consensus.FinishFinalityCount() + if node.Consensus.IsLeader() { if node.NodeConfig.ShardID == shard.BeaconChainShardID { node.BroadcastNewBlock(newBlock) diff --git a/node/node_newblock.go b/node/node_newblock.go index 467479f6d..c0fe1991d 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -47,6 +47,7 @@ func (node *Node) WaitForConsensusReadyV2(readySignal chan struct{}, stopChan ch Uint64("blockNum", node.Blockchain().CurrentBlock().NumberU64()+1). Msg("PROPOSING NEW BLOCK ------------------------------------------------") + node.Consensus.StartFinalityCount() newBlock, err := node.proposeNewBlock() if err != nil { utils.Logger().Err(err).Msg("!!!!!!!!!Failed Proposing New Block!!!!!!!!!") diff --git a/rpc/common/types.go b/rpc/common/types.go index 9c91aa176..69e418d02 100644 --- a/rpc/common/types.go +++ b/rpc/common/types.go @@ -37,6 +37,16 @@ type C struct { NotConnected int `json:"not-connected"` } +// ConsensusInternal captures consensus internal data +type ConsensusInternal struct { + ViewID uint64 `json:"viewId"` + ViewChangeID uint64 `json:"viewChangeId"` + Mode string `json:"mode"` + Phase string `json:"phase"` + BlockNum uint64 `json:"blocknum"` + ConsensusTime int64 `json:"finality"` +} + // NodeMetadata captures select metadata of the RPC answering node type NodeMetadata struct { BLSPublicKey []string `json:"blskey"` @@ -52,6 +62,7 @@ type NodeMetadata struct { Archival bool `json:"is-archival"` NodeBootTime int64 `json:"node-unix-start-time"` PeerID peer.ID `json:"peerid"` + Consensus ConsensusInternal `json:"consensus"` C C `json:"p2p-connectivity"` }