Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing deployments in Dotrain Yaml #1092

Merged
merged 7 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/common/src/add_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ price: 2e18;
orderbook: None,
};
let deployment = Deployment {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: "".to_string(),
scenario: Arc::new(scenario),
order: Arc::new(order),
};
Expand Down Expand Up @@ -614,6 +616,8 @@ _ _: 0 0;
orderbook: None,
};
let deployment = Deployment {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: "".to_string(),
scenario: Arc::new(scenario),
order: Arc::new(order),
};
Expand Down Expand Up @@ -758,6 +762,8 @@ _ _: 0 0;
orderbook: None,
};
let deployment = Deployment {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: "".to_string(),
scenario: Arc::new(scenario),
order: Arc::new(order),
};
Expand Down
187 changes: 184 additions & 3 deletions crates/settings/src/deployment.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
use crate::*;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, sync::Arc};
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use strict_yaml_rust::StrictYaml;
use thiserror::Error;
use typeshare::typeshare;
use yaml::{default_document, require_hash, require_string, YamlError, YamlParsableHash};

#[cfg(target_family = "wasm")]
use rain_orderbook_bindings::{impl_all_wasm_traits, wasm_traits::prelude::*};

#[typeshare]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "kebab-case")]
#[cfg_attr(target_family = "wasm", derive(Tsify))]
pub struct Deployment {
#[serde(skip, default = "default_document")]
pub document: Arc<RwLock<StrictYaml>>,
pub key: String,
#[typeshare(typescript(type = "Scenario"))]
pub scenario: Arc<Scenario>,
#[typeshare(typescript(type = "Order"))]
Expand All @@ -20,6 +28,82 @@ pub struct Deployment {
#[cfg(target_family = "wasm")]
impl_all_wasm_traits!(Deployment);

impl YamlParsableHash for Deployment {
fn parse_all_from_yaml(
document: Arc<RwLock<StrictYaml>>,
) -> Result<HashMap<String, Self>, YamlError> {
let document_read = document.read().map_err(|_| YamlError::ReadLockError)?;
let deployments_hash = require_hash(
&document_read,
Some("deployments"),
Some("missing field: deployments".to_string()),
)?;

deployments_hash
.iter()
.map(|(key_yaml, deployment_yaml)| {
let deployment_key = key_yaml.as_str().unwrap_or_default().to_string();

let scenario = Scenario::parse_from_yaml(
document.clone(),
&require_string(
deployment_yaml,
Some("scenario"),
Some(format!(
"scenario string missing in deployment: {deployment_key}"
)),
)?,
)?;
let order = Order::parse_from_yaml(
document.clone(),
&require_string(
deployment_yaml,
Some("order"),
Some(format!(
"order string missing in deployment: {deployment_key}"
)),
)?,
)?;

if let Some(deployer) = &order.deployer {
if deployer != &scenario.deployer {
return Err(YamlError::ParseDeploymentConfigSourceError(
ParseDeploymentConfigSourceError::NoMatch,
));
}
}

Ok((
deployment_key.clone(),
Deployment {
document: document.clone(),
key: deployment_key,
scenario: Arc::new(scenario),
order: Arc::new(order),
},
))
})
.collect()
}
}

impl Default for Deployment {
fn default() -> Self {
Self {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: String::new(),
scenario: Arc::new(Scenario::default()),
order: Arc::new(Order::default()),
}
}
}

impl PartialEq for Deployment {
fn eq(&self, other: &Self) -> bool {
self.key == other.key && self.scenario == other.scenario && self.order == other.order
}
}

#[derive(Error, Debug, PartialEq)]
pub enum ParseDeploymentConfigSourceError {
#[error("Scenario not found: {0}")]
Expand Down Expand Up @@ -57,7 +141,12 @@ impl DeploymentConfigSource {
}
};

Ok(Deployment { scenario, order })
Ok(Deployment {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: scenario.key.clone(),
scenario,
order,
})
}
}

Expand All @@ -67,6 +156,7 @@ mod tests {
use crate::test::*;
use std::sync::RwLock;
use strict_yaml_rust::StrictYaml;
use yaml::tests::get_document;

#[test]
fn test_try_into_deployment_success() {
Expand Down Expand Up @@ -133,4 +223,95 @@ mod tests {
Err(ParseDeploymentConfigSourceError::ScenarioNotFoundError(_))
));
}

#[test]
fn test_parse_deployments_from_yaml() {
let yaml = r#"
test: test
"#;
let error = Deployment::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("missing field: deployments".to_string())
);

let yaml = r#"
deployments:
deployment1:
test: test
"#;
let error = Deployment::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("scenario string missing in deployment: deployment1".to_string())
);

let yaml = r#"
networks:
network1:
rpc: https://eth.llamarpc.com
chain-id: 1
deployers:
deployer1:
address: 0x0000000000000000000000000000000000000000
network: network1
scenarios:
scenario1:
bindings:
test: test
deployer: deployer1
deployments:
deployment1:
scenario: scenario1
test: test
"#;
let error = Deployment::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("order string missing in deployment: deployment1".to_string())
);

let yaml = r#"
networks:
network1:
rpc: https://eth.llamarpc.com
chain-id: 1
network2:
rpc: https://test.com
chain-id: 2
deployers:
deployer1:
address: 0x0000000000000000000000000000000000000000
network: network1
deployer2:
address: 0x0000000000000000000000000000000000000000
network: network2
scenarios:
scenario1:
bindings:
test: test
deployer: deployer1
tokens:
token1:
address: 0x0000000000000000000000000000000000000000
network: network2
orders:
order1:
inputs:
- token: token1
outputs:
- token: token1
deployer: deployer2
deployments:
deployment1:
scenario: scenario1
order: order1
"#;
let error = Deployment::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error.to_string(),
YamlError::ParseDeploymentConfigSourceError(ParseDeploymentConfigSourceError::NoMatch)
.to_string()
);
}
}
2 changes: 2 additions & 0 deletions crates/settings/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ mod tests {
orderbook: None,
};
let deployment = Deployment {
document: Arc::new(RwLock::new(StrictYaml::String("".to_string()))),
key: "test-deployment".to_string(),
scenario: Arc::new(scenario),
order: Arc::new(order),
};
Expand Down
35 changes: 35 additions & 0 deletions crates/settings/src/scenario.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,5 +571,40 @@ scenarios:
)
.to_string()
);

let yaml = r#"
networks:
mainnet:
rpc: https://rpc.com
chain-id: 1
testnet:
rpc: https://rpc.com
chain-id: 2
deployers:
mainnet:
address: 0x1234567890123456789012345678901234567890
network: mainnet
testnet:
address: 0x1234567890123456789012345678901234567890
network: testnet
scenarios:
scenario1:
deployer: mainnet
bindings:
key1: some-value
scenarios:
scenario2:
bindings:
key2: value
deployer: testnet
"#;
let error = Scenario::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error.to_string(),
YamlError::ParseScenarioConfigSourceError(
ParseScenarioConfigSourceError::ParentDeployerShadowedError("testnet".to_string())
)
.to_string()
);
}
}
26 changes: 25 additions & 1 deletion crates/settings/src/yaml/dotrain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::{Order, Scenario};
use crate::{Deployment, Order, Scenario};
use std::sync::{Arc, RwLock};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -40,6 +40,14 @@ impl DotrainYaml {
pub fn get_scenario(&self, key: &str) -> Result<Scenario, YamlError> {
Scenario::parse_from_yaml(self.document.clone(), key)
}

pub fn get_deployment_keys(&self) -> Result<Vec<String>, YamlError> {
let deployments = Deployment::parse_all_from_yaml(self.document.clone())?;
Ok(deployments.keys().cloned().collect())
}
pub fn get_deployment(&self, key: &str) -> Result<Deployment, YamlError> {
Deployment::parse_from_yaml(self.document.clone(), key)
}
}

#[cfg(test)]
Expand Down Expand Up @@ -94,6 +102,10 @@ mod tests {
scenario2:
bindings:
key2: value2
deployments:
deployment1:
order: order1
scenario: scenario1
"#;

#[test]
Expand Down Expand Up @@ -135,5 +147,17 @@ mod tests {
*scenario2.deployer.as_ref(),
ob_yaml.get_deployer("deployer1").unwrap()
);

let deployment_keys = dotrain_yaml.get_deployment_keys().unwrap();
assert_eq!(deployment_keys.len(), 1);
let deployment = dotrain_yaml.get_deployment("deployment1").unwrap();
assert_eq!(
deployment.order,
dotrain_yaml.get_order("order1").unwrap().into()
);
assert_eq!(
deployment.scenario,
dotrain_yaml.get_scenario("scenario1").unwrap().into()
);
}
}
7 changes: 5 additions & 2 deletions crates/settings/src/yaml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ pub mod dotrain;
pub mod orderbook;

use crate::{
ParseDeployerConfigSourceError, ParseNetworkConfigSourceError, ParseOrderConfigSourceError,
ParseOrderbookConfigSourceError, ParseScenarioConfigSourceError, ParseTokenConfigSourceError,
ParseDeployerConfigSourceError, ParseDeploymentConfigSourceError,
ParseNetworkConfigSourceError, ParseOrderConfigSourceError, ParseOrderbookConfigSourceError,
ParseScenarioConfigSourceError, ParseTokenConfigSourceError,
};
use alloy::primitives::ruint::ParseError as RuintParseError;
use std::collections::HashMap;
Expand Down Expand Up @@ -96,6 +97,8 @@ pub enum YamlError {
ParseOrderConfigSourceError(#[from] ParseOrderConfigSourceError),
#[error(transparent)]
ParseScenarioConfigSourceError(#[from] ParseScenarioConfigSourceError),
#[error(transparent)]
ParseDeploymentConfigSourceError(#[from] ParseDeploymentConfigSourceError),
}
impl PartialEq for YamlError {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion packages/orderbook/test/js_api/gui.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ describe('Rain Orderbook JS API Package Bindgen Tests - Gui', async function ()

describe('state management tests', async () => {
let serializedState =
'H4sIAAAAAAAA_3WPTQoCMQyFZ1REb-FaUJq26TQ7j-AV0k4qg1BBZ-HxFUxdCL7Nlz_eI6fuI7DekQOkDHnIgdlxZBY_SikpcLFiLQsigCOIPpkEBYjIx1FCxLxQn60yTXWc6uUAvQ5Mv9HqfJeHzDvYt80TrPMYhkiGU34n_ut_zW3XtGxvGNMC18r5dpUK38uVEs0xvAARbQwj_QAAAA==';
'H4sIAAAAAAAA_3WNTQrCQAyFWxXRW7gWlKSdyWR2HsErzE8iRaigXXh8BVMXgm_zvfzw3qn5KBGjoqoP4rnkGFmFCrsoiQSiprdH5yoR51C7nhwrAlbKqQTJaWE5W2MexjqMlwO2toB2Y-58l4dMO9zPlyd2vfMUOELKpYr-m3_Du2bW0ogAc-HaON2uMuL3c2X0cKQXPMPJJ_0AAAA=';
let gui: DotrainOrderGui;
beforeAll(async () => {
mockServer
Expand Down
Loading
Loading