Skip to content

Commit

Permalink
Publish last accepted height through chits
Browse files Browse the repository at this point in the history
This commit adds the last accepted height to the Chits message.

The intention is that by receiving the latest accepted height of each node,
a node can know whether it is straggling behind the majority of the nodes in the chain.

I ran a build with the commit on a Fuji testnet node and verified the log matches the commit.

```
[10-02|19:59:48.312] VERBO <P Chain> snowman/engine.go:362 called Chits for the block {"nodeID": "NodeID-1AFBjE7UUM1AWWA1HtMGreRrvKwTh9Su", "requestID": 335, "preferredID": "zmoZ2RPy2mkx1ozSbhen9Ggh9boTewBCa6bgc5FnQu7d2umrf", "preferredIDAtHeight": "zmoZ2RPy2mkx1ozSbhen9Ggh9boTewBCa6bgc5FnQu7d2umrf", "acceptedID": "zmoZ2RPy2mkx1ozSbhen9Ggh9boTewBCa6bgc5FnQu7d2umrf", "acceptedHeight": 0}
```

Also verified on its grafana dashboard that it participates in consensus and that there are no failing health checks.

Signed-off-by: Yacov Manevich <yacov.manevich@avalabs.org>
  • Loading branch information
yacovm committed Oct 2, 2024
1 parent 7fd21ca commit f499876
Show file tree
Hide file tree
Showing 19 changed files with 255 additions and 140 deletions.
8 changes: 4 additions & 4 deletions message/messagemock/outbound_message_builder.go

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

3 changes: 3 additions & 0 deletions message/outbound_msg_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ type OutboundMsgBuilder interface {
preferredID ids.ID,
preferredIDAtHeight ids.ID,
acceptedID ids.ID,
acceptedHeight uint64,
) (OutboundMessage, error)

AppRequest(
Expand Down Expand Up @@ -639,6 +640,7 @@ func (b *outMsgBuilder) Chits(
preferredID ids.ID,
preferredIDAtHeight ids.ID,
acceptedID ids.ID,
acceptedHeight uint64,
) (OutboundMessage, error) {
return b.builder.createOutbound(
&p2p.Message{
Expand All @@ -649,6 +651,7 @@ func (b *outMsgBuilder) Chits(
PreferredId: preferredID[:],
PreferredIdAtHeight: preferredIDAtHeight[:],
AcceptedId: acceptedID[:],
AcceptedHeight: acceptedHeight,
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions proto/p2p/p2p.proto
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ message Chits {
bytes accepted_id = 4;
// Currently preferred block at the requested height
bytes preferred_id_at_height = 5;
// Last accepted block's height
uint64 accepted_height = 6;
}

// AppRequest is a VM-defined request.
Expand Down
88 changes: 50 additions & 38 deletions proto/pb/p2p/p2p.pb.go

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

8 changes: 4 additions & 4 deletions snow/engine/common/commonmock/sender.go

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

1 change: 1 addition & 0 deletions snow/engine/common/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ type ChitsHandler interface {
preferredID ids.ID,
preferredIDAtHeight ids.ID,
acceptedID ids.ID,
acceptedHeight uint64,
) error

// Notify this engine that a Query request it issued has failed.
Expand Down
3 changes: 2 additions & 1 deletion snow/engine/common/no_ops_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func NewNoOpChitsHandler(log logging.Logger) ChitsHandler {
return &noOpChitsHandler{log: log}
}

func (nop *noOpChitsHandler) Chits(_ context.Context, nodeID ids.NodeID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID) error {
func (nop *noOpChitsHandler) Chits(_ context.Context, nodeID ids.NodeID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID, acceptedHeight uint64) error {
nop.log.Debug("dropping request",
zap.String("reason", "unhandled by this gear"),
zap.Stringer("messageOp", message.ChitsOp),
Expand All @@ -246,6 +246,7 @@ func (nop *noOpChitsHandler) Chits(_ context.Context, nodeID ids.NodeID, request
zap.Stringer("preferredID", preferredID),
zap.Stringer("preferredIDAtHeight", preferredIDAtHeight),
zap.Stringer("acceptedID", acceptedID),
zap.Uint64("acceptedHeight", acceptedHeight),
)
return nil
}
Expand Down
1 change: 1 addition & 0 deletions snow/engine/common/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ type QuerySender interface {
preferredID ids.ID,
preferredIDAtHeight ids.ID,
acceptedID ids.ID,
acceptedHeight uint64,
)
}

Expand Down
4 changes: 2 additions & 2 deletions snow/engine/common/traced_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (e *tracedEngine) PushQuery(ctx context.Context, nodeID ids.NodeID, request
return e.engine.PushQuery(ctx, nodeID, requestID, container, requestedHeight)
}

func (e *tracedEngine) Chits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error {
func (e *tracedEngine) Chits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID, acceptedHeight uint64) error {
ctx, span := e.tracer.Start(ctx, "tracedEngine.Chits", oteltrace.WithAttributes(
attribute.Stringer("nodeID", nodeID),
attribute.Int64("requestID", int64(requestID)),
Expand All @@ -255,7 +255,7 @@ func (e *tracedEngine) Chits(ctx context.Context, nodeID ids.NodeID, requestID u
))
defer span.End()

return e.engine.Chits(ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID)
return e.engine.Chits(ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight)
}

func (e *tracedEngine) QueryFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
Expand Down
35 changes: 22 additions & 13 deletions snow/engine/common/tracker/accepted.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,28 @@ type Accepted interface {
validators.SetCallbackListener

// SetLastAccepted updates the latest accepted block for [nodeID] to
// [blockID]. If [nodeID] is not currently a validator, this is a noop.
SetLastAccepted(nodeID ids.NodeID, blockID ids.ID)
// [blockID], with a corresponding height.
// If [nodeID] is not currently a validator, this is a noop.
SetLastAccepted(nodeID ids.NodeID, blockID ids.ID, height uint64)
// LastAccepted returns the latest known accepted block of [nodeID]. If
// [nodeID]'s last accepted block was never unknown, false will be returned.
LastAccepted(nodeID ids.NodeID) (ids.ID, bool)
LastAccepted(nodeID ids.NodeID) (ids.ID, uint64, bool)
}

type idHeight struct {
id ids.ID
height uint64
}

type accepted struct {
lock sync.RWMutex
validators set.Set[ids.NodeID]
frontier map[ids.NodeID]ids.ID
lock sync.RWMutex
validators set.Set[ids.NodeID]
lastAccepted map[ids.NodeID]idHeight
}

func NewAccepted() Accepted {
return &accepted{
frontier: make(map[ids.NodeID]ids.ID),
lastAccepted: make(map[ids.NodeID]idHeight),
}
}

Expand All @@ -49,24 +55,27 @@ func (a *accepted) OnValidatorRemoved(nodeID ids.NodeID, _ uint64) {
defer a.lock.Unlock()

a.validators.Remove(nodeID)
delete(a.frontier, nodeID)
delete(a.lastAccepted, nodeID)
}

func (*accepted) OnValidatorWeightChanged(_ ids.NodeID, _, _ uint64) {}

func (a *accepted) SetLastAccepted(nodeID ids.NodeID, frontier ids.ID) {
func (a *accepted) SetLastAccepted(nodeID ids.NodeID, frontier ids.ID, height uint64) {
a.lock.Lock()
defer a.lock.Unlock()

if a.validators.Contains(nodeID) {
a.frontier[nodeID] = frontier
a.lastAccepted[nodeID] = idHeight{
id: frontier,
height: height,
}
}
}

func (a *accepted) LastAccepted(nodeID ids.NodeID) (ids.ID, bool) {
func (a *accepted) LastAccepted(nodeID ids.NodeID) (ids.ID, uint64, bool) {
a.lock.RLock()
defer a.lock.RUnlock()

acceptedID, ok := a.frontier[nodeID]
return acceptedID, ok
acceptedAndHeight, ok := a.lastAccepted[nodeID]
return acceptedAndHeight.id, acceptedAndHeight.height, ok
}
20 changes: 11 additions & 9 deletions snow/engine/common/tracker/accepted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,32 @@ func TestAccepted(t *testing.T) {

a := NewAccepted()

_, ok := a.LastAccepted(nodeID)
_, _, ok := a.LastAccepted(nodeID)
require.False(ok)

a.SetLastAccepted(nodeID, blkID0)
_, ok = a.LastAccepted(nodeID)
a.SetLastAccepted(nodeID, blkID0, 13)
_, _, ok = a.LastAccepted(nodeID)
require.False(ok)

a.OnValidatorAdded(nodeID, nil, ids.GenerateTestID(), 1)

_, ok = a.LastAccepted(nodeID)
_, _, ok = a.LastAccepted(nodeID)
require.False(ok)

a.SetLastAccepted(nodeID, blkID0)
blkID, ok := a.LastAccepted(nodeID)
a.SetLastAccepted(nodeID, blkID0, 11)
blkID, height, ok := a.LastAccepted(nodeID)
require.True(ok)
require.Equal(blkID0, blkID)
require.Equal(uint64(11), height)

a.SetLastAccepted(nodeID, blkID1)
blkID, ok = a.LastAccepted(nodeID)
a.SetLastAccepted(nodeID, blkID1, 12)
blkID, height, ok = a.LastAccepted(nodeID)
require.True(ok)
require.Equal(blkID1, blkID)
require.Equal(uint64(12), height)

a.OnValidatorRemoved(nodeID, 1)

_, ok = a.LastAccepted(nodeID)
_, _, ok = a.LastAccepted(nodeID)
require.False(ok)
}
Loading

0 comments on commit f499876

Please sign in to comment.