diff --git a/bitcoin-core-sv2/Cargo.toml b/bitcoin-core-sv2/Cargo.toml index 6c6897588..8238767f0 100644 --- a/bitcoin-core-sv2/Cargo.toml +++ b/bitcoin-core-sv2/Cargo.toml @@ -27,4 +27,4 @@ bitcoin_capnp_types_v31 = { package = "bitcoin-capnp-types", version = "0.2.1" } # fetching from github enables synchronizing development workflows across sv2-apps and stratum repos # it MUST be changed before bitcoin-core-sv2 is published to crates.io # with the proper version of stratum-core being fetched from crates.io as well -stratum-core = { git = "https://github.com/stratum-mining/stratum", branch = "main" } +stratum-core = { git = "https://github.com/marafoundation/stratum", branch = "feat/configurable-max-past-jobs" } diff --git a/integration-tests/Cargo.lock b/integration-tests/Cargo.lock index 0a9530e38..f7c92e0b4 100644 --- a/integration-tests/Cargo.lock +++ b/integration-tests/Cargo.lock @@ -1025,7 +1025,7 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -1210,7 +1210,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "aes-gcm", ] @@ -1347,7 +1347,7 @@ dependencies = [ [[package]] name = "channels_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -1460,7 +1460,7 @@ dependencies = [ [[package]] name = "codec_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1489,7 +1489,7 @@ dependencies = [ [[package]] name = "common_messages_sv2" version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1790,7 +1790,7 @@ dependencies = [ [[package]] name = "derive_codec_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" [[package]] name = "digest" @@ -1969,7 +1969,7 @@ dependencies = [ [[package]] name = "extensions_sv2" version = "0.3.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -2042,7 +2042,7 @@ dependencies = [ [[package]] name = "framing_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -2263,7 +2263,7 @@ dependencies = [ [[package]] name = "handlers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2826,7 +2826,7 @@ dependencies = [ [[package]] name = "job_declaration_sv2" version = "10.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -3071,7 +3071,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" version = "12.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -3124,7 +3124,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "chacha20poly1305", "rand 0.8.6", @@ -3286,7 +3286,7 @@ dependencies = [ [[package]] name = "parsers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -4399,7 +4399,7 @@ dependencies = [ [[package]] name = "stratum-core" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -4422,7 +4422,7 @@ dependencies = [ [[package]] name = "stratum_translation" version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -4469,7 +4469,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -4537,7 +4537,7 @@ dependencies = [ [[package]] name = "template_distribution_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] diff --git a/miner-apps/Cargo.lock b/miner-apps/Cargo.lock index 165c5f8d0..e7c8af036 100644 --- a/miner-apps/Cargo.lock +++ b/miner-apps/Cargo.lock @@ -839,7 +839,7 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -1005,7 +1005,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "aes-gcm", ] @@ -1136,7 +1136,7 @@ dependencies = [ [[package]] name = "channels_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -1228,7 +1228,7 @@ dependencies = [ [[package]] name = "codec_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1266,7 +1266,7 @@ dependencies = [ [[package]] name = "common_messages_sv2" version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1476,7 +1476,7 @@ dependencies = [ [[package]] name = "derive_codec_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" [[package]] name = "digest" @@ -1644,7 +1644,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" version = "0.3.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1712,7 +1712,7 @@ dependencies = [ [[package]] name = "framing_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1883,7 +1883,7 @@ dependencies = [ [[package]] name = "handlers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2405,7 +2405,7 @@ dependencies = [ [[package]] name = "job_declaration_sv2" version = "10.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -2597,7 +2597,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" version = "12.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -2637,7 +2637,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "chacha20poly1305", "rand 0.8.5", @@ -2767,7 +2767,7 @@ dependencies = [ [[package]] name = "parsers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -3771,7 +3771,7 @@ dependencies = [ [[package]] name = "stratum-core" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3794,7 +3794,7 @@ dependencies = [ [[package]] name = "stratum_translation" version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3841,7 +3841,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3897,7 +3897,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "template_distribution_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] diff --git a/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml b/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml index 62cfed85b..61a4e015e 100644 --- a/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml +++ b/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-local-infra-example.toml b/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-local-infra-example.toml index b56b3a533..5c58bd5c5 100644 --- a/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/mainnet/jdc-config-bitcoin-core-ipc-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/mainnet/jdc-config-hosted-infra-example.toml b/miner-apps/jd-client/config-examples/mainnet/jdc-config-hosted-infra-example.toml index 9b3edffcb..2ade76210 100644 --- a/miner-apps/jd-client/config-examples/mainnet/jdc-config-hosted-infra-example.toml +++ b/miner-apps/jd-client/config-examples/mainnet/jdc-config-hosted-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/mainnet/jdc-config-local-infra-example.toml b/miner-apps/jd-client/config-examples/mainnet/jdc-config-local-infra-example.toml index 3604a9354..7be8e9aa3 100644 --- a/miner-apps/jd-client/config-examples/mainnet/jdc-config-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/mainnet/jdc-config-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/mainnet/jdc-config-solo-mining-example.toml b/miner-apps/jd-client/config-examples/mainnet/jdc-config-solo-mining-example.toml index bfd69bfe6..9b3d991fd 100644 --- a/miner-apps/jd-client/config-examples/mainnet/jdc-config-solo-mining-example.toml +++ b/miner-apps/jd-client/config-examples/mainnet/jdc-config-solo-mining-example.toml @@ -40,6 +40,12 @@ upstreams = [] # Templates come directly from the Template Provider below. # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/signet/jdc-config-bitcoin-core-ipc-local-infra-example.toml b/miner-apps/jd-client/config-examples/signet/jdc-config-bitcoin-core-ipc-local-infra-example.toml index b2960a391..ead13a683 100644 --- a/miner-apps/jd-client/config-examples/signet/jdc-config-bitcoin-core-ipc-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/signet/jdc-config-bitcoin-core-ipc-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/signet/jdc-config-local-infra-example.toml b/miner-apps/jd-client/config-examples/signet/jdc-config-local-infra-example.toml index 922a3bc16..7f5221c3b 100644 --- a/miner-apps/jd-client/config-examples/signet/jdc-config-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/signet/jdc-config-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml b/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml index fbd77c349..c275df3f3 100644 --- a/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml +++ b/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-hosted-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-local-infra-example.toml b/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-local-infra-example.toml index c443b8dc6..a1e9f06dc 100644 --- a/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/testnet4/jdc-config-bitcoin-core-ipc-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/testnet4/jdc-config-hosted-infra-example.toml b/miner-apps/jd-client/config-examples/testnet4/jdc-config-hosted-infra-example.toml index 4d282f9a5..d6455b3e1 100644 --- a/miner-apps/jd-client/config-examples/testnet4/jdc-config-hosted-infra-example.toml +++ b/miner-apps/jd-client/config-examples/testnet4/jdc-config-hosted-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/config-examples/testnet4/jdc-config-local-infra-example.toml b/miner-apps/jd-client/config-examples/testnet4/jdc-config-local-infra-example.toml index 1d0823b20..f149545ae 100644 --- a/miner-apps/jd-client/config-examples/testnet4/jdc-config-local-infra-example.toml +++ b/miner-apps/jd-client/config-examples/testnet4/jdc-config-local-infra-example.toml @@ -53,6 +53,12 @@ monitoring_address = "0.0.0.0:9091" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs index 1c1a0da92..e109fcae7 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs @@ -323,6 +323,7 @@ impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { self.shares_per_minute, pool_tag_string, self.miner_tag_string.clone(), + self.max_past_jobs, ) { Ok(standard_channel) => Some(standard_channel), Err(e) => { @@ -564,6 +565,7 @@ impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { self.shares_per_minute, pool_tag_string, self.miner_tag_string.clone(), + self.max_past_jobs, ) { Ok(channel) => Some(channel), Err(e) => { diff --git a/miner-apps/jd-client/src/lib/channel_manager/mod.rs b/miner-apps/jd-client/src/lib/channel_manager/mod.rs index 01185ec83..365ce7132 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/mod.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/mod.rs @@ -301,6 +301,8 @@ pub struct ChannelManager { miner_tag_string: String, share_batch_size: SharesBatchSize, shares_per_minute: SharesPerMinute, + /// Past jobs retained per channel; `None` uses the `channels_sv2` default. + max_past_jobs: Option, user_identity: Arc>, reserved_downstream_rollable_extranonce_size: u8, /// This represent the current state of Upstream channel @@ -398,6 +400,14 @@ impl ChannelManager { ExtranonceAllocator::new(Vec::new(), SOLO_FULL_EXTRANONCE_SIZE, JDC_MAX_CHANNELS) .map_err(JDCError::::shutdown)?; + // Record the cap actually in force. When unset it comes from the `channels_sv2` + // default, so it appears nowhere in this application's own config and is + // otherwise not recoverable from a running instance. + match config.max_past_jobs() { + Some(n) if n > 0 => info!(max_past_jobs = n, "past-jobs retention cap configured"), + _ => info!("past-jobs retention cap: using channels_sv2 default"), + } + let channel_manager_io = ChannelManagerIo { upstream_sender, upstream_receiver, @@ -435,6 +445,7 @@ impl ChannelManager { cached_shares: SharedMap::new(), share_batch_size: config.share_batch_size(), shares_per_minute: config.shares_per_minute(), + max_past_jobs: config.max_past_jobs(), miner_tag_string: config.jdc_signature().to_string(), user_identity: Arc::new(OnceLock::new()), reserved_downstream_rollable_extranonce_size: config diff --git a/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs index efd8b4ec3..65ec094e0 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs @@ -187,6 +187,7 @@ impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { hashrate, true, msg.extranonce_size, + self.max_past_jobs, ); if let Some(prevhash) = self.last_new_prev_hash.get().map_err(JDCError::shutdown)? { diff --git a/miner-apps/jd-client/src/lib/config.rs b/miner-apps/jd-client/src/lib/config.rs index 906677f54..294e1829d 100644 --- a/miner-apps/jd-client/src/lib/config.rs +++ b/miner-apps/jd-client/src/lib/config.rs @@ -43,6 +43,13 @@ pub struct JobDeclaratorClientConfig { shares_per_minute: SharesPerMinute, /// share batch size share_batch_size: SharesBatchSize, + /// Past jobs retained per channel for late-share validation. + /// + /// `None` and `Some(0)` both select the `channels_sv2` default. This is a retention + /// window — `cap / template rate` — so the right value depends on this deployment's + /// template cadence and its downstreams' submission latency. + #[serde(default)] + max_past_jobs: Option, /// JDC mode: FullTemplate, CoinbaseOnly, or SoloMining #[serde(deserialize_with = "deserialize_jdc_mode", default)] pub mode: ConfigJDCMode, @@ -104,6 +111,9 @@ impl JobDeclaratorClientConfig { ) -> Self { Self { listening_address, + // Programmatic construction takes the library default; use + // `set_max_past_jobs` to override, as the file-based path does via serde. + max_past_jobs: None, max_supported_version: protocol_config.max_supported_version, min_supported_version: protocol_config.min_supported_version, authority_public_key: pool_config.authority_public_key, @@ -214,6 +224,17 @@ impl JobDeclaratorClientConfig { self.share_batch_size } + /// Past jobs retained per channel, or `None` to use the `channels_sv2` default. + pub fn max_past_jobs(&self) -> Option { + self.max_past_jobs + } + + /// Overrides the retained past-jobs cap. For tests and for deployments that vary it + /// between otherwise-identical instances. + pub fn set_max_past_jobs(&mut self, max_past_jobs: Option) { + self.max_past_jobs = max_past_jobs; + } + /// Returns the supported extensions. pub fn supported_extensions(&self) -> &[u16] { &self.supported_extensions @@ -403,3 +424,40 @@ mod tests { assert_eq!(upstream.user_identity, ""); } } + +#[cfg(test)] +mod max_past_jobs_tests { + /// Every shipped example must document the setting, commented out. + /// + /// Commented out matters: it keeps the library default in force for existing + /// deployments. Absent-means-default is also why `Some(0)` is treated as "no + /// opinion" rather than a literal zero — a zero cap would evict the job that just + /// retired and reject the most common late share as `invalid-job-id`. + /// + /// The test walks the directory rather than naming files, and asserts it found + /// some: an earlier version named one file, guessed the name wrong, and passed by + /// silently doing nothing. + #[test] + fn every_example_documents_the_cap_commented_out() { + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("config-examples"); + let mut checked = 0; + let mut stack = vec![dir]; + while let Some(d) = stack.pop() { + for entry in std::fs::read_dir(&d).expect("read config-examples") { + let path = entry.expect("dir entry").path(); + if path.is_dir() { + stack.push(path); + } else if path.extension().is_some_and(|e| e == "toml") { + let text = std::fs::read_to_string(&path).expect("read example"); + assert!( + text.contains("# max_past_jobs"), + "{} does not document max_past_jobs (commented out)", + path.display() + ); + checked += 1; + } + } + } + assert!(checked > 0, "no examples found — the test would be vacuous"); + } +} diff --git a/miner-apps/translator/config-examples/mainnet/tproxy-config-hosted-pool-example.toml b/miner-apps/translator/config-examples/mainnet/tproxy-config-hosted-pool-example.toml index f34f8dd1c..f7eecaa00 100644 --- a/miner-apps/translator/config-examples/mainnet/tproxy-config-hosted-pool-example.toml +++ b/miner-apps/translator/config-examples/mainnet/tproxy-config-hosted-pool-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/mainnet/tproxy-config-local-jdc-example.toml b/miner-apps/translator/config-examples/mainnet/tproxy-config-local-jdc-example.toml index 058107b98..45cc9a847 100644 --- a/miner-apps/translator/config-examples/mainnet/tproxy-config-local-jdc-example.toml +++ b/miner-apps/translator/config-examples/mainnet/tproxy-config-local-jdc-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/mainnet/tproxy-config-local-pool-example.toml b/miner-apps/translator/config-examples/mainnet/tproxy-config-local-pool-example.toml index e029d5eb9..f2e6fb125 100644 --- a/miner-apps/translator/config-examples/mainnet/tproxy-config-local-pool-example.toml +++ b/miner-apps/translator/config-examples/mainnet/tproxy-config-local-pool-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/signet/tproxy-config-local-jdc-example.toml b/miner-apps/translator/config-examples/signet/tproxy-config-local-jdc-example.toml index 058107b98..45cc9a847 100644 --- a/miner-apps/translator/config-examples/signet/tproxy-config-local-jdc-example.toml +++ b/miner-apps/translator/config-examples/signet/tproxy-config-local-jdc-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/signet/tproxy-config-local-pool-example.toml b/miner-apps/translator/config-examples/signet/tproxy-config-local-pool-example.toml index 1831c788c..af95c405c 100644 --- a/miner-apps/translator/config-examples/signet/tproxy-config-local-pool-example.toml +++ b/miner-apps/translator/config-examples/signet/tproxy-config-local-pool-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/testnet4/tproxy-config-hosted-pool-example.toml b/miner-apps/translator/config-examples/testnet4/tproxy-config-hosted-pool-example.toml index 77b178977..2cd775f58 100644 --- a/miner-apps/translator/config-examples/testnet4/tproxy-config-hosted-pool-example.toml +++ b/miner-apps/translator/config-examples/testnet4/tproxy-config-hosted-pool-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/testnet4/tproxy-config-local-jdc-example.toml b/miner-apps/translator/config-examples/testnet4/tproxy-config-local-jdc-example.toml index 058107b98..45cc9a847 100644 --- a/miner-apps/translator/config-examples/testnet4/tproxy-config-local-jdc-example.toml +++ b/miner-apps/translator/config-examples/testnet4/tproxy-config-local-jdc-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/config-examples/testnet4/tproxy-config-local-pool-example.toml b/miner-apps/translator/config-examples/testnet4/tproxy-config-local-pool-example.toml index b74a22036..4e9fc8d7e 100644 --- a/miner-apps/translator/config-examples/testnet4/tproxy-config-local-pool-example.toml +++ b/miner-apps/translator/config-examples/testnet4/tproxy-config-local-pool-example.toml @@ -39,6 +39,12 @@ monitoring_address = "0.0.0.0:9092" monitoring_cache_refresh_secs = 15 # LAN subnet containing ASIC miner web/API addresses (for example, 192.168.1.0/24). +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + [miner_telemetry] cidrs = ["192.168.1.0/24"] diff --git a/miner-apps/translator/src/lib/config.rs b/miner-apps/translator/src/lib/config.rs index 6d225a31f..2be2535ab 100644 --- a/miner-apps/translator/src/lib/config.rs +++ b/miner-apps/translator/src/lib/config.rs @@ -46,6 +46,13 @@ pub struct TranslatorConfig { /// If true, all miners share one channel. If false, each miner gets its own channel. pub aggregate_channels: bool, /// Protocol extensions that the translator supports (will request if supported by server). + /// Past jobs retained per channel for late-share validation. + /// + /// `None` and `Some(0)` both select the `channels_sv2` default. This is a retention + /// window — `cap / template rate` — so the right value depends on this deployment's + /// template cadence and its SV1 miners' submission latency. + #[serde(default)] + pub max_past_jobs: Option, #[serde(default)] pub supported_extensions: Vec, /// Protocol extensions that the translator requires (server must support these). @@ -124,6 +131,9 @@ impl TranslatorConfig { ) -> Self { Self { upstreams, + // Programmatic construction takes the library default; the file-based path + // sets it via serde, and callers can assign the field directly. + max_past_jobs: None, downstream_address, downstream_port, max_supported_version, @@ -574,3 +584,40 @@ mod tests { assert_eq!(config.upstreams[1].user_identity, "bc1qbackup.worker"); } } + +#[cfg(test)] +mod max_past_jobs_tests { + /// Every shipped example must document the setting, commented out. + /// + /// Commented out matters: it keeps the library default in force for existing + /// deployments. Absent-means-default is also why `Some(0)` is treated as "no + /// opinion" rather than a literal zero — a zero cap would evict the job that just + /// retired and reject the most common late share as `invalid-job-id`. + /// + /// The test walks the directory rather than naming files, and asserts it found + /// some: an earlier version named one file, guessed the name wrong, and passed by + /// silently doing nothing. + #[test] + fn every_example_documents_the_cap_commented_out() { + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("config-examples"); + let mut checked = 0; + let mut stack = vec![dir]; + while let Some(d) = stack.pop() { + for entry in std::fs::read_dir(&d).expect("read config-examples") { + let path = entry.expect("dir entry").path(); + if path.is_dir() { + stack.push(path); + } else if path.extension().is_some_and(|e| e == "toml") { + let text = std::fs::read_to_string(&path).expect("read example"); + assert!( + text.contains("# max_past_jobs"), + "{} does not document max_past_jobs (commented out)", + path.display() + ); + checked += 1; + } + } + } + assert!(checked > 0, "no examples found — the test would be vacuous"); + } +} diff --git a/miner-apps/translator/src/lib/monitoring.rs b/miner-apps/translator/src/lib/monitoring.rs index 42f65ae03..3e0cfd7bc 100644 --- a/miner-apps/translator/src/lib/monitoring.rs +++ b/miner-apps/translator/src/lib/monitoring.rs @@ -132,6 +132,7 @@ mod tests { vec![], vec![], TproxyMode::Aggregated, + None, true, ) } @@ -146,6 +147,7 @@ mod tests { 1.0, true, 4, + None, ) } diff --git a/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs b/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs index b5efdd830..f94f8e44a 100644 --- a/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs +++ b/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs @@ -179,6 +179,7 @@ impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { nominal_hashrate, version_rolling, m.extranonce_size, + self.max_past_jobs, ); self.extended_channels .insert(AGGREGATED_CHANNEL_ID, upstream_channel); @@ -197,6 +198,7 @@ impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { nominal_hashrate, true, downstream_extranonce_len as u16, + self.max_past_jobs, ); self.extended_channels .insert(1, new_downstream_extended_channel); @@ -329,6 +331,7 @@ impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { nominal_hashrate, version_rolling, downstream_extranonce_len as u16, + self.max_past_jobs, ); self.extended_channels .insert(m.channel_id, new_downstream_extended_channel); diff --git a/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs b/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs index b4b756c00..c1b32668b 100644 --- a/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs +++ b/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs @@ -136,6 +136,8 @@ pub struct ChannelManager { pub supported_extensions: Vec, /// Extensions that the translator requires (must be supported by server) pub required_extensions: Vec, + /// Past jobs retained per channel; `None` uses the `channels_sv2` default. + pub max_past_jobs: Option, /// Store pending channel info by downstream_id: (user_identity, hashrate, /// downstream_extranonce_len) /// @@ -305,8 +307,17 @@ impl ChannelManager { supported_extensions: Vec, required_extensions: Vec, tproxy_mode: TproxyMode, + max_past_jobs: Option, #[cfg(feature = "monitoring")] report_hashrate: bool, ) -> Self { + // Record the cap actually in force. When unset it comes from the `channels_sv2` + // default, so it appears nowhere in this application's own config and is + // otherwise not recoverable from a running instance. + match max_past_jobs { + Some(n) if n > 0 => info!(max_past_jobs = n, "past-jobs retention cap configured"), + _ => info!("past-jobs retention cap: using channels_sv2 default"), + } + let channel_manager_io = ChannelManagerIo::new( upstream_sender, upstream_receiver, @@ -318,6 +329,7 @@ impl ChannelManager { channel_manager_io, supported_extensions, required_extensions, + max_past_jobs, pending_downstream_channels: SharedMap::new(), extended_channels: SharedMap::new(), group_channels: SharedMap::new(), @@ -948,6 +960,7 @@ impl ChannelManager { hashrate, true, min_extranonce_size as u16, + self.max_past_jobs, ); self.extended_channels .insert(next_channel_id, new_downstream_extended_channel); @@ -1097,6 +1110,7 @@ mod tests { vec![], vec![], TproxyMode::from(true), + None, #[cfg(feature = "monitoring")] true, ) @@ -1116,6 +1130,7 @@ mod tests { vec![], vec![], TproxyMode::Aggregated, + None, #[cfg(feature = "monitoring")] true, ); @@ -1130,6 +1145,7 @@ mod tests { 1.0, true, 8, + None, ), ); manager @@ -1254,6 +1270,7 @@ mod tests { vec![], vec![], TproxyMode::Aggregated, + None, #[cfg(feature = "monitoring")] true, )); @@ -1344,6 +1361,7 @@ mod tests { 1.0, true, 6, + None, ), ); diff --git a/miner-apps/translator/src/lib/translator_runtime.rs b/miner-apps/translator/src/lib/translator_runtime.rs index c2ba9a83d..5c3e6217f 100644 --- a/miner-apps/translator/src/lib/translator_runtime.rs +++ b/miner-apps/translator/src/lib/translator_runtime.rs @@ -256,6 +256,7 @@ impl TranslatorRuntime { self.translator.config.supported_extensions.clone(), self.translator.config.required_extensions.clone(), self.tproxy_mode, + self.translator.config.max_past_jobs, #[cfg(feature = "monitoring")] self.translator .config diff --git a/pool-apps/Cargo.lock b/pool-apps/Cargo.lock index 1fea6b9c0..cfc1f814b 100644 --- a/pool-apps/Cargo.lock +++ b/pool-apps/Cargo.lock @@ -273,7 +273,7 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "aes-gcm", ] @@ -542,7 +542,7 @@ dependencies = [ [[package]] name = "channels_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -612,7 +612,7 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "codec_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -640,7 +640,7 @@ dependencies = [ [[package]] name = "common_messages_sv2" version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -808,7 +808,7 @@ dependencies = [ [[package]] name = "derive_codec_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" [[package]] name = "digest" @@ -937,7 +937,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" version = "0.3.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -998,7 +998,7 @@ dependencies = [ [[package]] name = "framing_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1133,7 +1133,7 @@ dependencies = [ [[package]] name = "handlers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -1533,7 +1533,7 @@ dependencies = [ [[package]] name = "job_declaration_sv2" version = "10.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1653,7 +1653,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" version = "12.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1693,7 +1693,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "chacha20poly1305", "rand", @@ -1817,7 +1817,7 @@ dependencies = [ [[package]] name = "parsers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2476,7 +2476,7 @@ dependencies = [ [[package]] name = "stratum-core" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -2543,7 +2543,7 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "template_distribution_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] diff --git a/pool-apps/pool/config-examples/mainnet/pool-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/mainnet/pool-config-bitcoin-core-ipc-example.toml index b4a220b9f..bb70aedf4 100644 --- a/pool-apps/pool/config-examples/mainnet/pool-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/mainnet/pool-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/mainnet/pool-config-hosted-sv2-tp-example.toml b/pool-apps/pool/config-examples/mainnet/pool-config-hosted-sv2-tp-example.toml index a38440a6c..7799c7177 100644 --- a/pool-apps/pool/config-examples/mainnet/pool-config-hosted-sv2-tp-example.toml +++ b/pool-apps/pool/config-examples/mainnet/pool-config-hosted-sv2-tp-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/mainnet/pool-config-local-sv2-tp-example.toml b/pool-apps/pool/config-examples/mainnet/pool-config-local-sv2-tp-example.toml index 51fe325e3..f68d90afb 100644 --- a/pool-apps/pool/config-examples/mainnet/pool-config-local-sv2-tp-example.toml +++ b/pool-apps/pool/config-examples/mainnet/pool-config-local-sv2-tp-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/mainnet/pool-jds-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/mainnet/pool-jds-config-bitcoin-core-ipc-example.toml index 88da338db..7abc5d555 100644 --- a/pool-apps/pool/config-examples/mainnet/pool-jds-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/mainnet/pool-jds-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Protocol Extensions Configuration # Extensions that the pool supports (will accept if requested by clients) diff --git a/pool-apps/pool/config-examples/signet/pool-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/signet/pool-config-bitcoin-core-ipc-example.toml index 17ac307f1..6ff332223 100644 --- a/pool-apps/pool/config-examples/signet/pool-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/signet/pool-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + monitoring_address = "127.0.0.1:9090" monitoring_cache_refresh_secs = 15 diff --git a/pool-apps/pool/config-examples/signet/pool-config-local-sv2-tp-example.toml b/pool-apps/pool/config-examples/signet/pool-config-local-sv2-tp-example.toml index d48658c77..97dc00ced 100644 --- a/pool-apps/pool/config-examples/signet/pool-config-local-sv2-tp-example.toml +++ b/pool-apps/pool/config-examples/signet/pool-config-local-sv2-tp-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + monitoring_address = "127.0.0.1:9090" monitoring_cache_refresh_secs = 15 diff --git a/pool-apps/pool/config-examples/signet/pool-jds-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/signet/pool-jds-config-bitcoin-core-ipc-example.toml index 4b07bd9da..ae4539624 100644 --- a/pool-apps/pool/config-examples/signet/pool-jds-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/signet/pool-jds-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Protocol Extensions Configuration # Extensions that the pool supports (will accept if requested by clients) diff --git a/pool-apps/pool/config-examples/testnet4/pool-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/testnet4/pool-config-bitcoin-core-ipc-example.toml index a29be049d..40438e2b6 100644 --- a/pool-apps/pool/config-examples/testnet4/pool-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/testnet4/pool-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/testnet4/pool-config-hosted-sv2-tp-example.toml b/pool-apps/pool/config-examples/testnet4/pool-config-hosted-sv2-tp-example.toml index 632370cb1..fce757d74 100644 --- a/pool-apps/pool/config-examples/testnet4/pool-config-hosted-sv2-tp-example.toml +++ b/pool-apps/pool/config-examples/testnet4/pool-config-hosted-sv2-tp-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/testnet4/pool-config-local-sv2-tp-example.toml b/pool-apps/pool/config-examples/testnet4/pool-config-local-sv2-tp-example.toml index 9ff3b80f1..b93d07186 100644 --- a/pool-apps/pool/config-examples/testnet4/pool-config-local-sv2-tp-example.toml +++ b/pool-apps/pool/config-examples/testnet4/pool-config-local-sv2-tp-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Monitoring HTTP server address for exposing channel data (optional) monitoring_address = "127.0.0.1:9090" diff --git a/pool-apps/pool/config-examples/testnet4/pool-jds-config-bitcoin-core-ipc-example.toml b/pool-apps/pool/config-examples/testnet4/pool-jds-config-bitcoin-core-ipc-example.toml index 033299581..689e0e5d9 100644 --- a/pool-apps/pool/config-examples/testnet4/pool-jds-config-bitcoin-core-ipc-example.toml +++ b/pool-apps/pool/config-examples/testnet4/pool-jds-config-bitcoin-core-ipc-example.toml @@ -25,6 +25,12 @@ pool_signature = "Stratum V2 SRI Pool" shares_per_minute = 6.0 # How many shares do we want to acknowledge in a batch share_batch_size = 10 +# Past jobs retained per channel for late-share validation (optional). Unset or 0 uses +# the channels_sv2 default (16), which covers the fastest configurable template cadence. +# Set `ceil(16s / your template period)` to reclaim memory: 3 at a typical 6s mainnet +# cadence is 13.5 kB per channel instead of 72. +# max_past_jobs = 3 + # Protocol Extensions Configuration # Extensions that the pool supports (will accept if requested by clients) diff --git a/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs b/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs index 2945cb052..248e9cb7a 100644 --- a/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs +++ b/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs @@ -238,6 +238,7 @@ impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { self.share_batch_size, self.shares_per_minute, self.pool_tag_string.clone(), + self.max_past_jobs, ) { Ok(channel) => channel, Err(e) => match e { @@ -477,6 +478,7 @@ impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { self.share_batch_size, self.shares_per_minute, self.pool_tag_string.clone(), + self.max_past_jobs, ) { Ok(channel) => channel, Err(e) => match e { diff --git a/pool-apps/pool/src/lib/channel_manager/mod.rs b/pool-apps/pool/src/lib/channel_manager/mod.rs index 5e9ad4cff..7c171c08b 100644 --- a/pool-apps/pool/src/lib/channel_manager/mod.rs +++ b/pool-apps/pool/src/lib/channel_manager/mod.rs @@ -111,6 +111,8 @@ pub struct ChannelManager { pool_tag_string: String, share_batch_size: usize, shares_per_minute: SharesPerMinute, + /// Past jobs retained per channel; `None` uses the `channels_sv2` default. + max_past_jobs: Option, coinbase_reward_script: CoinbaseRewardScript, /// Protocol extensions that the pool supports (will accept if requested by clients). supported_extensions: Vec, @@ -183,6 +185,14 @@ impl ChannelManager { downstream_receiver, }; + // Record the cap actually in force. When unset it comes from the `channels_sv2` + // default, so it appears nowhere in this application's own config and is + // otherwise not recoverable from a running pool. + match config.max_past_jobs() { + Some(n) if n > 0 => info!(max_past_jobs = n, "past-jobs retention cap configured"), + _ => info!("past-jobs retention cap: using channels_sv2 default"), + } + let channel_manager = ChannelManager { downstreams: SharedMap::new(), extranonce_allocator: SharedLock::new(extranonce_allocator), @@ -194,6 +204,7 @@ impl ChannelManager { channel_manager_io, share_batch_size: config.share_batch_size(), shares_per_minute: config.shares_per_minute(), + max_past_jobs: config.max_past_jobs(), pool_tag_string: config.pool_signature().to_string(), coinbase_reward_script: config.coinbase_reward_script().clone(), supported_extensions: config.supported_extensions().to_vec(), diff --git a/pool-apps/pool/src/lib/config.rs b/pool-apps/pool/src/lib/config.rs index 4322075c9..49cc10e90 100644 --- a/pool-apps/pool/src/lib/config.rs +++ b/pool-apps/pool/src/lib/config.rs @@ -50,6 +50,13 @@ pub struct PoolConfig { jds: Option, #[serde(default)] monitoring_cache_refresh_secs: Option, + /// Past jobs retained per channel for late-share validation. + /// + /// `None` (the default) and `Some(0)` both select the `channels_sv2` default. The cap is + /// really a retention window — `cap / template rate` — and the template rate belongs to + /// this deployment, not to the library, which is why it is settable here. + #[serde(default)] + max_past_jobs: Option, } impl PoolConfig { @@ -83,6 +90,7 @@ impl PoolConfig { pool_signature: pool_connection.signature, shares_per_minute, share_batch_size, + max_past_jobs: None, log_file: None, server_id, supported_extensions, @@ -139,6 +147,17 @@ impl PoolConfig { } /// Returns the shares per minute. + /// Past jobs retained per channel, or `None` to use the `channels_sv2` default. + pub fn max_past_jobs(&self) -> Option { + self.max_past_jobs + } + + /// Overrides the retained past-jobs cap. Mainly for tests and A/B deployments that vary + /// it between otherwise-identical instances. + pub fn set_max_past_jobs(&mut self, max_past_jobs: Option) { + self.max_past_jobs = max_past_jobs; + } + pub fn shares_per_minute(&self) -> f32 { self.shares_per_minute } @@ -239,3 +258,65 @@ impl ConnectionConfig { } } } + +#[cfg(test)] +mod tests { + use super::*; + use stratum_apps::config_helpers::load_config; + + /// Writes a minimal pool config with `extra` spliced in, so each test varies exactly + /// one thing, and loads it through the SAME loader the binary uses — not a bare + /// `toml::from_str`. That way the test covers serde attributes, the env-override layer + /// and the enum handling, rather than just the struct definition. + fn load_with(extra: &str, name: &str) -> PoolConfig { + let path = std::env::temp_dir().join(format!("pool-config-{name}.toml")); + std::fs::write( + &path, + format!( + r#" +listen_address = "0.0.0.0:34254" +authority_public_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" +authority_secret_key = "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n" +cert_validity_sec = 3600 +coinbase_reward_script = "addr(tb1qa0sm0hxzj0x25rh8gw5xlzwlsfvvyz8u96w3p8)" +pool_signature = "test" +shares_per_minute = 6.0 +share_batch_size = 10 +{extra} + +[template_provider_type.Sv2Tp] +address = "127.0.0.1:8442" +"# + ), + ) + .expect("write temp config"); + let cfg = load_config(&path, "POOL_TEST_UNUSED", &[], &["template_provider_type"]) + .expect("config loads"); + let _ = std::fs::remove_file(&path); + cfg + } + + #[test] + fn max_past_jobs_defaults_to_none_when_absent() { + // Absent must mean "use the library default", not 0: a zero cap would evict the job + // that just retired and reject the most common late share as invalid-job-id. + assert_eq!(load_with("", "absent").max_past_jobs(), None); + } + + #[test] + fn max_past_jobs_is_read_from_config() { + // The A/B deployment varies this single value between otherwise-identical pools, so + // it has to survive loading verbatim. + assert_eq!( + load_with("max_past_jobs = 2", "set").max_past_jobs(), + Some(2) + ); + } + + #[test] + fn max_past_jobs_setter_overrides() { + let mut cfg = load_with("", "setter"); + cfg.set_max_past_jobs(Some(50)); + assert_eq!(cfg.max_past_jobs(), Some(50)); + } +} diff --git a/stratum-apps/Cargo.lock b/stratum-apps/Cargo.lock index b89cea50d..73d5f05e3 100644 --- a/stratum-apps/Cargo.lock +++ b/stratum-apps/Cargo.lock @@ -774,7 +774,7 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -940,7 +940,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "aes-gcm", ] @@ -1071,7 +1071,7 @@ dependencies = [ [[package]] name = "channels_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -1117,7 +1117,7 @@ dependencies = [ [[package]] name = "codec_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1140,7 +1140,7 @@ dependencies = [ [[package]] name = "common_messages_sv2" version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1341,7 +1341,7 @@ dependencies = [ [[package]] name = "derive_codec_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" [[package]] name = "digest" @@ -1482,7 +1482,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" version = "0.3.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -1540,7 +1540,7 @@ dependencies = [ [[package]] name = "framing_sv2" version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1711,7 +1711,7 @@ dependencies = [ [[package]] name = "handlers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2140,7 +2140,7 @@ dependencies = [ [[package]] name = "job_declaration_sv2" version = "10.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -2328,7 +2328,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" version = "12.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] @@ -2368,7 +2368,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "2.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "chacha20poly1305", "rand 0.8.5", @@ -2492,7 +2492,7 @@ dependencies = [ [[package]] name = "parsers_sv2" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -3442,7 +3442,7 @@ dependencies = [ [[package]] name = "stratum-core" version = "0.6.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3465,7 +3465,7 @@ dependencies = [ [[package]] name = "stratum_translation" version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3506,7 +3506,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", "bitcoin", @@ -3562,7 +3562,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "template_distribution_sv2" version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#aa2427007358b6182ee28316f07e1915bcf2fd3d" +source = "git+https://github.com/marafoundation/stratum?branch=feat%2Fconfigurable-max-past-jobs#60dfd84d9a7c55ac58a2edc08d6d21b04849fca1" dependencies = [ "binary_sv2", ] diff --git a/stratum-apps/Cargo.toml b/stratum-apps/Cargo.toml index 93d1490b4..3b14927be 100644 --- a/stratum-apps/Cargo.toml +++ b/stratum-apps/Cargo.toml @@ -17,7 +17,7 @@ keywords = ["stratum", "mining", "bitcoin", "protocol", "sv2"] # fetching from github enables synchronizing development workflows across sv2-apps and stratum repos # it MUST be changed before stratum-apps is published to crates.io # with the proper version of stratum-core being fetched from crates.io as well -stratum-core = { git = "https://github.com/stratum-mining/stratum", branch = "main", optional = true } +stratum-core = { git = "https://github.com/marafoundation/stratum", branch = "feat/configurable-max-past-jobs", optional = true } bitcoin-core-sv2 = { package = "bitcoin_core_sv2", version = "0.5.0", path = "../bitcoin-core-sv2", optional = true } # External dependencies needed by the modules