diff --git a/Cargo.toml b/Cargo.toml index 708568b..6f87ed3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,9 +49,8 @@ scrolls-client = { version = "0.1.0", git = "https://github.com/free-honey/scrol secrecy = "0.8.0" [dependencies.blockfrost-http-client] -version = "0.0.12" -git = "https://github.com/MitchTurner/blockfrost-http-client.git" -rev = "bbb29df268464a055b17b5ebfae20d5f02165dc0" +version = "0.0.14" +#git = "https://github.com/MitchTurner/blockfrost-http-client.git" [dependencies.cardano-multiplatform-lib] version = "3.1.1" @@ -86,7 +85,7 @@ pallas-crypto = { version = "0.19.0-alpha.0", git = "https://github.com/txpipe/p #uplc = { version = "1.0.3-alpha", path = "../aiken-lang/aiken/crates/uplc" } #[patch."https://github.com/MitchTurner/blockfrost-http-client.git"] -#blockfrost-http-client = { version = "0.0.12", path = "../blockfrost-http-client"} +#blockfrost-http-client = { version = "0.0.13", path = "../blockfrost-http-client"} # #[patch."https://github.com/dcSpark/cardano-multiplatform-lib.git"] #cardano-multiplatform-lib = { version = "3.1.1", path = "../forks/cardano-multiplatform-lib/rust"} diff --git a/sample-dApps/checking_account/src/endpoints/init_account.rs b/sample-dApps/checking_account/src/endpoints/init_account.rs index f368b45..179ff4c 100644 --- a/sample-dApps/checking_account/src/endpoints/init_account.rs +++ b/sample-dApps/checking_account/src/endpoints/init_account.rs @@ -68,7 +68,6 @@ pub async fn init_account>( 1, ); - println!("address: {:?}", address.to_bech32()); let actions = TxActions::v2() .with_script_init(datum, values, address) .with_specific_input(my_input) diff --git a/src/ledger_client.rs b/src/ledger_client.rs index 89e8aac..044859b 100644 --- a/src/ledger_client.rs +++ b/src/ledger_client.rs @@ -54,6 +54,9 @@ pub trait LedgerClient: Send + Sync { async fn network(&self) -> LedgerClientResult; + /// Get the posix time of the most recent block + async fn last_block_time_secs(&self) -> LedgerClientResult; + /// Get the current time in seconds since the UNIX epoch. async fn current_time_secs(&self) -> LedgerClientResult; } @@ -82,6 +85,8 @@ pub enum LedgerClientError { CurrentTime(Box), #[error("While setting validity range: {0:?}")] ValidityRange(String), + #[error("While getting last block time: {0:?}")] + FailedToGetBlockTime(Box), } pub type LedgerClientResult = Result; diff --git a/src/ledger_client/test_ledger_client.rs b/src/ledger_client/test_ledger_client.rs index 629fbd2..7f95bb9 100644 --- a/src/ledger_client/test_ledger_client.rs +++ b/src/ledger_client/test_ledger_client.rs @@ -79,7 +79,7 @@ where pub fn build_in_memory( &self, ) -> Backend>> { - let block_length = 1000; + let block_length = 20; let ledger_client = TestLedgerClient::new_in_memory( self.signer.clone(), self.outputs.clone(), @@ -213,7 +213,7 @@ where { pub fn new_local_persisted(dir: T, signer: &Address, starting_amount: u64) -> Self { let signer_name = "Alice"; - let block_length = 1000; + let block_length = 20; let starting_time = 0; let storage = LocalPersistedStorage::init( dir, @@ -247,11 +247,11 @@ where Datum: Clone + Send + Sync + PartialEq, Storage: TestLedgerStorage + Send + Sync, { - pub async fn current_time_millis(&self) -> LedgerClientResult { + pub async fn current_time_secs(&self) -> LedgerClientResult { self.storage.current_time().await } - pub async fn set_current_time_millis(&self, posix_time: i64) -> LedgerClientResult<()> { + pub async fn set_current_time_secs(&self, posix_time: i64) -> LedgerClientResult<()> { self.storage.set_current_time(posix_time).await } @@ -298,7 +298,7 @@ where async fn issue(&self, tx: UnbuiltTransaction) -> LedgerClientResult { // Setup let valid_range = tx.valid_range; - let current_time = self.current_time_millis().await?; + let current_time = self.current_time_secs().await?; check_time_valid(valid_range, current_time) .map_err(|e| LedgerClientError::FailedToIssueTx(Box::new(e)))?; @@ -400,8 +400,12 @@ where self.storage.network().await } + async fn last_block_time_secs(&self) -> LedgerClientResult { + self.current_time_secs().await + } + async fn current_time_secs(&self) -> LedgerClientResult { - self.current_time_millis().await + self.current_time_secs().await } } diff --git a/src/ledger_client/test_ledger_client/local_persisted_storage.rs b/src/ledger_client/test_ledger_client/local_persisted_storage.rs index 6fcc42b..e2f8f6a 100644 --- a/src/ledger_client/test_ledger_client/local_persisted_storage.rs +++ b/src/ledger_client/test_ledger_client/local_persisted_storage.rs @@ -326,7 +326,7 @@ mod tests { use super::*; use tempfile::TempDir; - const BLOCK_LENGTH: i64 = 1000; + const BLOCK_LENGTH: i64 = 20; #[tokio::test] async fn outputs_at_address() { @@ -366,7 +366,7 @@ mod tests { ); let current_time = storage.current_time().await.unwrap(); assert_eq!(current_time, 0); - let new_time = 1000; + let new_time = 20; storage.set_current_time(new_time).await.unwrap(); let current_time = storage.current_time().await.unwrap(); assert_eq!(current_time, new_time); diff --git a/src/ledger_client/test_ledger_client/tests.rs b/src/ledger_client/test_ledger_client/tests.rs index 994ba67..24d8443 100644 --- a/src/ledger_client/test_ledger_client/tests.rs +++ b/src/ledger_client/test_ledger_client/tests.rs @@ -15,7 +15,7 @@ use crate::{ const ALICE: &str = "addr_test1qrmezjhpelwzvz83wjl0e6mx766de7j3nksu2338s00yzx870xyxfa97xyz2zn5rknyntu5g0c66s7ktjnx0p6f0an6s3dyxwr"; const BOB: &str = "addr_test1qzvrhz9v6lwcr26a52y8mmk2nzq37lky68359keq3dgth4lkzpnnjv8vf98m20lhqdzl60mcftq7r2lc4xtcsv0w6xjstag0ua"; -const BLOCK_LENGTH: i64 = 1000; +const BLOCK_LENGTH: i64 = 20; #[tokio::test] async fn outputs_at_address() { @@ -102,7 +102,7 @@ async fn issuing_tx_advances_time_by_block_length() { let outputs = vec![]; let record: TestLedgerClient<(), (), _> = TestLedgerClient::new_in_memory(signer.clone(), outputs, BLOCK_LENGTH, 0); - let starting_time = record.current_time_millis().await.unwrap(); + let starting_time = record.current_time_secs().await.unwrap(); let tx = UnbuiltTransaction { script_version: TransactionVersion::V2, script_inputs: vec![], @@ -113,7 +113,7 @@ async fn issuing_tx_advances_time_by_block_length() { }; record.issue(tx).await.unwrap(); let expected = starting_time + BLOCK_LENGTH; - let actual = record.current_time_millis().await.unwrap(); + let actual = record.current_time_secs().await.unwrap(); assert_eq!(expected, actual); } @@ -155,7 +155,7 @@ async fn cannot_transfer_before_valid_range() { let current_time = 5; let valid_time = 10; - record.set_current_time_millis(current_time).await.unwrap(); + record.set_current_time_secs(current_time).await.unwrap(); let mut values = Values::default(); values.add_one_value(&PolicyId::Lovelace, transfer_amount); @@ -187,7 +187,7 @@ async fn cannot_transfer_after_valid_range() { let current_time = 10_000; let valid_time = 5; - record.set_current_time_millis(current_time).await.unwrap(); + record.set_current_time_secs(current_time).await.unwrap(); let mut values = Values::default(); values.add_one_value(&PolicyId::Lovelace, transfer_amount); diff --git a/src/transaction.rs b/src/transaction.rs index 3ed9646..a10320f 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -230,7 +230,7 @@ pub enum TransactionVersion { V2, } -/// Range of times in milliseconds since the Unix epoch +/// Range of times in seconds since the Unix epoch type Range = (Option, Option); pub struct UnbuiltTransaction { diff --git a/src/trireme_ledger_client.rs b/src/trireme_ledger_client.rs index a455d60..406500b 100644 --- a/src/trireme_ledger_client.rs +++ b/src/trireme_ledger_client.rs @@ -458,7 +458,7 @@ where InnerClient::BlockFrost(_cml_client) => Err(LedgerClientError::CurrentTime(Box::new( Error::Trireme("Not implemented for Blockfrost client".to_string()), ))), - InnerClient::Mocked(test_client) => test_client.current_time_millis().await, + InnerClient::Mocked(test_client) => test_client.current_time_secs().await, InnerClient::OgmiosScrolls(_) => Err(LedgerClientError::CurrentTime(Box::new( Error::Trireme("Not implemented for Ogmios/Scrolls client".to_string()), ))), @@ -543,10 +543,25 @@ where .await } + async fn last_block_time_secs(&self) -> LedgerClientResult { + match &self.inner_client { + InnerClient::BlockFrost(cml_client) => cml_client.last_block_time_secs(), + InnerClient::Mocked(test_client) => test_client.last_block_time_secs(), + InnerClient::OgmiosScrolls(cml_client) => cml_client.last_block_time_secs(), + } + .await + } + async fn current_time_secs(&self) -> LedgerClientResult { match &self.inner_client { InnerClient::BlockFrost(cml_client) => cml_client.current_time_secs(), - InnerClient::Mocked(test_client) => test_client.current_time_secs(), + InnerClient::Mocked(test_client) => , + > as LedgerClient>::current_time_secs( + test_client + ), InnerClient::OgmiosScrolls(cml_client) => cml_client.current_time_secs(), } .await diff --git a/src/trireme_ledger_client/cml_client.rs b/src/trireme_ledger_client/cml_client.rs index f52c89c..545b263 100644 --- a/src/trireme_ledger_client/cml_client.rs +++ b/src/trireme_ledger_client/cml_client.rs @@ -184,6 +184,7 @@ impl ExecutionCost { #[async_trait] pub trait Ledger { + async fn last_block_time_secs(&self) -> Result; async fn get_utxos_for_addr(&self, addr: &CMLAddress, count: usize) -> Result>; async fn get_all_utxos_for_addr(&self, addr: &CMLAddress) -> Result>; async fn calculate_ex_units(&self, tx: &CMLTransaction) -> Result>; @@ -687,6 +688,13 @@ where Ok(network) } + async fn last_block_time_secs(&self) -> LedgerClientResult { + self.ledger + .last_block_time_secs() + .await + .map_err(as_failed_to_get_block_time) + } + async fn current_time_secs(&self) -> LedgerClientResult { let now = std::time::SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/src/trireme_ledger_client/cml_client/blockfrost_ledger.rs b/src/trireme_ledger_client/cml_client/blockfrost_ledger.rs index 49a01dc..ad6d469 100644 --- a/src/trireme_ledger_client/cml_client/blockfrost_ledger.rs +++ b/src/trireme_ledger_client/cml_client/blockfrost_ledger.rs @@ -99,6 +99,15 @@ pub fn cmlvalue_from_bfvalues(values: &[BFValue]) -> Result { #[async_trait] impl Ledger for BlockFrostLedger { + async fn last_block_time_secs(&self) -> Result { + let res = self + .client + .latest_block_info() + .await + .map_err(|e| CMLLCError::LedgerError(Box::new(e)))?; + Ok(res.time() as i64) + } + async fn get_utxos_for_addr(&self, addr: &CMLAddress, count: usize) -> Result> { let addr_string = addr .to_bech32(None) diff --git a/src/trireme_ledger_client/cml_client/error.rs b/src/trireme_ledger_client/cml_client/error.rs index ca74ff6..65a1f41 100644 --- a/src/trireme_ledger_client/cml_client/error.rs +++ b/src/trireme_ledger_client/cml_client/error.rs @@ -43,4 +43,10 @@ pub fn as_failed_to_issue_tx( LedgerClientError::FailedToIssueTx(Box::new(error)) } +pub fn as_failed_to_get_block_time( + error: E, +) -> LedgerClientError { + LedgerClientError::FailedToGetBlockTime(Box::new(error)) +} + pub type Result = std::result::Result; diff --git a/src/trireme_ledger_client/cml_client/ogmios_scrolls_ledger.rs b/src/trireme_ledger_client/cml_client/ogmios_scrolls_ledger.rs index 29d544f..d8b0829 100644 --- a/src/trireme_ledger_client/cml_client/ogmios_scrolls_ledger.rs +++ b/src/trireme_ledger_client/cml_client/ogmios_scrolls_ledger.rs @@ -100,6 +100,10 @@ impl OgmiosScrollsLedger { #[async_trait] impl Ledger for OgmiosScrollsLedger { + async fn last_block_time_secs(&self) -> Result { + todo!() + } + async fn get_utxos_for_addr(&self, addr: &CMLAddress, count: usize) -> Result> { let outputs = self .get_utxos(addr) diff --git a/trireme/src/environment.rs b/trireme/src/environment.rs index f954ce8..0263056 100644 --- a/trireme/src/environment.rs +++ b/trireme/src/environment.rs @@ -204,8 +204,8 @@ fn get_password_with_prompt(prompt: &str) -> Result { async fn setup_local_mocked_env(name: &str) -> Result<()> { let block_length: i64 = Input::new() - .with_prompt("What is the block length in ms?") - .default(1000) + .with_prompt("What is the block length in secs?") + .default(20) .interact_text()?; let alice_name = "Alice"; @@ -407,6 +407,13 @@ pub async fn current_time_impl() -> Result<()> { Ok(()) } +pub async fn last_block_time_impl() -> Result<()> { + let ledger_client: TriremeLedgerClient<(), ()> = get_trireme_ledger_client_from_file().await?; + let last_block_time = ledger_client.last_block_time_secs().await?; + println!("Last block time: {}", last_block_time); + Ok(()) +} + pub async fn advance_blocks(count: i64) -> Result<()> { let ledger_client: TriremeLedgerClient<(), ()> = get_trireme_ledger_client_from_file().await?; ledger_client.advance_blocks(count).await?; diff --git a/trireme/src/main.rs b/trireme/src/main.rs index 3423b72..2ddd49e 100644 --- a/trireme/src/main.rs +++ b/trireme/src/main.rs @@ -1,6 +1,6 @@ use crate::environment::{ active_signer_impl, advance_blocks, current_time_impl, get_address_impl, get_pubkey_hash_impl, - switch_signer_impl, + last_block_time_impl, switch_signer_impl, }; use crate::{ balance::{ada_balance_impl, balance_impl}, @@ -45,7 +45,9 @@ enum ActionParams { /// Switch to different signer 👽 (Mock Network Only) SwitchSigner, /// Get get time relative to your local environment 🕰 - CurrentTime, + Time, + /// Get the time of the last block in seconds + LastBlockTime, /// Advance time and block height by count 🧱 AdvanceBlocks { count: u16 }, } @@ -72,7 +74,8 @@ async fn main() -> Result<()> { ActionParams::PubKeyHash => get_pubkey_hash_impl().await?, ActionParams::Signer => active_signer_impl().await?, ActionParams::SwitchSigner => switch_signer_impl().await?, - ActionParams::CurrentTime => current_time_impl().await?, + ActionParams::Time => current_time_impl().await?, + ActionParams::LastBlockTime => last_block_time_impl().await?, ActionParams::AdvanceBlocks { count } => advance_blocks(count as i64).await?, } Ok(())