Skip to content

Commit 83e8a4d

Browse files
Seulgi Kimmergify[bot]
authored andcommitted
Update the term id and the last block id when the term changes
1 parent cb2c15d commit 83e8a4d

File tree

7 files changed

+157
-13
lines changed

7 files changed

+157
-13
lines changed

core/src/codechain_machine.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,16 @@ impl CodeChainMachine {
250250
live.state_mut().add_balance(address, amount).map_err(StateError::from)?;
251251
Ok(())
252252
}
253+
254+
pub fn change_term_id(
255+
&self,
256+
live: &mut ExecutedBlock,
257+
last_term_finished_block_num: u64,
258+
current_term_id: u64,
259+
) -> Result<(), Error> {
260+
live.state_mut().change_term_id(last_term_finished_block_num, current_term_id)?;
261+
Ok(())
262+
}
253263
}
254264

255265
fn is_order_disabled() -> bool {

core/src/consensus/solo/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl ConsensusEngine for Solo<CodeChainMachine> {
8181
fn on_close_block(
8282
&self,
8383
block: &mut ExecutedBlock,
84-
_parent_header: &Header,
84+
parent_header: &Header,
8585
parent_common_params: &CommonParams,
8686
) -> Result<(), Error> {
8787
let author = *block.header().author();
@@ -102,6 +102,20 @@ impl ConsensusEngine for Solo<CodeChainMachine> {
102102
let stakeholders_share = stake::stakeholders_share(total_min_fee, &stakes);
103103
self.machine.add_balance(block, &author, total_reward - stakeholders_share)?;
104104

105+
let term_seconds = parent_common_params.term_seconds();
106+
if term_seconds == 0 {
107+
return Ok(())
108+
}
109+
let (last_term_finished_block_num, current_term_id) = {
110+
let header = block.header();
111+
let term_id = header.timestamp() / term_seconds;
112+
let parent_term_id = parent_header.timestamp() / term_seconds;
113+
if term_id == parent_term_id {
114+
return Ok(())
115+
}
116+
(header.number(), term_id)
117+
};
118+
self.machine.change_term_id(block, last_term_finished_block_num, current_term_id)?;
105119
Ok(())
106120
}
107121

core/src/consensus/tendermint/engine.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl ConsensusEngine for Tendermint {
131131
fn on_close_block(
132132
&self,
133133
block: &mut ExecutedBlock,
134-
_parent_header: &Header,
134+
parent_header: &Header,
135135
parent_common_params: &CommonParams,
136136
) -> Result<(), Error> {
137137
let author = *block.header().author();
@@ -152,6 +152,20 @@ impl ConsensusEngine for Tendermint {
152152
let stakeholders_share = stake::stakeholders_share(total_min_fee, &stakes);
153153
self.machine.add_balance(block, &author, total_reward - stakeholders_share)?;
154154

155+
let term_seconds = parent_common_params.term_seconds();
156+
if term_seconds == 0 {
157+
return Ok(())
158+
}
159+
let (last_term_finished_block_num, current_term_id) = {
160+
let header = block.header();
161+
let term_id = header.timestamp() / term_seconds;
162+
let parent_term_id = parent_header.timestamp() / term_seconds;
163+
if term_id == parent_term_id {
164+
return Ok(())
165+
}
166+
(header.number(), term_id)
167+
};
168+
self.machine.change_term_id(block, last_term_finished_block_num, current_term_id)?;
155169
Ok(())
156170
}
157171

spec/Dynamic-Validator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ candidates = [ [address, deposits, nominate_end_at]+ ], address asc
222222
pending_rewards = [ [withdraw_at, address, quantity]+ ], [withdraw_at, address] asc
223223
banned = [ address+ ], address asc
224224
jailed = [ [address, deposits, custody_until, kicked_at]+ ], address asc
225-
term_id = [ block number, term id ]
225+
term_id = [ the last block number of the previous term, the current term id ]
226226
```
227227

228228
### on TermEnd events

state/src/impls/top_level.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,12 @@ impl TopState for TopLevelState {
974974
Ok(())
975975
}
976976

977+
fn change_term_id(&mut self, last_term_finished_block_num: u64, current_term_id: u64) -> StateResult<()> {
978+
let mut metadata = self.get_metadata_mut()?;
979+
metadata.change_term(last_term_finished_block_num, current_term_id);
980+
Ok(())
981+
}
982+
977983
fn update_action_data(&mut self, key: &H256, data: Bytes) -> StateResult<()> {
978984
let mut action_data = self.get_action_data_mut(key)?;
979985
*action_data = data.into();

state/src/item/metadata.rs

Lines changed: 108 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,18 @@ use ctypes::{CommonParams, ShardId};
2121

2222
use crate::CacheableItem;
2323

24+
#[derive(Clone, Debug, Default, PartialEq)]
25+
struct TermMetadata {
26+
last_term_finished_block_num: u64,
27+
current_term_id: u64,
28+
}
29+
2430
#[derive(Clone, Debug, PartialEq)]
2531
pub struct Metadata {
2632
number_of_shards: ShardId,
2733
number_of_initial_shards: ShardId,
2834
hashes: Vec<H256>,
35+
term: TermMetadata,
2936
seq: usize,
3037
params: Option<CommonParams>,
3138
}
@@ -36,6 +43,7 @@ impl Metadata {
3643
number_of_shards,
3744
number_of_initial_shards: number_of_shards,
3845
hashes: vec![],
46+
term: Default::default(),
3947
seq: 0,
4048
params: None,
4149
}
@@ -73,6 +81,13 @@ impl Metadata {
7381
pub fn params(&self) -> Option<&CommonParams> {
7482
self.params.as_ref()
7583
}
84+
85+
pub fn change_term(&mut self, last_term_finished_block_num: u64, current_term_id: u64) {
86+
assert!(self.term.last_term_finished_block_num < last_term_finished_block_num);
87+
assert!(self.term.current_term_id < current_term_id);
88+
self.term.last_term_finished_block_num = last_term_finished_block_num;
89+
self.term.current_term_id = current_term_id;
90+
}
7691
}
7792

7893
impl Default for Metadata {
@@ -93,28 +108,62 @@ const PREFIX: u8 = super::METADATA_PREFIX;
93108

94109
impl Encodable for Metadata {
95110
fn rlp_append(&self, s: &mut RlpStream) {
111+
const INITIAL_LEN: usize = 4;
112+
const TERM_LEN: usize = 2;
113+
const PARAMS_LEN: usize = 2;
114+
let mut len = INITIAL_LEN;
115+
116+
let term_changed = self.term != Default::default();
117+
if term_changed {
118+
len += TERM_LEN;
119+
}
120+
96121
let params_changed = self.seq != 0;
97122
if params_changed {
98-
s.begin_list(6);
99-
} else {
100-
s.begin_list(4);
123+
if !term_changed {
124+
len += TERM_LEN;
125+
}
126+
len += PARAMS_LEN;
101127
}
102-
s.append(&PREFIX)
128+
s.begin_list(len)
129+
.append(&PREFIX)
103130
.append(&self.number_of_shards)
104131
.append(&self.number_of_initial_shards)
105132
.append_list(&self.hashes);
133+
if term_changed {
134+
s.append(&self.term.last_term_finished_block_num).append(&self.term.current_term_id);
135+
}
106136
if params_changed {
107-
s.append(&self.seq);
108-
s.append(self.params.as_ref().unwrap());
137+
if !term_changed {
138+
const DEFAULT_LAST_TERM_FINISHED_BLOCK_NUM: u64 = 0;
139+
const DEFAULT_CURRENT_TERM_ID: u64 = 0;
140+
s.append(&DEFAULT_LAST_TERM_FINISHED_BLOCK_NUM).append(&DEFAULT_CURRENT_TERM_ID);
141+
}
142+
s.append(&self.seq).append(self.params.as_ref().unwrap());
109143
}
110144
}
111145
}
112146

113147
impl Decodable for Metadata {
114148
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
115-
let (seq, params) = match rlp.item_count()? {
116-
4 => (0, None),
117-
6 => (rlp.val_at(4)?, Some(rlp.val_at(5)?)),
149+
let (term, seq, params) = match rlp.item_count()? {
150+
4 => (TermMetadata::default(), 0, None),
151+
6 => (
152+
TermMetadata {
153+
last_term_finished_block_num: rlp.val_at(4)?,
154+
current_term_id: rlp.val_at(5)?,
155+
},
156+
0,
157+
None,
158+
),
159+
8 => (
160+
TermMetadata {
161+
last_term_finished_block_num: rlp.val_at(4)?,
162+
current_term_id: rlp.val_at(5)?,
163+
},
164+
rlp.val_at(6)?,
165+
Some(rlp.val_at(7)?),
166+
),
118167
item_count => {
119168
return Err(DecoderError::RlpInvalidLength {
120169
got: item_count,
@@ -131,6 +180,7 @@ impl Decodable for Metadata {
131180
number_of_shards: rlp.val_at(1)?,
132181
number_of_initial_shards: rlp.val_at(2)?,
133182
hashes: rlp.list_at(3)?,
183+
term,
134184
seq,
135185
params,
136186
})
@@ -190,11 +240,59 @@ mod tests {
190240
}
191241

192242
#[test]
193-
fn metadata_with_seq() {
243+
fn check_backward_compatibility() {
244+
let metadata = Metadata {
245+
number_of_shards: 10,
246+
number_of_initial_shards: 1,
247+
hashes: vec![],
248+
term: Default::default(),
249+
seq: 0,
250+
params: None,
251+
};
252+
let mut rlp = RlpStream::new_list(4);
253+
rlp.append(&PREFIX).append(&10u16).append(&1u16).append_list::<H256, H256>(&[]);
254+
assert_eq!(metadata.rlp_bytes(), rlp.drain());
255+
}
256+
257+
#[test]
258+
fn metadata_without_term_with_seq() {
259+
let metadata = Metadata {
260+
number_of_shards: 10,
261+
number_of_initial_shards: 1,
262+
hashes: vec![],
263+
term: Default::default(),
264+
seq: 3,
265+
params: Some(CommonParams::default_for_test()),
266+
};
267+
rlp_encode_and_decode_test!(metadata);
268+
}
269+
270+
#[test]
271+
fn metadata_with_term_without_seq() {
272+
let metadata = Metadata {
273+
number_of_shards: 10,
274+
number_of_initial_shards: 1,
275+
hashes: vec![],
276+
term: TermMetadata {
277+
last_term_finished_block_num: 1,
278+
current_term_id: 100,
279+
},
280+
seq: 0,
281+
params: None,
282+
};
283+
rlp_encode_and_decode_test!(metadata);
284+
}
285+
286+
#[test]
287+
fn metadata_with_term_and_seq() {
194288
let metadata = Metadata {
195289
number_of_shards: 10,
196290
number_of_initial_shards: 1,
197291
hashes: vec![],
292+
term: TermMetadata {
293+
last_term_finished_block_num: 1,
294+
current_term_id: 100,
295+
},
198296
seq: 3,
199297
params: Some(CommonParams::default_for_test()),
200298
};

state/src/traits.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ pub trait TopState {
177177
fn store_text(&mut self, key: &H256, text: Text, sig: &Signature) -> StateResult<()>;
178178
fn remove_text(&mut self, key: &H256, sig: &Signature) -> StateResult<()>;
179179

180+
fn change_term_id(&mut self, last_term_finished_block_num: u64, current_term_id: u64) -> StateResult<()>;
181+
180182
fn update_action_data(&mut self, key: &H256, data: Bytes) -> StateResult<()>;
181183
fn remove_action_data(&mut self, key: &H256);
182184
}

0 commit comments

Comments
 (0)