ckb_types/core/
transaction_meta.rs

1use crate::packed::Byte32;
2use bit_vec::BitVec;
3
4/// TODO(doc): @quake
5#[derive(Default, Debug, PartialEq, Eq, Clone)]
6pub struct TransactionMeta {
7    pub(crate) block_number: u64,
8    pub(crate) epoch_number: u64,
9    pub(crate) block_hash: Byte32,
10    pub(crate) cellbase: bool,
11    /// each bits indicate if transaction has dead cells
12    pub(crate) dead_cell: BitVec,
13}
14
15impl TransactionMeta {
16    /// TODO(doc): @quake
17    pub fn new(
18        block_number: u64,
19        epoch_number: u64,
20        block_hash: Byte32,
21        outputs_count: usize,
22        all_dead: bool,
23    ) -> TransactionMeta {
24        TransactionMeta {
25            block_number,
26            epoch_number,
27            block_hash,
28            cellbase: false,
29            dead_cell: BitVec::from_elem(outputs_count, all_dead),
30        }
31    }
32
33    /// New cellbase transaction
34    pub fn new_cellbase(
35        block_number: u64,
36        epoch_number: u64,
37        block_hash: Byte32,
38        outputs_count: usize,
39        all_dead: bool,
40    ) -> Self {
41        let mut result = Self::new(
42            block_number,
43            epoch_number,
44            block_hash,
45            outputs_count,
46            all_dead,
47        );
48        result.cellbase = true;
49        result
50    }
51
52    /// Returns true if it is a cellbase transaction
53    pub fn is_cellbase(&self) -> bool {
54        self.cellbase
55    }
56
57    /// Returns transaction outputs count
58    pub fn len(&self) -> usize {
59        self.dead_cell.len()
60    }
61
62    /// TODO(doc): @quake
63    pub fn block_number(&self) -> u64 {
64        self.block_number
65    }
66
67    /// TODO(doc): @quake
68    pub fn epoch_number(&self) -> u64 {
69        self.epoch_number
70    }
71
72    /// TODO(doc): @quake
73    pub fn block_hash(&self) -> Byte32 {
74        self.block_hash.clone()
75    }
76
77    /// TODO(doc): @quake
78    pub fn is_empty(&self) -> bool {
79        self.dead_cell.is_empty()
80    }
81
82    /// TODO(doc): @quake
83    pub fn is_dead(&self, index: usize) -> Option<bool> {
84        self.dead_cell.get(index)
85    }
86
87    /// TODO(doc): @quake
88    pub fn all_dead(&self) -> bool {
89        self.dead_cell.all()
90    }
91
92    /// TODO(doc): @quake
93    pub fn set_dead(&mut self, index: usize) {
94        if index < self.len() {
95            self.dead_cell.set(index, true);
96        }
97    }
98
99    /// TODO(doc): @quake
100    pub fn unset_dead(&mut self, index: usize) {
101        if index < self.len() {
102            self.dead_cell.set(index, false);
103        }
104    }
105}
106
107/// TODO(doc): @quake
108#[derive(Default)]
109pub struct TransactionMetaBuilder {
110    block_number: u64,
111    epoch_number: u64,
112    block_hash: Byte32,
113    cellbase: bool,
114    bits: Vec<u8>,
115    len: usize,
116}
117
118impl TransactionMetaBuilder {
119    /// TODO(doc): @quake
120    pub fn block_number(mut self, block_number: u64) -> Self {
121        self.block_number = block_number;
122        self
123    }
124
125    /// TODO(doc): @quake
126    pub fn epoch_number(mut self, epoch_number: u64) -> Self {
127        self.epoch_number = epoch_number;
128        self
129    }
130
131    /// TODO(doc): @quake
132    pub fn block_hash(mut self, block_hash: Byte32) -> Self {
133        self.block_hash = block_hash;
134        self
135    }
136
137    /// TODO(doc): @quake
138    pub fn cellbase(mut self, cellbase: bool) -> Self {
139        self.cellbase = cellbase;
140        self
141    }
142
143    /// TODO(doc): @quake
144    pub fn bits(mut self, bits: Vec<u8>) -> Self {
145        self.bits = bits;
146        self
147    }
148
149    /// TODO(doc): @quake
150    pub fn len(mut self, len: usize) -> Self {
151        self.len = len;
152        self
153    }
154
155    /// TODO(doc): @quake
156    pub fn build(self) -> TransactionMeta {
157        let TransactionMetaBuilder {
158            block_number,
159            epoch_number,
160            block_hash,
161            cellbase,
162            bits,
163            len,
164        } = self;
165        let mut dead_cell = BitVec::from_bytes(&bits);
166        dead_cell.truncate(len);
167        TransactionMeta {
168            block_number,
169            epoch_number,
170            block_hash,
171            cellbase,
172            dead_cell,
173        }
174    }
175}