mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-12 18:29:50 +00:00
minor refactor
This commit is contained in:
parent
3c5a1c9d0a
commit
fa2fd857a9
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1462,6 +1462,13 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clock_core"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nssa_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cobs"
|
name = "cobs"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -1511,6 +1518,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"borsh",
|
"borsh",
|
||||||
|
"clock_core",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"logos-blockchain-common-http-client",
|
"logos-blockchain-common-http-client",
|
||||||
@ -5259,6 +5267,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"borsh",
|
"borsh",
|
||||||
|
"clock_core",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"hex",
|
"hex",
|
||||||
"hex-literal 1.1.0",
|
"hex-literal 1.1.0",
|
||||||
@ -5897,6 +5906,7 @@ dependencies = [
|
|||||||
"amm_program",
|
"amm_program",
|
||||||
"ata_core",
|
"ata_core",
|
||||||
"ata_program",
|
"ata_program",
|
||||||
|
"clock_core",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
"risc0-zkvm",
|
"risc0-zkvm",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@ -15,6 +15,7 @@ members = [
|
|||||||
"nssa/core",
|
"nssa/core",
|
||||||
"programs/amm/core",
|
"programs/amm/core",
|
||||||
"programs/amm",
|
"programs/amm",
|
||||||
|
"programs/clock/core",
|
||||||
"programs/token/core",
|
"programs/token/core",
|
||||||
"programs/token",
|
"programs/token",
|
||||||
"programs/associated_token_account/core",
|
"programs/associated_token_account/core",
|
||||||
@ -56,6 +57,7 @@ indexer_service_protocol = { path = "indexer/service/protocol" }
|
|||||||
indexer_service_rpc = { path = "indexer/service/rpc" }
|
indexer_service_rpc = { path = "indexer/service/rpc" }
|
||||||
wallet = { path = "wallet" }
|
wallet = { path = "wallet" }
|
||||||
wallet-ffi = { path = "wallet-ffi", default-features = false }
|
wallet-ffi = { path = "wallet-ffi", default-features = false }
|
||||||
|
clock_core = { path = "programs/clock/core" }
|
||||||
token_core = { path = "programs/token/core" }
|
token_core = { path = "programs/token/core" }
|
||||||
token_program = { path = "programs/token" }
|
token_program = { path = "programs/token" }
|
||||||
amm_core = { path = "programs/amm/core" }
|
amm_core = { path = "programs/amm/core" }
|
||||||
|
|||||||
@ -10,6 +10,7 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
nssa.workspace = true
|
nssa.workspace = true
|
||||||
nssa_core.workspace = true
|
nssa_core.workspace = true
|
||||||
|
clock_core.workspace = true
|
||||||
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|||||||
@ -47,14 +47,10 @@ impl NSSATransaction {
|
|||||||
/// Returns the canonical Block Context Program invocation transaction for the given block
|
/// 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.
|
/// timestamp. Every valid block must end with exactly one occurrence of this transaction.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn clock_invocation(timestamp: nssa_core::Timestamp) -> Self {
|
pub fn clock_invocation(timestamp: clock_core::Instruction) -> Self {
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
nssa::program::Program::clock().id(),
|
nssa::program::Program::clock().id(),
|
||||||
vec![
|
clock_core::CLOCK_PROGRAM_ACCOUNT_IDS.to_vec(),
|
||||||
nssa::CLOCK_01_PROGRAM_ACCOUNT_ID,
|
|
||||||
nssa::CLOCK_10_PROGRAM_ACCOUNT_ID,
|
|
||||||
nssa::CLOCK_50_PROGRAM_ACCOUNT_ID,
|
|
||||||
],
|
|
||||||
vec![],
|
vec![],
|
||||||
timestamp,
|
timestamp,
|
||||||
)
|
)
|
||||||
@ -65,6 +61,28 @@ impl NSSATransaction {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if this transaction is a user invocation of the clock program.
|
||||||
|
///
|
||||||
|
/// For public transactions: checks whether the program ID matches the clock program.
|
||||||
|
/// For privacy-preserving transactions: checks whether any clock account has a modified
|
||||||
|
/// post-state (i.e. `post != pre`), using the provided pre-state snapshot.
|
||||||
|
/// Pass an empty slice when only the public case is relevant (e.g. in committed blocks where
|
||||||
|
/// PP clock-touching transactions are already filtered out by the sequencer).
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_invocation_of_clock_program(
|
||||||
|
&self,
|
||||||
|
clock_pre_states: &[(nssa::AccountId, nssa::Account)],
|
||||||
|
) -> bool {
|
||||||
|
let clock_program_id = nssa::program::Program::clock().id();
|
||||||
|
match self {
|
||||||
|
Self::Public(tx) => tx.message().program_id == clock_program_id,
|
||||||
|
Self::PrivacyPreserving(pp) => clock_pre_states
|
||||||
|
.iter()
|
||||||
|
.any(|(id, pre)| pp.public_post_state_for(id).is_some_and(|post| post != pre)),
|
||||||
|
Self::ProgramDeployment(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Introduce type-safe wrapper around checked transaction, e.g. AuthenticatedTransaction
|
// TODO: Introduce type-safe wrapper around checked transaction, e.g. AuthenticatedTransaction
|
||||||
pub fn transaction_stateless_check(self) -> Result<Self, TransactionMalformationError> {
|
pub fn transaction_stateless_check(self) -> Result<Self, TransactionMalformationError> {
|
||||||
// Stateless checks here
|
// Stateless checks here
|
||||||
|
|||||||
@ -136,7 +136,7 @@ impl IndexerStore {
|
|||||||
.body
|
.body
|
||||||
.transactions
|
.transactions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|tx| *tx == &expected_clock_tx)
|
.filter(|tx| tx.is_invocation_of_clock_program(&[]))
|
||||||
.count();
|
.count();
|
||||||
anyhow::ensure!(
|
anyhow::ensure!(
|
||||||
clock_count == 1,
|
clock_count == 1,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { workspace = true, features = ["host"] }
|
nssa_core = { workspace = true, features = ["host"] }
|
||||||
|
clock_core.workspace = true
|
||||||
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|||||||
@ -17,7 +17,8 @@ pub use program_methods::PRIVACY_PRESERVING_CIRCUIT_ID;
|
|||||||
pub use public_transaction::PublicTransaction;
|
pub use public_transaction::PublicTransaction;
|
||||||
pub use signature::{PrivateKey, PublicKey, Signature};
|
pub use signature::{PrivateKey, PublicKey, Signature};
|
||||||
pub use state::{
|
pub use state::{
|
||||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID, V03State,
|
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||||
|
CLOCK_PROGRAM_ACCOUNT_IDS, V03State,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
|||||||
@ -8,6 +8,12 @@ use nssa_core::{
|
|||||||
program::ProgramId,
|
program::ProgramId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use clock_core::{
|
||||||
|
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||||
|
CLOCK_PROGRAM_ACCOUNT_IDS,
|
||||||
|
};
|
||||||
|
use clock_core::ClockAccountData;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::NssaError, merkle_tree::MerkleTree,
|
error::NssaError, merkle_tree::MerkleTree,
|
||||||
privacy_preserving_transaction::PrivacyPreservingTransaction, program::Program,
|
privacy_preserving_transaction::PrivacyPreservingTransaction, program::Program,
|
||||||
@ -17,15 +23,6 @@ use crate::{
|
|||||||
|
|
||||||
pub const MAX_NUMBER_CHAINED_CALLS: usize = 10;
|
pub const MAX_NUMBER_CHAINED_CALLS: usize = 10;
|
||||||
|
|
||||||
pub const CLOCK_01_PROGRAM_ACCOUNT_ID: AccountId =
|
|
||||||
AccountId::new(*b"/LEZ/ClockProgramAccount/0000001");
|
|
||||||
|
|
||||||
pub const CLOCK_10_PROGRAM_ACCOUNT_ID: AccountId =
|
|
||||||
AccountId::new(*b"/LEZ/ClockProgramAccount/0000010");
|
|
||||||
|
|
||||||
pub const CLOCK_50_PROGRAM_ACCOUNT_ID: AccountId =
|
|
||||||
AccountId::new(*b"/LEZ/ClockProgramAccount/0000050");
|
|
||||||
|
|
||||||
#[derive(Clone, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, BorshSerialize, BorshDeserialize)]
|
||||||
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
|
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
|
||||||
pub struct CommitmentSet {
|
pub struct CommitmentSet {
|
||||||
@ -166,14 +163,9 @@ impl V03State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert_clock_accounts(&mut self, genesis_timestamp: nssa_core::Timestamp) {
|
fn insert_clock_accounts(&mut self, genesis_timestamp: nssa_core::Timestamp) {
|
||||||
let mut data = [0_u8; 16];
|
let data = ClockAccountData { block_id: 0, timestamp: genesis_timestamp }.to_bytes();
|
||||||
data[8..].copy_from_slice(&genesis_timestamp.to_le_bytes());
|
|
||||||
let clock_program_id = Program::clock().id();
|
let clock_program_id = Program::clock().id();
|
||||||
for account_id in [
|
for account_id in CLOCK_PROGRAM_ACCOUNT_IDS {
|
||||||
CLOCK_01_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_10_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_50_PROGRAM_ACCOUNT_ID,
|
|
||||||
] {
|
|
||||||
self.public_state.insert(
|
self.public_state.insert(
|
||||||
account_id,
|
account_id,
|
||||||
Account {
|
Account {
|
||||||
@ -400,7 +392,7 @@ pub mod tests {
|
|||||||
signature::PrivateKey,
|
signature::PrivateKey,
|
||||||
state::{
|
state::{
|
||||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||||
MAX_NUMBER_CHAINED_CALLS,
|
CLOCK_PROGRAM_ACCOUNT_IDS, MAX_NUMBER_CHAINED_CALLS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -543,11 +535,7 @@ pub mod tests {
|
|||||||
..Account::default()
|
..Account::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
for account_id in [
|
for account_id in CLOCK_PROGRAM_ACCOUNT_IDS {
|
||||||
CLOCK_01_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_10_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_50_PROGRAM_ACCOUNT_ID,
|
|
||||||
] {
|
|
||||||
this.insert(
|
this.insert(
|
||||||
account_id,
|
account_id,
|
||||||
Account {
|
Account {
|
||||||
@ -736,11 +724,7 @@ pub mod tests {
|
|||||||
fn clock_transaction(timestamp: nssa_core::Timestamp) -> PublicTransaction {
|
fn clock_transaction(timestamp: nssa_core::Timestamp) -> PublicTransaction {
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
Program::clock().id(),
|
Program::clock().id(),
|
||||||
vec![
|
CLOCK_PROGRAM_ACCOUNT_IDS.to_vec(),
|
||||||
CLOCK_01_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_10_PROGRAM_ACCOUNT_ID,
|
|
||||||
CLOCK_50_PROGRAM_ACCOUNT_ID,
|
|
||||||
],
|
|
||||||
vec![],
|
vec![],
|
||||||
timestamp,
|
timestamp,
|
||||||
)
|
)
|
||||||
@ -753,9 +737,8 @@ pub mod tests {
|
|||||||
|
|
||||||
fn clock_account_data(state: &V03State, account_id: AccountId) -> (u64, nssa_core::Timestamp) {
|
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 data = state.get_account_by_id(account_id).data.into_inner();
|
||||||
let block_id = u64::from_le_bytes(data[..8].try_into().unwrap());
|
let parsed = clock_core::ClockAccountData::from_bytes(data[..16].try_into().unwrap());
|
||||||
let timestamp = u64::from_le_bytes(data[8..].try_into().unwrap());
|
(parsed.block_id, parsed.timestamp)
|
||||||
(block_id, timestamp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -9,6 +9,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core.workspace = true
|
nssa_core.workspace = true
|
||||||
|
clock_core.workspace = true
|
||||||
token_core.workspace = true
|
token_core.workspace = true
|
||||||
token_program.workspace = true
|
token_program.workspace = true
|
||||||
amm_core.workspace = true
|
amm_core.workspace = true
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
|
use clock_core::{
|
||||||
|
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||||
|
ClockAccountData, Instruction,
|
||||||
|
};
|
||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
account::AccountWithMetadata,
|
account::AccountWithMetadata,
|
||||||
program::{AccountPostState, ProgramInput, ProgramOutput, read_nssa_inputs},
|
program::{AccountPostState, ProgramInput, ProgramOutput, read_nssa_inputs},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Instruction = nssa_core::Timestamp;
|
|
||||||
|
|
||||||
fn update_if_multiple(
|
fn update_if_multiple(
|
||||||
pre: AccountWithMetadata,
|
pre: AccountWithMetadata,
|
||||||
divisor: u64,
|
divisor: u64,
|
||||||
@ -34,24 +36,28 @@ fn main() {
|
|||||||
) = read_nssa_inputs::<Instruction>();
|
) = read_nssa_inputs::<Instruction>();
|
||||||
|
|
||||||
let Ok([pre_01, pre_10, pre_50]) = <[_; 3]>::try_from(pre_states) else {
|
let Ok([pre_01, pre_10, pre_50]) = <[_; 3]>::try_from(pre_states) else {
|
||||||
return;
|
panic!("Invalid number of input accounts");
|
||||||
};
|
};
|
||||||
|
|
||||||
let prev_block_id = u64::from_le_bytes(
|
// Verify pre-states correspond to the expected clock account IDs.
|
||||||
pre_01.account.data.clone().into_inner()[..8]
|
if pre_01.account_id != CLOCK_01_PROGRAM_ACCOUNT_ID
|
||||||
|
|| pre_10.account_id != CLOCK_10_PROGRAM_ACCOUNT_ID
|
||||||
|
|| pre_50.account_id != CLOCK_50_PROGRAM_ACCOUNT_ID
|
||||||
|
{
|
||||||
|
panic!("Invalid input accounts");
|
||||||
|
}
|
||||||
|
|
||||||
|
let prev_data = ClockAccountData::from_bytes(
|
||||||
|
pre_01.account.data.clone().into_inner()[..16]
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("Clock account data should contain a LE-encoded block_id u64"),
|
.expect("Clock account data should be 16 bytes"),
|
||||||
);
|
);
|
||||||
let current_block_id = prev_block_id
|
let current_block_id = prev_data
|
||||||
|
.block_id
|
||||||
.checked_add(1)
|
.checked_add(1)
|
||||||
.expect("Next block id should be within u64 boundaries");
|
.expect("Next block id should be within u64 boundaries");
|
||||||
|
|
||||||
let updated_data = {
|
let updated_data = ClockAccountData { block_id: current_block_id, timestamp }.to_bytes();
|
||||||
let mut data = [0_u8; 16];
|
|
||||||
data[..8].copy_from_slice(¤t_block_id.to_le_bytes());
|
|
||||||
data[8..].copy_from_slice(×tamp.to_le_bytes());
|
|
||||||
data
|
|
||||||
};
|
|
||||||
|
|
||||||
let (pre_01, post_01) = update_if_multiple(pre_01, 1, 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_10, post_10) = update_if_multiple(pre_10, 10, current_block_id, updated_data);
|
||||||
@ -61,5 +67,6 @@ fn main() {
|
|||||||
instruction_words,
|
instruction_words,
|
||||||
vec![pre_01, pre_10, pre_50],
|
vec![pre_01, pre_10, pre_50],
|
||||||
vec![post_01, post_10, post_50],
|
vec![post_01, post_10, post_50],
|
||||||
).write();
|
)
|
||||||
|
.write();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,38 +225,20 @@ impl<BC: BlockSettlementClientTrait, IC: IndexerClientTrait> SequencerCore<BC, I
|
|||||||
let new_block_timestamp = u64::try_from(chrono::Utc::now().timestamp_millis())
|
let new_block_timestamp = u64::try_from(chrono::Utc::now().timestamp_millis())
|
||||||
.expect("Timestamp must be positive");
|
.expect("Timestamp must be positive");
|
||||||
|
|
||||||
let clock_program_id = nssa::program::Program::clock().id();
|
// Note: the clock accounts are only modified by the clock program, which is invoked
|
||||||
let clock_accounts_pre = [
|
// exclusively by the sequencer as the mandatory last transaction in each block. All user
|
||||||
(
|
// transactions are processed before that invocation, so this snapshot is always current
|
||||||
nssa::CLOCK_01_PROGRAM_ACCOUNT_ID,
|
// and constant for all transactions in the block
|
||||||
self.state
|
let clock_accounts_pre =
|
||||||
.get_account_by_id(nssa::CLOCK_01_PROGRAM_ACCOUNT_ID),
|
nssa::CLOCK_PROGRAM_ACCOUNT_IDS.map(|id| (id, self.state.get_account_by_id(id)));
|
||||||
),
|
|
||||||
(
|
|
||||||
nssa::CLOCK_10_PROGRAM_ACCOUNT_ID,
|
|
||||||
self.state
|
|
||||||
.get_account_by_id(nssa::CLOCK_10_PROGRAM_ACCOUNT_ID),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
nssa::CLOCK_50_PROGRAM_ACCOUNT_ID,
|
|
||||||
self.state
|
|
||||||
.get_account_by_id(nssa::CLOCK_50_PROGRAM_ACCOUNT_ID),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
while let Some(tx) = self.mempool.pop() {
|
while let Some(tx) = self.mempool.pop() {
|
||||||
let tx_hash = tx.hash();
|
let tx_hash = tx.hash();
|
||||||
|
|
||||||
// The Block Context Program is system-only. Reject:
|
// The Block Context Program is system-only. Reject:
|
||||||
// - any public tx that invokes the clock program ID, and
|
// - any public tx that invokes the clock program, and
|
||||||
// - any PP tx that declares a modified post-state for the clock account.
|
// - any PP tx that declares a modified post-state for a clock account.
|
||||||
let touches_system = match &tx {
|
let touches_system = tx.is_invocation_of_clock_program(&clock_accounts_pre);
|
||||||
NSSATransaction::Public(p) => p.message().program_id == clock_program_id,
|
|
||||||
NSSATransaction::PrivacyPreserving(pp) => clock_accounts_pre
|
|
||||||
.iter()
|
|
||||||
.any(|(id, pre)| pp.public_post_state_for(id).is_some_and(|post| post != pre)),
|
|
||||||
NSSATransaction::ProgramDeployment(_) => false,
|
|
||||||
};
|
|
||||||
if touches_system {
|
if touches_system {
|
||||||
warn!(
|
warn!(
|
||||||
"Dropping transaction from mempool: user transactions may not modify the system clock account"
|
"Dropping transaction from mempool: user transactions may not modify the system clock account"
|
||||||
@ -310,15 +292,14 @@ impl<BC: BlockSettlementClientTrait, IC: IndexerClientTrait> SequencerCore<BC, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Append the Block Context Program invocation as the mandatory last transaction.
|
// Append the Block Context Program invocation as the mandatory last transaction.
|
||||||
match self.execute_check_transaction_on_state(NSSATransaction::clock_invocation(new_block_timestamp), new_block_height, new_block_timestamp)
|
let clock_nssa_tx = self
|
||||||
{
|
.execute_check_transaction_on_state(
|
||||||
Ok(clock_nssa_tx) => {
|
NSSATransaction::clock_invocation(new_block_timestamp),
|
||||||
valid_transactions.push(clock_nssa_tx);
|
new_block_height,
|
||||||
}
|
new_block_timestamp,
|
||||||
Err(err) => {
|
)
|
||||||
error!("Clock transaction failed execution check: {err:#?}");
|
.context("Clock transaction failed — aborting block production")?;
|
||||||
}
|
valid_transactions.push(clock_nssa_tx);
|
||||||
}
|
|
||||||
|
|
||||||
let hashable_data = HashableBlockData {
|
let hashable_data = HashableBlockData {
|
||||||
block_id: new_block_height,
|
block_id: new_block_height,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user