Skip to content

Commit

Permalink
Release
Browse files Browse the repository at this point in the history
  • Loading branch information
inkeliz committed Jun 1, 2020
1 parent 667c29a commit c7f05fa
Show file tree
Hide file tree
Showing 13 changed files with 941 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
*.apk

# Test binary, built with `go test -c`
*.test
Expand All @@ -13,3 +14,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/

.idea
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Golang NanoPoW

NanoPoW is an implementation of the proof-of-work used by Nano. That supports CPU and GPU (currently only OpenCL).

## Usage



```golang
func main() {
nanopow.GenerateWork([]byte{/** PREVIOUS HASH **/}, nanopow.V1BaseDifficult)
}
```

### CPU

By default, we always uses CPU. If GPU is available, it will use CPU and GPU, combined.

### GPU

By default, we don't support GPU. You need to enable it using the "build tags", when build use:

```bash
go build -tags cl
```

Currently the only available option is OpenCL ("cl" tag).


## "Benchmarks"

I don't have an huge amount of data to compare and limited devices to test against. Some devices doesn't supports OpenCL. All times are using the V1 difficulty.


| Device | OS | CPU-Only | CPU + OpenCL
| ------------- | ------------- | ------------- |------------- |
| Samsung Galaxy S20+ | Android | ~9.62 seg | _Untested_ |
| Blackberry KeyOne | Android | ~36.7 seg | _Untested_ |
| | | |
| R9 3900X + RX 5700XT | Windows | ~0.66 seg | ~0.27 seg |


## Limitations

#### Support OpenGL, OpenGLES or Vulkan:

Currently we only support OpenCL, which is not natively supported by some devices. I have some plans to add some support for OpenGL, OpenGLES or Vulkan. Seems that Vulkan Compute, if possible, is the best solution since it's compatible with Windows, Linux and Android.

#### Support multi-GPU:

Currently only one GPU is supported, but it can be easily fixed, but I don't have a multi-GPU setup to be able to test. :(


## Contributing
Pull requests are welcome.

## License
[MIT](https://choosealicense.com/licenses/mit/)
52 changes: 52 additions & 0 deletions cpu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package nanopow

import (
"encoding/binary"
"golang.org/x/crypto/blake2b"
"math"
"runtime"
)

type cpuWorker struct {
thread uint64
}

func NewWorkerCPU() (*cpuWorker, error) {
return NewWorkerCPUThread(uint64(runtime.NumCPU()))
}

func NewWorkerCPUThread(threads uint64) (*cpuWorker, error) {
return &cpuWorker{thread: threads}, nil
}

func (w *cpuWorker) GenerateWork(ctx *Context, root []byte, difficulty uint64) (err error) {
for i := uint64(0); i < w.thread; i++ {
go w.generateWork(ctx, root, difficulty, math.MaxUint32 + ((math.MaxUint32 / w.thread) * i))
}

return nil
}

func (w *cpuWorker) generateWork(ctx *Context, root []byte, difficulty uint64, result uint64) (err error) {
h, _ := blake2b.New(8, nil)
nonce := make([]byte, 40)
copy(nonce[8:], root)

for ; ; result++ {
select {
default:
binary.LittleEndian.PutUint64(nonce[:8], result) // Using `binary.Write(h, ...) is worse

h.Write(nonce)

if binary.LittleEndian.Uint64(h.Sum(nil)) >= difficulty {
ctx.workerResult(result)
return nil
}

h.Reset()
case <-ctx.workerStop():
return nil
}
}
}
32 changes: 32 additions & 0 deletions cpu_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package nanopow

import (
"math/rand"
"testing"
)

func TestNewWorkerCPU(t *testing.T) {
rand.Seed(1) // To make always test the same

hash, difficulty := make([]byte, 32), CalculateDifficulty(0)
rand.Read(hash)

cpu, err := NewWorkerCPU()
if err != nil {
t.Fatal(err)
}

ctx := NewContext()

if err := cpu.GenerateWork(ctx, hash, difficulty); err != nil {
t.Error(err)
}

w := ctx.Result()

if IsValid(hash, difficulty, w) == false {
t.Error("create invalid work")
}

return
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/inkeliz/nanopow

go 1.14

require (
github.com/Inkeliz/go-opencl v0.0.0-20200513154410-b275e70a49ac
github.com/stretchr/testify v1.6.0 // indirect
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/exp/errors v0.0.0-20200513190911-00229845015e
)
23 changes: 23 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
github.com/Inkeliz/go-opencl v0.0.0-20200513154410-b275e70a49ac h1:mC2j+cY2TGhNkTB3OK1RaL3wI1+cN9GH7Tt8hjl7Mfk=
github.com/Inkeliz/go-opencl v0.0.0-20200513154410-b275e70a49ac/go.mod h1:9ILtD1/UTP/Y7JMCU8loWZMDvhrQuTgHzHatG6z9ZdQ=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp/errors v0.0.0-20200513190911-00229845015e h1:Ig6CpZm9nvqybF+P3mORbWMG22rp2qZnx/RU8FzdlMc=
golang.org/x/exp/errors v0.0.0-20200513190911-00229845015e/go.mod h1:YgqsNsAu4fTvlab/7uiYK9LJrCIzKg/NiZUIH1/ayqo=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
17 changes: 17 additions & 0 deletions gpu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// +build !cl,!vk,!gl

package nanopow

type noneGPUWorker struct {}

func NewWorkerGPU() (*noneGPUWorker, error) {
return NewWorkerGPUThread(0)
}

func NewWorkerGPUThread(_ uint64) (*noneGPUWorker, error) {
return nil, ErrNotSupported
}

func (w *noneGPUWorker) GenerateWork(ctx *Context, root []byte, difficulty uint64) (err error) {
return ErrNotSupported
}
Loading

0 comments on commit c7f05fa

Please sign in to comment.