Skip to content

Commit

Permalink
Merge pull request #2 from lemois-1337/2023_cleanup_replace_kaspa_wit…
Browse files Browse the repository at this point in the history
…h_karlsen

[Stratum] Full support for Karlsen BlockDAG
  • Loading branch information
lemois-1337 authored Nov 29, 2023
2 parents af505e3 + 47a645f commit 22e0687
Show file tree
Hide file tree
Showing 35 changed files with 317 additions and 284 deletions.
13 changes: 7 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# Many thanks to original author Brandon Smith (onemorebsmith).
FROM golang:1.19.1 as builder

LABEL org.opencontainers.image.description="Dockerized Kaspa Stratum Bridge"
LABEL org.opencontainers.image.authors="onemorebsmith"
LABEL org.opencontainers.image.source="https://github.com/onemorebsmith/kaspa-stratum-bridge"
LABEL org.opencontainers.image.description="Dockerized Karlsen Stratum Bridge"
LABEL org.opencontainers.image.authors="Karlsen Community"
LABEL org.opencontainers.image.source="https://github.com/karlsen-network/karlsen-stratum-bridge"

WORKDIR /go/src/app
ADD go.mod .
ADD go.sum .
RUN go mod download

ADD . .
RUN go build -o /go/bin/app ./cmd/kaspabridge
RUN go build -o /go/bin/app ./cmd/karlsenbridge


FROM gcr.io/distroless/base:nonroot
COPY --from=builder /go/bin/app /
COPY cmd/kaspabridge/config.yaml /
COPY cmd/karlsenbridge/config.yaml /

WORKDIR /
ENTRYPOINT ["/app"]
170 changes: 102 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,155 @@
# Kaspa Stratum Adapter
# Karlsen Stratum Adapter

This is a lightweight daemon that allows mining to a local (or remote) kaspa node using stratum-base miners.
This is a lightweight daemon that allows mining to a local (or remote)
karlsen node using stratum-base miners.

This daemon is confirmed working with the miners below in both dual-mining
and karlsen-only modes (for those that support it) and Windows, Linux,
macOS and HiveOS.

This daemon is confirmed working with the miners below in both dual-mining and kaspa-only modes (for those that support it) and Windows/MacOs/Linux/HiveOs.
* bzminer
* lolminer
* srbminer
* teamreadminer

No fee, forever. Do what you want with it.

Discord discussions/issues: [here](https://discord.com/channels/599153230659846165/1025501807570600027)
No fee, forever.

Huge shoutout to https://github.com/KaffinPX/KStratum for the inspiration

Tips appreciated: `kaspa:qp9v6090sr8jjlkq7r3f4h9un5rtfhu3raknfg3cca9eapzee57jzew0kxwlp`
Discord discussions/issues: [here](https://discord.gg/pPNESjGfb5)

Try my 0-fee [Kaspa Pool](http://ghost-pool.io/) built with this code!
Huge shoutout to https://github.com/KaffinPX/KStratum and
https://github.com/onemorebsmith/karlsen-stratum-bridge for the
inspiration.

Tips appreciated: `karlsen:qqe3p64wpjf5y27kxppxrgks298ge6lhu6ws7ndx4tswzj7c84qkjlrspcuxw`

## Hive Setup
[detailed instructions here](hive-setup.md)

[detailed instructions here](hive-setup.md)

# Features:
# Features

Shares-based work allocation with miner-like periodic stat output:

![image](https://user-images.githubusercontent.com/59971111/191983487-479e19ec-a8cb-4edb-afc4-55a1165e79fc.png)
```
===============================================================================
worker name | avg hashrate | acc/stl/inv | blocks | uptime
-------------------------------------------------------------------------------
lemois | 0.13GH/s | 3/0/0 | 0 | 6m48s
-------------------------------------------------------------------------------
| 0.13GH/s | 3/0/0 | 0 | 7m20s
========================================================= kls_bridge_v1.0.0 ===
```

## Grafana UI

The grafana monitoring UI is an optional component but included for
convenience. It will help to visualize collected statistics.

Optional monitoring UI:
[detailed instructions here](monitoring-setup.md)

https://github.com/onemorebsmith/kaspa-stratum-bridge/blob/main/monitoring-setup.md
![Grafana Monitoring 1](images/grafana-1.png)

![image](https://user-images.githubusercontent.com/59971111/192025446-f20d74a5-f9e0-4290-b98b-9f56af8f23b4.png)
![Grafana Monitoring 2](images/grafana-2.png)

![image](https://user-images.githubusercontent.com/59971111/191980688-2d0faf6b-d551-4880-a316-de2303cfeb7d.png)
![Grafana KLSB Monitoring 1](images/grafana-3.png)

![Grafana KLSB Monitoring 2](images/grafana-4.png)

Prometheus API:
## Prometheus API

If the app is run with the `-prom={port}` flag the application will host stats on the port specified by `{port}`, these stats are documented in the file [prom.go](src/kaspastratum/prom.go). This is intended to be use by prometheus but the stats can be fetched and used independently if desired. `curl http://localhost:2114/metrics | grep ks_` will get a listing of current stats. All published stats have a `ks_` prefix for ease of use.
If the app is run with the `-prom={port}` flag the application will host
stats on the port specified by `{port}`, these stats are documented in
the file [prom.go](src/karlsenstratum/prom.go). This is intended to be use
by prometheus but the stats can be fetched and used independently if
desired. `curl http://localhost:2114/metrics | grep kls_` will get a
listing of current stats. All published stats have a `kls_` prefix for
ease of use.

```
user:~$ curl http://localhost:2114/metrics | grep ks_
# HELP ks_estimated_network_hashrate_gauge Gauge representing the estimated network hashrate
# TYPE ks_estimated_network_hashrate_gauge gauge
ks_estimated_network_hashrate_gauge 2.43428982879776e+14
# HELP ks_network_block_count Gauge representing the network block count
# TYPE ks_network_block_count gauge
ks_network_block_count 271966
# HELP ks_network_difficulty_gauge Gauge representing the network difficulty
# TYPE ks_network_difficulty_gauge gauge
ks_network_difficulty_gauge 1.2526479386202519e+14
# HELP ks_valid_share_counter Number of shares found by worker over time
# TYPE ks_valid_share_counter counter
ks_valid_share_counter{ip="192.168.0.17",miner="SRBMiner-MULTI/1.0.8",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="002"} 276
ks_valid_share_counter{ip="192.168.0.24",miner="BzMiner-v11.1.0",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="003"} 43
ks_valid_share_counter{ip="192.168.0.65",miner="BzMiner-v11.1.0",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="001"} 307
# HELP ks_worker_job_counter Number of jobs sent to the miner by worker over time
# TYPE ks_worker_job_counter counter
ks_worker_job_counter{ip="192.168.0.17",miner="SRBMiner-MULTI/1.0.8",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="002"} 3471
ks_worker_job_counter{ip="192.168.0.24",miner="BzMiner-v11.1.0",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="003"} 3399
ks_worker_job_counter{ip="192.168.0.65",miner="BzMiner-v11.1.0",wallet="kaspa:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="001"} 3425
user:~$ curl http://localhost:2114/metrics | grep kls_
# HELP kls_estimated_network_hashrate_gauge Gauge representing the estimated network hashrate
# TYPE kls_estimated_network_hashrate_gauge gauge
kls_estimated_network_hashrate_gauge 2.43428982879776e+14
# HELP kls_network_block_count Gauge representing the network block count
# TYPE kls_network_block_count gauge
kls_network_block_count 271966
# HELP kls_network_difficulty_gauge Gauge representing the network difficulty
# TYPE kls_network_difficulty_gauge gauge
kls_network_difficulty_gauge 1.2526479386202519e+14
# HELP kls_valid_share_counter Number of shares found by worker over time
# TYPE kls_valid_share_counter counter
kls_valid_share_counter{ip="192.168.0.17",miner="SRBMiner-MULTI/1.0.8",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="002"} 276
kls_valid_share_counter{ip="192.168.0.24",miner="BzMiner-v11.1.0",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="003"} 43
kls_valid_share_counter{ip="192.168.0.65",miner="BzMiner-v11.1.0",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="001"} 307
# HELP kls_worker_job_counter Number of jobs sent to the miner by worker over time
# TYPE kls_worker_job_counter counter
kls_worker_job_counter{ip="192.168.0.17",miner="SRBMiner-MULTI/1.0.8",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="002"} 3471
kls_worker_job_counter{ip="192.168.0.24",miner="BzMiner-v11.1.0",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="003"} 3399
kls_worker_job_counter{ip="192.168.0.65",miner="BzMiner-v11.1.0",wallet="karlsen:qzk3uh2twkhu0fmuq50mdy3r2yzuwqvstq745hxs7tet25hfd4egcafcdmpdl",worker="001"} 3425
```

# Install

## Docker All-in-one
## Docker (all-in-one)

Note: This does requires that docker is installed.


`docker compose -f docker-compose-all.yml up -d` will run the bridge with
default settings. This assumes a local karlsend node with default port
settings and exposes port 5555 to incoming stratum connections.

`docker compose -f docker-compose-all.yml up -d` will run the bridge with default settings. This assumes a local kaspad node with default port settings and exposes port 5555 to incoming stratum connections.
This also spins up a local prometheus and grafana instance that gather
stats and host the metrics dashboard. Once the services are up and
running you can view the dashboard using `http://127.0.0.1:3000/d/x7cE7G74k/monitoring`



This also spins up a local prometheus and grafana instance that gather stats and host the metrics dashboard. Once the services are up and running you can view the dashboard using `http://127.0.0.1:3000/d/x7cE7G74k/monitoring`

Default grafana user/pass: admin/admin

Most of the stats on the graph are averaged over an hour time period, so keep in mind that the metrics might be inaccurate for the first hour or so that the bridge is up.
Default grafana user: `admin`
Default grafana pass: `admin`

Most of the stats on the graph are averaged over an hour time period, so
keep in mind that the metrics might be inaccurate for the first hour or
so that the bridge is up.

## Docker (non-compose)

Note: This does not require pulling down the repo, it only requires that docker is installed.

`docker run -p 5555:5555 onemorebsmith/kaspa_bridge:latest --log=false` will run the bridge with default settings. This assumes a local kaspad node with default port settings and exposes port 5555 to incoming stratum connections.
Note: This does not require pulling down the repo, it only requires that
docker is installed.

`docker run -p 5555:5555 karlsennetwork/karlsen_bridge:latest --log=false`

Detailed:
This will run the bridge with default settings. This assumes a local
karlsend node with default port settings and exposes port 5555 to incoming
stratum connections.

`docker run -p {stratum_port}:5555 onemorebsmith/kaspa_bridge --log=false --kaspa={kaspad_address} --stats={false}` will run the bridge targeting a kaspad node at {kaspad_address}. stratum port accepting connections on {stratum_port}, and only logging connection activity, found blocks, and errors
Advanced and customized configuration.

`docker run -p {stratum_port}:5555 karlsennetwork/karlsen_bridge --log=false --karlsen={karlsend_address} --stats={false}`

## Manual build
This will run the bridge targeting a karlsend node at {karlsend_address}.
Stratum port accepting connections on {stratum_port}, and only logging
connection activity, found blocks, and errors.

Install go 1.18 using whatever package manager is approprate for your system
## Non-Docker (manual build)


Install go 1.18 using whatever package manager is appropriate for your
system.

run `cd cmd/kaspabridge;go build .`



Modify the config file in ./cmd/bridge/config.yaml with your setup, the file comments explain the various flags
```
cd cmd/karlsenbridge
go build .
```


Modify the config file in `./cmd/karlsenbridge/config.yaml` with your setup,
the file comments explain the various flags.

run `./kaspabridge` in the `cmd/kaspabridge` directory
```
./karlsenbridge
```


To recap the entire process of initiating the compilation and launching
the karlsen dridge, follow these steps:

all-in-one (build + run) `cd cmd/kaspabridge/;go build .;./kaspabridge`
```
cd cmd/karlsenbridge
go build .
./karlsenbridge
```
10 changes: 4 additions & 6 deletions cmd/kaspabridge/config.yaml → cmd/karlsenbridge/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Note `:PORT` format is needed if not specifiying a specific ip range
stratum_port: :5555

# kaspad_address: address/port of the rpc server for kaspad, typically 16110
# karlsend_address: address/port of the rpc server for karlsend, typically 42110
# For a list of public nodes, run `nslookup mainnet-dnsseed.daglabs-dev.com`
# uncomment for to use a public node
# kaspad_address: 46.17.104.200:16110
kaspad_address: localhost:16110
# karlsend_address: 46.17.104.200:42110
karlsend_address: localhost:42110

# min_share_diff: only accept shares of the specified difficulty (or higher) from
# the miner(s). Higher values will reduce the number of shares submitted, thereby
Expand All @@ -15,7 +15,7 @@ kaspad_address: localhost:16110
# accurate hashrate measurements
# min_share_diff: 4

# block_wait_time: time to wait since last new block message from kaspad before
# block_wait_time: time to wait since last new block message from karlsend before
# manually requesting a new block
# block_wait_time: 500ms

Expand All @@ -42,5 +42,3 @@ log_to_file: true
# `curl http://localhost:{prom_port}/metrics`
# Note `:PORT` format is needed if not specifiying a specific ip range
prom_port: :2114


12 changes: 6 additions & 6 deletions cmd/kaspabridge/main.go → cmd/karlsenbridge/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"path"
"time"

"github.com/karlsen-network/karlsen-stratum-bridge/src/kaspastratum"
"github.com/karlsen-network/karlsen-stratum-bridge/src/karlsenstratum"
"gopkg.in/yaml.v2"
)

Expand All @@ -21,15 +21,15 @@ func main() {
log.Printf("config file not found: %s", err)
os.Exit(1)
}
cfg := kaspastratum.BridgeConfig{}
cfg := karlsenstratum.BridgeConfig{}
if err := yaml.Unmarshal(rawCfg, &cfg); err != nil {
log.Printf("failed parsing config file: %s", err)
os.Exit(1)
}

flag.StringVar(&cfg.StratumPort, "stratum", cfg.StratumPort, "stratum port to listen on, default `:5555`")
flag.BoolVar(&cfg.PrintStats, "stats", cfg.PrintStats, "true to show periodic stats to console, default `true`")
flag.StringVar(&cfg.RPCServer, "kaspa", cfg.RPCServer, "address of the kaspad node, default `localhost:16110`")
flag.StringVar(&cfg.RPCServer, "karlsen", cfg.RPCServer, "address of the karlsend node, default `localhost:42110`")
flag.DurationVar(&cfg.BlockWaitTime, "blockwait", cfg.BlockWaitTime, "time in ms to wait before manually requesting new block, default `500`")
flag.UintVar(&cfg.MinShareDiff, "mindiff", cfg.MinShareDiff, "minimum share difficulty to accept from miner(s), default `4`")
flag.UintVar(&cfg.ExtranonceSize, "extranonce", cfg.ExtranonceSize, "size in bytes of extranonce, default `0`")
Expand All @@ -42,12 +42,12 @@ func main() {
cfg.MinShareDiff = 4
}
if cfg.BlockWaitTime == 0 {
cfg.BlockWaitTime = 5 * time.Second // this should never happen due to kas 1s block times
cfg.BlockWaitTime = 5 * time.Second // this should never happen due to kls 1s block times
}

log.Println("----------------------------------")
log.Printf("initializing bridge")
log.Printf("\tkaspad: %s", cfg.RPCServer)
log.Printf("\tkarlsend: %s", cfg.RPCServer)
log.Printf("\tstratum: %s", cfg.StratumPort)
log.Printf("\tprom: %s", cfg.PromPort)
log.Printf("\tstats: %t", cfg.PrintStats)
Expand All @@ -58,7 +58,7 @@ func main() {
log.Printf("\thealth check: %s", cfg.HealthCheckPort)
log.Println("----------------------------------")

if err := kaspastratum.ListenAndServe(cfg); err != nil {
if err := karlsenstratum.ListenAndServe(cfg); err != nil {
log.Println(err)
}
}
12 changes: 6 additions & 6 deletions docker-compose-all.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
volumes:
prometheus_data: {}
services:
ks_bridge:
image: onemorebsmith/kaspa_bridge:latest
container_name: ks_bridge
kls_bridge:
image: karlsennetwork/karlsen_bridge:latest
container_name: kls_bridge
restart: unless-stopped
user: "0"
command:
- '-log=true'
- '-stats=false'
- '-stratum=:5555'
- '-prom=:2114'
- '-kaspa=host.docker.internal:42110'
- '-karlsen=host.docker.internal:42110'
ports:
- 5555:5555
- 2114:2114
extra_hosts:
- host.docker.internal:host-gateway
grafana:
image: grafana/grafana-oss:latest
container_name: ks_grafana
container_name: kls_grafana
restart: unless-stopped
user: "0"
volumes:
Expand All @@ -32,7 +32,7 @@ services:
- host.docker.internal:host-gateway
prometheus:
image: prom/prometheus:latest
container_name: ks_prom
container_name: kls_prom
restart: unless-stopped
volumes:
- prometheus_data:/prometheus
Expand Down
4 changes: 2 additions & 2 deletions docker-compose-monitoring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ volumes:
services:
grafana:
image: grafana/grafana-oss:latest
container_name: ks_grafana
container_name: kls_grafana
restart: unless-stopped
user: "0"
volumes:
Expand All @@ -16,7 +16,7 @@ services:
- host.docker.internal:host-gateway
prometheus:
image: prom/prometheus:latest
container_name: ks_prom
container_name: kls_prom
restart: unless-stopped
volumes:
- prometheus_data:/prometheus
Expand Down
Binary file modified docker/grafana/grafana.db
Binary file not shown.
Loading

0 comments on commit 22e0687

Please sign in to comment.