mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-04-08 12:13:24 +00:00
handle comments
This commit is contained in:
parent
55c75c55ae
commit
deae71b09f
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1466,6 +1466,7 @@ checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||
name = "clock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
]
|
||||
|
||||
@ -7146,7 +7147,6 @@ dependencies = [
|
||||
"borsh",
|
||||
"bytesize",
|
||||
"chrono",
|
||||
"clock_core",
|
||||
"common",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
|
||||
@ -44,7 +44,7 @@ impl NSSATransaction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the canonical Block Context Program invocation transaction for the given block
|
||||
/// Returns the canonical Clock Program invocation transaction for the given block
|
||||
/// timestamp. Every valid block must end with exactly one occurrence of this transaction.
|
||||
#[must_use]
|
||||
pub fn clock_invocation(timestamp: clock_core::Instruction) -> Self {
|
||||
|
||||
@ -177,9 +177,9 @@ impl V03State {
|
||||
Account {
|
||||
program_owner: clock_program_id,
|
||||
data: data
|
||||
.to_vec()
|
||||
.clone()
|
||||
.try_into()
|
||||
.expect("16 bytes should fit within accounts data"),
|
||||
.expect("Clock account data should fit within accounts data"),
|
||||
..Account::default()
|
||||
},
|
||||
);
|
||||
@ -724,7 +724,7 @@ pub mod tests {
|
||||
|
||||
fn clock_account_data(state: &V03State, account_id: AccountId) -> (u64, nssa_core::Timestamp) {
|
||||
let data = state.get_account_by_id(account_id).data.into_inner();
|
||||
let parsed = clock_core::ClockAccountData::from_bytes(data[..16].try_into().unwrap());
|
||||
let parsed = clock_core::ClockAccountData::from_bytes(&data);
|
||||
(parsed.block_id, parsed.timestamp)
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ pub struct StateDiff {
|
||||
/// The validated output of executing or verifying a transaction, ready to be applied to the state.
|
||||
///
|
||||
/// Can only be constructed by the transaction validation functions inside this crate, ensuring the
|
||||
/// diff has been cryptographically checked before any state mutation occurs.
|
||||
/// diff has been checked before any state mutation occurs.
|
||||
pub struct ValidatedStateDiff(StateDiff);
|
||||
|
||||
impl ValidatedStateDiff {
|
||||
|
||||
@ -1,3 +1,13 @@
|
||||
//! Clock Program.
|
||||
//!
|
||||
//! A system program that records the current block ID and timestamp into dedicated clock accounts.
|
||||
//! Three accounts are maintained, updated at different block intervals (every 1, 10, and 50
|
||||
//! blocks), allowing programs to read recent timestamps at various granularities.
|
||||
//!
|
||||
//! This program can only be invoked exclusively by the sequencer as the last transaction in every
|
||||
//! block. Clock accounts are assigned to the clock program at genesis, so no claiming is required
|
||||
//! here.
|
||||
|
||||
use clock_core::{
|
||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||
ClockAccountData, Instruction,
|
||||
@ -11,14 +21,14 @@ fn update_if_multiple(
|
||||
pre: AccountWithMetadata,
|
||||
divisor: u64,
|
||||
current_block_id: u64,
|
||||
updated_data: [u8; 16],
|
||||
updated_data: &[u8],
|
||||
) -> (AccountWithMetadata, AccountPostState) {
|
||||
if current_block_id.is_multiple_of(divisor) {
|
||||
let mut post_account = pre.account.clone();
|
||||
post_account.data = updated_data
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("16 bytes should fit in account data");
|
||||
.expect("Clock account data should fit in account data");
|
||||
(pre, AccountPostState::new(post_account))
|
||||
} else {
|
||||
let post = AccountPostState::new(pre.account.clone());
|
||||
@ -48,11 +58,15 @@ fn main() {
|
||||
panic!("Invalid input accounts");
|
||||
}
|
||||
|
||||
let prev_data = ClockAccountData::from_bytes(
|
||||
pre_01.account.data.clone().into_inner()[..16]
|
||||
.try_into()
|
||||
.expect("Clock account data should be 16 bytes"),
|
||||
);
|
||||
// Verify all clock accounts are owned by this program (assigned at genesis).
|
||||
if pre_01.account.program_owner != self_program_id
|
||||
|| pre_10.account.program_owner != self_program_id
|
||||
|| pre_50.account.program_owner != self_program_id
|
||||
{
|
||||
panic!("Clock accounts must be owned by the clock program");
|
||||
}
|
||||
|
||||
let prev_data = ClockAccountData::from_bytes(&pre_01.account.data.clone().into_inner());
|
||||
let current_block_id = prev_data
|
||||
.block_id
|
||||
.checked_add(1)
|
||||
@ -64,9 +78,9 @@ fn main() {
|
||||
}
|
||||
.to_bytes();
|
||||
|
||||
let (pre_01, post_01) = update_if_multiple(pre_01, 1, current_block_id, updated_data);
|
||||
let (pre_10, post_10) = update_if_multiple(pre_10, 10, current_block_id, updated_data);
|
||||
let (pre_50, post_50) = update_if_multiple(pre_50, 50, current_block_id, updated_data);
|
||||
let (pre_01, post_01) = update_if_multiple(pre_01, 1, current_block_id, &updated_data);
|
||||
let (pre_10, post_10) = update_if_multiple(pre_10, 10, current_block_id, &updated_data);
|
||||
let (pre_50, post_50) = update_if_multiple(pre_50, 50, current_block_id, &updated_data);
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
|
||||
@ -9,3 +9,4 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core.workspace = true
|
||||
borsh.workspace = true
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
//! Core data structures and constants for the Clock Program.
|
||||
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use nssa_core::{Timestamp, account::AccountId};
|
||||
|
||||
pub const CLOCK_01_PROGRAM_ACCOUNT_ID: AccountId =
|
||||
@ -22,7 +23,7 @@ pub const CLOCK_PROGRAM_ACCOUNT_IDS: [AccountId; 3] = [
|
||||
pub type Instruction = Timestamp;
|
||||
|
||||
/// The data stored in a clock account: `[block_id: u64 LE | timestamp: u64 LE]`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
|
||||
pub struct ClockAccountData {
|
||||
pub block_id: u64,
|
||||
pub timestamp: Timestamp,
|
||||
@ -30,20 +31,12 @@ pub struct ClockAccountData {
|
||||
|
||||
impl ClockAccountData {
|
||||
#[must_use]
|
||||
pub fn to_bytes(self) -> [u8; 16] {
|
||||
let mut data = [0_u8; 16];
|
||||
data[..8].copy_from_slice(&self.block_id.to_le_bytes());
|
||||
data[8..].copy_from_slice(&self.timestamp.to_le_bytes());
|
||||
data
|
||||
pub fn to_bytes(self) -> Vec<u8> {
|
||||
borsh::to_vec(&self).expect("ClockAccountData serialization should not fail")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_bytes(bytes: &[u8; 16]) -> Self {
|
||||
let block_id = u64::from_le_bytes(bytes[..8].try_into().unwrap());
|
||||
let timestamp = u64::from_le_bytes(bytes[8..].try_into().unwrap());
|
||||
Self {
|
||||
block_id,
|
||||
timestamp,
|
||||
}
|
||||
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||
borsh::from_slice(bytes).expect("ClockAccountData deserialization should not fail")
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,4 +41,3 @@ mock = []
|
||||
[dev-dependencies]
|
||||
futures.workspace = true
|
||||
test_program_methods.workspace = true
|
||||
clock_core.workspace = true
|
||||
|
||||
@ -24,7 +24,7 @@ pub struct SequencerConfig {
|
||||
pub genesis_id: u64,
|
||||
/// If `True`, then adds random sequence of bytes to genesis block.
|
||||
pub is_genesis_random: bool,
|
||||
/// Maximum number of transactions in block.
|
||||
/// Maximum number of user transactions in a block (excludes the mandatory clock transaction).
|
||||
pub max_num_tx_in_block: usize,
|
||||
/// Maximum block size (includes header and transactions).
|
||||
#[serde(default = "default_max_block_size")]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user