mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
162 lines
4.0 KiB
Go
162 lines
4.0 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package getter
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/luxfi/consensus/engine/dag/state"
|
|
"github.com/luxfi/consensus/networking/sender"
|
|
"github.com/luxfi/ids"
|
|
log "github.com/luxfi/log"
|
|
)
|
|
|
|
// Getter gets vertices
|
|
type Getter interface {
|
|
// Get gets a vertex
|
|
Get(context.Context, ids.NodeID, uint32, ids.ID) error
|
|
|
|
// GetAncestors gets ancestors
|
|
GetAncestors(context.Context, ids.NodeID, uint32, ids.ID, int) error
|
|
|
|
// Put puts a vertex
|
|
Put(context.Context, ids.NodeID, uint32, []byte) error
|
|
|
|
// PushQuery pushes a query
|
|
PushQuery(context.Context, ids.NodeID, uint32, []byte) error
|
|
|
|
// PullQuery pulls a query
|
|
PullQuery(context.Context, ids.NodeID, uint32, ids.ID) error
|
|
}
|
|
|
|
// Handler handles get requests for DAG vertices
|
|
type Handler interface {
|
|
Getter
|
|
}
|
|
|
|
// getter implementation
|
|
type getter struct {
|
|
vtxManager state.Manager
|
|
sender sender.Sender
|
|
log log.Logger
|
|
maxTimeGetAncestors time.Duration
|
|
ancestorsMaxContainers int
|
|
}
|
|
|
|
// Config for creating a Handler
|
|
type Config struct {
|
|
VtxManager state.Manager
|
|
Sender sender.Sender
|
|
Log log.Logger
|
|
MaxTimeGetAncestors time.Duration
|
|
AncestorsMaxContainers int
|
|
}
|
|
|
|
// New creates a new getter
|
|
func New() Getter {
|
|
return &getter{}
|
|
}
|
|
|
|
// NewHandler creates a new handler with config
|
|
func NewHandler(
|
|
vtxManager state.Manager,
|
|
sender sender.Sender,
|
|
log log.Logger,
|
|
maxTimeGetAncestors time.Duration,
|
|
ancestorsMaxContainers int,
|
|
) (Handler, error) {
|
|
return &getter{
|
|
vtxManager: vtxManager,
|
|
sender: sender,
|
|
log: log,
|
|
maxTimeGetAncestors: maxTimeGetAncestors,
|
|
ancestorsMaxContainers: ancestorsMaxContainers,
|
|
}, nil
|
|
}
|
|
|
|
// Get gets a vertex
|
|
func (g *getter) Get(ctx context.Context, nodeID ids.NodeID, requestID uint32, vertexID ids.ID) error {
|
|
if g.vtxManager == nil {
|
|
return nil
|
|
}
|
|
vtx, err := g.vtxManager.GetVertex(vertexID)
|
|
if err != nil {
|
|
return nil // Vertex not found is not an error
|
|
}
|
|
if vtx != nil && g.sender != nil {
|
|
return g.sender.SendResponse(ctx, nodeID, requestID, vtx.Bytes())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetAncestors gets ancestors
|
|
func (g *getter) GetAncestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, vertexID ids.ID, maxVertices int) error {
|
|
if g.vtxManager == nil {
|
|
return nil
|
|
}
|
|
|
|
vtx, err := g.vtxManager.GetVertex(vertexID)
|
|
if err != nil || vtx == nil {
|
|
return nil
|
|
}
|
|
|
|
ancestors := [][]byte{vtx.Bytes()}
|
|
|
|
// Get parent vertices up to maxVertices
|
|
toProcess := vtx.ParentIDs()
|
|
visited := make(map[ids.ID]bool)
|
|
visited[vertexID] = true
|
|
|
|
for len(toProcess) > 0 && len(ancestors) < maxVertices {
|
|
parentID := toProcess[0]
|
|
toProcess = toProcess[1:]
|
|
|
|
if visited[parentID] {
|
|
continue
|
|
}
|
|
visited[parentID] = true
|
|
|
|
parent, err := g.vtxManager.GetVertex(parentID)
|
|
if err != nil || parent == nil {
|
|
continue
|
|
}
|
|
|
|
ancestors = append(ancestors, parent.Bytes())
|
|
toProcess = append(toProcess, parent.ParentIDs()...)
|
|
}
|
|
|
|
if g.sender != nil {
|
|
// Serialize ancestors to bytes (length-prefixed format)
|
|
var ancestorBytes []byte
|
|
for _, a := range ancestors {
|
|
// Simple length-prefix encoding
|
|
lenBytes := make([]byte, 4)
|
|
lenBytes[0] = byte(len(a) >> 24)
|
|
lenBytes[1] = byte(len(a) >> 16)
|
|
lenBytes[2] = byte(len(a) >> 8)
|
|
lenBytes[3] = byte(len(a))
|
|
ancestorBytes = append(ancestorBytes, lenBytes...)
|
|
ancestorBytes = append(ancestorBytes, a...)
|
|
}
|
|
return g.sender.SendResponse(ctx, nodeID, requestID, ancestorBytes)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Put puts a vertex
|
|
func (g *getter) Put(ctx context.Context, nodeID ids.NodeID, requestID uint32, vertex []byte) error {
|
|
return nil
|
|
}
|
|
|
|
// PushQuery pushes a query
|
|
func (g *getter) PushQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, vertex []byte) error {
|
|
return nil
|
|
}
|
|
|
|
// PullQuery pulls a query
|
|
func (g *getter) PullQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, vertexID ids.ID) error {
|
|
return nil
|
|
}
|