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

Add auto_fill_txn #76

Closed
wants to merge 21 commits into from
Closed
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
4 changes: 2 additions & 2 deletions .cargo-husky/hooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ echo 'Running all pre-commit checks:'
cargo fmt
cargo test --no-default-features --features core,models,utils
cargo test --no-default-features --features core,models,utils,embedded-ws
cargo test --no-default-features --features core,models,utils,tungstenite
cargo test --no-default-features --features core,models,utils,json-rpc-std
cargo test --no-default-features --features std,core,models,utils,tungstenite
cargo test --no-default-features --features std,core,models,utils,json-rpc-std
cargo test --all-features
cargo clippy --fix --allow-staged
cargo doc --no-deps
Expand Down
7 changes: 3 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
// }
// ]
// Use 'postCreateCommand' to run commands after the container is created.
"postStartCommand": "rustup --version && rustup component add rustfmt && rustup component add clippy",
"postCreateCommand": "rustup install nightly && rustup --version && rustup component add cargo && rustup component add rustfmt && rustup component add clippy",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"Gydunhn.vsc-essentials",
"GitHub.copilot",
"swellaby.rust-pack",
"panicbit.cargo",
"vadimcn.vscode-lldb",
"tamasfe.even-better-toml",
"Swellaby.vscode-rust-test-adapter"
Expand All @@ -36,7 +35,7 @@
}
}
}
}
},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
"remoteUser": "root"
}
4 changes: 2 additions & 2 deletions .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: build
args: --release --no-default-features --features core,models,tungstenite
args: --release --no-default-features --features core,models,tungstenite,std
- uses: actions-rs/cargo@v1
with:
command: test
args: --all-features
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features core,models,tungstenite
args: --no-default-features --features core,models,tungstenite,std
- uses: actions-rs/cargo@v1
with:
command: test
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ results = ["core", "amounts", "currencies"]
ledger = ["core", "amounts", "currencies"]
amounts = ["core"]
currencies = ["core"]
json-rpc = ["reqwless", "embedded-nal-async"]
json-rpc-std = ["reqwest"]
json-rpc = ["url", "reqwless", "embedded-nal-async"]
json-rpc-std = ["url", "reqwest"]
tungstenite = [
"url",
"futures",
Expand Down
47 changes: 47 additions & 0 deletions src/asynch/account/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use alloc::borrow::Cow;
use anyhow::Result;

use crate::{
core::addresscodec::{is_valid_xaddress, xaddress_to_classic_address},
models::{ledger::AccountRoot, requests::AccountInfo, results},
Err,
};

use super::clients::AsyncClient;

pub async fn get_next_valid_seq_number(
address: Cow<'_, str>,
client: &impl AsyncClient,
ledger_index: Option<Cow<'_, str>>,
) -> Result<u32> {
let account_info =
get_account_root(address, client, ledger_index.unwrap_or("current".into())).await?;
Ok(account_info.sequence)
}

pub async fn get_account_root<'a>(
address: Cow<'_, str>,
client: &impl AsyncClient,
ledger_index: Cow<'_, str>,
) -> Result<AccountRoot<'a>> {
let mut classic_address = address;
if is_valid_xaddress(&classic_address) {
classic_address = match xaddress_to_classic_address(&classic_address) {
Ok(addr) => addr.0.into(),
Err(e) => return Err!(e),
};
}
let account_info = client
.request::<results::AccountInfo, _>(AccountInfo::new(
None,
classic_address,
None,
Some(ledger_index),
None,
None,
None,
))
.await?;

Ok(account_info.try_into_result()?.account_data)
}
9 changes: 5 additions & 4 deletions src/asynch/clients/async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ use anyhow::Result;
use serde::{Deserialize, Serialize};

#[allow(async_fn_in_trait)]
pub trait AsyncClient<'a>: Client<'a> {
pub trait AsyncClient: Client {
async fn request<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
request: Req,
) -> Result<XRPLResponse<'_, Res, Req>> {
) -> Result<XRPLResponse<'a, Res, Req>> {
self.request_impl(request).await
}
}

impl<'a, T: Client<'a>> AsyncClient<'a> for T {}
impl<'a, T: Client> AsyncClient for T {}
35 changes: 28 additions & 7 deletions src/asynch/clients/client.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
use crate::models::{requests::Request, results::XRPLResponse};
use crate::models::{
requests::{Request, ServerState},
results::{ServerState as ServerStateResult, XRPLResponse},
};
#[cfg(feature = "std")]
use crate::utils::get_random_id;
use alloc::borrow::Cow;
use anyhow::Result;
use serde::{Deserialize, Serialize};

use super::CommonFields;

#[allow(async_fn_in_trait)]
pub trait Client<'a> {
pub trait Client {
async fn request_impl<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
request: Req,
) -> Result<XRPLResponse<'_, Res, Req>>;
) -> Result<XRPLResponse<'a, Res, Req>>;

fn set_request_id<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
request: &mut Req,
) -> Cow<'_, str> {
) -> Cow<'a, str> {
let common_fields = request.get_common_fields();
let request_id: Cow<'_, str> = match common_fields.id.clone() {
Some(id) => id,
Expand All @@ -31,10 +39,23 @@ pub trait Client<'a> {
Cow::Owned(get_random_id(&mut rng))
}
#[cfg(not(feature = "std"))]
unimplemented!("get_random_id is not yet implemented for no_std. Please provide an `id` in the request.");
todo!("get_random_id is not yet implemented for no_std. Please provide an `id` in the request.");
}
};
request.get_common_fields_mut().id = Some(request_id.clone());
request_id
}

async fn get_common_fields(&self) -> Result<CommonFields<'_>> {
let server_state = self
.request_impl::<ServerStateResult, _>(ServerState::new(None))
.await?;
let state = server_state.try_into_result()?.state;
let common_fields = CommonFields {
network_id: state.network_id,
build_version: Some(state.build_version),
};

Ok(common_fields)
}
}
22 changes: 12 additions & 10 deletions src/asynch/clients/json_rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use alloc::{string::String, sync::Arc};

Check warning on line 1 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `sync::Arc`

Check warning on line 1 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `sync::Arc`

Check warning on line 1 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `sync::Arc`

Check warning on line 1 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `sync::Arc`

Check warning on line 1 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `sync::Arc`
use anyhow::Result;
use embassy_sync::{blocking_mutex::raw::RawMutex, mutex::Mutex};

Check warning on line 3 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `blocking_mutex::raw::RawMutex` and `mutex::Mutex`

Check warning on line 3 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `blocking_mutex::raw::RawMutex` and `mutex::Mutex`

Check warning on line 3 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `blocking_mutex::raw::RawMutex` and `mutex::Mutex`

Check warning on line 3 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `blocking_mutex::raw::RawMutex` and `mutex::Mutex`

Check warning on line 3 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `blocking_mutex::raw::RawMutex` and `mutex::Mutex`
use serde::{Deserialize, Serialize};

Check warning on line 4 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Deserialize`

Check warning on line 4 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Deserialize`

Check warning on line 4 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Deserialize`

Check warning on line 4 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Deserialize`

Check warning on line 4 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Deserialize`

use crate::{
models::{requests::Request, results::XRPLResponse},

Check warning on line 7 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `requests::Request` and `results::XRPLResponse`

Check warning on line 7 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `requests::Request` and `results::XRPLResponse`

Check warning on line 7 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `requests::Request` and `results::XRPLResponse`

Check warning on line 7 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `requests::Request` and `results::XRPLResponse`

Check warning on line 7 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `requests::Request` and `results::XRPLResponse`
Err,
};

mod exceptions;
pub use exceptions::XRPLJsonRpcException;

use super::{client::Client, SingleExecutorMutex};

Check warning on line 14 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `SingleExecutorMutex` and `client::Client`

Check warning on line 14 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `SingleExecutorMutex` and `client::Client`

Check warning on line 14 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `SingleExecutorMutex` and `client::Client`

Check warning on line 14 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `SingleExecutorMutex` and `client::Client`

Check warning on line 14 in src/asynch/clients/json_rpc/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused imports: `SingleExecutorMutex` and `client::Client`

/// Renames the requests field `command` to `method` for JSON-RPC.
fn request_to_json_rpc(request: &impl Serialize) -> Result<String> {
Expand All @@ -29,7 +29,7 @@
}
}

#[cfg(feature = "json-rpc-std")]
#[cfg(all(feature = "json-rpc-std", not(feature = "json-rpc")))]
mod std_client {
use super::*;
use reqwest::Client as HttpClient;
Expand Down Expand Up @@ -67,17 +67,18 @@
}
}

impl<'a, M> Client<'a> for AsyncJsonRpcClient<M>
impl<M> Client for AsyncJsonRpcClient<M>
where
M: RawMutex,
{
async fn request_impl<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
request: Req,
) -> Result<XRPLResponse<'_, Res, Req>> {
) -> Result<XRPLResponse<'a, Res, Req>> {
let client = self.client.lock().await;
match client
.post(self.url.as_ref())
Expand All @@ -95,7 +96,7 @@
}
}

#[cfg(feature = "json-rpc")]
#[cfg(all(feature = "json-rpc", not(feature = "json-rpc-std")))]
mod no_std_client {
use super::*;
use embedded_nal_async::{Dns, TcpConnect};
Expand Down Expand Up @@ -137,19 +138,20 @@
}
}

impl<'a, const BUF: usize, T, D, M> Client<'a> for AsyncJsonRpcClient<'a, BUF, T, D, M>
impl<const BUF: usize, T, D, M> Client for AsyncJsonRpcClient<'_, BUF, T, D, M>
where
M: RawMutex,
T: TcpConnect + 'a,
D: Dns + 'a,
T: TcpConnect,
D: Dns,
{
async fn request_impl<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
request: Req,
) -> Result<XRPLResponse<'_, Res, Req>> {
) -> Result<XRPLResponse<'a, Res, Req>> {
let request_json_rpc = request_to_json_rpc(&request)?;
let request_buf = request_json_rpc.as_bytes();
let mut rx_buffer = [0; BUF];
Expand Down
14 changes: 11 additions & 3 deletions src/asynch/clients/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@ mod client;
mod json_rpc;
mod websocket;

use alloc::borrow::Cow;
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};

pub type MultiExecutorMutex = CriticalSectionRawMutex;
pub type SingleExecutorMutex = NoopRawMutex;
use serde::{Deserialize, Serialize};

pub use async_client::*;
pub use json_rpc::*;
pub use websocket::*;

pub type MultiExecutorMutex = CriticalSectionRawMutex;
pub type SingleExecutorMutex = NoopRawMutex;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommonFields<'a> {
pub build_version: Option<Cow<'a, str>>,
pub network_id: Option<u32>,
}
7 changes: 4 additions & 3 deletions src/asynch/clients/websocket/embedded_websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ where
}
}

impl<'a, const BUF: usize, M, Tcp, B, E, Rng: RngCore> ClientTrait<'a>
impl<const BUF: usize, M, Tcp, B, E, Rng: RngCore> ClientTrait
for AsyncWebsocketClient<BUF, Tcp, B, E, Rng, M, WebsocketOpen>
where
M: RawMutex,
Expand All @@ -244,12 +244,13 @@ where
Tcp: Stream<Item = Result<B, E>> + for<'b> Sink<&'b [u8], Error = E> + Unpin,
{
async fn request_impl<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
mut request: Req,
) -> Result<XRPLResponse<'_, Res, Req>> {
) -> Result<XRPLResponse<'a, Res, Req>> {
// setup request future
let request_id = self.set_request_id::<Res, Req>(&mut request);
let mut websocket_base = self.websocket_base.lock().await;
Expand Down
2 changes: 2 additions & 0 deletions src/asynch/clients/websocket/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt::{Debug, Display};

Check warning on line 1 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Display`

Check warning on line 1 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Display`

use crate::{models::results::XRPLResponse, Err};

Check warning on line 3 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Err`

Check warning on line 3 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `Err`
#[cfg(all(feature = "tungstenite", not(feature = "embedded-ws")))]
use alloc::string::String;
#[cfg(all(feature = "embedded-ws", not(feature = "tungstenite")))]
Expand All @@ -12,8 +12,10 @@
use futures::{Sink, SinkExt, Stream, StreamExt};
use serde::{Deserialize, Serialize};

#[cfg(any(feature = "embedded-ws", feature = "tungstenite"))]
mod websocket_base;
#[cfg(any(feature = "embedded-ws", feature = "tungstenite"))]
use websocket_base::MessageHandler;

Check warning on line 18 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `websocket_base::MessageHandler`

Check warning on line 18 in src/asynch/clients/websocket/mod.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `websocket_base::MessageHandler`

#[cfg(all(feature = "embedded-ws", feature = "std", not(feature = "tungstenite")))]
pub mod codec;
Expand Down
20 changes: 4 additions & 16 deletions src/asynch/clients/websocket/tungstenite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,18 @@ where
}
}

impl<'a, M> Client<'a> for AsyncWebsocketClient<M, WebsocketOpen>
impl<M> Client for AsyncWebsocketClient<M, WebsocketOpen>
where
M: RawMutex,
{
async fn request_impl<
'a,
Res: Serialize + for<'de> Deserialize<'de>,
Req: Serialize + for<'de> Deserialize<'de> + Request<'a>,
>(
&'a self,
&self,
mut request: Req,
) -> Result<XRPLResponse<'_, Res, Req>> {
) -> Result<XRPLResponse<'a, Res, Req>> {
// setup request future
let request_id = self.set_request_id::<Res, Req>(&mut request);
let mut websocket_base = self.websocket_base.lock().await;
Expand Down Expand Up @@ -250,17 +251,4 @@ where
}
}
}

// async fn get_common_fields(&self) -> Result<CommonFields<'a>> {
// let server_state = self
// .request::<results::server_state::ServerState>(requests::ServerState::new(None))
// .await?;
// let state = server_state.result.state;
// let common_fields = CommonFields {
// network_id: state.network_id,
// build_version: Some(state.build_version),
// };

// Ok(common_fields)
// }
}
Loading
Loading