diff --git a/chainsync.go b/chainsync.go index 9245f6f..3e118a2 100644 --- a/chainsync.go +++ b/chainsync.go @@ -25,6 +25,10 @@ import ( ocommon "github.com/blinklabs-io/gouroboros/protocol/common" ) +const ( + chainsyncIntersectPointCount = 100 +) + func (n *Node) chainsyncServerConnOpts() []ochainsync.ChainSyncOptionFunc { return []ochainsync.ChainSyncOptionFunc{ ochainsync.WithFindIntersectFunc(n.chainsyncServerFindIntersect), @@ -45,12 +49,22 @@ func (n *Node) chainsyncClientStart(connId ouroboros.ConnectionId) error { return fmt.Errorf("failed to lookup connection ID: %s", connId.String()) } oConn := conn.Conn - // TODO: use our recent blocks to build intersect points - tip, err := oConn.ChainSync().Client.GetCurrentTip() + intersectPoints, err := n.ledgerState.RecentChainPoints(chainsyncIntersectPointCount) if err != nil { return err } - intersectPoints := []ocommon.Point{tip.Point} + // Empty intersect point means initial sync + if len(intersectPoints) == 0 { + // TODO: make this behavior configurable (genesis, tip, or specific point) + tip, err := oConn.ChainSync().Client.GetCurrentTip() + if err != nil { + return err + } + intersectPoints = append( + intersectPoints, + tip.Point, + ) + } if err := oConn.ChainSync().Client.Sync(intersectPoints); err != nil { return err } diff --git a/internal/node/node.go b/internal/node/node.go index 7c6298e..bdc5eee 100644 --- a/internal/node/node.go +++ b/internal/node/node.go @@ -32,6 +32,8 @@ func Run(logger *slog.Logger) error { n, err := node.New( node.NewConfig( node.WithLogger(logger), + // TODO: uncomment and make this configurable + //node.WithDataDir(".data"), // TODO: make this configurable node.WithNetwork("preview"), node.WithListeners( diff --git a/state/state.go b/state/state.go index 6b82b60..db3609d 100644 --- a/state/state.go +++ b/state/state.go @@ -27,7 +27,6 @@ import ( "gorm.io/gorm" ochainsync "github.com/blinklabs-io/gouroboros/protocol/chainsync" - "github.com/blinklabs-io/gouroboros/protocol/common" ocommon "github.com/blinklabs-io/gouroboros/protocol/common" badger "github.com/dgraph-io/badger/v4" ) @@ -155,8 +154,28 @@ func (ls *LedgerState) GetBlock(point ocommon.Point) (*models.Block, error) { return &ret, nil } -func (ls *LedgerState) GetIntersectPoint(points []common.Point) (*common.Point, error) { - var ret common.Point +// RecentChainPoints returns the requested count of recent chain points in descending order. This is used mostly +// for building a set of intersect points when acting as a chainsync client +func (ls *LedgerState) RecentChainPoints(count int) ([]ocommon.Point, error) { + ls.RLock() + defer ls.RUnlock() + var tmpBlocks []models.Block + result := ls.db.Metadata().Order("number DESC").Limit(count).Find(&tmpBlocks) + if result.Error != nil { + return nil, result.Error + } + var ret []ocommon.Point + for _, tmpBlock := range tmpBlocks { + ret = append( + ret, + ocommon.NewPoint(tmpBlock.Slot, tmpBlock.Hash), + ) + } + return ret, nil +} + +func (ls *LedgerState) GetIntersectPoint(points []ocommon.Point) (*ocommon.Point, error) { + var ret ocommon.Point for _, point := range points { // Ignore points with a slot earlier than an existing match if point.Slot < ret.Slot { @@ -180,7 +199,7 @@ func (ls *LedgerState) GetIntersectPoint(points []common.Point) (*common.Point, return nil, nil } -func (ls *LedgerState) GetChainFromPoint(point common.Point) (*ChainIterator, error) { +func (ls *LedgerState) GetChainFromPoint(point ocommon.Point) (*ChainIterator, error) { return newChainIterator(ls, point) }