Add solver
This commit is contained in:
parent
859bd989be
commit
b4a1c4dc37
94
internal/pow/solver/solver.go
Normal file
94
internal/pow/solver/solver.go
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package solver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
|
||||
"hash-of-wisdom/internal/pow/challenge"
|
||||
)
|
||||
|
||||
// Solver handles parallel PoW solving with configurable parallelism
|
||||
type Solver struct {
|
||||
workers int
|
||||
}
|
||||
|
||||
// SolverOption represents functional options for solver configuration
|
||||
type solverOption func(*Solver)
|
||||
|
||||
// WithWorkers sets the number of parallel workers
|
||||
func WithWorkers(workers int) solverOption {
|
||||
return func(s *Solver) {
|
||||
s.workers = workers
|
||||
}
|
||||
}
|
||||
|
||||
// NewSolver creates a new parallel PoW solver
|
||||
func NewSolver(options ...solverOption) *Solver {
|
||||
solver := &Solver{
|
||||
workers: runtime.NumCPU(), // Default to CPU count
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(solver)
|
||||
}
|
||||
|
||||
return solver
|
||||
}
|
||||
|
||||
// Solve attempts to find a valid nonce for the given challenge
|
||||
func (s *Solver) Solve(ctx context.Context, ch *challenge.Challenge) (*challenge.Solution, error) {
|
||||
// Create cancellable context for workers
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// Channel to receive solution from any worker
|
||||
solutionCh := make(chan *challenge.Solution, 1)
|
||||
|
||||
// Shared nonce counter for work distribution
|
||||
var nonceCounter atomic.Uint64
|
||||
|
||||
// Start parallel workers
|
||||
for i := range s.workers {
|
||||
go func(workerID int) {
|
||||
s.worker(ctx, ch, &nonceCounter, solutionCh)
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait for either solution or context cancellation
|
||||
select {
|
||||
case solution := <-solutionCh:
|
||||
return solution, nil
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// worker performs PoW computation in parallel
|
||||
func (s *Solver) worker(ctx context.Context, ch *challenge.Challenge, nonceCounter *atomic.Uint64, solutionCh chan<- *challenge.Solution) {
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
// Get next nonce to try
|
||||
nonce := nonceCounter.Add(1) - 1
|
||||
|
||||
// Try this nonce
|
||||
if ch.VerifySolution(nonce) {
|
||||
// Found solution! Send it back
|
||||
solution := &challenge.Solution{
|
||||
Challenge: *ch,
|
||||
Nonce: nonce,
|
||||
}
|
||||
|
||||
select {
|
||||
case solutionCh <- solution:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue