From a7916eae7ba591f4c8381e8677eb3e4cca8a68e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=BE=D0=BB=D0=BB=D0=B8?= Date: Wed, 11 Mar 2026 12:04:56 +0300 Subject: [PATCH] add IT for JD mining mode negotiation Add integration tests for all three JD mining mode scenarios: - Mode mismatch (JDS requires FullTemplate, JDC asks CoinbaseOnly) -> SetupConnectionError - CoinbaseOnly mode: no DeclareMiningJob exchanged, block propagation only from JDC - FullTemplate mode: DeclareMiningJob exchanged with JDS Extend start_jds() and start_jdc() to accept mode configuration parameters. Add set_full_template_mode_required() setter to JDS config. Closes #21 --- integration-tests/lib/mod.rs | 11 ++- .../tests/bitcoin_core_ipc_integration.rs | 3 +- .../jd_coinbase_only_block_propagation.rs | 57 +++++++++++ .../tests/jd_full_template_mode.rs | 40 ++++++++ integration-tests/tests/jd_integration.rs | 22 +++-- integration-tests/tests/jd_mining_modes.rs | 96 +++++++++++++++++++ .../tests/jd_provide_missing_transaction.rs | 3 +- .../tests/jd_tproxy_integration.rs | 6 +- .../tests/jdc_block_propagation.rs | 3 +- integration-tests/tests/jdc_cached_shares.rs | 3 +- .../jdc_receives_submit_shares_success.rs | 3 +- .../tests/jds_block_propagation.rs | 3 +- integration-tests/tests/pool_integration.rs | 3 +- pool-apps/jd-server/src/lib/config.rs | 4 + 14 files changed, 238 insertions(+), 19 deletions(-) create mode 100644 integration-tests/tests/jd_coinbase_only_block_propagation.rs create mode 100644 integration-tests/tests/jd_full_template_mode.rs create mode 100644 integration-tests/tests/jd_mining_modes.rs diff --git a/integration-tests/lib/mod.rs b/integration-tests/lib/mod.rs index f2e08eb2c..d32ea30a5 100644 --- a/integration-tests/lib/mod.rs +++ b/integration-tests/lib/mod.rs @@ -187,6 +187,7 @@ pub fn start_jdc( template_provider_config: TemplateProviderType, supported_extensions: Vec, required_extensions: Vec, + jdc_mode: Option<&str>, ) -> (JobDeclaratorClient, SocketAddr) { use jd_client_sv2::config::{JobDeclaratorClientConfig, PoolConfig, ProtocolConfig, Upstream}; let jdc_address = get_available_address(); @@ -239,7 +240,7 @@ pub fn start_jdc( template_provider_config, upstreams, jdc_signature, - None, + jdc_mode.map(|s| s.to_string()), supported_extensions, required_extensions, ); @@ -249,7 +250,10 @@ pub fn start_jdc( (ret, jdc_address) } -pub fn start_jds(tp_rpc_connection: &ConnectParams) -> (JobDeclaratorServer, SocketAddr) { +pub fn start_jds( + tp_rpc_connection: &ConnectParams, + full_template_mode_required: bool, +) -> (JobDeclaratorServer, SocketAddr) { use jd_server::config::{CoreRpc, JobDeclaratorServerConfig}; let authority_public_key = JdServerSecp256k1PublicKey::try_from( "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72".to_string(), @@ -277,7 +281,7 @@ pub fn start_jds(tp_rpc_connection: &ConnectParams) -> (JobDeclaratorServer, Soc user, password, ); - let config = JobDeclaratorServerConfig::new( + let mut config = JobDeclaratorServerConfig::new( listen_jd_address.to_string(), authority_public_key, authority_secret_key, @@ -286,6 +290,7 @@ pub fn start_jds(tp_rpc_connection: &ConnectParams) -> (JobDeclaratorServer, Soc core_rpc, std::time::Duration::from_secs(1), ); + config.set_full_template_mode_required(full_template_mode_required); let job_declarator_server = JobDeclaratorServer::new(config); let job_declarator_server_clone = job_declarator_server.clone(); tokio::spawn(async move { diff --git a/integration-tests/tests/bitcoin_core_ipc_integration.rs b/integration-tests/tests/bitcoin_core_ipc_integration.rs index 978d2c812..615348b03 100644 --- a/integration-tests/tests/bitcoin_core_ipc_integration.rs +++ b/integration-tests/tests/bitcoin_core_ipc_integration.rs @@ -46,7 +46,7 @@ async fn jdc_propagates_block_with_bitcoin_core_ipc() { let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let current_block_hash = tp.get_best_block_hash().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let ignore_push_solution = IgnoreMessage::new(MessageDirection::ToUpstream, MESSAGE_TYPE_PUSH_SOLUTION); let (sniffer, sniffer_addr) = start_sniffer( @@ -61,6 +61,7 @@ async fn jdc_propagates_block_with_bitcoin_core_ipc() { ipc_config(tp.data_dir().clone(), tp.is_signet()), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/jd_coinbase_only_block_propagation.rs b/integration-tests/tests/jd_coinbase_only_block_propagation.rs new file mode 100644 index 000000000..1a20456fc --- /dev/null +++ b/integration-tests/tests/jd_coinbase_only_block_propagation.rs @@ -0,0 +1,57 @@ +use integration_tests_sv2::{interceptor::MessageDirection, template_provider::DifficultyLevel, *}; +use stratum_apps::stratum_core::{ + common_messages_sv2::*, job_declaration_sv2::*, template_distribution_sv2::*, +}; + +// In CoinbaseOnly mode, block propagation should happen only from JDC to TP. +// PushSolution to JDS should NOT occur since no job was declared. +#[tokio::test] +async fn coinbase_only_block_propagated_from_jdc_not_jds() { + start_tracing(); + let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); + let current_block_hash = tp.get_best_block_hash().unwrap(); + let (_pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; + let (_jds, jds_addr) = start_jds(tp.rpc_info(), false); + let (jdc_jds_sniffer, jdc_jds_sniffer_addr) = + start_sniffer("jdc-jds", jds_addr, false, vec![], None); + let (jdc_tp_sniffer, jdc_tp_sniffer_addr) = + start_sniffer("jdc-tp", tp_addr, false, vec![], None); + let (_jdc, jdc_addr) = start_jdc( + &[(pool_addr, jdc_jds_sniffer_addr)], + sv2_tp_config(jdc_tp_sniffer_addr), + vec![], + vec![], + Some("COINBASEONLY"), + ); + jdc_jds_sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + jdc_jds_sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, + ) + .await; + + let (_translator, tproxy_addr) = + start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; + let (_minerd_process, _minerd_addr) = start_minerd(tproxy_addr, None, None, false).await; + + jdc_tp_sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SUBMIT_SOLUTION) + .await; + let new_block_hash = tp.get_best_block_hash().unwrap(); + assert_ne!(current_block_hash, new_block_hash); + + jdc_jds_sniffer.clean_queue(MessageDirection::ToUpstream); + assert!( + jdc_jds_sniffer + .assert_message_not_present( + MessageDirection::ToUpstream, + MESSAGE_TYPE_PUSH_SOLUTION, + std::time::Duration::from_secs(3), + ) + .await, + "PushSolution should NOT be sent to JDS in CoinbaseOnly mode" + ); +} diff --git a/integration-tests/tests/jd_full_template_mode.rs b/integration-tests/tests/jd_full_template_mode.rs new file mode 100644 index 000000000..51c2f0cba --- /dev/null +++ b/integration-tests/tests/jd_full_template_mode.rs @@ -0,0 +1,40 @@ +use integration_tests_sv2::{interceptor::MessageDirection, template_provider::DifficultyLevel, *}; +use stratum_apps::stratum_core::{common_messages_sv2::*, job_declaration_sv2::*}; + +// JDC in FullTemplate mode (default) should exchange DeclareMiningJob with JDS +#[tokio::test] +async fn jd_full_template_mode_declare_mining_job_exchanged() { + start_tracing(); + let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); + let (_pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); + let (jdc_jds_sniffer, jdc_jds_sniffer_addr) = + start_sniffer("jdc-jds", jds_addr, false, vec![], None); + let (_jdc, jdc_addr) = start_jdc( + &[(pool_addr, jdc_jds_sniffer_addr)], + sv2_tp_config(tp_addr), + vec![], + vec![], + None, + ); + jdc_jds_sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + jdc_jds_sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, + ) + .await; + + let (_translator, tproxy_addr) = + start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; + let (_minerd_process, _minerd_addr) = start_minerd(tproxy_addr, None, None, false).await; + + jdc_jds_sniffer + .wait_for_message_type( + MessageDirection::ToUpstream, + MESSAGE_TYPE_DECLARE_MINING_JOB, + ) + .await; +} diff --git a/integration-tests/tests/jd_integration.rs b/integration-tests/tests/jd_integration.rs index 96ec84cb5..c85f6530a 100644 --- a/integration-tests/tests/jd_integration.rs +++ b/integration-tests/tests/jd_integration.rs @@ -23,13 +23,14 @@ async fn jds_should_not_panic_if_jdc_shutsdown() { start_tracing(); let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (sniffer_a, sniffer_addr_a) = start_sniffer("0", jds_addr, false, vec![], None); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, sniffer_addr_a)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); sniffer_a .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) @@ -48,6 +49,7 @@ async fn jds_should_not_panic_if_jdc_shutsdown() { sv2_tp_config(tp_addr), vec![], vec![], + None, ); sniffer .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) @@ -64,13 +66,14 @@ async fn jdc_tp_success_setup() { start_tracing(); let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (tp_jdc_sniffer, tp_jdc_sniffer_addr) = start_sniffer("0", tp_addr, false, vec![], None); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, jds_addr)], sv2_tp_config(tp_jdc_sniffer_addr), vec![], vec![], + None, ); // This is needed because jd-client waits for a downstream connection before it starts // exchanging messages with the Template Provider. @@ -98,7 +101,7 @@ async fn jds_receive_solution_while_processing_declared_job_test() { let (tp_1, tp_addr_1) = start_template_provider(None, DifficultyLevel::Low); let (tp_2, tp_addr_2) = start_template_provider(None, DifficultyLevel::Low); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr_1), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp_1.rpc_info()); + let (_jds, jds_addr) = start_jds(tp_1.rpc_info(), true); let prev_hash = U256::Owned(vec![ 184, 103, 138, 88, 153, 105, 236, 29, 123, 246, 107, 203, 1, 33, 10, 122, 188, 139, 218, @@ -135,6 +138,7 @@ async fn jds_receive_solution_while_processing_declared_job_test() { sv2_tp_config(tp_addr_2), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; @@ -197,7 +201,7 @@ async fn jds_wont_exit_upon_receiving_unexpected_txids_in_provide_missing_transa assert!(tp_2.create_mempool_transaction().is_ok()); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr_1), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp_1.rpc_info()); + let (_jds, jds_addr) = start_jds(tp_1.rpc_info(), true); let provide_missing_transaction_success_replace = ReplaceMessage::new( MessageDirection::ToUpstream, @@ -227,6 +231,7 @@ async fn jds_wont_exit_upon_receiving_unexpected_txids_in_provide_missing_transa sv2_tp_config(tp_addr_2), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr_1], false, vec![], vec![], None).await; @@ -285,13 +290,14 @@ async fn jdc_group_extended_channels() { let (tp, tp_addr) = start_template_provider(sv2_interval, DifficultyLevel::Low); tp.fund_wallet().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (sniffer, sniffer_addr) = start_sniffer("sniffer", jdc_addr, false, vec![], None); @@ -468,13 +474,14 @@ async fn jdc_group_standard_channels() { let (tp, tp_addr) = start_template_provider(sv2_interval, DifficultyLevel::Low); tp.fund_wallet().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (sniffer, sniffer_addr) = start_sniffer("sniffer", jdc_addr, false, vec![], None); @@ -660,13 +667,14 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { let (tp, tp_addr) = start_template_provider(sv2_interval, DifficultyLevel::Low); tp.fund_wallet().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (sniffer, sniffer_addr) = start_sniffer("sniffer", jdc_addr, false, vec![], None); diff --git a/integration-tests/tests/jd_mining_modes.rs b/integration-tests/tests/jd_mining_modes.rs new file mode 100644 index 000000000..de8900a7f --- /dev/null +++ b/integration-tests/tests/jd_mining_modes.rs @@ -0,0 +1,96 @@ +use integration_tests_sv2::{interceptor::MessageDirection, template_provider::DifficultyLevel, *}; +use stratum_apps::stratum_core::{common_messages_sv2::*, job_declaration_sv2::*, mining_sv2::*}; + +// JDS requires FullTemplate but JDC asks for CoinbaseOnly +#[tokio::test] +async fn jd_mode_mismatch_setup_connection_fails() { + start_tracing(); + let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); + let (_pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); + let (sniffer, sniffer_addr) = start_sniffer("jdc-jds", jds_addr, false, vec![], None); + let (_jdc, _jdc_addr) = start_jdc( + &[(pool_addr, sniffer_addr)], + sv2_tp_config(tp_addr), + vec![], + vec![], + Some("COINBASEONLY"), + ); + sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SETUP_CONNECTION_ERROR, + ) + .await; +} + +// JDS allows CoinbaseOnly and JDC asks for CoinbaseOnly +// DeclareMiningJob should NOT be exchanged +#[tokio::test] +async fn jd_coinbase_only_mode_no_declare_mining_job() { + start_tracing(); + let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); + let (_pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; + let (_jds, jds_addr) = start_jds(tp.rpc_info(), false); + let (jdc_jds_sniffer, jdc_jds_sniffer_addr) = + start_sniffer("jdc-jds", jds_addr, false, vec![], None); + let (jdc_pool_sniffer, jdc_pool_sniffer_addr) = + start_sniffer("jdc-pool", pool_addr, false, vec![], None); + let (_jdc, jdc_addr) = start_jdc( + &[(jdc_pool_sniffer_addr, jdc_jds_sniffer_addr)], + sv2_tp_config(tp_addr), + vec![], + vec![], + Some("COINBASEONLY"), + ); + jdc_jds_sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + jdc_jds_sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, + ) + .await; + + let (_translator, tproxy_addr) = + start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; + let (_minerd_process, _minerd_addr) = start_minerd(tproxy_addr, None, None, false).await; + + jdc_pool_sniffer + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + jdc_pool_sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, + ) + .await; + jdc_pool_sniffer + .wait_for_message_type( + MessageDirection::ToUpstream, + MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, + ) + .await; + jdc_pool_sniffer + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS, + ) + .await; + + jdc_jds_sniffer.clean_queue(MessageDirection::ToUpstream); + assert!( + jdc_jds_sniffer + .assert_message_not_present( + MessageDirection::ToUpstream, + MESSAGE_TYPE_DECLARE_MINING_JOB, + std::time::Duration::from_secs(5), + ) + .await, + "DeclareMiningJob should NOT be sent to JDS in CoinbaseOnly mode" + ); +} diff --git a/integration-tests/tests/jd_provide_missing_transaction.rs b/integration-tests/tests/jd_provide_missing_transaction.rs index a67778f07..b476b9083 100644 --- a/integration-tests/tests/jd_provide_missing_transaction.rs +++ b/integration-tests/tests/jd_provide_missing_transaction.rs @@ -7,13 +7,14 @@ async fn jds_ask_for_missing_transactions() { let (tp_1, tp_addr_1) = start_template_provider(None, DifficultyLevel::Low); let (tp_2, tp_addr_2) = start_template_provider(None, DifficultyLevel::Low); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr_1), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp_1.rpc_info()); + let (_jds, jds_addr) = start_jds(tp_1.rpc_info(), true); let (sniffer, sniffer_addr) = start_sniffer("A", jds_addr, false, vec![], None); let (jdc, jdc_addr) = start_jdc( &[(pool_addr, sniffer_addr)], sv2_tp_config(tp_addr_2), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/jd_tproxy_integration.rs b/integration-tests/tests/jd_tproxy_integration.rs index 40d8ca47c..8297922a9 100644 --- a/integration-tests/tests/jd_tproxy_integration.rs +++ b/integration-tests/tests/jd_tproxy_integration.rs @@ -8,12 +8,13 @@ async fn jd_non_aggregated_tproxy_integration() { let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; let (jdc_pool_sniffer, jdc_pool_sniffer_addr) = start_sniffer("0", pool_addr, false, vec![], None); - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(jdc_pool_sniffer_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (tproxy_jdc_sniffer, tproxy_jdc_sniffer_addr) = start_sniffer("1", jdc_addr, false, vec![], None); @@ -84,12 +85,13 @@ async fn jd_aggregated_tproxy_integration() { let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; let (jdc_pool_sniffer, jdc_pool_sniffer_addr) = start_sniffer("0", pool_addr, false, vec![], None); - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(jdc_pool_sniffer_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (tproxy_jdc_sniffer, tproxy_jdc_sniffer_addr) = start_sniffer("1", jdc_addr, false, vec![], None); diff --git a/integration-tests/tests/jdc_block_propagation.rs b/integration-tests/tests/jdc_block_propagation.rs index 94ac13f0d..076fe228f 100644 --- a/integration-tests/tests/jdc_block_propagation.rs +++ b/integration-tests/tests/jdc_block_propagation.rs @@ -12,7 +12,7 @@ async fn propagated_from_jdc_to_tp() { let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let current_block_hash = tp.get_best_block_hash().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let ignore_push_solution = IgnoreMessage::new(MessageDirection::ToUpstream, MESSAGE_TYPE_PUSH_SOLUTION); let (jdc_jds_sniffer, jdc_jds_sniffer_addr) = start_sniffer( @@ -28,6 +28,7 @@ async fn propagated_from_jdc_to_tp() { sv2_tp_config(jdc_tp_sniffer_addr), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/jdc_cached_shares.rs b/integration-tests/tests/jdc_cached_shares.rs index e0164101a..f63c1da12 100644 --- a/integration-tests/tests/jdc_cached_shares.rs +++ b/integration-tests/tests/jdc_cached_shares.rs @@ -26,7 +26,7 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { // Otherwise, a discovered block would trigger a chain tip change, // causing `SetCustomMiningJob.Success` to fail. let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::High); - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let mock_pool_addr = get_available_address(); let mock_pool = MockUpstream::new( @@ -43,6 +43,7 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/jdc_receives_submit_shares_success.rs b/integration-tests/tests/jdc_receives_submit_shares_success.rs index 18780e78e..605b9a5b9 100644 --- a/integration-tests/tests/jdc_receives_submit_shares_success.rs +++ b/integration-tests/tests/jdc_receives_submit_shares_success.rs @@ -7,12 +7,13 @@ async fn jdc_submit_shares_success() { let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; let (sniffer, sniffer_addr) = start_sniffer("0", pool_addr, false, vec![], None); - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(sniffer_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/jds_block_propagation.rs b/integration-tests/tests/jds_block_propagation.rs index fabf91d78..d9900eeeb 100644 --- a/integration-tests/tests/jds_block_propagation.rs +++ b/integration-tests/tests/jds_block_propagation.rs @@ -12,7 +12,7 @@ async fn propagated_from_jds_to_tp() { let (tp, tp_addr) = start_template_provider(None, DifficultyLevel::Low); let current_block_hash = tp.get_best_block_hash().unwrap(); let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc_jds_sniffer, jdc_jds_sniffer_addr) = start_sniffer("0", jds_addr, false, vec![], None); let ignore_submit_solution = IgnoreMessage::new(MessageDirection::ToUpstream, MESSAGE_TYPE_SUBMIT_SOLUTION); @@ -28,6 +28,7 @@ async fn propagated_from_jds_to_tp() { sv2_tp_config(jdc_tp_sniffer_addr), vec![], vec![], + None, ); let (translator, tproxy_addr) = start_sv2_translator(&[jdc_addr], false, vec![], vec![], None).await; diff --git a/integration-tests/tests/pool_integration.rs b/integration-tests/tests/pool_integration.rs index b0a685e2b..30e48f62c 100644 --- a/integration-tests/tests/pool_integration.rs +++ b/integration-tests/tests/pool_integration.rs @@ -244,12 +244,13 @@ async fn pool_does_not_send_jobs_to_jdc() { let (pool, pool_addr) = start_pool(sv2_tp_config(tp_addr), vec![], vec![]).await; let (pool_jdc_sniffer, pool_jdc_sniffer_addr) = start_sniffer("pool_jdc", pool_addr, false, vec![], None); - let (_jds, jds_addr) = start_jds(tp.rpc_info()); + let (_jds, jds_addr) = start_jds(tp.rpc_info(), true); let (jdc, jdc_addr) = start_jdc( &[(pool_jdc_sniffer_addr, jds_addr)], sv2_tp_config(tp_addr), vec![], vec![], + None, ); // Block NewExtendedMiningJob and SetNewPrevHash messages between JDC and translator proxy let (_tproxy_jdc_sniffer, tproxy_jdc_sniffer_addr) = start_sniffer( diff --git a/pool-apps/jd-server/src/lib/config.rs b/pool-apps/jd-server/src/lib/config.rs index 304039ff7..49cbc69d5 100644 --- a/pool-apps/jd-server/src/lib/config.rs +++ b/pool-apps/jd-server/src/lib/config.rs @@ -145,6 +145,10 @@ impl JobDeclaratorServerConfig { self.log_file = Some(path); } } + + pub fn set_full_template_mode_required(&mut self, required: bool) { + self.full_template_mode_required = required; + } } fn default_true() -> bool {