1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use ckb_db::RocksDBWriteBatch;
use ckb_db_schema::{
Col, COLUMN_BLOCK_BODY, COLUMN_BLOCK_HEADER, COLUMN_BLOCK_PROPOSAL_IDS, COLUMN_BLOCK_UNCLE,
COLUMN_CELL, COLUMN_CELL_DATA, COLUMN_NUMBER_HASH,
};
use ckb_error::Error;
use ckb_types::{core::BlockNumber, packed, prelude::*};
pub struct StoreWriteBatch {
pub(crate) inner: RocksDBWriteBatch,
}
impl StoreWriteBatch {
pub fn put(&mut self, col: Col, key: &[u8], value: &[u8]) -> Result<(), Error> {
self.inner.put(col, key, value)
}
pub fn delete(&mut self, col: Col, key: &[u8]) -> Result<(), Error> {
self.inner.delete(col, key)
}
pub fn size_in_bytes(&self) -> usize {
self.inner.size_in_bytes()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn clear(&mut self) -> Result<(), Error> {
self.inner.clear()
}
pub fn insert_cells(
&mut self,
cells: impl Iterator<
Item = (
packed::OutPoint,
packed::CellEntry,
Option<packed::CellDataEntry>,
),
>,
) -> Result<(), Error> {
for (out_point, cell, cell_data) in cells {
let key = out_point.to_cell_key();
self.put(COLUMN_CELL, &key, cell.as_slice())?;
if let Some(data) = cell_data {
self.put(COLUMN_CELL_DATA, &key, data.as_slice())?;
} else {
self.put(COLUMN_CELL_DATA, &key, &[])?;
}
}
Ok(())
}
pub fn delete_cells(
&mut self,
out_points: impl Iterator<Item = packed::OutPoint>,
) -> Result<(), Error> {
for out_point in out_points {
let key = out_point.to_cell_key();
self.delete(COLUMN_CELL, &key)?;
self.delete(COLUMN_CELL_DATA, &key)?;
}
Ok(())
}
pub fn delete_block_body(
&mut self,
number: BlockNumber,
hash: &packed::Byte32,
txs_len: u32,
) -> Result<(), Error> {
self.inner.delete(COLUMN_BLOCK_UNCLE, hash.as_slice())?;
self.inner
.delete(COLUMN_BLOCK_PROPOSAL_IDS, hash.as_slice())?;
self.inner.delete(
COLUMN_NUMBER_HASH,
packed::NumberHash::new_builder()
.number(number.pack())
.block_hash(hash.clone())
.build()
.as_slice(),
)?;
let txs_start_key = packed::TransactionKey::new_builder()
.block_hash(hash.clone())
.index(0u32.pack())
.build();
let txs_end_key = packed::TransactionKey::new_builder()
.block_hash(hash.clone())
.index(txs_len.pack())
.build();
self.inner.delete_range(
COLUMN_BLOCK_BODY,
txs_start_key.as_slice(),
txs_end_key.as_slice(),
)?;
Ok(())
}
pub fn delete_block(
&mut self,
number: BlockNumber,
hash: &packed::Byte32,
txs_len: u32,
) -> Result<(), Error> {
self.inner.delete(COLUMN_BLOCK_HEADER, hash.as_slice())?;
self.delete_block_body(number, hash, txs_len)
}
}