handle comments

This commit is contained in:
Sergio Chouhy 2026-04-03 18:11:34 -03:00
parent 55c75c55ae
commit deae71b09f
9 changed files with 38 additions and 31 deletions

2
Cargo.lock generated
View File

@ -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",

View File

@ -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 {

View File

@ -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)
}

View File

@ -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 {

View File

@ -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,

View File

@ -9,3 +9,4 @@ workspace = true
[dependencies]
nssa_core.workspace = true
borsh.workspace = true

View File

@ -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")
}
}

View File

@ -41,4 +41,3 @@ mock = []
[dev-dependencies]
futures.workspace = true
test_program_methods.workspace = true
clock_core.workspace = true

View File

@ -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")]