diff --git a/core/storage/src/relational/insert.rs b/core/storage/src/relational/insert.rs index e0b2ee43b..14eb5a378 100644 --- a/core/storage/src/relational/insert.rs +++ b/core/storage/src/relational/insert.rs @@ -1,6 +1,6 @@ use crate::relational::table::{ - BlockTable, BsonBytes, CanonicalChainTable, CellTable, LiveCellTable, RegisteredAddressTable, - ScriptTable, TransactionTable, + BlockTable, BsonBytes, CanonicalChainTable, CellTable, ConsumedInfo, LiveCellTable, + RegisteredAddressTable, ScriptTable, TransactionTable, }; use crate::relational::{generate_id, sql, to_bson_bytes, RelationalStorage}; @@ -43,6 +43,7 @@ impl RelationalStorage { let mut live_cell_set = Vec::new(); let mut tx_set = Vec::new(); let mut script_set = HashSet::new(); + let mut consumed_infos = Vec::new(); for (idx, transaction) in txs.iter().enumerate() { let index = idx as u32; @@ -64,6 +65,7 @@ impl RelationalStorage { &mut output_cell_set, &mut live_cell_set, &mut script_set, + &mut consumed_infos, ) .await?; @@ -87,6 +89,36 @@ impl RelationalStorage { tx.save_batch(&script_batch, &[]).await?; } + self.update_consumed_cells(consumed_infos, tx).await?; + + Ok(()) + } + + async fn update_consumed_cells( + &self, + infos: Vec<ConsumedInfo>, + tx: &mut RBatisTxExecutor<'_>, + ) -> Result<()> { + for info in infos.iter() { + let tx_hash = to_bson_bytes(&info.out_point.tx_hash().raw_data()); + let output_index: u32 = info.out_point.index().unpack(); + + self.remove_live_cell_by_out_point(&info.out_point, tx) + .await?; + sql::update_consume_cell( + tx, + info.consumed_block_number, + info.consumed_block_hash.clone(), + info.consumed_tx_hash.clone(), + info.consumed_tx_index, + info.input_index, + info.since.clone(), + tx_hash, + output_index, + ) + .await?; + } + Ok(()) } @@ -99,14 +131,21 @@ impl RelationalStorage { output_cell_set: &mut Vec<CellTable>, live_cell_set: &mut Vec<LiveCellTable>, script_set: &mut HashSet<ScriptTable>, + consumed_infos: &mut Vec<ConsumedInfo>, ) -> Result<()> { let block_hash = to_bson_bytes(&block_view.hash().raw_data()); let block_number = block_view.number(); let epoch = block_view.epoch(); if tx_index > 0 { - self.consume_input_cells(tx_view, block_number, block_hash.clone(), tx_index, tx) - .await?; + self.collect_consume_input_cells( + tx_view, + block_number, + block_hash.clone(), + tx_index, + consumed_infos, + ) + .await?; } self.insert_output_cells( @@ -195,36 +234,28 @@ impl RelationalStorage { Ok(()) } - async fn consume_input_cells( + async fn collect_consume_input_cells( &self, tx_view: &TransactionView, consumed_block_number: u64, consumed_block_hash: BsonBytes, tx_index: u32, - tx: &mut RBatisTxExecutor<'_>, + consumed_infos: &mut Vec<ConsumedInfo>, ) -> Result<()> { let consumed_tx_hash = to_bson_bytes(&tx_view.hash().raw_data()); for (idx, input) in tx_view.inputs().into_iter().enumerate() { - let out_point = input.previous_output(); let since: u64 = input.since().unpack(); - let since = to_bson_bytes(&since.to_be_bytes()); - let tx_hash = to_bson_bytes(&out_point.tx_hash().raw_data()); - let output_index: u32 = out_point.index().unpack(); - self.remove_live_cell_by_out_point(&out_point, tx).await?; - sql::update_consume_cell( - tx, + consumed_infos.push(ConsumedInfo { + out_point: input.previous_output(), + input_index: idx as u32, + consumed_block_hash: consumed_block_hash.clone(), consumed_block_number, - consumed_block_hash.clone(), - consumed_tx_hash.clone(), - tx_index, - idx as u32, - since, - tx_hash, - output_index, - ) - .await?; + consumed_tx_hash: consumed_tx_hash.clone(), + consumed_tx_index: tx_index, + since: to_bson_bytes(&since.to_be_bytes()), + }); } Ok(()) diff --git a/core/storage/src/relational/mod.rs b/core/storage/src/relational/mod.rs index 6cf98ac22..7188bbdce 100644 --- a/core/storage/src/relational/mod.rs +++ b/core/storage/src/relational/mod.rs @@ -64,7 +64,7 @@ impl Storage for RelationalStorage { let end_03 = minstant::now(); log::info!( "[storage] commit transaction cost {:?}", - ministant_elapsed(end_03, end_02) + ministant_elapsed(end_02, end_03) ); Ok(()) } diff --git a/core/storage/src/relational/table.rs b/core/storage/src/relational/table.rs index 2c7c7127f..f91274ce1 100644 --- a/core/storage/src/relational/table.rs +++ b/core/storage/src/relational/table.rs @@ -505,6 +505,16 @@ pub fn decode_since(input: &[u8]) -> u64 { u64::from_be_bytes(to_fixed_array::<8>(input)) } +pub(crate) struct ConsumedInfo { + pub(crate) out_point: packed::OutPoint, + pub(crate) consumed_block_number: u64, + pub(crate) consumed_block_hash: BsonBytes, + pub(crate) consumed_tx_hash: BsonBytes, + pub(crate) consumed_tx_index: u32, + pub(crate) input_index: u32, + pub(crate) since: BsonBytes, +} + #[cfg(test)] mod tests { use super::*;