Skip to content

Commit d66205b

Browse files
committed
feat: chainsync server support
Fixes #347
1 parent 24c6a9f commit d66205b

File tree

4 files changed

+81
-21
lines changed

4 files changed

+81
-21
lines changed

protocol/chainsync/chainsync.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,20 @@ type ChainSync struct {
112112

113113
// Config is used to configure the ChainSync protocol instance
114114
type Config struct {
115-
RollBackwardFunc RollBackwardFunc
116-
RollForwardFunc RollForwardFunc
117-
IntersectTimeout time.Duration
118-
BlockTimeout time.Duration
119-
PipelineLimit int
115+
RollBackwardFunc RollBackwardFunc
116+
RollForwardFunc RollForwardFunc
117+
FindIntersectFunc FindIntersectFunc
118+
RequestNextFunc RequestNextFunc
119+
IntersectTimeout time.Duration
120+
BlockTimeout time.Duration
121+
PipelineLimit int
120122
}
121123

122124
// Callback function types
123125
type RollBackwardFunc func(common.Point, Tip) error
124126
type RollForwardFunc func(uint, interface{}, Tip) error
127+
type FindIntersectFunc func([]common.Point) (common.Point, Tip, error)
128+
type RequestNextFunc func() error
125129

126130
// New returns a new ChainSync object
127131
func New(protoOptions protocol.ProtocolOptions, cfg *Config) *ChainSync {
@@ -169,6 +173,20 @@ func WithRollForwardFunc(rollForwardFunc RollForwardFunc) ChainSyncOptionFunc {
169173
}
170174
}
171175

176+
// WithFindIntersectFunc specifies the FindIntersect callback function
177+
func WithFindIntersectFunc(findIntersectFunc FindIntersectFunc) ChainSyncOptionFunc {
178+
return func(c *Config) {
179+
c.FindIntersectFunc = findIntersectFunc
180+
}
181+
}
182+
183+
// WithRequestNextFunc specifies the RequestNext callback function
184+
func WithRequestNextFunc(requestNextFunc RequestNextFunc) ChainSyncOptionFunc {
185+
return func(c *Config) {
186+
c.RequestNextFunc = requestNextFunc
187+
}
188+
}
189+
172190
// WithIntersectTimeout specifies the timeout for intersect operations
173191
func WithIntersectTimeout(timeout time.Duration) ChainSyncOptionFunc {
174192
return func(c *Config) {

protocol/chainsync/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ func (c *Client) handleAwaitReply() error {
252252
}
253253

254254
func (c *Client) handleRollForward(msgGeneric protocol.Message) error {
255-
if c.config.RollForwardFunc == nil && !c.wantFirstBlock {
255+
if (c.config == nil || c.config.RollForwardFunc == nil) && !c.wantFirstBlock {
256256
return fmt.Errorf(
257257
"received chain-sync RollForward message but no callback function is defined",
258258
)
@@ -367,6 +367,6 @@ func (c *Client) handleIntersectNotFound(msgGeneric protocol.Message) error {
367367
msgIntersectNotFound := msgGeneric.(*MsgIntersectNotFound)
368368
c.currentTipChan <- msgIntersectNotFound.Tip
369369
}
370-
c.intersectResultChan <- IntersectNotFoundError{}
370+
c.intersectResultChan <- IntersectNotFoundError
371371
return nil
372372
}

protocol/chainsync/error.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,10 @@
1414

1515
package chainsync
1616

17-
import (
18-
"fmt"
19-
)
17+
import "errors"
2018

21-
// IntersectNotFoundError represents a failure to find a chain intersection
22-
type IntersectNotFoundError struct {
23-
}
24-
25-
func (e IntersectNotFoundError) Error() string {
26-
return "chain intersection not found"
27-
}
19+
var IntersectNotFoundError = errors.New("chain intersection not found")
2820

2921
// StopChainSync is used as a special return value from a RollForward or RollBackward handler function
3022
// to signify that the sync process should be stopped
31-
var StopSyncProcessError = fmt.Errorf("stop sync process")
23+
var StopSyncProcessError = errors.New("stop sync process")

protocol/chainsync/server.go

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ package chainsync
1616

1717
import (
1818
"fmt"
19+
20+
"github.com/blinklabs-io/gouroboros/ledger"
1921
"github.com/blinklabs-io/gouroboros/protocol"
22+
"github.com/blinklabs-io/gouroboros/protocol/common"
2023
)
2124

2225
// Server implements the ChainSync server
@@ -54,6 +57,31 @@ func NewServer(protoOptions protocol.ProtocolOptions, cfg *Config) *Server {
5457
return s
5558
}
5659

60+
func (s *Server) RollBackward(point common.Point, tip Tip) error {
61+
msg := NewMsgRollBackward(point, tip)
62+
return s.SendMessage(msg)
63+
}
64+
65+
func (s *Server) RollForward(blockType uint, blockData []byte, tip Tip) error {
66+
if s.Mode() == protocol.ProtocolModeNodeToNode {
67+
eraId := ledger.BlockToBlockHeaderTypeMap[blockType]
68+
msg := NewMsgRollForwardNtN(
69+
eraId,
70+
0,
71+
blockData,
72+
tip,
73+
)
74+
return s.SendMessage(msg)
75+
} else {
76+
msg := NewMsgRollForwardNtC(
77+
blockType,
78+
blockData,
79+
tip,
80+
)
81+
return s.SendMessage(msg)
82+
}
83+
}
84+
5785
func (s *Server) messageHandler(msg protocol.Message) error {
5886
var err error
5987
switch msg.Type() {
@@ -74,12 +102,34 @@ func (s *Server) messageHandler(msg protocol.Message) error {
74102
}
75103

76104
func (s *Server) handleRequestNext(msg protocol.Message) error {
77-
// TODO
78-
return nil
105+
if s.config == nil || s.config.RequestNextFunc == nil {
106+
return fmt.Errorf(
107+
"received chain-sync RequestNext message but no callback function is defined",
108+
)
109+
}
110+
return s.config.RequestNextFunc()
79111
}
80112

81113
func (s *Server) handleFindIntersect(msg protocol.Message) error {
82-
// TODO
114+
if s.config == nil || s.config.FindIntersectFunc == nil {
115+
return fmt.Errorf(
116+
"received chain-sync FindIntersect message but no callback function is defined",
117+
)
118+
}
119+
msgFindIntersect := msg.(*MsgFindIntersect)
120+
point, tip, err := s.config.FindIntersectFunc(msgFindIntersect.Points)
121+
if err != nil {
122+
if err == IntersectNotFoundError {
123+
msgResp := NewMsgIntersectNotFound(tip)
124+
if err := s.SendMessage(msgResp); err != nil {
125+
return err
126+
}
127+
}
128+
}
129+
msgResp := NewMsgIntersectFound(point, tip)
130+
if err := s.SendMessage(msgResp); err != nil {
131+
return err
132+
}
83133
return nil
84134
}
85135

0 commit comments

Comments
 (0)