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

fix: return empty available block range when at chain tip #472

Merged
merged 1 commit into from
Dec 31, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions protocol/chainsync/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type Client struct {
currentTipChan chan Tip
wantFirstBlock bool
firstBlockChan chan common.Point
wantIntersectPoint bool
intersectPointChan chan common.Point
onceStop sync.Once
}

Expand All @@ -58,6 +60,7 @@ func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client {
readyForNextBlockChan: make(chan bool),
currentTipChan: make(chan Tip),
firstBlockChan: make(chan common.Point),
intersectPointChan: make(chan common.Point),
}
// Update state map with timeouts
stateMap := StateMap.Copy()
Expand Down Expand Up @@ -92,6 +95,7 @@ func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client {
close(c.readyForNextBlockChan)
close(c.currentTipChan)
close(c.firstBlockChan)
close(c.intersectPointChan)
}()
return c
}
Expand Down Expand Up @@ -150,26 +154,46 @@ func (c *Client) GetCurrentTip() (*Tip, error) {
}

// GetAvailableBlockRange returns the start and end of the range of available blocks given the provided intersect
// point(s).
// point(s). Empty start/end points will be returned if there are no additional blocks available.
func (c *Client) GetAvailableBlockRange(
intersectPoints []common.Point,
) (common.Point, common.Point, error) {
c.busyMutex.Lock()
defer c.busyMutex.Unlock()
var start, end common.Point
// Find our chain intersection
c.wantCurrentTip = true
c.wantIntersectPoint = true
msgFindIntersect := NewMsgFindIntersect(intersectPoints)
if err := c.SendMessage(msgFindIntersect); err != nil {
return start, end, err
}
select {
case err := <-c.intersectResultChan:
if err != nil {
return start, end, err
gotIntersectResult := false
for {
select {
case tip := <-c.currentTipChan:
end = tip.Point
c.wantCurrentTip = false
case point := <-c.intersectPointChan:
start = point
c.wantIntersectPoint = false
case err := <-c.intersectResultChan:
if err != nil {
return start, end, err
}
gotIntersectResult = true
}
if !c.wantIntersectPoint && !c.wantCurrentTip && gotIntersectResult {
break
}
}
// If we're already at the chain tip, return an empty range
if start.Slot >= end.Slot {
return common.Point{}, common.Point{}, nil
}
// Request the next block to get the first block after the intersect point. This should result in a rollback
c.wantCurrentTip = true
c.wantFirstBlock = true
// Request the next block. This should result in a rollback
msgRequestNext := NewMsgRequestNext()
if err := c.SendMessage(msgRequestNext); err != nil {
return start, end, err
Expand All @@ -193,6 +217,10 @@ func (c *Client) GetAvailableBlockRange(
break
}
}
// If we're already at the chain tip, return an empty range
if start.Slot >= end.Slot {
return common.Point{}, common.Point{}, nil
}
return start, end, nil
}

Expand Down Expand Up @@ -356,11 +384,14 @@ func (c *Client) handleRollBackward(msg protocol.Message) error {
return nil
}

func (c *Client) handleIntersectFound(msgGeneric protocol.Message) error {
func (c *Client) handleIntersectFound(msg protocol.Message) error {
msgIntersectFound := msg.(*MsgIntersectFound)
if c.wantCurrentTip {
msgIntersectFound := msgGeneric.(*MsgIntersectFound)
c.currentTipChan <- msgIntersectFound.Tip
}
if c.wantIntersectPoint {
c.intersectPointChan <- msgIntersectFound.Point
}
c.intersectResultChan <- nil
return nil
}
Expand Down