diff --git a/light-client/src/client.rs b/light-client/src/client.rs index 8958a59..5e10fd9 100644 --- a/light-client/src/client.rs +++ b/light-client/src/client.rs @@ -858,6 +858,9 @@ mod test { mock_consensus_state.insert(Height::new(0, input.trusted_height), trusted_cs.clone()); // Set fork spec boundary timestamp is all[1] + // This indicates that target is the HEADER immediately before the HF occurs. + // By setting the height of the HF to ClientState here, the next update_client will be able to validate headers after the HF. + // In order to validate the header after HF, it is necessary to set the height at which HF occurs in ClientState in advance. let mut boundary_fs = fork_spec_after_lorentz(); boundary_fs.height_or_timestamp = HeightOrTimestamp::Time(header.eth_header().all[1].milli_timestamp()); diff --git a/light-client/src/consensus_state.rs b/light-client/src/consensus_state.rs index 66eadb1..dc2083e 100644 --- a/light-client/src/consensus_state.rs +++ b/light-client/src/consensus_state.rs @@ -18,6 +18,7 @@ pub struct ConsensusState { /// the storage root of the IBC contract pub state_root: Hash, /// timestamp from execution payload + /// After Lorentz HF, the unit is millisecond. Before that, it was seconds. pub timestamp: Time, pub current_validators_hash: Hash, pub previous_validators_hash: Hash, diff --git a/light-client/src/fork_spec.rs b/light-client/src/fork_spec.rs index c59db31..8e11d22 100644 --- a/light-client/src/fork_spec.rs +++ b/light-client/src/fork_spec.rs @@ -9,10 +9,18 @@ pub enum HeightOrTimestamp { Time(u64), } +/// ForkSpec defines different parameters for each HF. +/// The ForkSpec of the supporting HF must be registered at CreateClient +/// This is a data structure that does not exist in the BSC node and is designed uniquely for the light client. #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ForkSpec { + /// The timestamp or height at which the HF will occur. + /// If you set the timestamp, you need to use the value described in bsc's ChainConfig. + /// https://github.com/bnb-chain/bsc/blob/5735d8a56540e8f2fb26d5585de0fa3959bb17b4/params/config.go#L192C3-L192C14 pub height_or_timestamp: HeightOrTimestamp, /// Items count after parent_beacon_root + /// The number of headers prior to Pascal HF is set to 0. + /// For example, the number of headers after Pascal HF is set to 1 because of the addition of the requestsHash. pub additional_header_item_count: u64, /// Block count in epoch pub epoch_length: u64, @@ -28,34 +36,35 @@ impl ForkSpec { /// with the previous fork specification. It calculates the previous last epoch, the current /// first epoch, and any intermediate epochs between them. /// - /// first = previous last epoch - /// last = current first epoch + /// previous_last: refers to the previous epoch of the height + /// current_first refers to the first epoch of the height divisible by the current fork epoch length. + /// intermediates: refers to the epochs between the previous last and current first. /// /// eg) height = 1501 - /// first = 1400 - /// mid = [1600, 1800] - /// last = 2000 + /// previous_last = 1400 + /// intermediates = [1600, 1800] + /// current_first = 2000 /// /// in Lorentz HF /// eg) height = 1600 - /// first = 1600 - /// mid = [1800] - /// last = 2000 + /// previous_last = 1600 + /// intermediates = [1800] + /// current_first = 2000 /// /// eg) height = 1601 - /// first = 1600 - /// mid = [1800] - /// last = 2000 + /// previous_last = 1600 + /// intermediates = [1800] + /// current_first = 2000 /// /// eg) height = 1800 - /// first = 1800 - /// mid = [] - /// last = 2000 + /// previous_last = 1800 + /// intermediates = [] + /// current_first = 2000 /// /// eg) height = 2000 - /// first = 2000 - /// mid = [] - /// last = 2000 + /// previous_last = 2000 + /// intermediates = [] + /// current_first = 2000 pub fn boundary_epochs(&self, prev_fork_spec: &ForkSpec) -> Result { if let HeightOrTimestamp::Height(height) = self.height_or_timestamp { let prev_last = height - (height % prev_fork_spec.epoch_length); @@ -137,12 +146,11 @@ impl BoundaryEpochs { if current_epoch_block_number == 0 { return 0; } - // first or under + // Before HF if current_epoch_block_number <= self.prev_last { return current_epoch_block_number - self.previous_fork_spec.epoch_length; } - // Hit mids eppchs for (i, mid) in self.intermediates.iter().enumerate() { if current_epoch_block_number == *mid { if i == 0 { @@ -153,7 +161,6 @@ impl BoundaryEpochs { } } - // is just current HF first if current_epoch_block_number == self.current_first { if self.intermediates.is_empty() { return self.prev_last; @@ -227,7 +234,6 @@ pub fn get_boundary_epochs( current_spec: &ForkSpec, fork_specs: &[ForkSpec], ) -> Result { - // find from last to first for (i, spec) in fork_specs.iter().enumerate() { if spec == current_spec { if i == 0 { diff --git a/light-client/src/header/eth_header.rs b/light-client/src/header/eth_header.rs index f58cf43..80e0e95 100644 --- a/light-client/src/header/eth_header.rs +++ b/light-client/src/header/eth_header.rs @@ -402,7 +402,7 @@ impl TryFrom for ETHHeader { type Error = Error; /// This includes part of header verification. - /// - verifyHeader: https://github.com/bnb-chain/bsc/blob/b4773e8b5080f37e1c65c083b543f60c895abb70/consensus/parlia/parlia.go#L324 + /// - verifyHeader: https://github.com/bnb-chain/bsc/blob/5735d8a56540e8f2fb26d5585de0fa3959bb17b4/consensus/parlia/parlia.go#L562 fn try_from(value: RawETHHeader) -> Result { let mut rlp = RlpIterator::new(Rlp::new(value.header.as_slice())); let parent_hash: Vec = rlp.try_next_as_val()?; diff --git a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto index 261f5c0..e67d5e3 100644 --- a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto @@ -12,8 +12,6 @@ message ForkSpec { uint64 height = 1; uint64 timestamp = 2; } - // The number of headers prior to Pascal HF is set to 0. - // For example, the number of headers before Pascal HF is set to 1 because of the addition of the requestsHash. uint64 additional_header_item_count = 3; uint64 epoch_length = 4; uint64 max_turn_length = 5; diff --git a/proto/src/prost/ibc.lightclients.parlia.v1.rs b/proto/src/prost/ibc.lightclients.parlia.v1.rs index 33fe1f1..62af31a 100644 --- a/proto/src/prost/ibc.lightclients.parlia.v1.rs +++ b/proto/src/prost/ibc.lightclients.parlia.v1.rs @@ -1,8 +1,6 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ForkSpec { - /// The number of headers prior to Pascal HF is set to 0. - /// For example, the number of headers before Pascal HF is set to 1 because of the addition of the requestsHash. #[prost(uint64, tag = "3")] pub additional_header_item_count: u64, #[prost(uint64, tag = "4")]