diff --git a/bin/tendermintx.rs b/bin/tendermintx.rs index 2e955e3..4bbd315 100644 --- a/bin/tendermintx.rs +++ b/bin/tendermintx.rs @@ -113,6 +113,27 @@ impl TendermintXOperator { Ok(request_id) } + async fn request_step_2(&self, trusted_hash: [u8; 32], trusted_block: u64) -> Result { + let trusted_header_hash = trusted_hash; + + let input = StepInputTuple::abi_encode_packed(&(trusted_block, trusted_header_hash)); + + let step_call = StepCall { trusted_block }; + let function_data = step_call.encode(); + + let request_id = self + .client + .submit_platform_request( + self.config.chain_id, + self.config.address, + function_data.into(), + self.config.step_function_id, + Bytes::copy_from_slice(&input), + ) + .await?; + Ok(request_id) + } + async fn request_skip(&self, trusted_block: u64, target_block: u64) -> Result { let trusted_header_hash = self .contract @@ -142,6 +163,36 @@ impl TendermintXOperator { Ok(request_id) } + async fn request_skip_2( + &self, + trusted_hash: [u8; 32], + trusted_block: u64, + target_block: u64, + ) -> Result { + let trusted_header_hash = trusted_hash; + + let input = + SkipInputTuple::abi_encode_packed(&(trusted_block, trusted_header_hash, target_block)); + + let skip_call = SkipCall { + trusted_block, + target_block, + }; + let function_data = skip_call.encode(); + + let request_id = self + .client + .submit_platform_request( + self.config.chain_id, + self.config.address, + function_data.into(), + self.config.skip_function_id, + Bytes::copy_from_slice(&input), + ) + .await?; + Ok(request_id) + } + async fn is_consistent(&mut self, current_block: u64) { let expected_current_signed_header = self .data_fetcher @@ -193,6 +244,8 @@ impl TendermintXOperator { .data_fetcher .find_block_to_request(current_block, max_end_block) .await; + println!("Current block: {}", current_block); + println!("Target block: {}", target_block); if target_block - current_block == 1 { // Request the step if the target block is the next block. @@ -221,14 +274,116 @@ impl TendermintXOperator { tokio::time::sleep(tokio::time::Duration::from_secs(60 * LOOP_DELAY)).await; } } + + async fn create_proof( + &mut self, + trusted_hash: [u8; 32], + current_block_input: u64, + target_block_input: u64, + ) { + if current_block_input >= target_block_input { + error!("Invalid block input"); + error!("Current block: {}", current_block_input); + error!("Target block: {}", target_block_input); + error!("trusted_hash: {:?}", trusted_hash); + return; + } + // The upper limit of the largest skip that can be requested. This is bounded by the unbonding + // period, which for most Tendermint chains is ~2 weeks, or ~100K blocks with a block time + // of 12s. + // let skip_max = self.contract.skip_max().await.unwrap(); + // let current_block = self.contract.latest_block().await.unwrap(); + let current_block = current_block_input; + + // Consistency check for the headers (this should only happen if an invalid header, + // typically the genesis header, is pushed to the contract). If this is triggered, + // double check the genesis header in the contract. + // self.is_consistent(current_block).await; + + // Get the head of the chain. + // let latest_signed_header = self.data_fetcher.get_latest_signed_header().await; + // let latest_block = latest_signed_header.header.height.value(); + + // Get the maximum block height we can request. + // let max_end_block = std::cmp::min(latest_block, current_block + skip_max); + + // let target_block = self + // .data_fetcher + // .find_block_to_request(current_block, max_end_block) + // .await; + + let target_block = target_block_input; + + println!("Current block: {}", current_block); + println!("Target block: {}", target_block); + + // let target_block = target_block_input; + println!("New target block: {}", target_block); + + // info!("request____start:{}request____end", "123123123"); + // return; + + if target_block - current_block == 1 { + // Request the step if the target block is the next block. + match self.request_step_2(trusted_hash, current_block).await { + Ok(request_id) => { + info!("request____start{}request____end", request_id); + info!("Step request submitted: {}", request_id) + } + Err(e) => { + error!("Step request failed: {}", e); + return; + } + }; + } else { + // Request a skip if the target block is not the next block. + match self + .request_skip_2(trusted_hash, current_block, target_block) + .await + { + Ok(request_id) => { + info!("request____start{}request____end", request_id); + info!("Skip request submitted: {}", request_id) + } + Err(e) => { + error!("Skip request failed: {}", e); + return; + } + }; + } + } } +// #[tokio::main] +// async fn main() { +// env::set_var("RUST_LOG", "info"); +// dotenv::dotenv().ok(); +// env_logger::init(); + +// let mut operator = TendermintXOperator::new(); +// operator.run().await; +// } + #[tokio::main] async fn main() { + /* + cargo run --package tendermintx --bin tendermintx --release 123456 654321 + */ + let arg = std::env::args().nth(3).expect("Expected a third argument"); + let args: Vec = std::env::args().collect(); + let trusted = args[1].parse::().unwrap(); + let height = args[2].parse::().unwrap(); + let bytes = hex::decode(arg).expect("Invalid hex string"); + let mut array: [u8; 32] = [0; 32]; + array.copy_from_slice(&bytes); + + println!("Trusted block: {:?}", bytes); + + println!("Proof height: {}", height); env::set_var("RUST_LOG", "info"); dotenv::dotenv().ok(); env_logger::init(); let mut operator = TendermintXOperator::new(); - operator.run().await; + operator.create_proof(array, trusted, height).await; }