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

[Consensus] add hotstuff view to ping route #1462

Merged
merged 1 commit into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ install-tools: crypto/relic/build check-go-version
cd ${GOPATH}; \
GO111MODULE=on go get github.com/golang/protobuf/protoc-gen-go@v1.3.2; \
GO111MODULE=on go get github.com/uber/prototool/cmd/prototool@v1.9.0; \
GO111MODULE=on go get github.com/gogo/protobuf/protoc-gen-gofast; \
GO111MODULE=on go get github.com/vektra/mockery/cmd/mockery@v1.1.2; \
GO111MODULE=on go get github.com/golang/mock/mockgen@v1.3.1; \
GO111MODULE=on go get golang.org/x/tools/cmd/stringer@master;
Expand Down
16 changes: 16 additions & 0 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/onflow/flow-go/admin"
"github.com/onflow/flow-go/cmd/build"
"github.com/onflow/flow-go/consensus/hotstuff/persister"
"github.com/onflow/flow-go/fvm"
"github.com/onflow/flow-go/model/bootstrap"
"github.com/onflow/flow-go/model/flow"
Expand Down Expand Up @@ -173,6 +174,21 @@ func (fnb *FlowNodeBuilder) EnqueueNetworkInit(ctx context.Context) {
},
}

// only consensus roles will need to report hotstuff view
if fnb.BaseConfig.NodeRole == flow.RoleConsensus.String() {
// initialize the persister
persist := persister.New(node.DB, node.RootChainID)

pingProvider.HotstuffViewFun = func() (uint64, error) {
curView, err := persist.GetStarted()
if err != nil {
return 0, err
}

return curView, nil
}
}

libP2PNodeFactory, err := p2p.DefaultLibP2PNodeFactory(ctx,
fnb.Logger.Level(zerolog.ErrorLevel),
fnb.Me.NodeID(),
Expand Down
2 changes: 1 addition & 1 deletion engine/access/ping/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,6 @@ func (e *Engine) pingNode(peer *flow.Identity) {

// if ping succeeded then update the node info metric
if pingErr == nil {
e.metrics.NodeInfo(peer, info, resp.Version, resp.BlockHeight)
e.metrics.NodeInfo(peer, info, resp.Version, resp.BlockHeight, resp.HotstuffView)
}
}
4 changes: 2 additions & 2 deletions integration/localnet/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ init-short-epochs:

.PHONY: start
start:
docker-compose -f docker-compose.metrics.yml up -d --remove-orphans
DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f docker-compose.nodes.yml up --remove-orphans --build -d
Comment on lines -50 to -51
Copy link
Member Author

Choose a reason for hiding this comment

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

This is useful, however, I had to remove it, because the --remove-orphans will stop the containers created by docker-compose -f docker-compose.metrics.yml

docker-compose -f docker-compose.metrics.yml up -d
DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f docker-compose.nodes.yml up --build -d

.PHONY: logs
logs:
Expand Down
4 changes: 2 additions & 2 deletions module/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,6 @@ type PingMetrics interface {
// The nodeInfo provides additional information about the node such as the name of the node operator
NodeReachable(node *flow.Identity, nodeInfo string, rtt time.Duration)

// NodeInfo tracks the software version and sealed height of a node
NodeInfo(node *flow.Identity, nodeInfo string, version string, sealedHeight uint64)
// NodeInfo tracks the software version, sealed height and hotstuff view of a node
NodeInfo(node *flow.Identity, nodeInfo string, version string, sealedHeight uint64, hotstuffCurView uint64)
Copy link
Contributor

Choose a reason for hiding this comment

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

@zhangchiqing - will all node type report this? or only consensus nodes

Copy link
Member Author

Choose a reason for hiding this comment

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

Only Consensus nodes will report metrics. See this screenshot

See the logic control here

}
20 changes: 17 additions & 3 deletions module/metrics/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (
)

type PingCollector struct {
reachable *prometheus.GaugeVec
sealedHeight *prometheus.GaugeVec
reachable *prometheus.GaugeVec
sealedHeight *prometheus.GaugeVec
hotstuffCurView *prometheus.GaugeVec
}

func NewPingCollector() *PingCollector {
Expand All @@ -28,6 +29,12 @@ func NewPingCollector() *PingCollector {
Subsystem: subsystemGossip,
Help: "the last sealed height of a node",
}, []string{LabelNodeID, LabelNodeAddress, LabelNodeRole, LabelNodeInfo, LabelNodeVersion}),
hotstuffCurView: promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "hotstuff_curview",
Namespace: namespaceNetwork,
Subsystem: subsystemGossip,
Help: "the hotstuff current view",
}, []string{LabelNodeID, LabelNodeAddress, LabelNodeRole, LabelNodeInfo}),
}

return pc
Expand All @@ -49,12 +56,19 @@ func (pc *PingCollector) NodeReachable(node *flow.Identity, nodeInfo string, rtt
Set(rttValue)
}

func (pc *PingCollector) NodeInfo(node *flow.Identity, nodeInfo string, version string, sealedHeight uint64) {
func (pc *PingCollector) NodeInfo(node *flow.Identity, nodeInfo string, version string, sealedHeight uint64, hotstuffCurView uint64) {
pc.sealedHeight.With(prometheus.Labels{
LabelNodeID: node.NodeID.String(),
LabelNodeAddress: node.Address,
LabelNodeRole: node.Role.String(),
LabelNodeInfo: nodeInfo,
LabelNodeVersion: version}).
Set(float64(sealedHeight))

pc.hotstuffCurView.With(prometheus.Labels{
LabelNodeID: node.NodeID.String(),
LabelNodeAddress: node.Address,
LabelNodeInfo: nodeInfo,
}).
Set(float64(hotstuffCurView))
}
6 changes: 3 additions & 3 deletions module/mock/ping_metrics.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion network/message/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
# go get github.com/gogo/protobuf/protoc-gen-gofast
# To re-generate the the protobuf go code, install tools first:
# ```
# cd flow-go
# make install-tools
# ```
# Install protoc:
# https://grpc.io/docs/protoc-installation/
#
# Then run:
# ```
# cd network/message
# make generate
# ```


.PHONY: generate
generate:
Expand Down
49 changes: 43 additions & 6 deletions network/message/ping.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions network/message/ping.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ message PingRequest {
message PingResponse {
string version = 1; // node software version
uint64 blockHeight = 2; // latest sealed block height
uint64 hotstuffView = 3; // latest hotstuff cur view
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to regenerate pb.go files as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

updated

}
14 changes: 14 additions & 0 deletions network/mocknetwork/ping_info_provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion network/p2p/dht_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func (suite *DHTTestSuite) CreateNodes(count int, dhtServer bool) (nodes []*Node

connManager := NewConnManager(logger, noopMetrics)

pingInfoProvider, _, _ := MockPingInfoProvider()
pingInfoProvider, _, _, _ := MockPingInfoProvider()

resolver := dns.NewResolver(noopMetrics)

Expand Down
17 changes: 10 additions & 7 deletions network/p2p/libp2pNode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,16 +558,16 @@ func (suite *LibP2PNodeTestSuite) TestPing() {
node1Id := *identities[0]
node2Id := *identities[1]

_, expectedVersion, expectedHeight := MockPingInfoProvider()
_, expectedVersion, expectedHeight, expectedView := MockPingInfoProvider()

// test node1 can ping node 2
testPing(suite.T(), node1, node2Id, expectedVersion, expectedHeight)
testPing(suite.T(), node1, node2Id, expectedVersion, expectedHeight, expectedView)

// test node 2 can ping node 1
testPing(suite.T(), node2, node1Id, expectedVersion, expectedHeight)
testPing(suite.T(), node2, node1Id, expectedVersion, expectedHeight, expectedView)
}

func testPing(t *testing.T, source *Node, target flow.Identity, expectedVersion string, expectedHeight uint64) {
func testPing(t *testing.T, source *Node, target flow.Identity, expectedVersion string, expectedHeight uint64, expectedView uint64) {
pctx, cancel := context.WithCancel(context.Background())
defer cancel()
pInfo, err := PeerAddressInfo(target)
Expand All @@ -578,6 +578,7 @@ func testPing(t *testing.T, source *Node, target flow.Identity, expectedVersion
assert.NotZero(t, rtt)
assert.Equal(t, expectedVersion, resp.Version)
assert.Equal(t, expectedHeight, resp.BlockHeight)
assert.Equal(t, expectedView, resp.HotstuffView)
}

// TestConnectionGating tests node allow listing by peer.ID
Expand Down Expand Up @@ -699,7 +700,7 @@ func NodeFixture(t *testing.T, log zerolog.Logger, key fcrypto.PrivateKey, rootI
handlerFunc = func(network.Stream) {}
}

pingInfoProvider, _, _ := MockPingInfoProvider()
pingInfoProvider, _, _, _ := MockPingInfoProvider()

// dns resolver
resolver := dns.NewResolver(metrics.NewNoopCollector())
Expand Down Expand Up @@ -740,13 +741,15 @@ func NodeFixture(t *testing.T, log zerolog.Logger, key fcrypto.PrivateKey, rootI
return n, *identity
}

func MockPingInfoProvider() (*mocknetwork.PingInfoProvider, string, uint64) {
func MockPingInfoProvider() (*mocknetwork.PingInfoProvider, string, uint64, uint64) {
version := "version_1"
height := uint64(5000)
view := uint64(10)
pingInfoProvider := new(mocknetwork.PingInfoProvider)
pingInfoProvider.On("SoftwareVersion").Return(version)
pingInfoProvider.On("SealedBlockHeight").Return(height)
return pingInfoProvider, version, height
pingInfoProvider.On("HotstuffView").Return(view)
return pingInfoProvider, version, height, view
}

// StopNodes stop all nodes in the input slice
Expand Down
18 changes: 16 additions & 2 deletions network/p2p/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ type PingService struct {
type PingInfoProvider interface {
SoftwareVersion() string
SealedBlockHeight() uint64
HotstuffView() uint64
}

type PingInfoProviderImpl struct {
SoftwareVersionFun func() string
SealedBlockHeightFun func() (uint64, error)
HotstuffViewFun func() (uint64, error)
}

func (p PingInfoProviderImpl) SoftwareVersion() string {
Expand All @@ -52,6 +54,14 @@ func (p PingInfoProviderImpl) SealedBlockHeight() uint64 {
return height
}

func (p PingInfoProviderImpl) HotstuffView() uint64 {
view, err := p.HotstuffViewFun()
if err != nil {
return uint64(0)
}
return view
}

func NewPingService(h host.Host, pingProtocolID protocol.ID, pingInfoProvider PingInfoProvider, logger zerolog.Logger) *PingService {
ps := &PingService{host: h, pingProtocolID: pingProtocolID, pingInfoProvider: pingInfoProvider, logger: logger}
h.SetStreamHandler(pingProtocolID, ps.PingHandler)
Expand Down Expand Up @@ -115,10 +125,14 @@ func (ps *PingService) PingHandler(s network.Stream) {
// query for the lastest finalized block height
blockHeight := ps.pingInfoProvider.SealedBlockHeight()

// query for the hotstuff view
hotstuffView := ps.pingInfoProvider.HotstuffView()

// create a PingResponse
pingResponse := &message.PingResponse{
Version: version,
BlockHeight: blockHeight,
Version: version,
BlockHeight: blockHeight,
HotstuffView: hotstuffView,
}

// send the PingResponse
Expand Down