Files
zeekay 7cf87b230b node-unified is the node
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.
2026-09-07 16:15:25 -07:00

126 lines
3.5 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package timer
import (
"encoding/binary"
"time"
)
// ProgressFromHash returns the progress out of MaxUint64 assuming [b] is a key
// in a uniformly distributed sequence that is being iterated lexicographically.
func ProgressFromHash(b []byte) uint64 {
// binary.BigEndian.Uint64 will panic if the input length is less than 8, so
// pad 0s as needed.
var progress [8]byte
copy(progress[:], b)
return binary.BigEndian.Uint64(progress[:])
}
// EstimateETA attempts to estimate the remaining time for a job to finish given
// the [startTime] and it's current progress.
func EstimateETA(startTime time.Time, progress, end uint64) time.Duration {
timeSpent := time.Since(startTime)
percentExecuted := float64(progress) / float64(end)
estimatedTotalDuration := time.Duration(float64(timeSpent) / percentExecuted)
eta := estimatedTotalDuration - timeSpent
return eta.Round(time.Second)
}
// EtaTracker provides exponentially weighted moving average ETA estimates
type EtaTracker struct {
startTime time.Time
samples int
alpha float64
sampleCount int
lastProgress uint64
lastSampleTime time.Time
}
// NewEtaTracker creates a new ETA tracker with the given number of samples and alpha
func NewEtaTracker(samples int, alpha float64) *EtaTracker {
return &EtaTracker{
startTime: time.Now(),
samples: samples,
alpha: alpha,
}
}
// Update updates the ETA tracker with new progress
func (e *EtaTracker) Update(progress, total uint64) {
// Simple implementation - just track the time
}
// AddSample adds a sample to the ETA tracker and returns ETA pointer and progress percentage
func (e *EtaTracker) AddSample(progress, total uint64, sampleTime time.Time) (*time.Duration, float64) {
if total == 0 {
return nil, 0
}
// Initialize start time on first sample
if e.sampleCount == 0 {
e.startTime = sampleTime
e.lastProgress = progress
e.lastSampleTime = sampleTime
}
// Update sample count
e.sampleCount++
// Check if we have enough samples
if e.sampleCount < e.samples {
e.lastProgress = progress
e.lastSampleTime = sampleTime
return nil, 0
}
// Check if time went backwards
if sampleTime.Before(e.lastSampleTime) {
return nil, 0
}
// Check if progress didn't advance
if progress <= e.lastProgress {
return nil, 0
}
// If we're at or past the end, return 0 ETA immediately
if progress >= total {
e.lastProgress = progress
e.lastSampleTime = sampleTime
eta := time.Duration(0)
return &eta, 100.0
}
// Calculate ETA based on recent rate (since last sample), not overall rate
// This allows us to detect acceleration/deceleration
timeSinceLastSample := sampleTime.Sub(e.lastSampleTime)
progressSinceLastSample := progress - e.lastProgress
if timeSinceLastSample > 0 && progressSinceLastSample > 0 {
// Calculate rate: progress per unit time
rate := float64(progressSinceLastSample) / timeSinceLastSample.Seconds()
remaining := total - progress
etaSeconds := float64(remaining) / rate
eta := time.Duration(etaSeconds * float64(time.Second)).Round(time.Second)
e.lastProgress = progress
e.lastSampleTime = sampleTime
progressPercent := (float64(progress) / float64(total)) * 100
return &eta, progressPercent
}
e.lastProgress = progress
e.lastSampleTime = sampleTime
return nil, 0
}
// ETA returns the estimated time remaining
func (e *EtaTracker) ETA(progress, total uint64) time.Duration {
return EstimateETA(e.startTime, progress, total)
}