Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

icook/ngpool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ngpool

Notice: This is pre-v1 software, it is not feature complete or documented.

ngpool is a suite of services for hosting a cryptocurrency mining pool. It is the second generation of the simplecoin suite of tools. These services use etcd as a central configuration store and service discovery mechanism.

ngstratum

A stratum mining server. One port per process. Aux proof of work (merged-mining) support.

ngweb

Provides a REST API for end user interaction and management. Also contains all crontabs.

ngcoinserver

Runs alongside all "coinservers", or bitcoind-like processes. It is a thin wrapper providing block notification pubsub, status monitoring and service announcement.

ngsigner

Signs raw transactions that ngweb produces to payout users. This is a simple utility that allows easy separate of private keys from main pool servers for added security. Does not require running coinservers on payout machine.

ngctl

A commandline utility for managing service configuration.

Motivations

Simplecoin had design shortcomings that made operational complexity very high. Ngpool addresses these in the following ways:

Configuration Complexity A full simplecoin installation might support a dozen currencies, each with a public and private coinserver (bitcoind), and then also a payout coinserver. In addition, there would likely be a dedicated stratum mining port for each currency. Each service had their own config, and some information (network/coin specifics, etc) were duplicated between configurations. This quickly became tedious to manage.

Ngpool changes addressing this problem with:

  • Service discovery. Connections between stratum ports and coinservers is done automatically, no configuration necessary, no restart required.
  • Shared configurations. No duplication when configuring services, as currency configuration and sharechain configuration is global.
  • Defaults. Configure site wide defaults for stratum, coinservers, etc.

Poor load tolerence Simplecoin stratum servers struggled to stay low latency with high levels of concurrency. powerpool was written in Python with Gevent, which is a great tool, but frankly it only stretches Python so far. Ngpool written in golang is substantially quicker in certain critical areas.

Difficult themeing Changing the UI to theme it for different deployments was challenging because the backend logic and frontend UI were tightly coupled with server side rendering in flask. UI is now a client side React application, and the backend is simply a REST api, so altering the frontend should be significantly simpler.

Poor testing coverage Many important parts of simplecoin were not written with testing in mind. Combined with the complexity of service interactions, lack of testing coverage lead to sluggish release intervals (lots of manual testing) as the codebase grew. Refactoring and improving many areas of code became "not worth the headache" because the manual testing required afterward.

Install

This is basic documentation for setting up a basic pool on Ubuntu. From a root (sudo -s) prompt:

# Install postgresql and other extras
root$ apt-get update
root$ apt-get install postgresql-9.6 git

# We require at least etcd 2.2.6 because of a bugfix. Check officail repo version.  
root$ apt-cache show etcd

# If result of above not > 2.2.6, install from snap
root$ apt-get install snapd
root$ snap install etcd
root$ cp /snap/etcd/current/etcd.conf.yml.sample /var/snap/etcd/common/etcd.conf.yml
root$ snap start etcd

# If etcd from repo is >2.2.6, just install it from the official repos
root$ apt-get install etcd

# Confirm etcd has started now. This should not error out
root$ etcdctl ls

# Create our postgresql user. Generate password with apg or similar secure generator
root$ su - postgres
postgres$ createuser --pwprompt ngpool  # enter password, don't loose it
postgres$ createdb -O ngpool ngpool
postgres$ <Ctrl-D>

# Create a new user, disallow login from all sources
root$ adduser ngpool
root$ usermod --expiredate 1 ngpool
root$ su - ngpool

# Download the latest release
root$ wget <url of release targz>
root$ tar xvzf ngpool.tar.gz
root$ cp ngpool/* /usr/local/bin/

# Download litecoin, install litecoind and litecoin-cli
root$ wget https://download.litecoin.org/litecoin-0.14.2/linux/litecoin-0.14.2-x86_64-linux-gnu.tar.gz
root$ tar xvzf litecoin-0.14.2-x86_64-linux-gnu.tar.gz
root$ cp litecoin-0.14.2/bin/litecoind /usr/local/bin/
root$ cp litecoin-0.14.2/bin/litecoin-cli /usr/local/bin/

# Generate a SubsidyAddress (where blocks are mined to) for the pool. Keep a backup of the private key somewhere safe if for production!!!
root$ ngcoinserver genkey litecoind -n test

Now write a simple keyfile for the payout signer to use. Ngpool separates signing of payouts to users so it can be run from a different machine. Currently there is no facility for encrypting this file.

root$ nano keys.yaml
LTC_T:
    keys:
        - [YOUR GENERATED PRIVATE KEY]

Setup a basic common config. This is configuration that all services use, like details about currency constants, etc. Replace the placeholder values with your own.

root$ ngctl common edit
api:
    CORSOrigins: "*"  #DONT RUN IN PROD
    DbConnectionString: "user=ngpool dbname=ngpool sslmode=disable password=[YOUR DATABASE PASSWORD]"
stratum:
    DbConnectionString: "user=ngpool dbname=ngpool sslmode=disable password=[YOUR DATABASE PASSWORD]"
ShareChains:
    "LTC_T":
        fee: 0.01
        payoutmethod: "pplns"
        algo: "scrypt"
Currencies:
    "LTC_T":
        subsidyAddress: "[YOUR GENERATED PUBLIC ADDRESS HERE]"
        powalgorithm: "scrypt"
        pubkeyaddrid: "6f"
        privkeyaddrid: "ef"
        netmagic: 0xfdd2c8f1
        blockmatureconfirms: 100
        payouttransactionfee: 110
        minimumrelayfee: 100000

Setup a stratum config

root$ ngctl stratum edit 3333
loglevel: info
sharechainname: LTC_T
basecurrency:
    currency: LTC_T
    algo: scrypt
    templatetype: getblocktemplate

Setup a coinserver config to run litcoind

root$ ngctl coinserver edit ltc1
blocklistenerbind: 127.0.0.1:3010
coinserverbinary: litecoind
currencycode: LTC_T
eventlistenerbind: 127.0.0.1:4010
hashingalgo: scrypt
loglevel: info
nodeconfig:
  port: "19010"
  rpcpassword: "123"
  rpcport: "19011"
  rpcuser: admin1
  server: "1"
  testnet: "1"
  datadir: "~/.litecoin"

Now you can run each component in their own terminal like such:

ngstratum run 3333
ngcoinserver run ltc1
ngweb run

With a cpuminer you can begin mining blocks...

minerd -a scrypt -o stratum+tcp://127.0.0.1:3333 -R 3 -D -u myusername

Once blocks are solved, run check their confirmations and generate credits to payout users.

ngweb confirmblocks

And then send payouts. This script could be run from a different machine and target the public web API to perform payouts out of band.

ngsign http://localhost:3000 keys