Skip to content

Commit 1f96419

Browse files
committed
Merge master (c72b493) into dash/s8-poolnode-share-messages-leaf3 — refresh vs current master to clear stale-base CI
2 parents a0be52e + c72b493 commit 1f96419

34 files changed

Lines changed: 1771 additions & 122 deletions

.github/workflows/build.yml

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@ jobs:
4141
with: { python-version: '3.12' }
4242

4343
- name: Install Conan 2
44-
run: pip install "conan>=2.0,<3.0"
44+
run: |
45+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
46+
pip install "conan>=2.0,<3.0"
47+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
48+
else
49+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
50+
fi
4551
4652
- name: Detect Conan profile
4753
run: |
@@ -94,7 +100,7 @@ jobs:
94100
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test nmc_mempool_name_test nmc_block_broadcast_test nmc_host_dualpath_test nmc_fallback_path_conformance_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
95101
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test dgb_aux_doge_mm_commitment_test dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test dgb_aux_broadcast_path_election_test \
96102
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
97-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test v37_test \
103+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test v37_test \
98104
-j8
99105
100106
- name: Run tests
@@ -168,7 +174,13 @@ jobs:
168174
with: { python-version: '3.12' }
169175

170176
- name: Install Conan 2
171-
run: pip install "conan>=2.0,<3.0"
177+
run: |
178+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
179+
pip install "conan>=2.0,<3.0"
180+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
181+
else
182+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
183+
fi
172184
173185
- name: Detect Conan profile
174186
run: |
@@ -237,7 +249,7 @@ jobs:
237249
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test nmc_mempool_name_test nmc_block_broadcast_test nmc_host_dualpath_test nmc_fallback_path_conformance_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
238250
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test dgb_aux_doge_mm_commitment_test dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test dgb_aux_broadcast_path_election_test \
239251
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
240-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
252+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
241253
v37_test \
242254
-j8
243255
@@ -285,7 +297,13 @@ jobs:
285297
with: { python-version: 3.12 }
286298

287299
- name: Install Conan 2
288-
run: pip install "conan>=2.0,<3.0"
300+
run: |
301+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
302+
pip install "conan>=2.0,<3.0"
303+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
304+
else
305+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
306+
fi
289307
290308
- name: Detect Conan profile
291309
run: |
@@ -333,7 +351,7 @@ jobs:
333351
bch_embedded_getwork_test bch_embedded_seam_workview_test \
334352
bch_embedded_block_broadcast_test bch_coin_node_seam_test \
335353
bch_asert_kat_test \
336-
bch_g1_oracle_byte_parity_test bch_g0_canonical_pin_test \
354+
bch_g1_oracle_byte_parity_test bch_g0_canonical_pin_test bch_g2_ratchet_gate_kat_test \
337355
-j8
338356
339357
- name: Run BCH tests
@@ -366,7 +384,13 @@ jobs:
366384
with: { python-version: 3.12 }
367385

368386
- name: Install Conan 2
369-
run: pip install "conan>=2.0,<3.0"
387+
run: |
388+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
389+
pip install "conan>=2.0,<3.0"
390+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
391+
else
392+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
393+
fi
370394
371395
- name: Detect Conan profile
372396
run: |
@@ -420,7 +444,7 @@ jobs:
420444
bch_embedded_getwork_test bch_embedded_seam_workview_test \
421445
bch_embedded_block_broadcast_test bch_coin_node_seam_test \
422446
bch_asert_kat_test \
423-
bch_g1_oracle_byte_parity_test bch_g0_canonical_pin_test \
447+
bch_g1_oracle_byte_parity_test bch_g0_canonical_pin_test bch_g2_ratchet_gate_kat_test \
424448
-j8
425449
426450
- name: Run BCH tests under sanitizers
@@ -710,7 +734,13 @@ jobs:
710734
with: { python-version: '3.12' }
711735

712736
- name: Install Conan 2
713-
run: pip install "conan>=2.0,<3.0"
737+
shell: bash
738+
run: |
739+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
740+
pip install "conan>=2.0,<3.0"
741+
else
742+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
743+
fi
714744
715745
- name: Detect Conan profile
716746
run: |
@@ -797,7 +827,13 @@ jobs:
797827
with: { python-version: 3.12 }
798828

799829
- name: Install Conan 2
800-
run: pip install "conan>=2.0,<3.0"
830+
run: |
831+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
832+
pip install "conan>=2.0,<3.0"
833+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
834+
else
835+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
836+
fi
801837
802838
- name: Detect Conan profile
803839
run: |

.github/workflows/codeql-analysis.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ jobs:
5757
- if: matrix.build-mode == 'manual'
5858
name: Install Conan 2
5959
run: |
60-
pip install "conan>=2.0,<3.0"
60+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
61+
pip install "conan>=2.0,<3.0"
62+
export PATH="$HOME/.local/bin:$PATH"
63+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
64+
else
65+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
66+
fi
6167
conan profile detect --force
6268
sed -i 's/compiler.cppstd=.*/compiler.cppstd=20/' \
6369
"$(conan profile path default)"

.github/workflows/coin-matrix.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ jobs:
5252

5353
- name: Install Conan 2
5454
if: steps.presence.outputs.exists == '1'
55-
run: pip install "conan>=2.0,<3.0"
55+
run: |
56+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
57+
pip install "conan>=2.0,<3.0"
58+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
59+
else
60+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
61+
fi
5662
5763
- name: Detect Conan profile
5864
if: steps.presence.outputs.exists == '1'

.github/workflows/release.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@ jobs:
8787

8888
- name: Install Conan 2
8989
if: steps.presence.outputs.exists == '1'
90-
run: pip install "conan>=2.0,<3.0"
90+
run: |
91+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
92+
pip install "conan>=2.0,<3.0"
93+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
94+
else
95+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
96+
fi
9197
9298
- name: Detect Conan profile
9399
if: steps.presence.outputs.exists == '1'
@@ -400,7 +406,12 @@ jobs:
400406

401407
- name: Install Conan 2
402408
if: steps.presence.outputs.exists == '1'
403-
run: pip install "conan>=2.0,<3.0"
409+
run: |
410+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
411+
pip install "conan>=2.0,<3.0"
412+
else
413+
conan --version # pre-provisioned at /usr/local/bin on self-hosted
414+
fi
404415
405416
- name: Detect Conan profile
406417
if: steps.presence.outputs.exists == '1'

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Original forum thread: <https://bitcointalk.org/index.php?topic=18313>
1414
> **First V36 Twin Block:** LTC [#3085349](https://blockchair.com/litecoin/block/3085349) + DOGE [#6154761](https://blockchair.com/dogecoin/block/6154761) (2026-04-05) — simultaneous LTC+DOGE block found by v36-signalling nodes running p2pool v36 producing V35 shares with `desired_version=36`; detected and displayed by c2pool's embedded block scanner
1515
>
1616
> **Sharechain Transparency Explorer** (2026-04-07) — defragmenter-style sharechain visualization with interactive PPLNS treemaps, animated hover effects, per-miner LTC+DOGE payout breakdown, V36 upgrade pressure for V35 miners
17+
>
18+
> **Recent Bitcoin Block Mined by P2pool** (2026-06-27 05:34:44 UTC) BTC [#955609](https://blockchair.com/bitcoin/block/955609)
19+
>
20+
> **Recent Bitcoin Block Mined by P2pool** (2025-03-07 06:08:22 UTC) BTC [#886688](https://blockchair.com/bitcoin/block/886688)
1721
1822
---
1923

@@ -514,6 +518,13 @@ cd build && ctest --output-on-failure -j$(nproc)
514518

515519
---
516520

521+
## V37 development
522+
523+
- Github pages: <[https://t.me/c2pooldev](https://frstrtr.github.io/c2pool/)>
524+
- V37 dev branch primitives: <[https://github.com/frstrtr/c2pool/compare/master...v37-dev](https://github.com/frstrtr/c2pool/compare/master...v37-dev)>
525+
526+
---
527+
517528
### Install guides
518529
- [Ubuntu / Debian / Linux](doc/build-unix.md)
519530
- [macOS (Intel & Apple Silicon)](doc/build-macos.md)

scripts/miner_notify_engine.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,13 +475,56 @@ def put(ts, worker, hr):
475475
nosub = dict(sub, enabled=0, channels=[])
476476
check(route_event(con, info_ev, nosub) is None, "unsub should route to None")
477477

478+
# --- daily-summary path (the `daily` subcommand, P1) ----------------
479+
# the sampler owns the `daily` rollup; build it here for the KAT
480+
dcon = connect(":memory:")
481+
dcon.execute("CREATE TABLE IF NOT EXISTS daily (day TEXT NOT NULL, "
482+
"worker TEXT NOT NULL, hours_online REAL NOT NULL, "
483+
"avg_hashrate REAL NOT NULL, shares INTEGER NOT NULL DEFAULT 0, "
484+
"stale_pct REAL NOT NULL DEFAULT 0, PRIMARY KEY(day,worker))")
485+
dcon.commit()
486+
dargs = argparse.Namespace(dry_run=True, smtp_host="x", smtp_port=0, sender="x")
487+
488+
# 10) no rollups yet -> daily() emits nothing (no fabricated summary)
489+
daily(dcon, dargs)
490+
nd = dcon.execute("SELECT COUNT(*) FROM notifications WHERE kind=?",
491+
(DAILY_SUMMARY,)).fetchone()[0]
492+
check(nd == 0, f"empty rollup must emit no summary, got {nd}")
493+
494+
for day, w, hrs, hr, stale in [
495+
("2026-06-25", "w1", 20.0, 90.0, 1.0),
496+
("2026-06-26", "w1", 23.5, 110.0, 0.5),
497+
("2026-06-26", "w2", 4.0, 5.0, 9.0),
498+
("2026-06-26", "__pool__", 24.0, 999.0, 0.0)]:
499+
dcon.execute("INSERT INTO daily(day,worker,hours_online,avg_hashrate,"
500+
"shares,stale_pct) VALUES(?,?,?,?,0,?)",
501+
(day, w, hrs, hr, stale))
502+
dcon.execute("INSERT INTO subscriptions(worker,channels,route,enabled) "
503+
"VALUES('w1','logonly','w1@route',1)")
504+
dcon.commit()
505+
506+
# 11) newest day only, __pool__ aggregate excluded -> w1,w2 summarized
507+
daily(dcon, dargs)
508+
drows = dcon.execute("SELECT worker,status FROM notifications WHERE kind=? "
509+
"ORDER BY worker", (DAILY_SUMMARY,)).fetchall()
510+
dworkers = sorted({r[0] for r in drows})
511+
check(dworkers == ["w1", "w2"],
512+
f"newest-day summary covers w1,w2 only (no __pool__/old day), got {dworkers}")
513+
514+
# 12) subscribed -> delivered; unsubscribed -> undelivered (honest, not dropped)
515+
dstat = dict(drows)
516+
check(dstat.get("w1") == "delivered", f"subscribed delivered, got {dstat.get('w1')}")
517+
check(dstat.get("w2") == "undelivered", f"unsubscribed undelivered, got {dstat.get('w2')}")
518+
dcon.close()
519+
520+
478521
con.close()
479522
if fails:
480523
print("SELFTEST FAILED:")
481524
for f in fails:
482525
print(" -", f)
483526
return 1
484-
print("SELFTEST OK (15/15)")
527+
print("SELFTEST OK (18/18)")
485528
return 0
486529

487530

0 commit comments

Comments
 (0)