mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
refactor: update dependencies and engine improvements
This commit is contained in:
@@ -39,10 +39,15 @@ const (
|
||||
PushQuery
|
||||
// PullQuery pulls a query
|
||||
PullQuery
|
||||
// Chits is chits response
|
||||
Chits
|
||||
// Vote is the authenticated preference signal returned by polling
|
||||
Vote
|
||||
// GetContext requests the verification context (parent chain) for a block
|
||||
GetContext
|
||||
// Context is the response containing prerequisite blocks needed to verify/attach a tip
|
||||
Context
|
||||
)
|
||||
|
||||
|
||||
// Field represents a message field
|
||||
type Field byte
|
||||
|
||||
|
||||
+60
-1
@@ -42,6 +42,12 @@ type BlockBuilder interface {
|
||||
GetBlock(context.Context, ids.ID) (block.Block, error)
|
||||
ParseBlock(context.Context, []byte) (block.Block, error)
|
||||
LastAccepted(context.Context) (ids.ID, error)
|
||||
// SetPreference tells the VM which block to build on next.
|
||||
// This MUST be called after accepting a block to keep the VM's preferred
|
||||
// block in sync with the last accepted block. Without this, the VM's
|
||||
// Preferred() returns the old block while GetLastAccepted() returns the
|
||||
// new block, causing GetState(preferred) to fail during block building.
|
||||
SetPreference(context.Context, ids.ID) error
|
||||
}
|
||||
|
||||
// BlockProposer submits blocks to validators.
|
||||
@@ -416,9 +422,12 @@ func (t *Transitive) Notify(ctx context.Context, msg Message) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
fmt.Printf("[CONSENSUS DEBUG] Notify: msg.Type=%v\n", msg.Type)
|
||||
|
||||
switch msg.Type {
|
||||
case PendingTxs:
|
||||
t.pendingBuildBlocks++
|
||||
fmt.Printf("[CONSENSUS DEBUG] PendingTxs received, pendingBuildBlocks=%d\n", t.pendingBuildBlocks)
|
||||
return t.buildBlocksLocked(ctx)
|
||||
case StateSyncDone:
|
||||
return nil
|
||||
@@ -470,6 +479,29 @@ func (t *Transitive) PendingBuildBlocks() int {
|
||||
return t.pendingBuildBlocks
|
||||
}
|
||||
|
||||
// HasPendingBlock checks if a block is in the pending blocks map (built or received but not yet finalized).
|
||||
// This is used by the Vote handler to determine if votes should be processed immediately
|
||||
// (block exists) or buffered (block not yet available).
|
||||
func (t *Transitive) HasPendingBlock(blockID ids.ID) bool {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
_, exists := t.pendingBlocks[blockID]
|
||||
return exists
|
||||
}
|
||||
|
||||
// GetPendingBlock returns the VMBlock for a pending block if it exists.
|
||||
// This allows the Vote handler to process votes for blocks that are in consensus
|
||||
// but not yet verified/stored in the VM.
|
||||
func (t *Transitive) GetPendingBlock(blockID ids.ID) (block.Block, bool) {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
pending, exists := t.pendingBlocks[blockID]
|
||||
if !exists || pending.VMBlock == nil {
|
||||
return nil, false
|
||||
}
|
||||
return pending.VMBlock, true
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Internal
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -492,11 +524,18 @@ func (t *Transitive) processPendingBlocks() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if len(t.pendingBlocks) > 0 {
|
||||
fmt.Printf("[CONSENSUS DEBUG] processPendingBlocks: %d pending blocks\n", len(t.pendingBlocks))
|
||||
}
|
||||
|
||||
for blockID, pending := range t.pendingBlocks {
|
||||
if pending.Decided {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("[CONSENSUS DEBUG] checking block %s: votes=%d isAccepted=%v isRejected=%v\n",
|
||||
blockID, pending.VoteCount, t.consensus.IsAccepted(blockID), t.consensus.IsRejected(blockID))
|
||||
|
||||
if t.consensus.IsAccepted(blockID) {
|
||||
pending.Decided = true
|
||||
t.blocksAccepted++
|
||||
@@ -505,6 +544,17 @@ func (t *Transitive) processPendingBlocks() {
|
||||
fmt.Printf("warning: accept failed for %s: %v\n", blockID, err)
|
||||
}
|
||||
}
|
||||
// After accepting a block, update the VM's preferred block to build on
|
||||
// This is critical: without this, the VM's Preferred() returns the old block
|
||||
// while GetLastAccepted() returns the newly accepted block, causing
|
||||
// GetState(preferred) to fail when building the next block
|
||||
if t.vm != nil {
|
||||
if err := t.vm.SetPreference(t.ctx, blockID); err != nil {
|
||||
fmt.Printf("warning: SetPreference failed for %s: %v\n", blockID, err)
|
||||
} else {
|
||||
fmt.Printf("[CONSENSUS DEBUG] SetPreference updated to %s\n", blockID)
|
||||
}
|
||||
}
|
||||
delete(t.pendingBlocks, blockID)
|
||||
} else if t.consensus.IsRejected(blockID) {
|
||||
pending.Decided = true
|
||||
@@ -556,16 +606,22 @@ func (t *Transitive) handleVote(vote Vote) {
|
||||
|
||||
func (t *Transitive) buildBlocksLocked(ctx context.Context) error {
|
||||
if t.vm == nil {
|
||||
fmt.Println("[CONSENSUS DEBUG] buildBlocksLocked: vm is nil")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("[CONSENSUS DEBUG] buildBlocksLocked: pendingBuildBlocks=%d\n", t.pendingBuildBlocks)
|
||||
|
||||
for t.pendingBuildBlocks > 0 {
|
||||
t.pendingBuildBlocks--
|
||||
|
||||
fmt.Println("[CONSENSUS DEBUG] calling vm.BuildBlock")
|
||||
vmBlock, err := t.vm.BuildBlock(ctx)
|
||||
if err != nil {
|
||||
fmt.Printf("[CONSENSUS DEBUG] vm.BuildBlock error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("[CONSENSUS DEBUG] vm.BuildBlock success: block=%s height=%d\n", vmBlock.ID(), vmBlock.Height())
|
||||
|
||||
t.blocksBuilt++
|
||||
|
||||
@@ -578,17 +634,20 @@ func (t *Transitive) buildBlocksLocked(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if err := t.consensus.AddBlock(ctx, consensusBlock); err != nil {
|
||||
fmt.Printf("[CONSENSUS DEBUG] AddBlock failed: %v\n", err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("[CONSENSUS DEBUG] AddBlock success for block=%s\n", vmBlock.ID())
|
||||
|
||||
t.pendingBlocks[vmBlock.ID()] = &PendingBlock{
|
||||
ConsensusBlock: consensusBlock,
|
||||
VMBlock: vmBlock,
|
||||
ProposedAt: time.Now(),
|
||||
VoteCount: 0,
|
||||
VoteCount: 1, // Count proposer's own vote
|
||||
Decided: false,
|
||||
}
|
||||
|
||||
fmt.Printf("[CONSENSUS DEBUG] proposer=%v\n", t.proposer != nil)
|
||||
if t.proposer != nil {
|
||||
proposal := BlockProposal{
|
||||
BlockID: vmBlock.ID(),
|
||||
|
||||
+145
-49
@@ -27,6 +27,10 @@ type NetworkConfig struct {
|
||||
Gossiper Gossiper
|
||||
// VM implements BlockBuilder for block creation
|
||||
VM BlockBuilder
|
||||
// Params are optional consensus parameters. If nil, DefaultParams() is used.
|
||||
// For small validator sets (e.g., 5 nodes), use LocalParams() which has
|
||||
// K=5, Beta=4 - appropriate thresholds for the validator count.
|
||||
Params *config.Parameters
|
||||
}
|
||||
|
||||
// Gossiper abstracts the network layer for consensus message broadcasting.
|
||||
@@ -40,39 +44,50 @@ type Gossiper interface {
|
||||
GossipPut(chainID ids.ID, networkID ids.ID, blockData []byte) int
|
||||
// SendPullQuery sends a PullQuery to specific validators requesting votes.
|
||||
SendPullQuery(chainID ids.ID, networkID ids.ID, blockID ids.ID, validators []ids.NodeID) int
|
||||
// SendVote sends a vote response back to the proposer node.
|
||||
// Vote response back to the proposer
|
||||
// This is called after fast-follow acceptance to notify the proposer
|
||||
// that this node has accepted the block, enabling the proposer to
|
||||
// reach vote threshold and finalize its own copy.
|
||||
SendVote(chainID ids.ID, toNodeID ids.NodeID, blockID ids.ID) error
|
||||
}
|
||||
|
||||
// IntegratedEngine wraps Transitive with network integration and VM notification handling.
|
||||
// Use NewIntegratedEngine to create - this is the "one right way" to set up consensus.
|
||||
type IntegratedEngine struct {
|
||||
// Runtime wraps Transitive with network integration and VM notification handling.
|
||||
// Use NewRuntime to create - this is the "one right way" to set up consensus.
|
||||
type Runtime struct {
|
||||
*Transitive
|
||||
config NetworkConfig
|
||||
}
|
||||
|
||||
// NewIntegratedEngine creates a fully wired consensus engine ready for production use.
|
||||
// NewRuntime creates a fully wired consensus runtime ready for production use.
|
||||
//
|
||||
// This is the single, canonical way to create a chain consensus engine for node integration.
|
||||
// This is the single, canonical way to create a chain consensus runtime for node integration.
|
||||
// It:
|
||||
// 1. Creates the Transitive engine with default parameters
|
||||
// 2. Wires the network gossiper as the BlockProposer
|
||||
// 3. Registers the VM for block building
|
||||
// 4. Returns a ready-to-start engine
|
||||
// 4. Returns a ready-to-start runtime
|
||||
//
|
||||
// Usage in manager.go:
|
||||
//
|
||||
// engine := chain.NewIntegratedEngine(chain.NetworkConfig{
|
||||
// runtime := chain.NewRuntime(chain.NetworkConfig{
|
||||
// ChainID: chainParams.ID,
|
||||
// NetworkID: chainParams.ChainID, // PrimaryNetworkID for P/X/C
|
||||
// Logger: m.Log,
|
||||
// Gossiper: &networkGossiper{net: m.Net, msgCreator: m.MsgCreator},
|
||||
// VM: vm.(chain.BlockBuilder),
|
||||
// })
|
||||
// if err := engine.Start(ctx, true); err != nil { return err }
|
||||
// go engine.ForwardVMNotifications(toEngine)
|
||||
func NewIntegratedEngine(cfg NetworkConfig) *IntegratedEngine {
|
||||
engine := NewWithParams(config.DefaultParams())
|
||||
// if err := runtime.Start(ctx, true); err != nil { return err }
|
||||
// go runtime.ForwardVMNotifications(toEngine)
|
||||
func NewRuntime(cfg NetworkConfig) *Runtime {
|
||||
// Use provided params or default
|
||||
params := config.DefaultParams()
|
||||
if cfg.Params != nil {
|
||||
params = *cfg.Params
|
||||
}
|
||||
engine := NewWithParams(params)
|
||||
|
||||
ie := &IntegratedEngine{
|
||||
rt := &Runtime{
|
||||
Transitive: engine,
|
||||
config: cfg,
|
||||
}
|
||||
@@ -90,7 +105,7 @@ func NewIntegratedEngine(cfg NetworkConfig) *IntegratedEngine {
|
||||
engine.SetVM(cfg.VM)
|
||||
}
|
||||
|
||||
return ie
|
||||
return rt
|
||||
}
|
||||
|
||||
// ForwardVMNotifications reads from the VM's toEngine channel and forwards
|
||||
@@ -98,33 +113,33 @@ func NewIntegratedEngine(cfg NetworkConfig) *IntegratedEngine {
|
||||
//
|
||||
// Call this as a goroutine after Start():
|
||||
//
|
||||
// go engine.ForwardVMNotifications(toEngine)
|
||||
// go runtime.ForwardVMNotifications(toEngine)
|
||||
//
|
||||
// The goroutine exits when the channel is closed.
|
||||
func (ie *IntegratedEngine) ForwardVMNotifications(toEngine <-chan block.Message) {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Info("starting VM notification forwarder for Lux consensus",
|
||||
log.Stringer("chainID", ie.config.ChainID))
|
||||
func (rt *Runtime) ForwardVMNotifications(toEngine <-chan block.Message) {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("starting VM notification forwarder for Lux consensus",
|
||||
log.Stringer("chainID", rt.config.ChainID))
|
||||
}
|
||||
|
||||
for msg := range toEngine {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Debug("received VM notification, forwarding to consensus engine",
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("received VM notification, forwarding to consensus engine",
|
||||
log.Uint32("type", uint32(msg.Type)))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := ie.Notify(ctx, Message{Type: MessageType(msg.Type)}); err != nil {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Warn("failed to notify consensus engine",
|
||||
if err := rt.Notify(ctx, Message{Type: MessageType(msg.Type)}); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Warn("failed to notify consensus engine",
|
||||
log.Uint32("type", uint32(msg.Type)),
|
||||
log.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Info("VM notification forwarder stopped")
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("VM notification forwarder stopped")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,21 +195,27 @@ func (p *gossiperProposer) RequestVotes(ctx context.Context, req VoteRequest) er
|
||||
}
|
||||
|
||||
// HandleIncomingBlock processes a block received from network gossip.
|
||||
// Instead of auto-accepting, it:
|
||||
// 1. Parses and verifies the block
|
||||
// 2. Adds it to pending blocks for consensus tracking
|
||||
// 3. Votes in favor of the block
|
||||
// For follower nodes receiving blocks from the proposer, this uses a "fast-follow"
|
||||
// pattern where verified blocks extending the accepted chain are accepted immediately.
|
||||
//
|
||||
// This is necessary because in the current architecture, votes are only sent back
|
||||
// to the proposer (not gossiped to all validators). So followers would never reach
|
||||
// the vote threshold on their own. Instead, followers trust that:
|
||||
// 1. The proposer collected enough votes before gossiping the block
|
||||
// 2. The block verifies correctly against their state
|
||||
// 3. The block extends their current chain tip
|
||||
//
|
||||
// Returns the parsed block if successful, nil otherwise.
|
||||
func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData []byte, fromNodeID ids.NodeID) (block.Block, error) {
|
||||
if ie.config.VM == nil {
|
||||
func (rt *Runtime) HandleIncomingBlock(ctx context.Context, blockData []byte, fromNodeID ids.NodeID) (block.Block, error) {
|
||||
if rt.config.VM == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Parse the block
|
||||
blk, err := ie.config.VM.ParseBlock(ctx, blockData)
|
||||
blk, err := rt.config.VM.ParseBlock(ctx, blockData)
|
||||
if err != nil {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Debug("failed to parse incoming block",
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("failed to parse incoming block",
|
||||
log.Stringer("from", fromNodeID),
|
||||
log.Err(err))
|
||||
}
|
||||
@@ -203,8 +224,8 @@ func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData [
|
||||
|
||||
// Verify the block
|
||||
if err := blk.Verify(ctx); err != nil {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Debug("incoming block failed verification",
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("incoming block failed verification",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Stringer("from", fromNodeID),
|
||||
log.Err(err))
|
||||
@@ -212,13 +233,88 @@ func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData [
|
||||
return nil, nil // Don't return error - just skip invalid blocks
|
||||
}
|
||||
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Info("received and verified block from gossip",
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("received and verified block from gossip",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Uint64("height", blk.Height()),
|
||||
log.Stringer("from", fromNodeID))
|
||||
}
|
||||
|
||||
// Fast-follow pattern: Accept blocks that extend our chain from valid proposers
|
||||
// This is safe because:
|
||||
// 1. Block has been verified (cryptographic integrity, state transitions)
|
||||
// 2. Block came from a known validator (fromNodeID)
|
||||
// 3. Block extends our accepted chain (parent check below)
|
||||
lastAccepted, err := rt.config.VM.LastAccepted(ctx)
|
||||
if err == nil {
|
||||
parentID := blk.ParentID()
|
||||
// Accept if this block extends our last accepted block
|
||||
// OR if it's at height 1 (first block after genesis)
|
||||
if parentID == lastAccepted || blk.Height() == 1 {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("fast-follow: accepting block from validator",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Uint64("height", blk.Height()),
|
||||
log.Stringer("from", fromNodeID),
|
||||
log.Stringer("parent", parentID),
|
||||
log.Stringer("lastAccepted", lastAccepted))
|
||||
}
|
||||
|
||||
// Accept the block directly
|
||||
if err := blk.Accept(ctx); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Warn("failed to accept block in fast-follow",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Err(err))
|
||||
}
|
||||
} else {
|
||||
// Update VM preference to build on this block
|
||||
if err := rt.config.VM.SetPreference(ctx, blk.ID()); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Warn("failed to set preference after fast-follow accept",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Err(err))
|
||||
}
|
||||
}
|
||||
rt.Transitive.blocksAccepted++
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("fast-follow: block accepted successfully",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Uint64("height", blk.Height()))
|
||||
}
|
||||
|
||||
// CRITICAL: Send vote back to proposer so they can reach threshold
|
||||
// and finalize their own copy of the block. Without this, the
|
||||
// proposer (node1) stays at height 0 while followers advance.
|
||||
if rt.config.Gossiper != nil {
|
||||
if err := rt.config.Gossiper.SendVote(rt.config.ChainID, fromNodeID, blk.ID()); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Warn("failed to send vote to proposer after fast-follow",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Stringer("proposer", fromNodeID),
|
||||
log.Err(err))
|
||||
}
|
||||
} else {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Info("fast-follow: sent vote back to proposer",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Stringer("proposer", fromNodeID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return blk, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If fast-follow doesn't apply, fall back to consensus tracking
|
||||
// (This handles out-of-order blocks or conflicting chains)
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("block does not extend chain tip, adding to consensus tracking",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Uint64("height", blk.Height()))
|
||||
}
|
||||
|
||||
// Create consensus block and add to tracking
|
||||
consensusBlock := &Block{
|
||||
id: blk.ID(),
|
||||
@@ -229,9 +325,9 @@ func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData [
|
||||
}
|
||||
|
||||
// Add to consensus engine
|
||||
if err := ie.Transitive.consensus.AddBlock(ctx, consensusBlock); err != nil {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Debug("failed to add block to consensus",
|
||||
if err := rt.Transitive.consensus.AddBlock(ctx, consensusBlock); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("failed to add block to consensus",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Err(err))
|
||||
}
|
||||
@@ -239,9 +335,9 @@ func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData [
|
||||
}
|
||||
|
||||
// Add to pending blocks for tracking
|
||||
ie.Transitive.mu.Lock()
|
||||
if _, exists := ie.Transitive.pendingBlocks[blk.ID()]; !exists {
|
||||
ie.Transitive.pendingBlocks[blk.ID()] = &PendingBlock{
|
||||
rt.Transitive.mu.Lock()
|
||||
if _, exists := rt.Transitive.pendingBlocks[blk.ID()]; !exists {
|
||||
rt.Transitive.pendingBlocks[blk.ID()] = &PendingBlock{
|
||||
ConsensusBlock: consensusBlock,
|
||||
VMBlock: blk,
|
||||
ProposedAt: time.Now(),
|
||||
@@ -250,15 +346,15 @@ func (ie *IntegratedEngine) HandleIncomingBlock(ctx context.Context, blockData [
|
||||
}
|
||||
} else {
|
||||
// Block already tracked, increment vote count
|
||||
ie.Transitive.pendingBlocks[blk.ID()].VoteCount++
|
||||
rt.Transitive.pendingBlocks[blk.ID()].VoteCount++
|
||||
}
|
||||
ie.Transitive.mu.Unlock()
|
||||
rt.Transitive.mu.Unlock()
|
||||
|
||||
// Vote in favor of the block (process our vote)
|
||||
responses := map[ids.ID]int{blk.ID(): 1}
|
||||
if err := ie.Transitive.consensus.Poll(ctx, responses); err != nil {
|
||||
if ie.config.Logger != nil {
|
||||
ie.config.Logger.Debug("failed to vote on block",
|
||||
if err := rt.Transitive.consensus.Poll(ctx, responses); err != nil {
|
||||
if rt.config.Logger != nil {
|
||||
rt.config.Logger.Debug("failed to vote on block",
|
||||
log.Stringer("blockID", blk.ID()),
|
||||
log.Err(err))
|
||||
}
|
||||
|
||||
@@ -192,8 +192,8 @@ func (b *Bootstrapper) PullQuery(ctx context.Context, nodeID ids.NodeID, request
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chits handles chit messages
|
||||
func (b *Bootstrapper) Chits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error {
|
||||
// Vote handles vote messages
|
||||
func (b *Bootstrapper) Vote(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/luxfi/consensus/examples/01-simple-bridge
|
||||
|
||||
go 1.24.5
|
||||
go 1.25.5
|
||||
|
||||
require github.com/luxfi/dex v0.0.0
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ require github.com/luxfi/consensus v0.0.0
|
||||
require (
|
||||
github.com/ALTree/bigfloat v0.2.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf // indirect
|
||||
github.com/cloudflare/circl v1.6.2 // indirect
|
||||
github.com/consensys/gnark-crypto v0.19.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/luxfi/crypto v1.17.29 // indirect
|
||||
github.com/luxfi/crypto v1.17.31 // indirect
|
||||
github.com/luxfi/ids v1.2.5 // indirect
|
||||
github.com/luxfi/lattice/v7 v7.0.0 // indirect
|
||||
github.com/luxfi/corona v0.2.0 // indirect
|
||||
@@ -23,7 +23,7 @@ require (
|
||||
github.com/supranational/blst v0.3.16 // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -2,8 +2,7 @@ github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM
|
||||
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
|
||||
github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE=
|
||||
github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf h1:+0huF756d72ZdHxachRP5HYmvRkkOk8CLyKUmJM138c=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
|
||||
github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80=
|
||||
github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -18,8 +17,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
|
||||
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
|
||||
github.com/luxfi/crypto v1.17.29 h1:QfsRCxRBTWzlMbDD5tncjW/bKlh9LHzj/oUCXdXJLz0=
|
||||
github.com/luxfi/crypto v1.17.29/go.mod h1:B28NGjs40QN3hrQwhsP9lyLfWzlxS6UGTX4cQHLe7xk=
|
||||
github.com/luxfi/crypto v1.17.31 h1:XLHRG49WA5bjp8D/zghWvipSV9ynwFGO2VlbTYcaV9Y=
|
||||
github.com/luxfi/ids v1.2.5 h1:w4YSj3S6LQiUXhiChUmcbrMCRMfkCaBFIGn0Eo4ZSxk=
|
||||
github.com/luxfi/ids v1.2.5/go.mod h1:vZBjJWSmqMIZuodgnoszvTDvXIwsbnhM2pkktg6FGrg=
|
||||
github.com/luxfi/lattice/v7 v7.0.0 h1:d1vgan6mlb2KtwYfPc1g69uxVYaoVYZmlrIm4aCO88w=
|
||||
@@ -46,8 +44,7 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
|
||||
@@ -5,15 +5,23 @@ go 1.25.5
|
||||
replace github.com/luxfi/consensus => ../..
|
||||
|
||||
require (
|
||||
github.com/luxfi/consensus v0.0.0
|
||||
github.com/luxfi/consensus v1.22.9
|
||||
github.com/luxfi/ids v1.2.5
|
||||
github.com/stretchr/testify v1.11.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/holiman/uint256 v1.3.2 // indirect
|
||||
github.com/luxfi/crypto v1.17.31 // indirect
|
||||
github.com/luxfi/log v1.1.26 // indirect
|
||||
github.com/luxfi/vm v1.0.2 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/luxfi/crypto v1.17.31 h1:XLHRG49WA5bjp8D/zghWvipSV9ynwFGO2VlbTYcaV9Y=
|
||||
github.com/luxfi/ids v1.2.5 h1:w4YSj3S6LQiUXhiChUmcbrMCRMfkCaBFIGn0Eo4ZSxk=
|
||||
github.com/luxfi/log v1.1.26 h1:ECnJ4wV7TF6WZ5gC6CD6ddZ4OhF+zhQij4bgVUhumDg=
|
||||
github.com/luxfi/vm v1.0.2 h1:JnMm6QTh1nwWKXFy4Qf9Ej38KyXzFeprcy3Rp8/516s=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -26,11 +26,11 @@ require (
|
||||
require (
|
||||
github.com/ALTree/bigfloat v0.2.0 // indirect
|
||||
github.com/DataDog/zstd v1.5.7 // indirect
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 // indirect
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251230134950-44c893854e3f // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf // indirect
|
||||
github.com/cloudflare/circl v1.6.2 // indirect
|
||||
github.com/cockroachdb/errors v1.12.0 // indirect
|
||||
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect
|
||||
@@ -42,21 +42,23 @@ require (
|
||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.8.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.9.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emicklei/dot v1.10.0 // indirect
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect
|
||||
github.com/ethereum/go-verkle v0.2.2 // indirect
|
||||
github.com/getsentry/sentry-go v0.35.1 // indirect
|
||||
github.com/getsentry/sentry-go v0.40.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gofrs/flock v0.13.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/google/flatbuffers v25.12.19+incompatible // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/gorilla/rpc v1.2.1 // indirect
|
||||
github.com/holiman/uint256 v1.3.2 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.18.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
@@ -69,6 +71,8 @@ require (
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/onsi/gomega v1.38.3 // indirect
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/common v0.67.4 // indirect
|
||||
@@ -76,16 +80,18 @@ require (
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/supranational/blst v0.3.16 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
|
||||
@@ -2,8 +2,7 @@ github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM
|
||||
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
|
||||
github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=
|
||||
github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 h1:RNTau6sw5B3ltE+2GlzEom63eBMzoLUc+dhjmdIwNpI=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251230134950-44c893854e3f h1:a5PUgHGinaD6XrLmIDLQmGHocjIjBsBAcR5gALjZvMU=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE=
|
||||
@@ -13,8 +12,7 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf h1:+0huF756d72ZdHxachRP5HYmvRkkOk8CLyKUmJM138c=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
|
||||
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
|
||||
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
||||
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
|
||||
@@ -44,16 +42,13 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dgraph-io/badger/v4 v4.8.0 h1:JYph1ChBijCw8SLeybvPINizbDKWZ5n/GYbz2yhN/bs=
|
||||
github.com/dgraph-io/badger/v4 v4.8.0/go.mod h1:U6on6e8k/RTbUWxqKR0MvugJuVmkxSNc79ap4917h4w=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
|
||||
github.com/dgraph-io/badger/v4 v4.9.0 h1:tpqWb0NewSrCYqTvywbcXOhQdWcqephkVkbBmaaqHzc=
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0 h1:qTQ38m7oIyd4GAed/QkUZyPFNMnvVWyazGXRwvOt5zk=
|
||||
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
|
||||
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emicklei/dot v1.9.0 h1:FyaJNctdMfaEIbTQ1FkKZ1UCZyJJSkyvkrXOVoNZPKU=
|
||||
github.com/emicklei/dot v1.9.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
|
||||
github.com/emicklei/dot v1.10.0 h1:z17n0ce/FBMz3QbShSzVGhiW447Qhu7fljzvp3Gs6ig=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs=
|
||||
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
|
||||
@@ -65,8 +60,7 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/getsentry/sentry-go v0.35.1 h1:iopow6UVLE2aXu46xKVIs8Z9D/YZkJrHkgozrxa+tOQ=
|
||||
github.com/getsentry/sentry-go v0.35.1/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=
|
||||
github.com/getsentry/sentry-go v0.40.0 h1:VTJMN9zbTvqDqPwheRVLcp0qcUcM+8eFivvGocAaSbo=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -77,8 +71,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
|
||||
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
|
||||
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -93,8 +86,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -110,8 +102,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -178,10 +169,9 @@ github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM=
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -210,10 +200,8 @@ github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jq
|
||||
github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
|
||||
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
|
||||
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
|
||||
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
|
||||
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
|
||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
@@ -224,14 +212,11 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
|
||||
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
@@ -242,13 +227,13 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
||||
@@ -43,5 +43,8 @@ const (
|
||||
Put = router.Put
|
||||
PushQuery = router.PushQuery
|
||||
PullQuery = router.PullQuery
|
||||
Chits = router.Chits
|
||||
Vote = router.Vote
|
||||
GetContext = router.GetContext
|
||||
Context = router.Context
|
||||
)
|
||||
|
||||
|
||||
@@ -45,5 +45,5 @@ const (
|
||||
Put = router.Put
|
||||
PushQuery = router.PushQuery
|
||||
PullQuery = router.PullQuery
|
||||
Chits = router.Chits
|
||||
Vote = router.Vote
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ const (
|
||||
Put = router.Put
|
||||
PushQuery = router.PushQuery
|
||||
PullQuery = router.PullQuery
|
||||
Chits = router.Chits
|
||||
Vote = router.Vote
|
||||
)
|
||||
|
||||
// manager implementation
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/luxfi/crypto/bls"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/math/math"
|
||||
"github.com/luxfi/math"
|
||||
"github.com/luxfi/math/set"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user