Skip to content

Commit

Permalink
feat: support cuda worker
Browse files Browse the repository at this point in the history
  • Loading branch information
hunjixin authored and hunjixin committed Jun 21, 2024
1 parent 34182bb commit 221c765
Show file tree
Hide file tree
Showing 14 changed files with 1,022 additions and 199 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ require (
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/holiman/uint256 v1.2.4
github.com/ipfs/go-merkledag v0.11.0
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.31.0
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
github.com/theckman/yacspin v0.13.12
gorgonia.org/cu v0.9.6
k8s.io/apimachinery v0.28.3
)

replace gorgonia.org/cu => github.com/hunjixin/cu v0.0.0-20240618140529-d11ba74b75b6

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
Expand Down
147 changes: 147 additions & 0 deletions go.sum

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion pkg/options/resource-provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ func NewResourceProviderOptions() resourceprovider.ResourceProviderOptions {

func GetDefaultResourceProviderPowOptions() resourceprovider.ResourceProviderPowOptions {
return resourceprovider.ResourceProviderPowOptions{
EnablePow: GetDefaultServeOptionBool("ENABLE_POW", false),
EnablePow: GetDefaultServeOptionBool("ENABLE_POW", false),
NumWorkers: GetDefaultServeOptionInt("NUM_WORKER", 0),

CudaGridSize: GetDefaultServeOptionInt("CUDA_GRID_SIZE", 256),
CudaBlockSize: GetDefaultServeOptionInt("CUDA_BLOCK_SIZE", 512),
}
}

Expand Down Expand Up @@ -84,6 +88,19 @@ func AddResourceProviderPowCliFlags(cmd *cobra.Command, options *resourceprovide
&options.EnablePow, "enable-pow", options.EnablePow,
`Start pow mining (ENABLE_POW)`,
)
cmd.PersistentFlags().IntVar(
&options.NumWorkers, "num-worker", options.NumWorkers,
`Start pow mining (NUM_WORKER)`,
)

cmd.PersistentFlags().IntVar(
&options.CudaGridSize, "cuda-grid-size", options.CudaGridSize,
`Cuda grid size (CUDA_GRID_SIZE)`,
)
cmd.PersistentFlags().IntVar(
&options.CudaBlockSize, "cuda-block-size", options.CudaBlockSize,
`Cuda block size (CUDA_BLOCK_SIZE)`,
)
}

func AddResourceProviderCliFlags(cmd *cobra.Command, options *resourceprovider.ResourceProviderOptions) {
Expand Down
109 changes: 109 additions & 0 deletions pkg/resourceprovider/cpuworker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package resourceprovider

import (
"context"
"math/big"
"sync/atomic"
"time"

"github.com/ethereum/go-ethereum/crypto"
"github.com/holiman/uint256"
"github.com/rs/zerolog/log"
)

var (
bigOne = uint256.NewInt(1)
)

type CpuWorker struct {
cfg *WorkerConfig

state atomic.Int32
quit chan chan struct{}
}

func NewCpuWorker(cfg *WorkerConfig) (Worker, error) {
return &CpuWorker{
cfg: cfg,
quit: make(chan chan struct{}, 1),
}, nil
}

func (w *CpuWorker) Stop() {
if w.state.Load() == 0 {
return
}

//cancel previous task
waitChan := make(chan struct{})
select {
case w.quit <- waitChan: // may already exit
<-waitChan
default:
}
}

func (w *CpuWorker) FindSolution(ctx context.Context, task *Task) {
w.state.Store(1)
defer w.state.Store(0)

nonce := task.From.Clone()
startTime := time.Now()

hashesCompleted := uint64(0)
ticker := time.NewTicker(time.Second * hashUpdateSecs)
defer ticker.Stop()

OUT:
for {
select {
case <-ctx.Done():
break OUT
case respCh := <-w.quit:
respCh <- struct{}{}
return
case <-ticker.C:
w.cfg.updateHashes <- hashesCompleted
hashesCompleted = 0
default:
// Non-blocking select to fall through
}

if nonce.Cmp(task.End) >= 0 {
return
}
hashNumber, err := calculateHashNumber(task.Challenge, nonce.ToBig())
if err != nil {
log.Err(err).Msg("Calculate hash number")
return
}
hashesCompleted += 1

// Check if the hash is below the target difficulty
if hashNumber.Cmp(task.Difficulty) == -1 {
log.Info().Str("Elapsed Time", time.Since(startTime).String()).
Str("challenge", new(big.Int).SetBytes(task.Challenge[:]).String()).
Str("Nonce", nonce.String()).
Str("HashNumber", hashNumber.String()).
Msg("Success!")
w.cfg.resultCh <- TaskResult{
Id: task.Id,
Nonce: nonce.Clone(),
}
}

nonce.Add(nonce, bigOne)
}
}

func calculateHashNumber(challenge [32]byte, nonce *big.Int) (*uint256.Int, error) {
data, err := formatMinerArgs(challenge, nonce)
if err != nil {
return nil, err
}

// Calculate Keccak-256 hash
hashResult := crypto.Keccak256(data)

return new(uint256.Int).SetBytes(hashResult), nil
}
File renamed without changes.
26 changes: 26 additions & 0 deletions pkg/resourceprovider/cudaminer/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Type Definitions for CUDA Hashing Algos
*
* Date: 12 June 2019
* Revision: 1
*
* This file is released into the Public Domain.
*/

#pragma once
#define USE_MD2 1
#define USE_MD5 1
#define USE_SHA1 1
#define USE_SHA256 1

#define CUDA_HASH 1
#define OCL_HASH 0

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long long LONG;

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
Loading

0 comments on commit 221c765

Please sign in to comment.