diff --git a/test/message-generator/test/translation-proxy/translation-proxy.json b/test/message-generator/test/translation-proxy/translation-proxy.json index d529dd2767..afd129be62 100644 --- a/test/message-generator/test/translation-proxy/translation-proxy.json +++ b/test/message-generator/test/translation-proxy/translation-proxy.json @@ -147,10 +147,11 @@ "results": [ { "type": "match_message_type", - "value": "0x1b" + "value": "0x1b", + "condition": "WaitUntil" } ], - "actiondoc": "Sends NewExtendedMiningJob and SetNewPrevHash and waits that a SubmitsShareExtended is submitted" + "actiondoc": "Sends NewExtendedMiningJob and SetNewPrevHash and waits until a SubmitsShareExtended is submitted" } ], "setup_commands": [ diff --git a/utils/message-generator/src/executor.rs b/utils/message-generator/src/executor.rs index 22843e03a2..d9c6652963 100644 --- a/utils/message-generator/src/executor.rs +++ b/utils/message-generator/src/executor.rs @@ -3,7 +3,7 @@ use crate::{ into_static::into_static, net::{setup_as_downstream, setup_as_upstream}, parser::sv2_messages::ReplaceField, - Action, ActionResult, Command, Role, SaveField, Sv2Type, Test, + Action, ActionResult, Command, Condition, Role, SaveField, Sv2Type, Test, }; use async_channel::{Receiver, Sender}; use binary_sv2::Serialize; @@ -200,30 +200,65 @@ impl Executor { ); match result { - ActionResult::MatchMessageType(message_type) => { - let message = match recv.recv().await { - Ok(message) => message, - Err(_) => { - success = false; - error!("Connection closed before receiving the message"); - break; - } - }; + ActionResult::MatchMessageType(message_type, condition) => { + match condition { + None => { + let message = match recv.recv().await { + Ok(message) => message, + Err(_) => { + success = false; + error!("Connection closed before receiving the message"); + break; + } + }; - let message: Sv2Frame, _> = message.try_into().unwrap(); - debug!("RECV {:#?}", message); - let header = message.get_header().unwrap(); + let message: Sv2Frame, _> = + message.try_into().unwrap(); + debug!("RECV {:#?}", message); + let header = message.get_header().unwrap(); - if header.msg_type() != *message_type { - error!( - "WRONG MESSAGE TYPE expected: {} received: {}", - message_type, - header.msg_type() - ); - success = false; - break; - } else { - info!("MATCHED MESSAGE TYPE {}", message_type); + if header.msg_type() != *message_type { + error!( + "WRONG MESSAGE TYPE expected: {} received: {}", + message_type, + header.msg_type() + ); + success = false; + break; + } else { + info!("MATCHED MESSAGE TYPE {}", message_type); + } + } + Some(condition_inner) => { + match condition_inner { + Condition::WaitUntil => loop { + let message = match recv.recv().await { + Ok(message) => message, + Err(_) => { + success = false; + error!("Connection closed before receiving the message"); + break; + } + }; + + let message: Sv2Frame, _> = + message.try_into().unwrap(); + debug!("RECV {:#?}", message); + let header = message.get_header().unwrap(); + if header.msg_type() != *message_type { + info!( + "RECEIVED {}, WAITING MESSAGE TYPE {}", + header.msg_type(), + message_type + ); + continue; + } else { + info!("MATCHED WAITED MESSAGE TYPE {}", message_type); + break; + } + }, + }; + } } } ActionResult::MatchMessageField(( diff --git a/utils/message-generator/src/main.rs b/utils/message-generator/src/main.rs index 327d50cbc7..5f902372fa 100644 --- a/utils/message-generator/src/main.rs +++ b/utils/message-generator/src/main.rs @@ -11,6 +11,7 @@ extern crate load_file; use crate::parser::sv2_messages::ReplaceField; use binary_sv2::{Deserialize, Serialize}; use codec_sv2::StandardEitherFrame as EitherFrame; +use core::fmt::Display; use external_commands::*; use key_utils::{Secp256k1PublicKey, Secp256k1SecretKey}; use rand::Rng; @@ -179,9 +180,22 @@ pub struct SaveField { keyword: String, } +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub enum Condition { + WaitUntil, +} + +impl Display for Condition { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Condition::WaitUntil => write!(f, "WaitUntil"), + } + } +} + #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] enum ActionResult { - MatchMessageType(u8), + MatchMessageType(u8, Option), MatchMessageField((String, String, Vec<(String, Sv2Type)>)), GetMessageField { subprotocol: String, @@ -209,13 +223,22 @@ enum Sv1ActionResult { impl std::fmt::Display for ActionResult { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - ActionResult::MatchMessageType(message_type) => { - write!( - f, - "MatchMessageType: {} ({:#x})", - message_type, message_type - ) - } + ActionResult::MatchMessageType(message_type, condition) => match condition { + None => { + write!( + f, + "MatchMessageType: {} ({:#x})", + message_type, message_type + ) + } + Some(condition_inner) => { + write!( + f, + "MatchMessageType: {} ({:#x}) with condition {}", + message_type, message_type, condition_inner + ) + } + }, ActionResult::MatchMessageField(message_field) => { write!(f, "MatchMessageField: {:?}", message_field) } diff --git a/utils/message-generator/src/parser/actions.rs b/utils/message-generator/src/parser/actions.rs index 23bf6188be..23988c93c0 100644 --- a/utils/message-generator/src/parser/actions.rs +++ b/utils/message-generator/src/parser/actions.rs @@ -1,4 +1,6 @@ -use crate::{Action, ActionResult, Role, SaveField, Sv1Action, Sv1ActionResult, Sv2Type}; +use crate::{ + Action, ActionResult, Condition, Role, SaveField, Sv1Action, Sv1ActionResult, Sv2Type, +}; use codec_sv2::{buffer_sv2::Slice, StandardEitherFrame, Sv2Frame}; use roles_logic_sv2::parsers::AnyMessage; use serde_json::{Map, Value}; @@ -52,7 +54,23 @@ impl Sv2ActionParser { match result.get("type").unwrap().as_str().unwrap() { "match_message_type" => { let message_type = u8::from_str_radix(&result.get("value").unwrap().as_str().unwrap()[2..], 16).expect("Result message_type should be an hex value starting with 0x and not bigger than 0xff"); - action_results.push(ActionResult::MatchMessageType(message_type)); + match result.get("condition") { + Some(condition_inner) => { + let condition_ = + serde_json::from_value::(condition_inner.clone()) + .unwrap(); + match condition_ { + Condition::WaitUntil => { + action_results.push(ActionResult::MatchMessageType( + message_type, + Some(Condition::WaitUntil), + )) + } + } + } + None => action_results + .push(ActionResult::MatchMessageType(message_type, None)), + }; } "get_message_field" => { let sv2_type = result.get("value").unwrap().clone();