Skip to content

Commit 148f1d0

Browse files
committed
Merge branch 'feature/term_common_params' into feature/era-test
2 parents f83de3d + 60a235b commit 148f1d0

File tree

9 files changed

+135
-63
lines changed

9 files changed

+135
-63
lines changed

core/src/block.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::client::{EngineInfo, TermInfo};
3333
use crate::consensus::CodeChainEngine;
3434
use crate::error::{BlockError, Error};
3535
use crate::transaction::{SignedTransaction, UnverifiedTransaction};
36+
use crate::BlockId;
3637

3738
/// A block, encoded as it is on the block chain.
3839
#[derive(Debug, Clone, PartialEq)]
@@ -504,16 +505,7 @@ pub fn enact<C: ChainTimeInfo + EngineInfo + FindActionHandler + TermInfo>(
504505
b.push_transactions(transactions, client, parent.number(), parent.timestamp())?;
505506

506507
let parent_common_params = client.common_params((*header.parent_hash()).into()).unwrap();
507-
let term_common_params = {
508-
let block_number = client
509-
.last_term_finished_block_num((*header.parent_hash()).into())
510-
.expect("The block of the parent hash should exist");
511-
if block_number == 0 {
512-
None
513-
} else {
514-
Some(client.common_params((block_number).into()).expect("Common params should exist"))
515-
}
516-
};
508+
let term_common_params = client.term_common_params(BlockId::Hash(*header.parent_hash()));
517509
b.close_and_lock(parent, &parent_common_params, term_common_params.as_ref())
518510
}
519511

core/src/client/client.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,23 @@ impl TermInfo for Client {
826826
.map(|state| state.metadata().unwrap().expect("Metadata always exist"))
827827
.map(|metadata| metadata.current_term_id())
828828
}
829+
830+
fn term_common_params(&self, id: BlockId) -> Option<CommonParams> {
831+
let state = self.state_at(id)?;
832+
let metadata = state.metadata().unwrap().expect("Metadata always exist");
833+
834+
if let Some(term_params) = metadata.term_params() {
835+
Some(*term_params)
836+
} else {
837+
let block_number =
838+
self.last_term_finished_block_num(id).expect("The block of the parent hash should exist");
839+
if block_number == 0 {
840+
None
841+
} else {
842+
Some(self.common_params((block_number).into()).expect("Common params should exist"))
843+
}
844+
}
845+
}
829846
}
830847

831848
impl AccountData for Client {

core/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ pub trait ConsensusClient: BlockChainClient + EngineClient + EngineInfo + TermIn
119119
pub trait TermInfo {
120120
fn last_term_finished_block_num(&self, id: BlockId) -> Option<BlockNumber>;
121121
fn current_term_id(&self, id: BlockId) -> Option<u64>;
122+
fn term_common_params(&self, id: BlockId) -> Option<CommonParams>;
122123
}
123124

124125
/// Provides methods to access account info

core/src/client/test_client.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ impl TermInfo for TestBlockChainClient {
679679
fn current_term_id(&self, _id: BlockId) -> Option<u64> {
680680
self.term_id
681681
}
682+
683+
fn term_common_params(&self, _id: BlockId) -> Option<CommonParams> {
684+
None
685+
}
682686
}
683687

684688
impl StateInfo for TestBlockChainClient {

core/src/consensus/tendermint/engine.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use std::sync::{Arc, Weak};
2424
use ckey::{public_to_address, Address};
2525
use cnetwork::NetworkService;
2626
use crossbeam_channel as crossbeam;
27-
use cstate::{ActionHandler, TopStateView};
27+
use cstate::{ActionHandler, TopState, TopStateView};
2828
use ctypes::{BlockHash, CommonParams, Header};
2929
use num_rational::Ratio;
3030

@@ -238,6 +238,14 @@ impl ConsensusEngine for Tendermint {
238238

239239
stake::on_term_close(block.state_mut(), block_number, &inactive_validators)?;
240240

241+
match term {
242+
0 => {}
243+
_ => match term_common_params.expect("Term common params should exist").era() {
244+
0 => {}
245+
1 => block.state_mut().snapshot_term_params()?,
246+
_ => unimplemented!("It is not decided how we handle this"),
247+
},
248+
}
241249
Ok(())
242250
}
243251

core/src/miner/miner.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -604,16 +604,7 @@ impl Miner {
604604
(parent_header.decode(), parent_hash)
605605
};
606606
let parent_common_params = chain.common_params(parent_hash.into()).unwrap();
607-
let term_common_params = {
608-
let block_number = chain
609-
.last_term_finished_block_num(parent_hash.into())
610-
.expect("The block of the parent hash should exist");
611-
if block_number == 0 {
612-
None
613-
} else {
614-
Some(chain.common_params((block_number).into()).expect("Common params should exist"))
615-
}
616-
};
607+
let term_common_params = chain.term_common_params(parent_hash.into());
617608
let block = open_block.close(&parent_header, &parent_common_params, term_common_params.as_ref())?;
618609

619610
let fetch_seq = |p: &Public| {

state/src/impls/top_level.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,12 @@ impl TopState for TopLevelState {
999999
metadata.increase_seq();
10001000
Ok(())
10011001
}
1002+
1003+
fn snapshot_term_params(&mut self) -> StateResult<()> {
1004+
let mut metadata = self.get_metadata_mut()?;
1005+
metadata.snapshot_term_params();
1006+
Ok(())
1007+
}
10021008
}
10031009

10041010
fn is_active_account(state: &dyn TopStateView, address: &Address) -> TrieResult<bool> {

state/src/item/metadata.rs

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct Metadata {
3434
term: TermMetadata,
3535
seq: u64,
3636
params: Option<CommonParams>,
37+
term_params: Option<CommonParams>,
3738
}
3839

3940
impl Metadata {
@@ -45,6 +46,7 @@ impl Metadata {
4546
term: Default::default(),
4647
seq: 0,
4748
params: None,
49+
term_params: None,
4850
}
4951
}
5052

@@ -93,6 +95,14 @@ impl Metadata {
9395
self.params = Some(params);
9496
}
9597

98+
pub fn term_params(&self) -> Option<&CommonParams> {
99+
self.term_params.as_ref()
100+
}
101+
102+
pub fn snapshot_term_params(&mut self) {
103+
self.term_params = self.params;
104+
}
105+
96106
pub fn increase_term_id(&mut self, last_term_finished_block_num: u64) {
97107
assert!(self.term.last_term_finished_block_num < last_term_finished_block_num);
98108
self.term.last_term_finished_block_num = last_term_finished_block_num;
@@ -124,25 +134,31 @@ impl CacheableItem for Metadata {
124134

125135
const PREFIX: u8 = super::METADATA_PREFIX;
126136

137+
const INITIAL_LEN: usize = 4;
138+
const TERM_LEN: usize = INITIAL_LEN + 2;
139+
const PARAMS_LEN: usize = TERM_LEN + 2;
140+
const TERM_PARAMS_LEN: usize = PARAMS_LEN + 1;
141+
const VALID_LEN: &[usize] = &[INITIAL_LEN, TERM_LEN, PARAMS_LEN, TERM_PARAMS_LEN];
142+
127143
impl Encodable for Metadata {
128144
fn rlp_append(&self, s: &mut RlpStream) {
129-
const INITIAL_LEN: usize = 4;
130-
const TERM_LEN: usize = 2;
131-
const PARAMS_LEN: usize = 2;
132-
let mut len = INITIAL_LEN;
133-
134145
let term_changed = self.term != Default::default();
135-
if term_changed {
136-
len += TERM_LEN;
137-
}
138-
139146
let params_changed = self.seq != 0;
140-
if params_changed {
141-
if !term_changed {
142-
len += TERM_LEN;
147+
let term_params_exist = self.term_params.is_some();
148+
149+
let len = if term_params_exist {
150+
if !params_changed {
151+
panic!("Term params only can be changed if params changed");
143152
}
144-
len += PARAMS_LEN;
145-
}
153+
TERM_PARAMS_LEN
154+
} else if params_changed {
155+
PARAMS_LEN
156+
} else if term_changed {
157+
TERM_LEN
158+
} else {
159+
INITIAL_LEN
160+
};
161+
146162
s.begin_list(len)
147163
.append(&PREFIX)
148164
.append(&self.number_of_shards)
@@ -159,48 +175,63 @@ impl Encodable for Metadata {
159175
}
160176
s.append(&self.seq).append(self.params.as_ref().unwrap());
161177
}
178+
if term_params_exist {
179+
if !params_changed {
180+
unreachable!("Term params only can be changed if params changed");
181+
}
182+
s.append(self.term_params.as_ref().unwrap());
183+
}
162184
}
163185
}
164186

165187
impl Decodable for Metadata {
166188
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
167-
let (term, seq, params) = match rlp.item_count()? {
168-
4 => (TermMetadata::default(), 0, None),
169-
6 => (
170-
TermMetadata {
171-
last_term_finished_block_num: rlp.val_at(4)?,
172-
current_term_id: rlp.val_at(5)?,
173-
},
174-
0,
175-
None,
176-
),
177-
8 => (
178-
TermMetadata {
179-
last_term_finished_block_num: rlp.val_at(4)?,
180-
current_term_id: rlp.val_at(5)?,
181-
},
182-
rlp.val_at(6)?,
183-
Some(rlp.val_at(7)?),
184-
),
185-
item_count => {
186-
return Err(DecoderError::RlpInvalidLength {
187-
got: item_count,
188-
expected: 4,
189-
})
190-
}
191-
};
189+
let item_count = rlp.item_count()?;
190+
if !VALID_LEN.contains(&item_count) {
191+
return Err(DecoderError::RlpInvalidLength {
192+
got: item_count,
193+
expected: 4,
194+
})
195+
}
196+
192197
let prefix = rlp.val_at::<u8>(0)?;
193198
if PREFIX != prefix {
194199
cdebug!(STATE, "{} is not an expected prefix for asset", prefix);
195200
return Err(DecoderError::Custom("Unexpected prefix"))
196201
}
202+
let number_of_shards = rlp.val_at(1)?;
203+
let number_of_initial_shards = rlp.val_at(2)?;
204+
let hashes = rlp.list_at(3)?;
205+
206+
let term = if item_count >= TERM_LEN {
207+
TermMetadata {
208+
last_term_finished_block_num: rlp.val_at(4)?,
209+
current_term_id: rlp.val_at(5)?,
210+
}
211+
} else {
212+
TermMetadata::default()
213+
};
214+
215+
let (seq, params) = if item_count >= PARAMS_LEN {
216+
(rlp.val_at(6)?, Some(rlp.val_at(7)?))
217+
} else {
218+
Default::default()
219+
};
220+
221+
let term_params = if item_count >= TERM_PARAMS_LEN {
222+
Some(rlp.val_at(8)?)
223+
} else {
224+
Default::default()
225+
};
226+
197227
Ok(Self {
198-
number_of_shards: rlp.val_at(1)?,
199-
number_of_initial_shards: rlp.val_at(2)?,
200-
hashes: rlp.list_at(3)?,
228+
number_of_shards,
229+
number_of_initial_shards,
230+
hashes,
201231
term,
202232
seq,
203233
params,
234+
term_params,
204235
})
205236
}
206237
}
@@ -266,6 +297,7 @@ mod tests {
266297
term: Default::default(),
267298
seq: 0,
268299
params: None,
300+
term_params: None,
269301
};
270302
let mut rlp = RlpStream::new_list(4);
271303
rlp.append(&PREFIX).append(&10u16).append(&1u16).append_list::<H256, H256>(&[]);
@@ -281,6 +313,7 @@ mod tests {
281313
term: Default::default(),
282314
seq: 3,
283315
params: Some(CommonParams::default_for_test()),
316+
term_params: Some(CommonParams::default_for_test()),
284317
};
285318
rlp_encode_and_decode_test!(metadata);
286319
}
@@ -297,6 +330,7 @@ mod tests {
297330
},
298331
seq: 0,
299332
params: None,
333+
term_params: None,
300334
};
301335
rlp_encode_and_decode_test!(metadata);
302336
}
@@ -313,6 +347,24 @@ mod tests {
313347
},
314348
seq: 3,
315349
params: Some(CommonParams::default_for_test()),
350+
term_params: Some(CommonParams::default_for_test()),
351+
};
352+
rlp_encode_and_decode_test!(metadata);
353+
}
354+
355+
#[test]
356+
fn metadata_with_term_and_seq_but_not_term_params() {
357+
let metadata = Metadata {
358+
number_of_shards: 10,
359+
number_of_initial_shards: 1,
360+
hashes: vec![],
361+
term: TermMetadata {
362+
last_term_finished_block_num: 1,
363+
current_term_id: 100,
364+
},
365+
seq: 3,
366+
params: Some(CommonParams::default_for_test()),
367+
term_params: None,
316368
};
317369
rlp_encode_and_decode_test!(metadata);
318370
}

state/src/traits.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ pub trait TopState {
183183
fn remove_action_data(&mut self, key: &H256);
184184

185185
fn update_params(&mut self, metadata_seq: u64, params: CommonParams) -> StateResult<()>;
186+
fn snapshot_term_params(&mut self) -> StateResult<()>;
186187
}
187188

188189
pub trait StateWithCache {

0 commit comments

Comments
 (0)