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
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
}
}