mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
172 lines
4.2 KiB
Go
172 lines
4.2 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package scheduler
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/luxfi/log"
|
|
vmcore "github.com/luxfi/vm"
|
|
)
|
|
|
|
// AutominingScheduler is a scheduler that continuously produces blocks at a fixed interval
|
|
type AutominingScheduler interface {
|
|
Scheduler
|
|
|
|
// StartAutomining starts continuous block production
|
|
StartAutomining(interval time.Duration)
|
|
// StopAutomining stops continuous block production
|
|
StopAutomining()
|
|
}
|
|
|
|
type autominingScheduler struct {
|
|
*scheduler
|
|
|
|
// Channel to control automining
|
|
autominingControl chan autominingCommand
|
|
// Whether automining is currently active
|
|
autominingActive bool
|
|
// Interval between automatic block productions
|
|
autominingInterval time.Duration
|
|
}
|
|
|
|
type autominingCommand struct {
|
|
start bool
|
|
interval time.Duration
|
|
}
|
|
|
|
// NewAutomining creates a new scheduler with automining capabilities
|
|
func NewAutomining(log log.Logger, toEngine chan<- vmcore.Message) (AutominingScheduler, chan<- vmcore.Message) {
|
|
vmToEngine := make(chan vmcore.Message, cap(toEngine))
|
|
baseScheduler := &scheduler{
|
|
log: log,
|
|
fromVM: vmToEngine,
|
|
toEngine: toEngine,
|
|
newBuildBlockTime: make(chan time.Time),
|
|
}
|
|
|
|
return &autominingScheduler{
|
|
scheduler: baseScheduler,
|
|
autominingControl: make(chan autominingCommand, 1),
|
|
}, vmToEngine
|
|
}
|
|
|
|
func (s *autominingScheduler) Dispatch(buildBlockTime time.Time) {
|
|
timer := time.NewTimer(time.Until(buildBlockTime))
|
|
defer timer.Stop()
|
|
|
|
// Automining ticker - initially stopped
|
|
autominingTicker := time.NewTicker(time.Hour)
|
|
autominingTicker.Stop()
|
|
defer autominingTicker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-timer.C: // It's time to tell the engine to try to build a block
|
|
s.handleBuildRequest()
|
|
|
|
// If automining is active, reset the timer for the next block
|
|
if s.autominingActive {
|
|
timer.Reset(s.autominingInterval)
|
|
}
|
|
|
|
case <-autominingTicker.C: // Automining interval elapsed
|
|
s.handleBuildRequest()
|
|
|
|
case cmd := <-s.autominingControl:
|
|
if cmd.start {
|
|
s.log.Info("starting automining",
|
|
log.Duration("interval", cmd.interval),
|
|
)
|
|
s.autominingActive = true
|
|
s.autominingInterval = cmd.interval
|
|
|
|
// Stop the regular timer and start automining ticker
|
|
if !timer.Stop() {
|
|
select {
|
|
case <-timer.C:
|
|
default:
|
|
}
|
|
}
|
|
|
|
autominingTicker.Reset(cmd.interval)
|
|
} else {
|
|
s.log.Info("stopping automining")
|
|
s.autominingActive = false
|
|
autominingTicker.Stop()
|
|
|
|
// Reset the regular timer
|
|
timer.Reset(time.Until(buildBlockTime))
|
|
}
|
|
|
|
case buildBlockTime, ok := <-s.newBuildBlockTime:
|
|
// Stop the timer and clear [timer.C] if needed
|
|
if !timer.Stop() {
|
|
select {
|
|
case <-timer.C:
|
|
default:
|
|
}
|
|
}
|
|
|
|
if !ok {
|
|
// s.Close() was called
|
|
return
|
|
}
|
|
|
|
// Only update the timer if automining is not active
|
|
if !s.autominingActive {
|
|
timer.Reset(time.Until(buildBlockTime))
|
|
}
|
|
|
|
case msg := <-s.fromVM:
|
|
// Forward the message from VM to engine
|
|
select {
|
|
case s.toEngine <- msg:
|
|
default:
|
|
// If the channel to the engine is full, drop the message
|
|
s.log.Debug("dropping message from VM",
|
|
log.String("reason", "channel to engine is full"),
|
|
log.Reflect("message", msg),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *autominingScheduler) handleBuildRequest() {
|
|
// Send a build block message to the engine
|
|
msg := vmcore.Message{Type: vmcore.PendingTxs}
|
|
select {
|
|
case s.toEngine <- msg:
|
|
s.log.Debug("sent build block request to engine",
|
|
log.Bool("automining", s.autominingActive),
|
|
)
|
|
default:
|
|
s.log.Debug("dropping build block request",
|
|
log.String("reason", "channel to engine is full"),
|
|
)
|
|
}
|
|
}
|
|
|
|
func (s *autominingScheduler) StartAutomining(interval time.Duration) {
|
|
select {
|
|
case s.autominingControl <- autominingCommand{start: true, interval: interval}:
|
|
default:
|
|
s.log.Warn("automining control channel full, command dropped")
|
|
}
|
|
}
|
|
|
|
func (s *autominingScheduler) StopAutomining() {
|
|
select {
|
|
case s.autominingControl <- autominingCommand{start: false}:
|
|
default:
|
|
s.log.Warn("automining control channel full, command dropped")
|
|
}
|
|
}
|
|
|
|
func (s *autominingScheduler) Close() {
|
|
s.scheduler.Close()
|
|
close(s.autominingControl)
|
|
}
|