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
129
130
use ckb_chain_spec::consensus::ProposalWindow;
use ckb_types::{
core::{BlockNumber, EpochNumber, EpochNumberWithFraction, HeaderView},
packed::Byte32,
};
#[derive(Debug, Clone, Copy)]
enum TxVerifyPhase {
Submitted,
Proposed(BlockNumber),
Committed,
}
#[derive(Debug, Clone)]
pub struct TxVerifyEnv {
phase: TxVerifyPhase,
number: BlockNumber,
epoch: EpochNumberWithFraction,
hash: Byte32,
parent_hash: Byte32,
}
impl TxVerifyEnv {
pub fn new_submit(header: &HeaderView) -> Self {
Self {
phase: TxVerifyPhase::Submitted,
number: header.number(),
epoch: header.epoch(),
hash: header.hash(),
parent_hash: header.parent_hash(),
}
}
pub fn new_proposed(header: &HeaderView, n_blocks: BlockNumber) -> Self {
Self {
phase: TxVerifyPhase::Proposed(n_blocks),
number: header.number(),
epoch: header.epoch(),
hash: header.hash(),
parent_hash: header.parent_hash(),
}
}
pub fn new_commit(header: &HeaderView) -> Self {
Self {
phase: TxVerifyPhase::Committed,
number: header.number(),
epoch: header.epoch(),
hash: header.hash(),
parent_hash: header.parent_hash(),
}
}
pub fn block_number(&self, proposal_window: ProposalWindow) -> BlockNumber {
match self.phase {
TxVerifyPhase::Submitted => self.number + 1 + proposal_window.closest(),
TxVerifyPhase::Proposed(already_proposed) => {
self.number.saturating_sub(already_proposed) + proposal_window.closest()
}
TxVerifyPhase::Committed => self.number,
}
}
pub fn epoch_number(&self, proposal_window: ProposalWindow) -> EpochNumber {
let n_blocks = match self.phase {
TxVerifyPhase::Submitted => 1 + proposal_window.closest(),
TxVerifyPhase::Proposed(already_proposed) => {
proposal_window.closest().saturating_sub(already_proposed)
}
TxVerifyPhase::Committed => 0,
};
self.epoch.minimum_epoch_number_after_n_blocks(n_blocks)
}
pub fn parent_hash(&self) -> Byte32 {
match self.phase {
TxVerifyPhase::Submitted => &self.hash,
TxVerifyPhase::Proposed(_) => &self.hash,
TxVerifyPhase::Committed => &self.parent_hash,
}
.to_owned()
}
pub fn epoch(&self) -> EpochNumberWithFraction {
self.epoch
}
pub fn epoch_number_without_proposal_window(&self) -> EpochNumber {
let n_blocks = match self.phase {
TxVerifyPhase::Submitted | TxVerifyPhase::Proposed(_) => 1,
TxVerifyPhase::Committed => 0,
};
self.epoch.minimum_epoch_number_after_n_blocks(n_blocks)
}
}