Skip to content

Commit

Permalink
Merge pull request #374 from rainlanguage/2024-02-29-new-yaml-structure
Browse files Browse the repository at this point in the history
utilize new yaml structure
  • Loading branch information
mattyg authored Mar 15, 2024
2 parents 778bccf + f15a630 commit ec40f68
Show file tree
Hide file tree
Showing 61 changed files with 1,587 additions and 1,920 deletions.
498 changes: 258 additions & 240 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ comfy-table = "7.1.0"
cynic-codegen = { version = "3.4.0", features = ["rkyv"] }
cynic = "3.4.0"
chrono = "0.4.31"
typeshare = "1.0.1"
typeshare = { git = "https://github.com/1password/typeshare", rev = "556b44aafd5304eedf17206800f69834e3820b7c" }
thiserror = "1.0.56"
strict-yaml-rust = "0.1.2"
dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" }
Expand All @@ -45,7 +45,6 @@ rain-interpreter-eval = { path = "lib/rain.interpreter/crates/eval" }
csv = "1.3.0"
insta = { version = "1.34.0" }
proptest = "1.4.0"
k256 = "=0.13.3"
derive_builder = "0.20.0"

[workspace.dependencies.rain_orderbook_bindings]
Expand Down
1 change: 1 addition & 0 deletions crates/bindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ homepage.workspace = true
[dependencies]
alloy-sol-types = { workspace = true, features = ["json"] }
alloy-primitives = { workspace = true }
serde = { workspace = true }
6 changes: 6 additions & 0 deletions crates/bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ use alloy_sol_types::sol;

sol!(
#![sol(all_derives = true)]
#[derive(serde::Serialize, serde::Deserialize)]
IOrderBookV3, "../../out/IOrderBookV3.sol/IOrderBookV3.json"
);

sol!(
#![sol(all_derives = true)]
IERC20, "../../out/IERC20.sol/IERC20.json"
);

sol!(
#![sol(all_derives = true)]
ERC20, "../../out/ERC20.sol/ERC20.json"
);
1 change: 0 additions & 1 deletion crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ rain_orderbook_subgraph_client = { workspace = true }
rain_orderbook_bindings = { workspace = true }
rain_orderbook_common = { workspace = true }
rain_orderbook_app_settings = { workspace = true }
serde_yaml = { workspace = true }
anyhow = { workspace = true }
clap = { workspace = true }
reqwest = { workspace = true }
Expand Down
5 changes: 3 additions & 2 deletions crates/cli/src/commands/chart/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::execute::Execute;
use anyhow::{anyhow, Result};
use clap::Args;
use rain_orderbook_app_settings::string_structs::ConfigString;
use rain_orderbook_app_settings::{string_structs::ConfigString, Config};
use rain_orderbook_common::dotrain::RainDocument;
use rain_orderbook_common::fuzz::FuzzRunner;
use std::fs::read_to_string;
Expand All @@ -22,7 +22,8 @@ impl Execute for Chart {
async fn execute(&self) -> Result<()> {
let dotrain = read_to_string(self.dotrain_file.clone()).map_err(|e| anyhow!(e))?;
let frontmatter = RainDocument::get_front_matter(&dotrain).unwrap();
let config = serde_yaml::from_str::<ConfigString>(frontmatter)?.try_into()?;
let config_string: ConfigString = frontmatter.to_string().try_into()?;
let config: Config = config_string.try_into()?;
let mut fuzzer = FuzzRunner::new(&dotrain, config, None).await;
let chart_data = fuzzer.build_chart_datas().await?;

Expand Down
25 changes: 19 additions & 6 deletions crates/cli/src/commands/order/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ use crate::{
};
use anyhow::{anyhow, Result};
use clap::Args;
use rain_orderbook_app_settings::Config;
use rain_orderbook_common::add_order::AddOrderArgs;
use rain_orderbook_common::frontmatter::parse_frontmatter;
use rain_orderbook_common::transaction::TransactionArgs;
use std::fs::read_to_string;
use std::ops::Deref;
use std::path::PathBuf;
use tracing::info;

Expand All @@ -18,22 +21,32 @@ pub struct CliOrderAddArgs {
)]
dotrain_file: PathBuf,

#[arg(short = 'e', long, help = "Deployment key to select from frontmatter")]
deployment: String,

#[clap(flatten)]
pub transaction_args: CliTransactionArgs,
}

impl TryFrom<CliOrderAddArgs> for AddOrderArgs {
type Error = anyhow::Error;
impl CliOrderAddArgs {
async fn to_add_order_args(&self) -> Result<AddOrderArgs> {
let text = read_to_string(&self.dotrain_file).map_err(|e| anyhow!(e))?;
let config: Config = parse_frontmatter(text.clone())?.try_into()?;
let config_deployment = config
.deployments
.get(&self.deployment)
.ok_or(anyhow!("specified deployment is undefined!"))?;

fn try_from(val: CliOrderAddArgs) -> Result<Self> {
let text = read_to_string(val.dotrain_file).map_err(|e| anyhow!(e))?;
Ok(Self { dotrain: text })
Ok(
AddOrderArgs::new_from_deployment(text.clone(), config_deployment.deref().clone())
.await?,
)
}
}

impl Execute for CliOrderAddArgs {
async fn execute(&self) -> Result<()> {
let add_order_args: AddOrderArgs = self.clone().try_into()?;
let add_order_args: AddOrderArgs = self.clone().to_add_order_args().await?;
let mut tx_args: TransactionArgs = self.transaction_args.clone().into();
tx_args.try_fill_chain_id().await?;

Expand Down
138 changes: 98 additions & 40 deletions crates/common/src/add_order.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
use crate::{
dotrain_add_order_lsp::LANG_SERVICES,
frontmatter::{try_parse_frontmatter, FrontmatterError},
transaction::{TransactionArgs, TransactionArgsError},
};
use alloy_ethers_typecast::transaction::{
ReadableClientError, ReadableClientHttp, WritableClientError, WriteTransaction,
WriteTransactionStatus,
ReadContractParameters, ReadableClientError, ReadableClientHttp, WritableClientError,
WriteTransaction, WriteTransactionStatus,
};
use alloy_primitives::{hex::FromHexError, Address, U256};
use dotrain::{error::ComposeError, RainDocument};
use dotrain::{error::ComposeError, RainDocument, Rebind};
use rain_interpreter_dispair::{DISPair, DISPairError};
use rain_interpreter_parser::{Parser, ParserError, ParserV1};
use rain_metadata::{
ContentEncoding, ContentLanguage, ContentType, Error as RainMetaError, KnownMagic,
RainMetaDocumentV1Item,
};
use rain_orderbook_bindings::IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2};
use rain_orderbook_app_settings::deployment::Deployment;
use rain_orderbook_bindings::{
IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2, IO},
ERC20::decimalsCall,
};
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use std::collections::HashMap;
use thiserror::Error;

pub static ORDERBOOK_ORDER_ENTRYPOINTS: [&str; 2] = ["calculate-io", "handle-io"];
Expand All @@ -26,8 +30,6 @@ pub static ORDERBOOK_ORDER_ENTRYPOINTS: [&str; 2] = ["calculate-io", "handle-io"
pub enum AddOrderArgsError {
#[error("Empty Front Matter")]
EmptyFrontmatter,
#[error("Front Matter: {0}")]
FrontmatterError(#[from] FrontmatterError),
#[error(transparent)]
DISPairError(#[from] DISPairError),
#[error(transparent)]
Expand All @@ -47,40 +49,88 @@ pub enum AddOrderArgsError {
}

#[derive(Serialize, Deserialize, Clone)]
#[serde(rename = "kebab-case")]
pub struct AddOrderArgs {
/// Text of a dotrain file describing an addOrder call
/// Text MUST have strict yaml frontmatter of the following structure
///
/// ```yaml
/// orderbook:
/// order:
/// deployer: 0x1111111111111111111111111111111111111111
/// valid-inputs:
/// - address: 0x2222222222222222222222222222222222222222
/// decimals: 18
/// vault-id: 0x1234
/// valid-outputs:
/// - address: 0x5555555555555555555555555555555555555555
/// decimals: 8
/// vault-id: 0x5678
/// ```
///
/// Text MUST have valid dotrain body succeding frontmatter.
/// The dotrain body must contain two entrypoints: `calulate-io` and `handle-io`.
pub dotrain: String,
pub inputs: Vec<IO>,
pub outputs: Vec<IO>,
pub deployer: Address,
pub bindings: HashMap<String, String>,
}

impl AddOrderArgs {
/// create a new instance from Deployment
pub async fn new_from_deployment(
dotrain: String,
deployment: Deployment,
) -> Result<AddOrderArgs, AddOrderArgsError> {
let mut inputs = vec![];
for input in &deployment.order.inputs {
if let Some(decimals) = input.token.decimals {
inputs.push(IO {
token: input.token.address,
vaultId: input.vault_id,
decimals,
});
} else {
let client = ReadableClientHttp::new_from_url(input.token.network.rpc.to_string())?;
let parameters = ReadContractParameters {
address: input.token.address,
call: decimalsCall {},
block_number: None,
};
let decimals = client.read(parameters).await?._0;
inputs.push(IO {
token: input.token.address,
vaultId: input.vault_id,
decimals,
});
}
}

let mut outputs = vec![];
for output in &deployment.order.inputs {
if let Some(decimals) = output.token.decimals {
outputs.push(IO {
token: output.token.address,
vaultId: output.vault_id,
decimals,
});
} else {
let client =
ReadableClientHttp::new_from_url(output.token.network.rpc.to_string())?;
let parameters = ReadContractParameters {
address: output.token.address,
call: decimalsCall {},
block_number: None,
};
let decimals = client.read(parameters).await?._0;
outputs.push(IO {
token: output.token.address,
vaultId: output.vault_id,
decimals,
});
}
}

Ok(AddOrderArgs {
dotrain: dotrain.to_string(),
inputs,
outputs,
deployer: deployment.scenario.deployer.address,
bindings: deployment.scenario.bindings.to_owned(),
})
}

/// Read parser address from deployer contract, then call parser to parse rainlang into bytecode and constants
async fn try_parse_rainlang(
&self,
rpc_url: String,
deployer: Address,
rainlang: String,
) -> Result<(Vec<u8>, Vec<U256>), AddOrderArgsError> {
let client = ReadableClientHttp::new_from_url(rpc_url)
.map_err(AddOrderArgsError::ReadableClientError)?;
let dispair = DISPair::from_deployer(deployer, client.clone())
let dispair = DISPair::from_deployer(self.deployer, client.clone())
.await
.map_err(AddOrderArgsError::DISPairError)?;

Expand Down Expand Up @@ -116,27 +166,29 @@ impl AddOrderArgs {
// Parse file into dotrain document
let meta_store = LANG_SERVICES.meta_store();

let frontmatter = RainDocument::get_front_matter(&self.dotrain)
.ok_or(AddOrderArgsError::EmptyFrontmatter)?;

// Prepare call
let (deployer, valid_inputs, valid_outputs, rebinds) = try_parse_frontmatter(frontmatter)?;
let mut rebinds = None;
if !self.bindings.is_empty() {
rebinds = Some(
self.bindings
.iter()
.map(|(key, value)| Rebind(key.clone(), value.clone()))
.collect(),
);
};

let dotrain_doc =
RainDocument::create(self.dotrain.clone(), Some(meta_store), None, rebinds);
let rainlang = dotrain_doc.compose(&ORDERBOOK_ORDER_ENTRYPOINTS)?;

let (bytecode, constants) = self
.try_parse_rainlang(rpc_url, deployer, rainlang.clone())
.await?;
let (bytecode, constants) = self.try_parse_rainlang(rpc_url, rainlang.clone()).await?;
let meta = self.try_generate_meta(rainlang)?;

Ok(addOrderCall {
config: OrderConfigV2 {
validInputs: valid_inputs,
validOutputs: valid_outputs,
validInputs: self.inputs.clone(),
validOutputs: self.outputs.clone(),
evaluableConfig: EvaluableConfigV3 {
deployer,
deployer: self.deployer,
bytecode,
constants,
},
Expand Down Expand Up @@ -182,7 +234,13 @@ max-amount: 100e18,
price: 2e18;
",
);
let args = AddOrderArgs { dotrain: "".into() };
let args = AddOrderArgs {
dotrain: "".into(),
inputs: vec![],
outputs: vec![],
bindings: HashMap::new(),
deployer: Address::default(),
};

let meta_bytes = args.try_generate_meta(dotrain_body).unwrap();
assert_eq!(
Expand Down
Loading

0 comments on commit ec40f68

Please sign in to comment.