Skip to content

Issue: Potential Blocking in BroadcastConsensus May Compromise BFT Liveness #628

Description

@zhanghefan123

The current implementation of BroadcastConsensus in the Controller may block when sending messages to other nodes, potentially compromising the BFT protocol's liveness. This occurs because:

c.Comm.SendConsensus(node, m) can block when gRPC's getTransport function has no available connections

The synchronous nature of the broadcast means a single blocked send can delay all subsequent messages

This blocking behavior could prevent timely dissemination of consensus messages, violating the protocol's liveness guarantees

func (c *Controller) BroadcastConsensus(m *protos.Message) {
    for _, node := range c.NodesList {
        if c.ID == node {
            continue
        }
        c.Comm.SendConsensus(node, m) // Synchronous call that may block
    }
    if m.GetPrePrepare() != nil || m.GetPrepare() != nil || m.GetCommit() != nil {
        if leader, _ := c.iAmTheLeader(); leader {
            c.LeaderMonitor.HeartbeatWasSent()
        }
    }
}

the proposed solution is as follows:

func (c *Controller) BroadcastConsensus(m *protos.Message) {
    for _, node := range c.NodesList {
        if c.ID == node {
            continue
        }
        go c.Comm.SendConsensus(node, m) // Asynchronous non-blocking call
    }
    if m.GetPrePrepare() != nil || m.GetPrepare() != nil || m.GetCommit() != nil {
        if leader, _ := c.iAmTheLeader(); leader {
            c.LeaderMonitor.HeartbeatWasSent()
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions