diff --git a/roles/jd-client/src/lib/upstream_sv2/upstream.rs b/roles/jd-client/src/lib/upstream_sv2/upstream.rs index e16e931527..62ab2db329 100644 --- a/roles/jd-client/src/lib/upstream_sv2/upstream.rs +++ b/roles/jd-client/src/lib/upstream_sv2/upstream.rs @@ -665,6 +665,8 @@ impl ParseUpstreamMiningMessages Result, RolesLogicError> { + dbg!("received submit shares error"); + dbg!(&_m); self.pool_chaneger_trigger .safe_lock(|t| t.start(self.tx_status.clone())) .unwrap(); diff --git a/roles/tests-integration/lib/mod.rs b/roles/tests-integration/lib/mod.rs index c6cb7354c6..8006c665d1 100644 --- a/roles/tests-integration/lib/mod.rs +++ b/roles/tests-integration/lib/mod.rs @@ -82,7 +82,7 @@ pub async fn start_pool(template_provider_address: Option) -> (PoolS assert!(pool_clone.start().await.is_ok()); }); // Wait a bit to let the pool exchange initial messages with the TP - tokio::time::sleep(std::time::Duration::from_secs(1)).await; + sleep(1).await; (pool, listening_address) } @@ -95,7 +95,7 @@ pub async fn start_template_provider(sv2_interval: Option) -> (TemplateProv } pub async fn start_jdc( - pool_address: SocketAddr, + pool_addresses: Vec, tp_address: SocketAddr, jds_address: SocketAddr, ) -> (JobDeclaratorClient, SocketAddr) { @@ -115,7 +115,6 @@ pub async fn start_jdc( "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n".to_string(), ) .unwrap(); - let cert_validity_sec = 3600; let coinbase_outputs = vec![CoinbaseOutput::new( "P2WPKH".to_string(), "036adc3bdf21e6f9a0f0fb0066bf517e5b7909ed1563d6958a10993849a7554075".to_string(), @@ -125,12 +124,17 @@ pub async fn start_jdc( ) .unwrap(); let pool_signature = "Stratum v2 SRI Pool".to_string(); - let upstreams = vec![Upstream::new( - authority_pubkey, - pool_address.to_string(), - jds_address.to_string(), - pool_signature, - )]; + let upstreams = pool_addresses + .iter() + .map(|addr| { + Upstream::new( + authority_pubkey, + addr.to_string(), + jds_address.to_string(), + pool_signature.clone(), + ) + }) + .collect(); let pool_config = PoolConfig::new(authority_public_key, authority_secret_key); let tp_config = TPConfig::new(1000, tp_address.to_string(), None); let protocol_config = ProtocolConfig::new( @@ -146,12 +150,12 @@ pub async fn start_jdc( pool_config, tp_config, upstreams, - std::time::Duration::from_secs(cert_validity_sec), + std::time::Duration::from_secs(1), ); let ret = jd_client::JobDeclaratorClient::new(jd_client_proxy); let ret_clone = ret.clone(); tokio::spawn(async move { ret_clone.start().await }); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; + sleep(2).await; (ret, jdc_address) } @@ -191,7 +195,7 @@ pub async fn start_jds(tp_address: SocketAddr) -> (JobDeclaratorServer, SocketAd tokio::spawn(async move { job_declarator_server_clone.start().await; }); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; + sleep(2).await; (job_declarator_server, listen_jd_address) } @@ -241,7 +245,7 @@ pub async fn start_sv2_translator(upstream: SocketAddr) -> (TranslatorSv2, Socke tokio::spawn(async move { clone_translator_v2.start().await; }); - tokio::time::sleep(std::time::Duration::from_secs(1)).await; + sleep(1).await; (translator_v2, listening_address) } @@ -285,7 +289,7 @@ pub async fn start_mining_device_sv1(upstream_addr: SocketAddr) { tokio::spawn(async move { mining_device_sv1::client::Client::connect(80, upstream_addr).await; }); - tokio::time::sleep(std::time::Duration::from_secs(3)).await; + sleep(3).await; } pub async fn start_mining_sv2_proxy(upstream: SocketAddr) -> SocketAddr { @@ -315,3 +319,7 @@ pub async fn start_mining_sv2_proxy(upstream: SocketAddr) -> SocketAddr { }); mining_proxy_listening_address } + +pub async fn sleep(seconds: u64) { + tokio::time::sleep(std::time::Duration::from_secs(seconds)).await; +} diff --git a/roles/tests-integration/tests/jdc_integration.rs b/roles/tests-integration/tests/jdc_integration.rs new file mode 100644 index 0000000000..3bbf5894ca --- /dev/null +++ b/roles/tests-integration/tests/jdc_integration.rs @@ -0,0 +1,58 @@ +use std::convert::TryInto; + +use const_sv2::{ + MESSAGE_TYPE_SETUP_CONNECTION, MESSAGE_TYPE_SUBMIT_SHARES_ERROR, + MESSAGE_TYPE_SUBMIT_SHARES_SUCCESS, +}; +use integration_tests_sv2::*; +use sniffer::InterceptMessage; + +use crate::sniffer::MessageDirection; +use roles_logic_sv2::{ + mining_sv2::SubmitSharesError, + parsers::{CommonMessages, Mining, PoolMessages}, +}; + +// Start JDClient with two pools in the pool list config. The test forces the first pool to send a +// share submission rejection by altering a message(MINING_SET_NEW_PREV_HASH) sent by the pool. The +// test verifies that the second pool will be used as a fallback. +#[tokio::test] +async fn test_jdc_pool_fallback_after_submit_rejection() { + let (_tp, tp_addr) = start_template_provider(None).await; + let (_pool, pool_addr) = start_pool(Some(tp_addr)).await; + let (sniffer_1, sniffer_addr) = start_sniffer( + "0".to_string(), + pool_addr, + false, + Some(vec![InterceptMessage::new( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SUBMIT_SHARES_SUCCESS, + PoolMessages::Mining(Mining::SubmitSharesError(SubmitSharesError { + channel_id: 0, + sequence_number: 0, + error_code: "invalid-nonce".to_string().into_bytes().try_into().unwrap(), + })), + )]), + ) + .await; + let (_pool_2, pool_addr_2) = start_pool(Some(tp_addr)).await; + let (sniffer_2, sniffer_addr_2) = + start_sniffer("1".to_string(), pool_addr_2, false, None).await; + let (_jds, jds_addr) = start_jds(tp_addr).await; + let (_jdc, jdc_addr) = start_jdc(vec![sniffer_addr, sniffer_addr_2], tp_addr, jds_addr).await; + assert_common_message!(&sniffer_1.next_message_from_downstream(), SetupConnection); + let (_translator, sv2_translator_addr) = start_sv2_translator(jdc_addr).await; + let _ = start_mining_device_sv1(sv2_translator_addr).await; + dbg!("here 1"); + sniffer_1 + .wait_for_message_type( + MessageDirection::ToDownstream, + MESSAGE_TYPE_SUBMIT_SHARES_ERROR, + ) + .await; + dbg!("here 2"); + sniffer_2 + .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) + .await; + dbg!("here 3"); +} diff --git a/scripts/message-generator-tests.sh b/scripts/message-generator-tests.sh index a7897a07d5..6fc12045e1 100755 --- a/scripts/message-generator-tests.sh +++ b/scripts/message-generator-tests.sh @@ -3,13 +3,8 @@ search_dir="test/message-generator/test/" for entry in `ls $search_dir`; do - if [ "$entry" = "interop-jdc-change-upstream" ]; then - echo "Skipping $entry" - continue - fi - echo $entry - $search_dir$entry/$entry.sh + $search_dir$entry/$entry.sh done cd roles diff --git a/test/config/interop-jd-change-upstream/jdc-config.toml b/test/config/interop-jd-change-upstream/jdc-config.toml deleted file mode 100644 index c03b36e5f5..0000000000 --- a/test/config/interop-jd-change-upstream/jdc-config.toml +++ /dev/null @@ -1,49 +0,0 @@ -# Local Mining Device Downstream Connection -downstream_address = "127.0.0.1" -downstream_port = 34265 - -# Version support -max_supported_version = 2 -min_supported_version = 2 - -# Minimum extranonce2 size for downstream -# Max value: 16 (leaves 0 bytes for search space splitting of downstreams) -# Max value for CGminer: 8 -# Min value: 2 -min_extranonce2_size = 8 - -# Withhold -withhold = false - -# Auth keys for open encrypted connection downstream -authority_public_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" -authority_secret_key = "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n" -cert_validity_sec = 3600 - -# How many time the JDC try to reinitialize itself after a failure -retry = 10 - -tp_address = "75.119.150.111:8442" -tp_authority_pub_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" - - - -coinbase_outputs = [ - { output_script_type = "P2WPKH", output_script_value = "036adc3bdf21e6f9a0f0fb0066bf517e5b7909ed1563d6958a10993849a7554075" }, -] - -[timeout] -unit = "secs" -value = 1 - -[[upstreams]] -authority_pubkey = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" -pool_address = "127.0.0.1:44254" -jd_address = "127.0.0.1:34264" -pool_signature = "Stratum v2 SRI Pool" - -[[upstreams]] -authority_pubkey = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" -pool_address = "127.0.0.1:44255" -jd_address = "127.0.0.1:34264" -pool_signature = "Stratum v2 SRI Pool" diff --git a/test/config/interop-jd-change-upstream/jds-config.toml b/test/config/interop-jd-change-upstream/jds-config.toml deleted file mode 100644 index acda73227c..0000000000 --- a/test/config/interop-jd-change-upstream/jds-config.toml +++ /dev/null @@ -1,20 +0,0 @@ -# SRI Pool config -authority_public_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" -authority_secret_key = "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n" -cert_validity_sec = 3600 - -# list of compressed or uncompressed pubkeys for coinbase payout (only supports 1 item in the array at this point) -coinbase_outputs = [ - { output_script_type = "P2WPKH", output_script_value = "036adc3bdf21e6f9a0f0fb0066bf517e5b7909ed1563d6958a10993849a7554075" }, -] - -listen_jd_address = "127.0.0.1:34264" - -core_rpc_url = "" -core_rpc_port = 18332 -core_rpc_user = "" -core_rpc_pass = "" -# Time interval used for JDS mempool update -[mempool_update_interval] -unit = "secs" -value = 1 \ No newline at end of file diff --git a/test/config/interop-jd-change-upstream/proxy-config.toml b/test/config/interop-jd-change-upstream/proxy-config.toml deleted file mode 100644 index 3ed024c137..0000000000 --- a/test/config/interop-jd-change-upstream/proxy-config.toml +++ /dev/null @@ -1,13 +0,0 @@ -upstreams = [ - { channel_kind = "Extended", address = "127.0.0.1", port = 34265, pub_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72"}, -] -listen_address = "127.0.0.1" -listen_mining_port = 34255 -max_supported_version = 2 -min_supported_version = 2 -downstream_share_per_minute = 1 -coinbase_reward_sat = 5_000_000_000 -# This value is used by the proxy to communicate to the pool the expected hash rate when we open an -# extended channel, based on it the pool will set a target for the channel -expected_total_downstream_hr = 10_000 -reconnect = true diff --git a/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.json b/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.json deleted file mode 100644 index 344b8d6ce7..0000000000 --- a/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.json +++ /dev/null @@ -1,214 +0,0 @@ -{ - "version": "2", - "doc": [ - "This test does", - "Launch a pool mocks", - "Launch jds", - "Launch jdc", - "Launch mining-proxy", - "Launch a mining device", - "Act like a pool", - "Connect jdc to the first pool", - "Receive an submit share error from first pool", - "Close jdc connection with first pool", - "Connect jdc the pool mocked by this test" - ], - "frame_builders": [ - { - "type": "automatic", - "message_id": "test/message-generator/messages/common_messages.json::setup_connection_success_tproxy" - } - ], - "actions": [ - { - "message_ids": [], - "role": "server", - "results": [ - { - "type": "match_message_type", - "value": "0x00" - } - ], - "actiondoc": "This action checks that a Setupconnection message is received" - }, - { - "message_ids": ["setup_connection_success_tproxy"], - "role": "server", - "results": [ - { - "type": "match_message_type", - "value": "0x13" - } - ], - "actiondoc": "This action sends SetupConnection.Success and check that a open_extended_mining_channel is received" - } - ], - "setup_commands": [ - { - "command": "cargo", - "args": [ - "run", - "../../test/message-generator/mock/pool-mock-invalid-share.json" - ], - "conditions": { - "WithConditions": { - "conditions": [ - { - "output_string": "Running `target/debug/message_generator_sv2 ../../test/message-generator/mock/pool-mock-invalid-share.json`", - "output_location": "StdErr", - "late_condition": false, - "condition": true - } - ], - "timer_secs": 600, - "warn_no_panic": false - } - } - }, - { - "command": "sleep", - "args": ["10000"], - "conditions": "None" - }, - { - "command": "cargo", - "args": [ - "llvm-cov", - "--no-report", - "run", - "-p", - "jd_server", - "--", - "-c", - "../test/config/interop-jd-change-upstream/jds-config.toml" - ], - "conditions": { - "WithConditions": { - "conditions": [ - { - "output_string": "JD INITIALIZED", - "output_location": "StdOut", - "late_condition": false, - "condition": true - } - ], - "timer_secs": 600, - "warn_no_panic": false - } - } - }, - { - "command": "cargo", - "args": [ - "llvm-cov", - "--no-report", - "run", - "-p", - "jd_client", - "--", - "-c", - "../test/config/interop-jd-change-upstream/jdc-config.toml" - ], - "conditions": { - "WithConditions": { - "conditions": [ - { - "output_string": "Listening for downstream mining connections on", - "output_location": "StdOut", - "late_condition": false, - "condition": true - } - ], - "timer_secs": 600, - "warn_no_panic": false - } - } - }, - { - "command": "cargo", - "args": [ - "llvm-cov", - "--no-report", - "run", - "-p", - "mining_proxy_sv2", - "--", - "-c", - "../test/config/interop-jd-change-upstream/proxy-config.toml" - ], - "conditions": { - "WithConditions": { - "conditions": [ - { - "output_string": "Listening for downstream mining connections on 127.0.0.1:34255", - "output_location": "StdOut", - "late_condition": false, - "condition": true - } - ], - "timer_secs": 600, - "warn_no_panic": false - } - } - }, - { - "command": "sleep", - "args": ["10000"], - "conditions": "None" - }, - { - "command": "cargo", - "args": [ - "run", - "-p", - "mining-device" - ], - "conditions": { - "WithConditions": { - "conditions": [ - { - "output_string": "SUCCESS SubmitSharesSuccess", - "output_location": "StdOut", - "late_condition": false, - "condition": true - } - ], - "timer_secs": 600, - "warn_no_panic": false - } - } - } - ], - "execution_commands": [ - ], - "cleanup_commands": [ - { - "command": "pkill", - "args": ["-f", "mining_device", "-SIGINT"], - "conditions": "None" - }, - { - "command": "pkill", - "args": ["-f", "jd_server", "-SIGINT"], - "conditions": "None" - }, - { - "command": "pkill", - "args": ["-f", "jd_client", "-SIGINT"], - "conditions": "None" - }, - { - "command": "pkill", - "args": ["-f", "mining_proxy_sv2", "-SIGINT"], - "conditions": "None" - } - ], - "role": "none", - "role": "server", - "upstream": { - "ip": "127.0.0.1", - "port": 44255, - "pub_key": "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72", - "secret_key": "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n" - } -} diff --git a/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.sh b/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.sh deleted file mode 100755 index 514b2e79e1..0000000000 --- a/test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.sh +++ /dev/null @@ -1,12 +0,0 @@ -cd roles -cargo llvm-cov --no-report -p jd_server -cargo llvm-cov --no-report -p jd_client -cargo llvm-cov --no-report -p mining_proxy_sv2 -cargo build -p --no-report mining-device - -cd ../utils/message-generator/ -cargo build - -RUST_LOG=debug cargo run ../../test/message-generator/test/interop-jdc-change-upstream/interop-jdc-change-upstream.json || { echo 'mg test failed' ; exit 1; } - -sleep 10