diff --git a/Cargo.toml b/Cargo.toml index 63b12a13..a08a0c01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,3 +45,4 @@ test = [] [dev-dependencies] clap = { version = "3.1.9", features = ["derive"] } +httpmock = "0.6" \ No newline at end of file diff --git a/src/test_util.rs b/src/test_util.rs index 0dafb307..16bdc28a 100644 --- a/src/test_util.rs +++ b/src/test_util.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryFrom; +use ckb_jsonrpc_types::Serialize; use rand::{thread_rng, Rng}; use thiserror::Error; @@ -474,7 +475,7 @@ impl CellCollector for LiveCellsContext { block_number, tx_index: 0, }; - if query.match_cell(&live_cell, None) { + if query.match_cell(&live_cell, 0) { total_capacity += capacity; cells.push(live_cell); if apply_changes { @@ -524,3 +525,24 @@ pub fn random_out_point() -> OutPoint { }; OutPoint::new(tx_hash, 0) } + +#[derive(serde::Serialize)] +pub struct MockRpcResult { + id: u64, + jsonrpc: String, + result: T, +} + +impl MockRpcResult { + pub fn new(result: T) -> Self { + Self { + id: 42, + jsonrpc: "2.0".to_string(), + result, + } + } + + pub fn to_json(&self) -> String { + serde_json::to_string(&self).unwrap() + } +} diff --git a/src/traits/default_impls.rs b/src/traits/default_impls.rs index 7c5ff114..ed5505f3 100644 --- a/src/traits/default_impls.rs +++ b/src/traits/default_impls.rs @@ -313,7 +313,7 @@ impl CellCollector for DefaultCellCollector { let max_mature_number = get_max_mature_number(&mut self.ckb_client) .map_err(|err| CellCollectorError::Internal(err.into()))?; - self.offchain.max_mature_number = Some(max_mature_number); + self.offchain.max_mature_number = max_mature_number; let (mut cells, rest_cells, mut total_capacity) = self.offchain.collect(query); if total_capacity < query.min_total_capacity { @@ -337,7 +337,7 @@ impl CellCollector for DefaultCellCollector { } for cell in page.objects { let live_cell = LiveCell::from(cell); - if !query.match_cell(&live_cell, Some(max_mature_number)) + if !query.match_cell(&live_cell, max_mature_number) || locked_cells.contains(&( live_cell.out_point.tx_hash().unpack(), live_cell.out_point.index().unpack(), diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 781e7f21..47ba30a2 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -261,7 +261,7 @@ impl CellQueryOptions { pub fn new_type(primary_script: Script) -> CellQueryOptions { CellQueryOptions::new(primary_script, PrimaryScriptType::Type) } - pub fn match_cell(&self, cell: &LiveCell, max_mature_number: Option) -> bool { + pub fn match_cell(&self, cell: &LiveCell, max_mature_number: u64) -> bool { fn extract_raw_data(script: &Script) -> Vec { [ script.code_hash().as_slice(), @@ -334,18 +334,12 @@ impl CellQueryOptions { return false; } } - if let Some(max_mature_number) = max_mature_number { - let cell_is_mature = is_mature(cell, max_mature_number); - match self.maturity { - MaturityOption::Mature if cell_is_mature => {} - MaturityOption::Immature if !cell_is_mature => {} - MaturityOption::Both => {} - // Skip this live cell - _ => return false, - } + let cell_is_mature = is_mature(cell, max_mature_number); + match self.maturity { + MaturityOption::Mature => cell_is_mature, + MaturityOption::Immature => !cell_is_mature, + MaturityOption::Both => true, } - - true } } pub trait CellCollector { diff --git a/src/traits/offchain_impls.rs b/src/traits/offchain_impls.rs index e6ac5487..9313fc9a 100644 --- a/src/traits/offchain_impls.rs +++ b/src/traits/offchain_impls.rs @@ -57,14 +57,14 @@ impl HeaderDepResolver for OffchainHeaderDepResolver { pub struct OffchainCellCollector { pub locked_cells: HashSet<(H256, u32)>, pub live_cells: Vec, - pub max_mature_number: Option, + pub max_mature_number: u64, } impl OffchainCellCollector { pub fn new( locked_cells: HashSet<(H256, u32)>, live_cells: Vec, - max_mature_number: Option, + max_mature_number: u64, ) -> OffchainCellCollector { OffchainCellCollector { locked_cells, diff --git a/src/util.rs b/src/util.rs index 51da16a9..0054bb76 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,4 @@ -use std::{ptr, sync::atomic}; +use std::{convert::TryInto, ptr, sync::atomic}; use ckb_dao_utils::extract_dao_data; use ckb_types::{ @@ -26,28 +26,6 @@ pub fn zeroize_slice(data: &mut [u8]) { } } -// Calculate max mature block number -pub fn calc_max_mature_number( - tip_epoch: EpochNumberWithFraction, - max_mature_epoch: Option<(u64, u64)>, - cellbase_maturity: EpochNumberWithFraction, -) -> u64 { - if tip_epoch.to_rational() < cellbase_maturity.to_rational() { - 0 - } else if let Some((start_number, length)) = max_mature_epoch { - let epoch_delta = tip_epoch.to_rational() - cellbase_maturity.to_rational(); - let index_bytes: [u8; 32] = ((epoch_delta.clone() - epoch_delta.into_u256()) - * U256::from(length)) - .into_u256() - .to_le_bytes(); - let mut index_bytes_u64 = [0u8; 8]; - index_bytes_u64.copy_from_slice(&index_bytes[0..8]); - u64::from_le_bytes(index_bytes_u64) + start_number - } else { - 0 - } -} - pub fn get_max_mature_number(rpc_client: &mut CkbRpcClient) -> Result { let cellbase_maturity = EpochNumberWithFraction::from_full_value( rpc_client @@ -60,21 +38,38 @@ pub fn get_max_mature_number(rpc_client: &mut CkbRpcClient) -> Result