mirror of
https://github.com/serai-dex/serai.git
synced 2025-04-16 11:11:56 +00:00
Add the UNIX timestamp (in milliseconds to the block
This is read from the BABE pre-digest when converting from a SubstrateHeader. This causes the genesis block to have time 0 and all blocks produced with BABE to have a time of the slot time. While the slot time is in 6-second intervals (due to our target block time), defining in milliseconds preserves the ABI for long-term goals (sub-second blocks). Usage of the slot time deduplicates this field with BABE, and leaves the only possible manipulation to propose during a slot or to not propose during a slot. The actual reason this was implemented this way is because the Header trait is overly restrictive and doesn't allow definition with new fields. Even if we wanted to express the timestamp within the SubstrateHeader, we can't without replacing Header::new and making a variety of changes to the polkadot-sdk accordingly. Those aren't worth it at this moment compared to the solution implemented.
This commit is contained in:
parent
2d8f70036a
commit
dff9a04a8c
1 changed files with 27 additions and 2 deletions
|
@ -13,8 +13,11 @@ pub struct HeaderV1 {
|
|||
pub number: u64,
|
||||
/// The block this header builds upon.
|
||||
pub parent_hash: BlockHash,
|
||||
/// The UNIX time in milliseconds this block was created at.
|
||||
pub unix_time_in_millis: u64,
|
||||
/// The root of a Merkle tree commiting to the transactions within this block.
|
||||
// TODO: Review the format of this defined by Substrate
|
||||
// TODO: Review the format of this defined by Substrate. We don't want to commit to the signature
|
||||
// TODO: Some transactions don't have unique hashes due to assuming vaalidators set unique keys
|
||||
pub transactions_root: [u8; 32],
|
||||
/// A commitment to the consensus data used to justify adding this block to the blockchain.
|
||||
pub consensus_commitment: [u8; 32],
|
||||
|
@ -106,11 +109,33 @@ mod substrate {
|
|||
}
|
||||
|
||||
impl From<&SubstrateHeader> for Header {
|
||||
fn from(header: &SubstrateHeader) -> Header {
|
||||
fn from(header: &SubstrateHeader) -> Self {
|
||||
use sp_consensus_babe::SlotDuration;
|
||||
use sc_consensus_babe::CompatibleDigestItem;
|
||||
|
||||
match header {
|
||||
SubstrateHeader::V1(header) => Header::V1(HeaderV1 {
|
||||
number: header.number,
|
||||
parent_hash: BlockHash(header.parent_hash.0),
|
||||
unix_time_in_millis: header
|
||||
.consensus
|
||||
.digest
|
||||
.logs()
|
||||
.iter()
|
||||
.find_map(|digest_item| {
|
||||
digest_item.as_babe_pre_digest().map(|pre_digest| {
|
||||
pre_digest
|
||||
.slot()
|
||||
.timestamp(SlotDuration::from_millis(
|
||||
serai_primitives::constants::TARGET_BLOCK_TIME.as_millis().try_into().unwrap(),
|
||||
))
|
||||
// This returns `None` if the slot is so far in the future, it'd cause an
|
||||
// overflow.
|
||||
.unwrap_or(sp_timestamp::Timestamp::new(u64::MAX))
|
||||
.as_millis()
|
||||
})
|
||||
})
|
||||
.unwrap_or(0),
|
||||
transactions_root: header.transactions_root.0,
|
||||
consensus_commitment: sp_core::blake2_256(&header.consensus.encode()),
|
||||
}),
|
||||
|
|
Loading…
Reference in a new issue