-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 50308a4
Showing
6 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Publish | ||
|
||
# Controls when the action will run. | ||
on: | ||
# Triggers the workflow on new SemVer tags | ||
push: | ||
branches: | ||
- master | ||
tags: | ||
- 'v[0-9]+.[0-9]+.[0-9]+' | ||
- 'v[0-9]+.[0-9]+.[0-9]+-**' | ||
|
||
concurrency: | ||
group: ${{ github.workflow }} | ||
|
||
jobs: | ||
docker: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
packages: write | ||
contents: read | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: docker/setup-qemu-action@v3 | ||
- uses: docker/setup-buildx-action@v3 | ||
- uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.repository_owner }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
- uses: docker/metadata-action@v5 | ||
name: generate tags | ||
id: meta | ||
with: | ||
images: ghcr.io/${{ github.repository }} | ||
tags: | | ||
type=ref,event=branch | ||
type=sha,prefix= | ||
type=semver,pattern={{version}} | ||
- uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
platforms: linux/amd64,linux/arm64 | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
FROM docker.io/library/golang:1.21 AS builder | ||
|
||
WORKDIR /cpuminerd | ||
|
||
# Install dependencies | ||
COPY go.mod go.sum ./ | ||
RUN go mod download | ||
|
||
# Copy source | ||
COPY . . | ||
|
||
# Enable CGO for sqlite3 support | ||
ENV CGO_ENABLED=1 | ||
|
||
RUN go generate ./... | ||
RUN go build -o bin/ -tags='netgo timetzdata' -trimpath -a -ldflags '-s -w' ./cmd/cpuminerd | ||
|
||
FROM scratch | ||
LABEL maintainer="The Sia Foundation <[email protected]>" \ | ||
org.opencontainers.image.description.vendor="The Sia Foundation" \ | ||
org.opencontainers.image.description="A basic cpu miner for mining using a walletd node" \ | ||
org.opencontainers.image.source="https://github.com/SiaFoundation/cpuminer" \ | ||
org.opencontainers.image.licenses=MIT | ||
|
||
ENV PUID=0 | ||
ENV PGID=0 | ||
|
||
# copy binary and prepare data dir. | ||
COPY --from=builder /cpuminerd/bin/* /usr/bin/ | ||
|
||
# API port | ||
EXPOSE 9980/tcp | ||
# RPC port | ||
EXPOSE 9981/tcp | ||
|
||
USER ${PUID}:${PGID} | ||
|
||
ENTRYPOINT [ "cpuminerd" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# CPU Miner | ||
|
||
A very simple (and naive) single-threaded CPU miner for Siacoin testnet mining | ||
|
||
## Usage | ||
|
||
```bash | ||
./cpuminerd --addr="addr:000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69" --http="http://localhost:9980/api" --password="sia is cool" | ||
``` | ||
|
||
## Docker Compose | ||
```yml | ||
services: | ||
walletd: | ||
image: ghcr.io/siafoundation/walletd:master | ||
ports: | ||
- localhost:9980:9980 | ||
- 9981: 9981 | ||
volumes: | ||
- ./wallet:/data | ||
restart: unless-stopped | ||
cpu-miner: | ||
image: ghcr.io/siafoundation/cpuminer:master | ||
command: --addr="addr:000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69" --http="http://walletd:9980/api" --password="sia is cool" | ||
restart: unless-stopped | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"math/big" | ||
"os" | ||
"time" | ||
|
||
"go.sia.tech/core/types" | ||
"go.sia.tech/coreutils" | ||
"go.sia.tech/walletd/api" | ||
"go.uber.org/zap" | ||
"go.uber.org/zap/zapcore" | ||
"lukechampine.com/frand" | ||
) | ||
|
||
func runCPUMiner(c *api.Client, minerAddr types.Address, log *zap.Logger) { | ||
log.Info("starting cpu miner", zap.String("minerAddr", minerAddr.String())) | ||
start := time.Now() | ||
|
||
check := func(msg string, err error) bool { | ||
if err != nil { | ||
log.Error(msg, zap.Error(err)) | ||
time.Sleep(15 * time.Second) | ||
return false | ||
} | ||
return true | ||
} | ||
|
||
for { | ||
elapsed := time.Since(start) | ||
cs, err := c.ConsensusTipState() | ||
if !check("failed to get consensus tip state", err) { | ||
continue | ||
} | ||
|
||
d, _ := new(big.Int).SetString(cs.Difficulty.String(), 10) | ||
d.Mul(d, big.NewInt(int64(1+elapsed))) | ||
log := log.With(zap.Uint64("height", cs.Index.Height+1), zap.Stringer("parentID", cs.Index.ID), zap.Stringer("difficulty", d)) | ||
|
||
log.Debug("mining block") | ||
txns, v2txns, err := c.TxpoolTransactions() | ||
if !check("failed to get txpool transactions", err) { | ||
continue | ||
} | ||
|
||
b := types.Block{ | ||
ParentID: cs.Index.ID, | ||
Nonce: cs.NonceFactor() * frand.Uint64n(100), | ||
Timestamp: types.CurrentTimestamp(), | ||
MinerPayouts: []types.SiacoinOutput{{Address: minerAddr, Value: cs.BlockReward()}}, | ||
Transactions: txns, | ||
} | ||
for _, txn := range txns { | ||
b.MinerPayouts[0].Value = b.MinerPayouts[0].Value.Add(txn.TotalFees()) | ||
} | ||
for _, txn := range v2txns { | ||
b.MinerPayouts[0].Value = b.MinerPayouts[0].Value.Add(txn.MinerFee) | ||
} | ||
if len(v2txns) > 0 || cs.Index.Height+1 >= cs.Network.HardforkV2.RequireHeight { | ||
b.V2 = &types.V2BlockData{ | ||
Height: cs.Index.Height + 1, | ||
Transactions: v2txns, | ||
} | ||
b.V2.Commitment = cs.Commitment(cs.TransactionsCommitment(b.Transactions, b.V2Transactions()), b.MinerPayouts[0].Address) | ||
} | ||
|
||
if !coreutils.FindBlockNonce(cs, &b, time.Minute) { | ||
log.Debug("failed to find nonce") | ||
continue | ||
} | ||
log.Debug("found nonce", zap.Uint64("nonce", b.Nonce)) | ||
index := types.ChainIndex{Height: cs.Index.Height + 1, ID: b.ID()} | ||
tip, err := c.ConsensusTip() | ||
if !check("failed to get consensus tip:", err) { | ||
continue | ||
} | ||
|
||
if tip != cs.Index { | ||
log.Info("mined stale block", zap.Stringer("current", tip), zap.Stringer("original", cs.Index)) | ||
} else if err := c.SyncerBroadcastBlock(b); err != nil { | ||
log.Error("mined invalid block", zap.Error(err)) | ||
} | ||
log.Info("mined block", zap.Stringer("blockID", index.ID), zap.Stringer("fees", b.MinerPayouts[0].Value), zap.Int("transactions", len(b.Transactions)), zap.Int("v2transactions", len(b.V2Transactions()))) | ||
} | ||
} | ||
|
||
func parseLogLevel(level string) zap.AtomicLevel { | ||
switch level { | ||
case "debug": | ||
return zap.NewAtomicLevelAt(zap.DebugLevel) | ||
case "info": | ||
return zap.NewAtomicLevelAt(zap.InfoLevel) | ||
case "warn": | ||
return zap.NewAtomicLevelAt(zap.WarnLevel) | ||
case "error": | ||
return zap.NewAtomicLevelAt(zap.ErrorLevel) | ||
default: | ||
fmt.Printf("invalid log level %q", level) | ||
os.Exit(1) | ||
} | ||
panic("unreachable") | ||
} | ||
|
||
func main() { | ||
var ( | ||
minerAddrStr string | ||
|
||
apiAddress string | ||
apiPassword string | ||
|
||
logLevel string | ||
) | ||
|
||
flag.StringVar(&minerAddrStr, "address", "", "address to send mining rewards to") | ||
flag.StringVar(&apiAddress, "api", "localhost:9980", "address of the walletd API") | ||
flag.StringVar(&apiPassword, "password", "", "password for the walletd API") | ||
flag.StringVar(&logLevel, "log.level", "info", "log level") | ||
flag.Parse() | ||
|
||
var address types.Address | ||
if err := address.UnmarshalText([]byte(minerAddrStr)); err != nil { | ||
panic(err) | ||
} | ||
|
||
c := api.NewClient(apiAddress, apiPassword) | ||
if _, err := c.ConsensusTip(); err != nil { | ||
panic(err) | ||
} | ||
|
||
cfg := zap.NewProductionEncoderConfig() | ||
cfg.EncodeTime = zapcore.RFC3339TimeEncoder | ||
cfg.EncodeDuration = zapcore.StringDurationEncoder | ||
cfg.EncodeLevel = zapcore.CapitalColorLevelEncoder | ||
|
||
cfg.StacktraceKey = "" | ||
cfg.CallerKey = "" | ||
encoder := zapcore.NewConsoleEncoder(cfg) | ||
|
||
log := zap.New(zapcore.NewCore(encoder, zapcore.Lock(os.Stdout), parseLogLevel(logLevel))) | ||
defer log.Sync() | ||
|
||
zap.RedirectStdLog(log) | ||
|
||
runCPUMiner(c, address, log) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module go.sia.tech/cpuminerd | ||
|
||
go 1.21.8 | ||
|
||
toolchain go1.21.11 | ||
|
||
require ( | ||
go.sia.tech/core v0.2.7 | ||
go.sia.tech/coreutils v0.0.5 | ||
go.sia.tech/walletd v0.1.1-alpha.0.20240610172105-eb95d4161b91 | ||
go.uber.org/zap v1.27.0 | ||
lukechampine.com/frand v1.4.2 | ||
) | ||
|
||
require ( | ||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect | ||
github.com/julienschmidt/httprouter v1.3.0 // indirect | ||
github.com/stretchr/testify v1.9.0 // indirect | ||
go.etcd.io/bbolt v1.3.10 // indirect | ||
go.sia.tech/jape v0.11.2-0.20240306154058-9832414a5385 // indirect | ||
go.sia.tech/mux v1.2.0 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
golang.org/x/crypto v0.24.0 // indirect | ||
golang.org/x/sys v0.21.0 // indirect | ||
golang.org/x/tools v0.22.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= | ||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= | ||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= | ||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= | ||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= | ||
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/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= | ||
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= | ||
go.sia.tech/core v0.2.7 h1:9Q/3BHL6ziAMPeiko863hhTD/Zs2s7OqEUiPKouDny8= | ||
go.sia.tech/core v0.2.7/go.mod h1:BMgT/reXtgv6XbDgUYTCPY7wSMbspDRDs7KMi1vL6Iw= | ||
go.sia.tech/coreutils v0.0.5 h1:Jj03VrqAayYHgA9fwV13+X88WB+Wr1p8wuLw2B8d2FI= | ||
go.sia.tech/coreutils v0.0.5/go.mod h1:SkSpHeq3tBh2ff4HXuBk2WtlhkYQQtdcvU4Yv1Rd2bU= | ||
go.sia.tech/jape v0.11.2-0.20240306154058-9832414a5385 h1:Gho1g6pkv56o6Ut9cez/Yu5o4xlA8WNkDbPn6RWXL7g= | ||
go.sia.tech/jape v0.11.2-0.20240306154058-9832414a5385/go.mod h1:wU+h6Wh5olDjkPXjF0tbZ1GDgoZ6VTi4naFw91yyWC4= | ||
go.sia.tech/mux v1.2.0 h1:ofa1Us9mdymBbGMY2XH/lSpY8itFsKIo/Aq8zwe+GHU= | ||
go.sia.tech/mux v1.2.0/go.mod h1:Yyo6wZelOYTyvrHmJZ6aQfRoer3o4xyKQ4NmQLJrBSo= | ||
go.sia.tech/walletd v0.1.1-alpha.0.20240610172105-eb95d4161b91 h1:9saK9WcYSK3DDwj6aWyM3MUYlyZaJFiYzdm7KHg4I+Y= | ||
go.sia.tech/walletd v0.1.1-alpha.0.20240610172105-eb95d4161b91/go.mod h1:1CaApRlon10cIDnocnErbolh416CiUeP5jgEbVtmWx8= | ||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= | ||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= | ||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= | ||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= | ||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= | ||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= | ||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= | ||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= | ||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= | ||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | ||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= | ||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | ||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= | ||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= | ||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw= | ||
lukechampine.com/frand v1.4.2/go.mod h1:4S/TM2ZgrKejMcKMbeLjISpJMO+/eZ1zu3vYX9dtj3s= |