diff --git a/.changelog/unreleased/improvements/2383-comet-timestamp.md b/.changelog/unreleased/improvements/2383-comet-timestamp.md new file mode 100644 index 0000000000..2ed42d717d --- /dev/null +++ b/.changelog/unreleased/improvements/2383-comet-timestamp.md @@ -0,0 +1,2 @@ +- Updated block validation to require a valid timestamp. + ([\#2383](https://github.com/anoma/namada/pull/2383)) \ No newline at end of file diff --git a/crates/apps/src/lib/node/ledger/shell/mod.rs b/crates/apps/src/lib/node/ledger/shell/mod.rs index 61b513baea..e795beb229 100644 --- a/crates/apps/src/lib/node/ledger/shell/mod.rs +++ b/crates/apps/src/lib/node/ledger/shell/mod.rs @@ -82,7 +82,6 @@ use crate::config::{self, genesis, TendermintMode, ValidatorLocalConfig}; use crate::facade::tendermint::abci::types::{Misbehavior, MisbehaviorKind}; use crate::facade::tendermint::v0_37::abci::{request, response}; use crate::facade::tendermint::{self, validator}; -use crate::facade::tendermint_proto::google::protobuf::Timestamp; use crate::facade::tendermint_proto::v0_37::crypto::public_key; use crate::node::ledger::shims::abcipp_shim_types::shim; use crate::node::ledger::shims::abcipp_shim_types::shim::response::TxResult; @@ -585,25 +584,6 @@ where response } - /// Takes the optional tendermint timestamp of the block: if it's Some than - /// converts it to a [`DateTimeUtc`], otherwise retrieve from self the - /// time of the last block committed - pub fn get_block_timestamp( - &self, - tendermint_block_time: Option, - ) -> DateTimeUtc { - if let Some(t) = tendermint_block_time { - if let Ok(t) = t.try_into() { - return t; - } - } - // Default to last committed block time - self.wl_storage - .storage - .get_last_block_timestamp() - .expect("Failed to retrieve last block timestamp") - } - /// Read the value for a storage key dropping any error pub fn read_storage_key(&self, key: &Key) -> Option where @@ -1099,7 +1079,11 @@ where // Tx expiration if let Some(exp) = tx.header.expiration { - let last_block_timestamp = self.get_block_timestamp(None); + let last_block_timestamp = self + .wl_storage + .storage + .get_last_block_timestamp() + .expect("Failed to retrieve last block timestamp"); if last_block_timestamp > exp { response.code = ResultCode::ExpiredTx.into(); @@ -1799,6 +1783,7 @@ mod test_utils { &self, req: ProcessProposal, ) -> std::result::Result, TestError> { + let time = DateTimeUtc::now(); let (resp, tx_results) = self.shell.process_proposal(RequestProcessProposal { txs: req @@ -1816,6 +1801,11 @@ mod test_utils { ) .unwrap() .into(), + time: Some(Timestamp { + seconds: time.0.timestamp(), + nanos: time.0.timestamp_subsec_nanos() as i32, + }), + ..Default::default() }); let results = tx_results diff --git a/crates/apps/src/lib/node/ledger/shell/process_proposal.rs b/crates/apps/src/lib/node/ledger/shell/process_proposal.rs index bb2085a483..a92b9f27c3 100644 --- a/crates/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/crates/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -104,7 +104,10 @@ where let (tx_results, meta) = self.process_txs( &req.txs, - self.get_block_timestamp(req.time), + req.time + .expect("Missing timestamp in proposed block") + .try_into() + .expect("Failed conversion of Comet timestamp"), &native_block_proposer_address, ); diff --git a/crates/apps/src/lib/node/ledger/shell/testing/node.rs b/crates/apps/src/lib/node/ledger/shell/testing/node.rs index 42dfdf1cf9..a3ab32dcb6 100644 --- a/crates/apps/src/lib/node/ledger/shell/testing/node.rs +++ b/crates/apps/src/lib/node/ledger/shell/testing/node.rs @@ -34,6 +34,7 @@ use namada::types::key::tm_consensus_key_raw_hash; use namada::types::storage::{BlockHash, BlockHeight, Epoch, Header}; use namada::types::time::DateTimeUtc; use namada_sdk::queries::Client; +use namada_sdk::tendermint_proto::google::protobuf::Timestamp; use namada_sdk::tx::data::ResultCode; use regex::Regex; use tendermint_rpc::endpoint::block; @@ -506,9 +507,14 @@ impl MockNode { self.advance_to_allowed_block(); let (proposer_address, votes) = self.prepare_request(); + let time = DateTimeUtc::now(); let req = RequestProcessProposal { txs: txs.clone().into_iter().map(|tx| tx.into()).collect(), proposer_address: proposer_address.clone().into(), + time: Some(Timestamp { + seconds: time.0.timestamp(), + nanos: time.0.timestamp_subsec_nanos() as i32, + }), ..Default::default() }; let mut locked = self.shell.lock().unwrap();