Merge DATUM ngit proposal with preserved catalog entries
Reviewed ngit proposal 15ff5fb9 (pr/datum), head febdda968e. Preserve all existing catalog entries and normalize the new manifest memory limit to supported 512m syntax.
Validation: three configuration preservation tests and strict release catalog drift pass. Live miner shares, payout configuration and reboot acceptance remain separate.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
FROM debian:bookworm-slim@sha256:7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587 AS build
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates git build-essential cmake pkg-config libjansson-dev \
|
||||
libmicrohttpd-dev libsodium-dev libcurl4-openssl-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /src
|
||||
# DATUM v0.4.1beta. Verify the commit as well as the tag.
|
||||
RUN git init && git remote add origin https://github.com/OCEAN-xyz/datum_gateway.git \
|
||||
&& git fetch --depth 1 origin refs/tags/v0.4.1beta \
|
||||
&& git checkout --detach FETCH_HEAD \
|
||||
&& test "$(git rev-parse HEAD)" = 5b061233a3d3323771b2be98e17f543e59346619 \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release . && make -j2
|
||||
|
||||
FROM debian:bookworm-slim@sha256:7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates libjansson4 libmicrohttpd12 libsodium23 libcurl4 jq curl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& useradd --uid 1000 --create-home datum
|
||||
WORKDIR /app
|
||||
COPY --from=build /src/datum_gateway /app/datum_gateway
|
||||
COPY --from=build /src/www /app/www
|
||||
COPY entrypoint.sh /app/entrypoint.sh
|
||||
COPY configure.jq /app/configure.jq
|
||||
USER 1000:1000
|
||||
EXPOSE 7152 23334
|
||||
ENTRYPOINT ["sh", "/app/entrypoint.sh"]
|
||||
@@ -0,0 +1,19 @@
|
||||
if type != "object" then error("Datum config must be an object") else . end
|
||||
| .bitcoind.rpcurl = ("http://" + env.BITCOIN_RPC_HOST + ":8332")
|
||||
| .bitcoind.rpcuser = "archipelago"
|
||||
| .bitcoind.rpcpassword = env.BITCOIN_RPC_PASSWORD
|
||||
# Use upstream's getbestblockhash fallback; no host bitcoind hooks needed.
|
||||
| .bitcoind.notify_fallback = true
|
||||
| .stratum.listen_addr = "0.0.0.0"
|
||||
| .stratum.listen_port = 23334
|
||||
| .mining.pool_address //= ""
|
||||
| .mining.coinbase_tag_primary //= "DATUM Gateway"
|
||||
| .mining.coinbase_tag_secondary //= "Archipelago"
|
||||
| .api.listen_port = 7152
|
||||
| .api.admin_password = env.DATUM_ADMIN_PASSWORD
|
||||
| .api.modify_conf = true
|
||||
| .logger.log_to_console = true
|
||||
| .logger.log_to_file = false
|
||||
| if .datum.pool_pass_workers == null then .datum.pool_pass_workers = true else . end
|
||||
| if .datum.pool_pass_full_users == null then .datum.pool_pass_full_users = true else . end
|
||||
| if .datum.pooled_mining_only == null then .datum.pooled_mining_only = true else . end
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
umask 077
|
||||
: "${BITCOIN_RPC_HOST:?Bitcoin host is required}"
|
||||
: "${BITCOIN_RPC_PASSWORD:?Bitcoin RPC password is required}"
|
||||
: "${DATUM_ADMIN_PASSWORD:?Datum admin password is required}"
|
||||
|
||||
# Keep operator settings, including the payout address, across recreation.
|
||||
# Refresh platform-owned credentials and DNS names on every container start.
|
||||
config=/data/config.json
|
||||
if [ ! -e "$config" ]; then printf '{}\n' > "$config"; fi
|
||||
tmp=$(mktemp /data/config.json.XXXXXX)
|
||||
trap 'rm -f "$tmp"' EXIT HUP INT TERM
|
||||
jq -e -f /app/configure.jq "$config" > "$tmp"
|
||||
mv "$tmp" "$config"
|
||||
exec /app/datum_gateway --config "$config"
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Config upgrades must preserve payout policy and reject broken input."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
FILTER = Path(__file__).resolve().parents[1] / 'configure.jq'
|
||||
|
||||
|
||||
def configure(value, host='bitcoin-core', password='new-rpc'):
|
||||
return subprocess.run(['jq', '-e', '-f', str(FILTER)], input=json.dumps(value),
|
||||
text=True, capture_output=True,
|
||||
env={**os.environ, 'BITCOIN_RPC_HOST': host,
|
||||
'BITCOIN_RPC_PASSWORD': password,
|
||||
'DATUM_ADMIN_PASSWORD': 'test-admin'})
|
||||
|
||||
|
||||
class ConfigTests(unittest.TestCase):
|
||||
def test_first_run_has_no_borrowed_payout_address(self):
|
||||
result = configure({})
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
data = json.loads(result.stdout)
|
||||
self.assertEqual(data['mining']['pool_address'], '')
|
||||
self.assertTrue(data['datum']['pooled_mining_only'])
|
||||
self.assertTrue(data['api']['modify_conf'])
|
||||
|
||||
def test_restart_preserves_payout_and_explicit_false_settings(self):
|
||||
original = {'mining': {'pool_address': 'operator-address'},
|
||||
'datum': {'pool_pass_workers': False, 'pool_pass_full_users': False,
|
||||
'pooled_mining_only': False},
|
||||
'bitcoind': {'rpcurl': 'http://old-ip:8332', 'rpcpassword': 'old'}}
|
||||
result = configure(original, password='quotes"and\\slashes')
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
data = json.loads(result.stdout)
|
||||
self.assertEqual(data['mining']['pool_address'], 'operator-address')
|
||||
self.assertEqual(data['datum'], original['datum'])
|
||||
self.assertEqual(data['bitcoind']['rpcurl'], 'http://bitcoin-core:8332')
|
||||
self.assertEqual(data['bitcoind']['rpcpassword'], 'quotes"and\\slashes')
|
||||
|
||||
def test_invalid_root_is_rejected(self):
|
||||
for value in [None, [], 'broken', 1]:
|
||||
self.assertNotEqual(configure(value).returncode, 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user