mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-04-08 12:13:24 +00:00
add timestamp to clock
This commit is contained in:
parent
3324bcf391
commit
7078e403ed
Binary file not shown.
BIN
artifacts/program_methods/associated_token_account.bin
Normal file
BIN
artifacts/program_methods/associated_token_account.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
artifacts/test_program_methods/validity_window.bin
Normal file
BIN
artifacts/test_program_methods/validity_window.bin
Normal file
Binary file not shown.
BIN
artifacts/test_program_methods/validity_window_chain_caller.bin
Normal file
BIN
artifacts/test_program_methods/validity_window_chain_caller.bin
Normal file
Binary file not shown.
@ -8,7 +8,7 @@ use crate::{HashType, transaction::NSSATransaction};
|
||||
pub type MantleMsgId = [u8; 32];
|
||||
pub type BlockHash = HashType;
|
||||
pub type BlockId = u64;
|
||||
pub type TimeStamp = u64;
|
||||
pub use nssa_core::Timestamp;
|
||||
|
||||
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
|
||||
pub struct BlockMeta {
|
||||
@ -36,7 +36,7 @@ pub struct BlockHeader {
|
||||
pub block_id: BlockId,
|
||||
pub prev_block_hash: BlockHash,
|
||||
pub hash: BlockHash,
|
||||
pub timestamp: TimeStamp,
|
||||
pub timestamp: Timestamp,
|
||||
pub signature: nssa::Signature,
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ impl<'de> Deserialize<'de> for Block {
|
||||
pub struct HashableBlockData {
|
||||
pub block_id: BlockId,
|
||||
pub prev_block_hash: BlockHash,
|
||||
pub timestamp: TimeStamp,
|
||||
pub timestamp: Timestamp,
|
||||
pub transactions: Vec<NSSATransaction>,
|
||||
}
|
||||
|
||||
|
||||
@ -43,15 +43,15 @@ impl NSSATransaction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the canonical Block Context Program invocation transaction.
|
||||
/// Every valid block must end with exactly one occurrence of this transaction.
|
||||
/// Returns the canonical Block Context 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() -> Self {
|
||||
pub fn clock_invocation(timestamp: nssa_core::Timestamp) -> Self {
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
nssa::program::Program::clock().id(),
|
||||
vec![nssa::CLOCK_PROGRAM_ACCOUNT_ID],
|
||||
vec![],
|
||||
(),
|
||||
timestamp,
|
||||
)
|
||||
.expect("Clock invocation message should always be constructable");
|
||||
Self::Public(nssa::PublicTransaction::new(
|
||||
|
||||
@ -119,7 +119,7 @@ impl IndexerStore {
|
||||
|
||||
pub async fn put_block(&self, mut block: Block, l1_header: HeaderId) -> Result<()> {
|
||||
{
|
||||
let canonical_clock_tx = NSSATransaction::clock_invocation();
|
||||
let expected_clock_tx = NSSATransaction::clock_invocation(block.header.timestamp);
|
||||
|
||||
// Validate block structure: the last transaction must be the sole clock invocation.
|
||||
let last_tx = block
|
||||
@ -128,7 +128,7 @@ impl IndexerStore {
|
||||
.last()
|
||||
.ok_or_else(|| anyhow::anyhow!("Block must contain at least one transaction"))?;
|
||||
anyhow::ensure!(
|
||||
last_tx == &canonical_clock_tx,
|
||||
last_tx == &expected_clock_tx,
|
||||
"Last transaction in block must be the canonical clock invocation"
|
||||
);
|
||||
|
||||
@ -136,7 +136,7 @@ impl IndexerStore {
|
||||
.body
|
||||
.transactions
|
||||
.iter()
|
||||
.filter(|tx| *tx == &canonical_clock_tx)
|
||||
.filter(|tx| *tx == &expected_clock_tx)
|
||||
.count();
|
||||
anyhow::ensure!(
|
||||
clock_count == 1,
|
||||
@ -196,7 +196,7 @@ mod tests {
|
||||
let storage = IndexerStore::open_db_with_genesis(
|
||||
home.as_ref(),
|
||||
&genesis_block(),
|
||||
&nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[]),
|
||||
&nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[], 0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -214,7 +214,7 @@ mod tests {
|
||||
let storage = IndexerStore::open_db_with_genesis(
|
||||
home.as_ref(),
|
||||
&genesis_block(),
|
||||
&nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[]),
|
||||
&nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[], 0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -232,10 +232,12 @@ mod tests {
|
||||
10,
|
||||
&sign_key,
|
||||
);
|
||||
let clock_tx = NSSATransaction::clock_invocation();
|
||||
let block_id = u64::try_from(i).unwrap();
|
||||
let block_timestamp = block_id.saturating_mul(100);
|
||||
let clock_tx = NSSATransaction::clock_invocation(block_timestamp);
|
||||
|
||||
let next_block = common::test_utils::produce_dummy_block(
|
||||
u64::try_from(i).unwrap(),
|
||||
block_id,
|
||||
Some(prev_hash),
|
||||
vec![tx, clock_tx],
|
||||
);
|
||||
|
||||
@ -80,7 +80,11 @@ impl IndexerCore {
|
||||
.map(|acc_data| (acc_data.account_id, acc_data.balance))
|
||||
.collect();
|
||||
|
||||
let mut state = nssa::V03State::new_with_genesis_accounts(&init_accs, &initial_commitments);
|
||||
let mut state = nssa::V03State::new_with_genesis_accounts(
|
||||
&init_accs,
|
||||
&initial_commitments,
|
||||
genesis_block.header.timestamp,
|
||||
);
|
||||
|
||||
// ToDo: Remove after testnet
|
||||
state.add_pinata_program(PINATA_BASE58.parse().unwrap());
|
||||
|
||||
@ -138,7 +138,7 @@ pub struct Account {
|
||||
}
|
||||
|
||||
pub type BlockId = u64;
|
||||
pub type TimeStamp = u64;
|
||||
pub type Timestamp = u64;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct Block {
|
||||
@ -153,7 +153,7 @@ pub struct BlockHeader {
|
||||
pub block_id: BlockId,
|
||||
pub prev_block_hash: HashType,
|
||||
pub hash: HashType,
|
||||
pub timestamp: TimeStamp,
|
||||
pub timestamp: Timestamp,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
reason = "We prefer to group methods by functionality rather than by type for encoding"
|
||||
)]
|
||||
|
||||
pub type Timestamp = u64;
|
||||
|
||||
pub use circuit_io::{PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput};
|
||||
pub use commitment::{
|
||||
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, DUMMY_COMMITMENT_HASH, MembershipProof,
|
||||
|
||||
@ -264,7 +264,7 @@ pub mod tests {
|
||||
fn state_for_tests() -> V03State {
|
||||
let (_, _, addr1, addr2) = keys_for_tests();
|
||||
let initial_data = [(addr1, 10000), (addr2, 20000)];
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
}
|
||||
|
||||
fn transaction_for_tests() -> PublicTransaction {
|
||||
|
||||
@ -121,6 +121,7 @@ impl V03State {
|
||||
pub fn new_with_genesis_accounts(
|
||||
initial_data: &[(AccountId, u128)],
|
||||
initial_commitments: &[nssa_core::Commitment],
|
||||
genesis_timestamp: nssa_core::Timestamp,
|
||||
) -> Self {
|
||||
let authenticated_transfer_program = Program::authenticated_transfer_program();
|
||||
let public_state = initial_data
|
||||
@ -146,25 +147,30 @@ impl V03State {
|
||||
programs: HashMap::new(),
|
||||
};
|
||||
|
||||
this.insert_program(Program::clock());
|
||||
this.insert_clock_accounts(genesis_timestamp);
|
||||
|
||||
this.insert_program(Program::authenticated_transfer_program());
|
||||
this.insert_program(Program::token());
|
||||
this.insert_program(Program::amm());
|
||||
this.insert_program(Program::clock());
|
||||
|
||||
this.public_state.insert(
|
||||
this
|
||||
}
|
||||
|
||||
fn insert_clock_accounts(&mut self, genesis_timestamp: nssa_core::Timestamp) {
|
||||
let mut data = [0u8; 16];
|
||||
data[8..].copy_from_slice(&genesis_timestamp.to_le_bytes());
|
||||
self.public_state.insert(
|
||||
CLOCK_PROGRAM_ACCOUNT_ID,
|
||||
Account {
|
||||
program_owner: Program::clock().id(),
|
||||
data: 0_u64
|
||||
.to_le_bytes()
|
||||
data: data
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("u64 bytes should fit within accounts data"),
|
||||
.expect("16 bytes should fit within accounts data"),
|
||||
..Account::default()
|
||||
},
|
||||
);
|
||||
|
||||
this
|
||||
}
|
||||
|
||||
pub(crate) fn insert_program(&mut self, program: Program) {
|
||||
@ -371,7 +377,7 @@ pub mod tests {
|
||||
program::Program,
|
||||
public_transaction,
|
||||
signature::PrivateKey,
|
||||
state::MAX_NUMBER_CHAINED_CALLS,
|
||||
state::{CLOCK_PROGRAM_ACCOUNT_ID, MAX_NUMBER_CHAINED_CALLS},
|
||||
};
|
||||
|
||||
impl V03State {
|
||||
@ -490,6 +496,7 @@ pub mod tests {
|
||||
let addr2 = AccountId::from(&PublicKey::new_from_private_key(&key2));
|
||||
let initial_data = [(addr1, 100_u128), (addr2, 151_u128)];
|
||||
let authenticated_transfers_program = Program::authenticated_transfer_program();
|
||||
let clock_program = Program::clock();
|
||||
let expected_public_state = {
|
||||
let mut this = HashMap::new();
|
||||
this.insert(
|
||||
@ -508,6 +515,17 @@ pub mod tests {
|
||||
..Account::default()
|
||||
},
|
||||
);
|
||||
this.insert(
|
||||
CLOCK_PROGRAM_ACCOUNT_ID,
|
||||
Account {
|
||||
program_owner: clock_program.id(),
|
||||
data: [0u8; 16]
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
..Account::default()
|
||||
},
|
||||
);
|
||||
this
|
||||
};
|
||||
let expected_builtin_programs = {
|
||||
@ -516,12 +534,13 @@ pub mod tests {
|
||||
authenticated_transfers_program.id(),
|
||||
authenticated_transfers_program,
|
||||
);
|
||||
this.insert(clock_program.id(), clock_program);
|
||||
this.insert(Program::token().id(), Program::token());
|
||||
this.insert(Program::amm().id(), Program::amm());
|
||||
this
|
||||
};
|
||||
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
|
||||
assert_eq!(state.public_state, expected_public_state);
|
||||
assert_eq!(state.programs, expected_builtin_programs);
|
||||
@ -529,7 +548,7 @@ pub mod tests {
|
||||
|
||||
#[test]
|
||||
fn insert_program() {
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
let program_to_insert = Program::simple_balance_transfer();
|
||||
let program_id = program_to_insert.id();
|
||||
assert!(!state.programs.contains_key(&program_id));
|
||||
@ -544,7 +563,7 @@ pub mod tests {
|
||||
let key = PrivateKey::try_new([1; 32]).unwrap();
|
||||
let account_id = AccountId::from(&PublicKey::new_from_private_key(&key));
|
||||
let initial_data = [(account_id, 100_u128)];
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
let expected_account = &state.public_state[&account_id];
|
||||
|
||||
let account = state.get_account_by_id(account_id);
|
||||
@ -555,7 +574,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn get_account_by_account_id_default_account() {
|
||||
let addr2 = AccountId::new([0; 32]);
|
||||
let state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
let expected_account = Account::default();
|
||||
|
||||
let account = state.get_account_by_id(addr2);
|
||||
@ -565,7 +584,7 @@ pub mod tests {
|
||||
|
||||
#[test]
|
||||
fn builtin_programs_getter() {
|
||||
let state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
|
||||
let builtin_programs = state.programs();
|
||||
|
||||
@ -577,7 +596,7 @@ pub mod tests {
|
||||
let key = PrivateKey::try_new([1; 32]).unwrap();
|
||||
let account_id = AccountId::from(&PublicKey::new_from_private_key(&key));
|
||||
let initial_data = [(account_id, 100)];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
let from = account_id;
|
||||
let to = AccountId::new([2; 32]);
|
||||
assert_eq!(state.get_account_by_id(to), Account::default());
|
||||
@ -597,7 +616,7 @@ pub mod tests {
|
||||
let key = PrivateKey::try_new([1; 32]).unwrap();
|
||||
let account_id = AccountId::from(&PublicKey::new_from_private_key(&key));
|
||||
let initial_data = [(account_id, 100)];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
let from = account_id;
|
||||
let from_key = key;
|
||||
let to = AccountId::new([2; 32]);
|
||||
@ -621,7 +640,7 @@ pub mod tests {
|
||||
let account_id1 = AccountId::from(&PublicKey::new_from_private_key(&key1));
|
||||
let account_id2 = AccountId::from(&PublicKey::new_from_private_key(&key2));
|
||||
let initial_data = [(account_id1, 100), (account_id2, 200)];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
let from = account_id2;
|
||||
let from_key = key2;
|
||||
let to = account_id1;
|
||||
@ -644,7 +663,7 @@ pub mod tests {
|
||||
let key2 = PrivateKey::try_new([2; 32]).unwrap();
|
||||
let account_id2 = AccountId::from(&PublicKey::new_from_private_key(&key2));
|
||||
let initial_data = [(account_id1, 100)];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
let account_id3 = AccountId::new([3; 32]);
|
||||
let balance_to_move = 5;
|
||||
|
||||
@ -666,7 +685,7 @@ pub mod tests {
|
||||
fn program_should_fail_if_modifies_nonces() {
|
||||
let initial_data = [(AccountId::new([1; 32]), 100)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_ids = vec![AccountId::new([1; 32])];
|
||||
let program_id = Program::nonce_changer_program().id();
|
||||
let message =
|
||||
@ -683,7 +702,7 @@ pub mod tests {
|
||||
fn program_should_fail_if_output_accounts_exceed_inputs() {
|
||||
let initial_data = [(AccountId::new([1; 32]), 100)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_ids = vec![AccountId::new([1; 32])];
|
||||
let program_id = Program::extra_output_program().id();
|
||||
let message =
|
||||
@ -700,7 +719,7 @@ pub mod tests {
|
||||
fn program_should_fail_with_missing_output_accounts() {
|
||||
let initial_data = [(AccountId::new([1; 32]), 100)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_ids = vec![AccountId::new([1; 32]), AccountId::new([2; 32])];
|
||||
let program_id = Program::missing_output_program().id();
|
||||
let message =
|
||||
@ -717,7 +736,7 @@ pub mod tests {
|
||||
fn program_should_fail_if_modifies_program_owner_with_only_non_default_program_owner() {
|
||||
let initial_data = [(AccountId::new([1; 32]), 0)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_id = AccountId::new([1; 32]);
|
||||
let account = state.get_account_by_id(account_id);
|
||||
// Assert the target account only differs from the default account in the program owner
|
||||
@ -740,7 +759,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn program_should_fail_if_modifies_program_owner_with_only_non_default_balance() {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
.with_test_programs()
|
||||
.with_non_default_accounts_but_default_program_owners();
|
||||
let account_id = AccountId::new([255; 32]);
|
||||
@ -764,7 +783,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn program_should_fail_if_modifies_program_owner_with_only_non_default_nonce() {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
.with_test_programs()
|
||||
.with_non_default_accounts_but_default_program_owners();
|
||||
let account_id = AccountId::new([254; 32]);
|
||||
@ -788,7 +807,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn program_should_fail_if_modifies_program_owner_with_only_non_default_data() {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
.with_test_programs()
|
||||
.with_non_default_accounts_but_default_program_owners();
|
||||
let account_id = AccountId::new([253; 32]);
|
||||
@ -813,7 +832,7 @@ pub mod tests {
|
||||
fn program_should_fail_if_transfers_balance_from_non_owned_account() {
|
||||
let initial_data = [(AccountId::new([1; 32]), 100)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let sender_account_id = AccountId::new([1; 32]);
|
||||
let receiver_account_id = AccountId::new([2; 32]);
|
||||
let balance_to_move: u128 = 1;
|
||||
@ -840,7 +859,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn program_should_fail_if_modifies_data_of_non_owned_account() {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
.with_test_programs()
|
||||
.with_non_default_accounts_but_default_program_owners();
|
||||
let account_id = AccountId::new([255; 32]);
|
||||
@ -866,7 +885,7 @@ pub mod tests {
|
||||
fn program_should_fail_if_does_not_preserve_total_balance_by_minting() {
|
||||
let initial_data = [];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_id = AccountId::new([1; 32]);
|
||||
let program_id = Program::minter().id();
|
||||
|
||||
@ -883,7 +902,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn program_should_fail_if_does_not_preserve_total_balance_by_burning() {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0)
|
||||
.with_test_programs()
|
||||
.with_account_owned_by_burner_program();
|
||||
let program_id = Program::burner().id();
|
||||
@ -1075,7 +1094,7 @@ pub mod tests {
|
||||
let recipient_keys = test_private_account_keys_1();
|
||||
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&[(sender_keys.account_id(), 200)], &[]);
|
||||
V03State::new_with_genesis_accounts(&[(sender_keys.account_id(), 200)], &[], 0);
|
||||
|
||||
let balance_to_move = 37;
|
||||
|
||||
@ -1123,7 +1142,7 @@ pub mod tests {
|
||||
};
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0)
|
||||
.with_private_account(&sender_keys, &sender_private_account);
|
||||
|
||||
let balance_to_move = 37;
|
||||
@ -1193,6 +1212,7 @@ pub mod tests {
|
||||
let mut state = V03State::new_with_genesis_accounts(
|
||||
&[(recipient_keys.account_id(), recipient_initial_balance)],
|
||||
&[],
|
||||
0,
|
||||
)
|
||||
.with_private_account(&sender_keys, &sender_private_account);
|
||||
|
||||
@ -2144,7 +2164,7 @@ pub mod tests {
|
||||
};
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[])
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0)
|
||||
.with_private_account(&sender_keys, &sender_private_account);
|
||||
|
||||
let balance_to_move = 37;
|
||||
@ -2229,7 +2249,7 @@ pub mod tests {
|
||||
let initial_balance = 100;
|
||||
let initial_data = [(account_id, initial_balance)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let from = account_id;
|
||||
let from_key = key;
|
||||
let to = AccountId::new([2; 32]);
|
||||
@ -2270,7 +2290,7 @@ pub mod tests {
|
||||
let initial_balance = 1000;
|
||||
let initial_data = [(from, initial_balance), (to, 0)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let from_key = key;
|
||||
let amount: u128 = 37;
|
||||
let instruction: (u128, ProgramId, u32, Option<PdaSeed>) = (
|
||||
@ -2315,7 +2335,7 @@ pub mod tests {
|
||||
let initial_balance = 100;
|
||||
let initial_data = [(from, initial_balance), (to, 0)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let from_key = key;
|
||||
let amount: u128 = 0;
|
||||
let instruction: (u128, ProgramId, u32, Option<PdaSeed>) = (
|
||||
@ -2353,7 +2373,7 @@ pub mod tests {
|
||||
let initial_balance = 1000;
|
||||
let initial_data = [(from, initial_balance), (to, 0)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let amount: u128 = 58;
|
||||
let instruction: (u128, ProgramId, u32, Option<PdaSeed>) = (
|
||||
amount,
|
||||
@ -2399,7 +2419,7 @@ pub mod tests {
|
||||
let initial_balance = 100;
|
||||
let initial_data = [(account_id, initial_balance)];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let from = account_id;
|
||||
let from_key = key;
|
||||
let to = AccountId::new([2; 32]);
|
||||
@ -2474,6 +2494,7 @@ pub mod tests {
|
||||
let mut state = V03State::new_with_genesis_accounts(
|
||||
&[],
|
||||
&[from_commitment.clone(), to_commitment.clone()],
|
||||
0,
|
||||
)
|
||||
.with_test_programs();
|
||||
let amount: u128 = 37;
|
||||
@ -2580,7 +2601,7 @@ pub mod tests {
|
||||
..Account::default()
|
||||
};
|
||||
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
state.add_pinata_token_program(pinata_definition_id);
|
||||
|
||||
// Execution of the token program to create new token for the pinata token
|
||||
@ -2641,7 +2662,7 @@ pub mod tests {
|
||||
#[test]
|
||||
fn claiming_mechanism_cannot_claim_initialied_accounts() {
|
||||
let claimer = Program::claimer();
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[]).with_test_programs();
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0).with_test_programs();
|
||||
let account_id = AccountId::new([2; 32]);
|
||||
|
||||
// Insert an account with non-default program owner
|
||||
@ -2682,6 +2703,7 @@ pub mod tests {
|
||||
(recipient_id, recipient_init_balance),
|
||||
],
|
||||
&[],
|
||||
0,
|
||||
);
|
||||
|
||||
state.insert_program(Program::modified_transfer_program());
|
||||
@ -2731,7 +2753,7 @@ pub mod tests {
|
||||
|
||||
#[test]
|
||||
fn private_authorized_uninitialized_account() {
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
|
||||
// Set up keys for the authorized private account
|
||||
let private_keys = test_private_account_keys_1();
|
||||
@ -2783,7 +2805,7 @@ pub mod tests {
|
||||
|
||||
#[test]
|
||||
fn private_account_claimed_then_used_without_init_flag_should_fail() {
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[]).with_test_programs();
|
||||
let mut state = V03State::new_with_genesis_accounts(&[], &[], 0).with_test_programs();
|
||||
|
||||
// Set up keys for the private account
|
||||
let private_keys = test_private_account_keys_1();
|
||||
@ -2864,7 +2886,7 @@ pub mod tests {
|
||||
fn public_changer_claimer_no_data_change_no_claim_succeeds() {
|
||||
let initial_data = [];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_id = AccountId::new([1; 32]);
|
||||
let program_id = Program::changer_claimer().id();
|
||||
// Don't change data (None) and don't claim (false)
|
||||
@ -2888,7 +2910,7 @@ pub mod tests {
|
||||
fn public_changer_claimer_data_change_no_claim_fails() {
|
||||
let initial_data = [];
|
||||
let mut state =
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let account_id = AccountId::new([1; 32]);
|
||||
let program_id = Program::changer_claimer().id();
|
||||
// Change data but don't claim (false) - should fail
|
||||
@ -2985,6 +3007,7 @@ pub mod tests {
|
||||
let state = V03State::new_with_genesis_accounts(
|
||||
&[(sender_account.account_id, sender_account.account.balance)],
|
||||
std::slice::from_ref(&recipient_commitment),
|
||||
0,
|
||||
)
|
||||
.with_test_programs();
|
||||
|
||||
@ -3018,7 +3041,7 @@ pub mod tests {
|
||||
let account_id_1 = AccountId::new([1; 32]);
|
||||
let account_id_2 = AccountId::new([2; 32]);
|
||||
let initial_data = [(account_id_1, 100_u128), (account_id_2, 151_u128)];
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
|
||||
let state = V03State::new_with_genesis_accounts(&initial_data, &[], 0).with_test_programs();
|
||||
let bytes = borsh::to_vec(&state).unwrap();
|
||||
let state_from_bytes: V03State = borsh::from_slice(&bytes).unwrap();
|
||||
assert_eq!(state, state_from_bytes);
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = ();
|
||||
type Instruction = nssa_core::Timestamp;
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: (),
|
||||
instruction: timestamp,
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
@ -16,20 +16,24 @@ fn main() {
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let account_pre_data = account_pre.data.clone();
|
||||
let clock =
|
||||
u64::from_le_bytes(account_pre_data.into_inner().try_into().expect(
|
||||
"Block context program account data should be the LE encoding of a u64 integer",
|
||||
));
|
||||
let account_pre_data = account_pre.data.clone().into_inner();
|
||||
let block_id = u64::from_le_bytes(
|
||||
account_pre_data[..8]
|
||||
.try_into()
|
||||
.expect("Block context program account data should contain a LE-encoded block_id u64"),
|
||||
);
|
||||
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.data = clock
|
||||
let next_block_id = block_id
|
||||
.checked_add(1)
|
||||
.expect("Next timestap should be within u64 boundaries")
|
||||
.to_le_bytes()
|
||||
.expect("Next block id should be within u64 boundaries");
|
||||
let mut data = [0u8; 16];
|
||||
data[..8].copy_from_slice(&next_block_id.to_le_bytes());
|
||||
data[8..].copy_from_slice(×tamp.to_le_bytes());
|
||||
account_post.data = data
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("u64 byte length should fit in account data");
|
||||
.expect("16 bytes should fit in account data");
|
||||
|
||||
let post = AccountPostState::new(account_post);
|
||||
|
||||
|
||||
@ -2638,7 +2638,7 @@ fn new_definition_lp_symmetric_amounts() {
|
||||
|
||||
fn state_for_amm_tests() -> V03State {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
state.force_insert_account(
|
||||
IdForExeTests::pool_definition_id(),
|
||||
AccountsForExeTests::pool_definition_init(),
|
||||
@ -2681,7 +2681,7 @@ fn state_for_amm_tests() -> V03State {
|
||||
|
||||
fn state_for_amm_tests_with_new_def() -> V03State {
|
||||
let initial_data = [];
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[]);
|
||||
let mut state = V03State::new_with_genesis_accounts(&initial_data, &[], 0);
|
||||
state.force_insert_account(
|
||||
IdForExeTests::token_a_definition_id(),
|
||||
AccountsForExeTests::token_a_definition_account(),
|
||||
|
||||
@ -150,7 +150,7 @@ mod tests {
|
||||
let retrieved_tx = node_store.get_transaction_by_hash(tx.hash());
|
||||
assert_eq!(None, retrieved_tx);
|
||||
// Add the block with the transaction
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
node_store.update(&block, [1; 32], &dummy_state).unwrap();
|
||||
// Try again
|
||||
let retrieved_tx = node_store.get_transaction_by_hash(tx.hash());
|
||||
@ -209,7 +209,7 @@ mod tests {
|
||||
let block_hash = block.header.hash;
|
||||
let block_msg_id = [1; 32];
|
||||
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
node_store
|
||||
.update(&block, block_msg_id, &dummy_state)
|
||||
.unwrap();
|
||||
@ -244,7 +244,7 @@ mod tests {
|
||||
let block = common::test_utils::produce_dummy_block(1, None, vec![tx]);
|
||||
let block_id = block.header.block_id;
|
||||
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[]);
|
||||
let dummy_state = V03State::new_with_genesis_accounts(&[], &[], 0);
|
||||
node_store.update(&block, [1; 32], &dummy_state).unwrap();
|
||||
|
||||
// Verify initial status is Pending
|
||||
|
||||
@ -121,7 +121,11 @@ impl<BC: BlockSettlementClientTrait, IC: IndexerClientTrait> SequencerCore<BC, I
|
||||
.map(|acc_data| (acc_data.account_id, acc_data.balance))
|
||||
.collect();
|
||||
|
||||
nssa::V03State::new_with_genesis_accounts(&init_accs, &initial_commitments)
|
||||
nssa::V03State::new_with_genesis_accounts(
|
||||
&init_accs,
|
||||
&initial_commitments,
|
||||
genesis_block.header.timestamp,
|
||||
)
|
||||
};
|
||||
|
||||
#[cfg(feature = "testnet")]
|
||||
@ -268,7 +272,7 @@ impl<BC: BlockSettlementClientTrait, IC: IndexerClientTrait> SequencerCore<BC, I
|
||||
}
|
||||
|
||||
// Append the Block Context Program invocation as the mandatory last transaction.
|
||||
match self.execute_check_transaction_on_state(NSSATransaction::clock_invocation()) {
|
||||
match self.execute_check_transaction_on_state(NSSATransaction::clock_invocation(curr_time)) {
|
||||
Ok(clock_nssa_tx) => {
|
||||
valid_transactions.push(clock_nssa_tx);
|
||||
}
|
||||
@ -724,7 +728,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Only one user tx should be included; the clock tx is always appended last.
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation()]);
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation(block.header.timestamp)]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -750,7 +754,7 @@ mod tests {
|
||||
.get_block_at_id(sequencer.chain_height)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation()]);
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation(block.header.timestamp)]);
|
||||
|
||||
// Add same transaction should fail
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
@ -763,7 +767,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
// The replay is rejected, so only the clock tx is in the block.
|
||||
assert_eq!(block.body.transactions, vec![NSSATransaction::clock_invocation()]);
|
||||
assert_eq!(block.body.transactions, vec![NSSATransaction::clock_invocation(block.header.timestamp)]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -798,7 +802,7 @@ mod tests {
|
||||
.get_block_at_id(sequencer.chain_height)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation()]);
|
||||
assert_eq!(block.body.transactions, vec![tx.clone(), NSSATransaction::clock_invocation(block.header.timestamp)]);
|
||||
}
|
||||
|
||||
// Instantiating a new sequencer from the same config. This should load the existing block
|
||||
@ -928,7 +932,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
new_block.body.transactions,
|
||||
vec![tx, NSSATransaction::clock_invocation()],
|
||||
vec![tx, NSSATransaction::clock_invocation(new_block.header.timestamp)],
|
||||
"New block should contain the submitted transaction and the clock invocation"
|
||||
);
|
||||
}
|
||||
@ -954,7 +958,7 @@ mod tests {
|
||||
))
|
||||
};
|
||||
mempool_handle
|
||||
.push(NSSATransaction::clock_invocation())
|
||||
.push(NSSATransaction::clock_invocation(0))
|
||||
.await
|
||||
.unwrap();
|
||||
mempool_handle.push(crafted_clock_tx).await.unwrap();
|
||||
@ -969,7 +973,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Both transactions were dropped. Only the system-appended clock tx remains.
|
||||
assert_eq!(block.body.transactions, vec![NSSATransaction::clock_invocation()]);
|
||||
assert_eq!(block.body.transactions, vec![NSSATransaction::clock_invocation(block.header.timestamp)]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@ -990,7 +990,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn initial_state() -> V03State {
|
||||
nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[])
|
||||
nssa::V03State::new_with_genesis_accounts(&[(acc1(), 10000), (acc2(), 20000)], &[], 0)
|
||||
}
|
||||
|
||||
fn transfer(amount: u128, nonce: u128, direction: bool) -> NSSATransaction {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user