Skip to content

Commit 6a9c060

Browse files
committed
add non_aggregated_translator_handles_set_group_channel_message Integration Test
1 parent 40b3e9e commit 6a9c060

File tree

2 files changed

+182
-4
lines changed

2 files changed

+182
-4
lines changed

integration-tests/lib/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub mod sv1_minerd;
3737
pub mod sv1_sniffer;
3838
pub mod template_provider;
3939
pub mod types;
40-
pub(crate) mod utils;
40+
pub mod utils;
4141

4242
const SHARES_PER_MINUTE: f32 = 120.0;
4343

integration-tests/tests/translator_integration.rs

Lines changed: 181 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
// This file contains integration tests for the `TranslatorSv2` module.
22
use integration_tests_sv2::{
33
interceptor::{IgnoreMessage, MessageDirection, ReplaceMessage},
4+
mock_roles::MockUpstream,
45
template_provider::DifficultyLevel,
6+
utils::get_available_address,
57
*,
68
};
79
use stratum_apps::stratum_core::mining_sv2::*;
810

911
use stratum_apps::stratum_core::{
12+
binary_sv2::{Seq0255, Sv2Option},
1013
common_messages_sv2::{
11-
SetupConnectionError, MESSAGE_TYPE_SETUP_CONNECTION, MESSAGE_TYPE_SETUP_CONNECTION_ERROR,
12-
MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS,
14+
SetupConnectionError, SetupConnectionSuccess, MESSAGE_TYPE_SETUP_CONNECTION,
15+
MESSAGE_TYPE_SETUP_CONNECTION_ERROR, MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS,
1316
},
1417
mining_sv2::{
1518
OpenMiningChannelError, MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL,
1619
MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS,
1720
},
18-
parsers_sv2::{self, AnyMessage},
21+
parsers_sv2::{self, AnyMessage, CommonMessages},
1922
template_distribution_sv2::MESSAGE_TYPE_SUBMIT_SOLUTION,
2023
};
2124

@@ -712,3 +715,178 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() {
712715
}
713716
}
714717
}
718+
719+
#[tokio::test]
720+
async fn non_aggregated_translator_handles_set_group_channel_message() {
721+
start_tracing();
722+
723+
let mock_upstream_addr = get_available_address();
724+
let mock_upstream = MockUpstream::new(mock_upstream_addr);
725+
let send_to_tproxy = mock_upstream.start().await;
726+
727+
let (sniffer, sniffer_addr) = start_sniffer("", mock_upstream_addr, false, vec![], None);
728+
729+
let (_tproxy, tproxy_addr) = start_sv2_translator(&[sniffer_addr], false, vec![], vec![]).await;
730+
731+
sniffer
732+
.wait_for_message_type_and_clean_queue(
733+
MessageDirection::ToUpstream,
734+
MESSAGE_TYPE_SETUP_CONNECTION,
735+
)
736+
.await;
737+
738+
let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess(
739+
SetupConnectionSuccess {
740+
used_version: 2,
741+
flags: 0,
742+
},
743+
));
744+
send_to_tproxy.send(setup_connection_success).await.unwrap();
745+
746+
const N_EXTENDED_CHANNELS: u32 = 10;
747+
const GROUP_CHANNEL_ID_A: u32 = 100;
748+
const GROUP_CHANNEL_ID_B: u32 = 200;
749+
750+
// we need to keep references to each minerd
751+
// otherwise they would be dropped
752+
let mut minerd_vec = Vec::new();
753+
754+
// spawn minerd processes to force opening N_EXTENDED_CHANNELS extended channels
755+
for i in 0..N_EXTENDED_CHANNELS {
756+
let (minerd_process, _minerd_addr) = start_minerd(tproxy_addr, None, None, false).await;
757+
minerd_vec.push(minerd_process);
758+
759+
sniffer
760+
.wait_for_message_type(
761+
MessageDirection::ToUpstream,
762+
MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL,
763+
)
764+
.await;
765+
let open_extended_mining_channel = match sniffer.next_message_from_downstream() {
766+
Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => {
767+
msg
768+
}
769+
msg => panic!(
770+
"Expected OpenExtendedMiningChannel message, found: {:?}",
771+
msg
772+
),
773+
};
774+
775+
let open_extended_mining_channel_success =
776+
AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(
777+
OpenExtendedMiningChannelSuccess {
778+
request_id: open_extended_mining_channel.request_id,
779+
channel_id: i,
780+
target: hex::decode(
781+
"0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc",
782+
)
783+
.unwrap()
784+
.try_into()
785+
.unwrap(),
786+
// full extranonce has a total of 8 bytes
787+
extranonce_size: 4,
788+
extranonce_prefix: vec![0x00, 0x01, 0x00, i as u8].try_into().unwrap(),
789+
group_channel_id: GROUP_CHANNEL_ID_A,
790+
},
791+
));
792+
send_to_tproxy
793+
.send(open_extended_mining_channel_success)
794+
.await
795+
.unwrap();
796+
797+
sniffer
798+
.wait_for_message_type_and_clean_queue(
799+
MessageDirection::ToDownstream,
800+
MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS,
801+
)
802+
.await;
803+
}
804+
805+
// half of the channels belong to GROUP_CHANNEL_ID_A
806+
let group_channel_a_ids = (0..N_EXTENDED_CHANNELS)
807+
.filter(|i| i % 2 != 0)
808+
.collect::<Vec<_>>();
809+
810+
// half of the channels belong to GROUP_CHANNEL_ID_B
811+
let group_channel_b_ids = (0..N_EXTENDED_CHANNELS)
812+
.filter(|i| i % 2 == 0)
813+
.collect::<Vec<_>>();
814+
815+
// send a SetGroupChannel message to set GROUP_CHANNEL_ID_B
816+
let set_group_channel =
817+
AnyMessage::Mining(parsers_sv2::Mining::SetGroupChannel(SetGroupChannel {
818+
channel_ids: group_channel_b_ids.clone().into(),
819+
group_channel_id: GROUP_CHANNEL_ID_B,
820+
}));
821+
send_to_tproxy.send(set_group_channel).await.unwrap();
822+
823+
// send a NewExtendedMiningJob + SetNewPrevHash message pair ONLY to GROUP_CHANNEL_ID_B
824+
let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob {
825+
channel_id: GROUP_CHANNEL_ID_B,
826+
job_id: 1,
827+
min_ntime: Sv2Option::new(None),
828+
version: 0x20000000,
829+
version_rolling_allowed: true,
830+
merkle_path: Seq0255::new(vec![]).unwrap(),
831+
// scriptSig for a total of 8 bytes of extranonce
832+
coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff225200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(),
833+
coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(),
834+
}));
835+
836+
send_to_tproxy.send(new_extended_mining_job).await.unwrap();
837+
sniffer
838+
.wait_for_message_type_and_clean_queue(
839+
MessageDirection::ToDownstream,
840+
MESSAGE_TYPE_NEW_EXTENDED_MINING_JOB,
841+
)
842+
.await;
843+
844+
let set_new_prev_hash =
845+
AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash {
846+
channel_id: GROUP_CHANNEL_ID_B,
847+
job_id: 1,
848+
prev_hash: hex::decode(
849+
"3ab7089cd2cd30f133552cfde82c4cb239cd3c2310306f9d825e088a1772cc39",
850+
)
851+
.unwrap()
852+
.try_into()
853+
.unwrap(),
854+
min_ntime: 1766782170,
855+
nbits: 0x207fffff,
856+
}));
857+
send_to_tproxy.send(set_new_prev_hash).await.unwrap();
858+
sniffer
859+
.wait_for_message_type_and_clean_queue(
860+
MessageDirection::ToDownstream,
861+
MESSAGE_TYPE_MINING_SET_NEW_PREV_HASH,
862+
)
863+
.await;
864+
865+
// all channels in GROUP_CHANNEL_ID_B must submit at least one share
866+
// channels in GROUP_CHANNEL_ID_A must NOT submit any shares
867+
let mut channels_submitted_to: HashSet<u32> = group_channel_b_ids.clone().into_iter().collect();
868+
loop {
869+
sniffer
870+
.wait_for_message_type(
871+
MessageDirection::ToUpstream,
872+
MESSAGE_TYPE_SUBMIT_SHARES_EXTENDED,
873+
)
874+
.await;
875+
let submit_shares_extended = match sniffer.next_message_from_downstream() {
876+
Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg,
877+
msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg),
878+
};
879+
880+
if group_channel_a_ids.contains(&submit_shares_extended.channel_id) {
881+
panic!(
882+
"Channel {} should not have submitted a share",
883+
submit_shares_extended.channel_id
884+
);
885+
}
886+
887+
channels_submitted_to.remove(&submit_shares_extended.channel_id);
888+
if channels_submitted_to.is_empty() {
889+
break;
890+
}
891+
}
892+
}

0 commit comments

Comments
 (0)