Stratum Server (Microcurrency Pool/Proxy)

Technical discussion about nodes, wallets, transfers, miners, etc.
Post Reply
mqpickens
Posts: 48
Joined: Sat Jun 04, 2022 11:38 pm

Stratum Server (Microcurrency Pool/Proxy)

Post by mqpickens »

The stratum protocol became widely adopted as the de facto protocol for scaling Bitcoin mining operations.
It has become so entrenched that many of the mainstream ASIC miners no longer support the native GBT protocol
built into the Bitcoin Core client. In order to use a modern Bitcoin miners, a stratum pool/proxy must be setup/run
on the same machine as the node. Miners are then directed to the stratum server port rather than directly to the
Bitcoin Core node port.

Note: Stratum proxy servers are connected to stratum pool servers. In many ways, a proxy acts like a sub pool;
many miners can be connected to it, but it will look like just one miner on the main pool. The proxy can, but does
not need to be, run on the same machine as the main pool.


Compile/Install CKPool/CKProxy
  • sudo apt-get -y update
  • sudo apt-get -y upgrade
  • sudo apt-get -y install build-essential yasm autoconf automake libtool libzmq3-dev git
  • cd ckpool
  • ./autogen.sh
  • ./configure -prefix /usr
  • make clean
  • make
  • sudo make install
Create a ckpool System User
  • sudo useradd --system --shell=/sbin/nologin ckpool
Create Log Folders
  • sudo mkdir -p /var/log/stratum
  • sudo chown root:ckpool -R /var/log/stratum
  • sudo chmod 670 -R /var/log/stratum
Install rpcauth Utility
  • sudo apt-get -y install python
  • sha256sum /usr/share/python/rpcauth.py # Verify Checksum b0920f6d96f8c72cee49df90ee4d0bf826bbe845596ecc056c6bc0873c146d1f
  • sudo chmod +x /usr/share/python/rpcauth.py
  • echo "#"\!"/bin/sh" | sudo tee /usr/share/python/rpcauth.sh
  • echo "python3 /usr/share/python/rpcauth.py \$1 \$2" | sudo tee -a /usr/share/python/rpcauth.sh
  • sudo ln -s /usr/share/python/rpcauth.sh /usr/bin/rpcauth
  • sudo chmod 755 /usr/bin/rpcauth
Generate Strong Bitcoin RPC Password
  • BTCRPCPASSWD=$(openssl rand -base64 16)
  • BTCRPCPASSWD=${BTCRPCPASSWD//\//0} # Replace '/' characters with '0'
  • BTCRPCPASSWD=${BTCRPCPASSWD//+/1} # Replace '+' characters with '1'
  • BTCRPCPASSWD=${BTCRPCPASSWD//=/} # Replace '=' characters with ''
  • echo $BTCRPCPASSWD | sudo tee /root/rpcpasswd
  • BTCRPCPASSWD="" # Erase from memory
  • sudo chmod 400 /root/rpcpasswd
Update Bitcoin Configuration
  • btc stop
  • sudo sed -i 's/.*server.*/server=1/g' /etc/bitcoin.conf
  • sudo sed -i '/.*rpcuser.*/d' /etc/bitcoin.conf
  • sudo sed -i '/.*rpcpassword.*/d' /etc/bitcoin.conf
  • sudo sed -i "s/.*rpcauth.*/$(rpcauth satoshi $(sudo cat /root/rpcpasswd) | grep 'rpcauth')/g" /etc/bitcoin.conf
Create ckpool.service (Systemd)
  • cat << EOF | sudo tee /etc/systemd/system/ckpool.service
    [Unit]
    Description=Stratum Pool Server
    After=network-online.target
    Wants=bitcoind.service

    [Service]
    ExecStart=/usr/bin/ckpool --log-shares --killold --config /etc/ckpool.conf

    Type=simple
    PIDFile=/tmp/ckpool/main.pid
    Restart=always
    RestartSec=30
    TimeoutStopSec=30

    ### Run as ckpool:ckpool ###
    User=ckpool
    Group=ckpool

    ### Hardening measures ###
    ProtectSystem=full
    ProtectHome=true
    NoNewPrivileges=true
    PrivateDevices=true

    [Install]
    WantedBy=multi-user.target
    EOF
Create ckproxy.service (Systemd)
  • cat << EOF | sudo tee /etc/systemd/system/ckproxy.service
    [Unit]
    Description=Stratum Proxy Server
    After=network-online.target
    Wants=bitcoind.service

    [Service]
    ExecStart=/usr/bin/ckproxy --log-shares --killold --config /etc/ckproxy.conf

    Type=simple
    PIDFile=/tmp/ckproxy/main.pid
    Restart=always
    RestartSec=30
    TimeoutStopSec=30

    ### Run as ckpool:ckpool ###
    User=ckpool
    Group=ckpool

    ### Hardening measures ###
    ProtectSystem=full
    ProtectHome=true
    NoNewPrivileges=true
    PrivateDevices=true

    [Install]
    WantedBy=multi-user.target
    EOF
Create Stratum autossh (Systemd)
  • # Note: Reusing the p2pssh environment file and p2pkey authentication.
  • cat << EOF | sudo tee /etc/systemd/system/stratssh@.service
    [Unit]
    Description=Stratum AutoSSH %I Tunnel Service
    Before=ckproxy.service
    After=network-online.target

    [Service]
    Environment="AUTOSSH_GATETIME=0"
    EnvironmentFile=/etc/default/p2pssh@%i
    ExecStart=/usr/bin/autossh -M 0 -NT -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -o "ServerAliveCountMax 3" -i /root/.ssh/p2pkey -L 3334:localhost:3333 -p \${TARGET_PORT} p2p@\${TARGET}

    RestartSec=5
    Restart=always

    [Install]
    WantedBy=multi-user.target
    EOF
Reload the new service configurations
  • sudo systemctl daemon-reload
Create ckpool Configuration File
  • MININGADDRESS=$(btc -rpcwallet=mining getnewaddress "ckpool")
  • cat << EOF | sudo tee /etc/ckpool.conf
    {
    "btcd" : [
    $(printf '\t'){
    $(printf '\t')"url" : "localhost:19332",
    $(printf '\t')"auth" : "satoshi",
    $(printf '\t')"pass" : "$(sudo cat /root/rpcpasswd)",
    $(printf '\t')"notify" : true
    $(printf '\t')}
    ],
    "btcaddress" : "$MININGADDRESS",
    "btcsig" : "",
    "serverurl" : [
    $(printf '\t')"0.0.0.0:3333"
    ],
    "mindiff" : 1,
    "startdiff" : 42,
    "maxdiff" : 0,
    "zmqblock" : "tcp://127.0.0.1:28332",
    "logdir" : "/var/log/stratum"
    }
    Comments from here on are ignored.
    EOF
  • sudo chown root:ckpool /etc/ckpool.conf
  • sudo chmod 440 /etc/ckpool.conf
Create ckproxy Configuration File
  • MININGADDRESS=$(btc -rpcwallet=mining getnewaddress "ckproxy")
  • echo "Please enter your email to receive notifications from the pool"; read MININGEMAIL
  • cat << EOF | sudo tee /etc/ckproxy.conf
    {
    "btcd" : [
    $(printf '\t'){
    $(printf '\t')"url" : "localhost:19332",
    $(printf '\t')"auth" : "satoshi",
    $(printf '\t')"pass" : "$(sudo cat /root/rpcpasswd)",
    $(printf '\t')"notify" : true
    $(printf '\t')}
    ],
    "proxy" : [
    $(printf '\t'){
    $(printf '\t')"url" : "localhost:3334",
    $(printf '\t')"auth" : "${MININGADDRESS}.${MININGEMAIL}",
    $(printf '\t')"pass" : "x"
    $(printf '\t')}
    ],
    "btcaddress" : "",
    "serverurl" : [
    $(printf '\t')"0.0.0.0:3333"
    ],
    "mindiff" : 1,
    "startdiff" : 42,
    "maxdiff" : 0,
    "zmqblock" : "tcp://127.0.0.1:28332",
    "logdir" : "/var/log/stratum"
    }
    Comments from here on are ignored.
    EOF
  • sudo chown root:ckpool /etc/ckproxy.conf
  • sudo chmod 440 /etc/ckproxy.conf
Last edited by mqpickens on Tue May 30, 2023 5:52 pm, edited 15 times in total.
mqpickens
Posts: 48
Joined: Sat Jun 04, 2022 11:38 pm

Operating the Pool/Proxy

Post by mqpickens »

Everything is configured to run either a pool or a proxy, but NOT BOTH!
Pools are independent whereas proxies depend upon a pool to function.
Also, it is ok to double/triple stack proxies, but somewhere there needs to be a pool at the top.

Industrial Miner Firewall Configuration
  • # This opens up the stratum port (3333) to the local area network to connect industrial miners.
  • sudo ufw allow from 192.168.0.0/16 to any port 3333
Industrial Miner Firewall Configuration (WSL)
  • # For WSL, just open the port up to any IP and then restrict it to local IPs in windows (see WSL Node)
  • sudo ufw allow 3333/tcp
Enable/Run ckpool
  • sudo systemctl enable ckpool --now
Enable/Run ckproxy
  • sudo ls -all /etc/default/p2pssh@* # List all the SSH p2p node candidates that were configured previously
  • read STRATNAME # Enter the name of the pool where to connect the proxy
  • sudo systemctl enable stratssh@${STRATNAME} --now
  • sudo systemctl enable ckproxy --now
Last edited by mqpickens on Mon May 22, 2023 10:05 pm, edited 4 times in total.
mqpickens
Posts: 48
Joined: Sat Jun 04, 2022 11:38 pm

Calculating Payouts (Mining Contracts)

Post by mqpickens »

Offering mining contracts to those that would like to acquire a new coin during the distribution phase without getting their hands “dirty”
will likely be a critical element for success. A simple mining contract is one that directs a specific hashrate to a network on behalf of a
customer for a set amount of time. One way for calculating payouts for these contracts, without concerning oneself of the performance
of his/her own mining operation, that is both simple and more than fair, is as follows:
  • Payout = [(H * T) / (D * 2^32)] * [(S + F) * B]
    • H = Mining Contract Hashrate (h/s) # SEMI-STATIC: Customer may purchase more hashrate
    • T = Target Time per Block (seconds) # STATIC
    • D = Newly Calculated Difficulty on the Start of the next Difficulty Epoch.
    • S = Block Subsidy Reward # SEMI-STATIC: Changes after each halving
    • F = Average Fees Collected per Block during the Previous Difficulty Period
    • B = Number of Blocks in each Difficulty Period # STATIC
Note: Using this calculation, the frequency of payouts will be inline with the start of each new Difficulty Epoch. This payout amount is
for the previous difficulty period; yet, the calculation uses the newly generated difficulty on the first block of the next Difficulty Epoch.


Note: The average fee rate per block could be spoofed by other miners that create non-broadcasted transactions with outlandish
fees that only they mine. You may need to calculate average fees per block using only the blocks your own pool has successfully mined.


By definition, a Difficulty Epoch is a period in which a set amount of blocks are added to a ledger. (using the terms "Difficulty Epoch" and
"Difficulty Period" interchangeably can be confusing; so, personally, I try to use the term "Difficulty Epoch" to refer to the beginning of a
new Difficulty period where the a new difficulty is calculated)
The amount of blocks in this period and the amount of time it should take
for these blocks to be mined are immutably defined in the software used to uphold a network. With the genesis block starting at 0, the
block number for each new Difficulty Epoch can be calculated by simply multiplying the desired Epoch period (starting at 0) by the
statically defined number of blocks in a Difficulty Period.

Difficulty is a measure of how difficult it is to mine a block in a blockchain for a particular network. Difficulty adjustments are made by
comparing the time it should take to find all the blocks in a Difficulty Period to the actual time it took to find those blocks. The
calculation is as follows:
  • New Difficulty = Recent Difficulty x Target Time / Actual Time
Note: The new difficulty cannot be altered above (+300%) or below (-75%) four times the current difficulty level. Also, an error in the
original Bitcoin protocol makes difficulty level adjustments based on the previous 2,015 blocks instead of the theorized 2,016 blocks.
This same error was carried over into the launch of each new microcurrency.


Note: Because of the way difficulty is calculated, it highly favors a newly purchased mining contract. It would be more than fair to skip
the first two payouts after a contract has been established assuming said mining contract is a lengthy one (i.e. multi-year).


The difficulty level can also be understood as the estimated number of hashes required to mine a block. For a difficulty of 1 (the
smallest difficult possible), the number of hashes is approximately 2^32, a difficulty of 4 is approximately 4 * (2*32) hashes, and so on.
The purpose of difficulty is to keep the rate of coin issuance and block confirmation intervals steady over time to enforces protocol
rules. The approximate hash rate for a network can be calculated with the difficulty level as follows:
  • Hash Rate = Current Difficulty * 2^32 / Block Time (seconds)
mqpickens
Posts: 48
Joined: Sat Jun 04, 2022 11:38 pm

Profressional Mining Pool - Logrotate, Payouts ---- better title (WIP)

Post by mqpickens »

Once there are customers on the pool. We need to get this thing configured so it is running better.


~~~~~~~~~~~~~~~~~ let's wait and see on this one ~~~~~~~~~~~~~~~~~~~
cat << EOF | sudo tee /etc/logrotate.d/stratum
/var/log/stratum/ckpool.log, /var/log/stratum/ckproxy.log {
$(printf '\t')create 660 root ckpool
$(printf '\t')daily
$(printf '\t')rotate 14
$(printf '\t')compress
$(printf '\t')delaycompress
$(printf '\t')sharedscripts
$(printf '\t')postrotate
$(printf '\t')$(printf '\t')/sdf/asdf/asdf/managepool.sh <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$(printf '\t')endscript
}
EOF
Post Reply