From f6faf424cc1cfeda6c02806ef384bf4b3738ef38 Mon Sep 17 00:00:00 2001 From: Arya Date: Fri, 18 Oct 2024 19:05:26 -0400 Subject: [PATCH] Avoids returning genesis coinbase tx hash when indexes are missing --- .../service/finalized_state/disk_format/block.rs | 12 +++++++++++- .../service/finalized_state/zebra_db/shielded.rs | 15 +++++++++------ .../finalized_state/zebra_db/transparent.rs | 3 ++- zebra-state/src/service/read/block.rs | 3 ++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/zebra-state/src/service/finalized_state/disk_format/block.rs b/zebra-state/src/service/finalized_state/disk_format/block.rs index 378e157a82e..253e79d32d2 100644 --- a/zebra-state/src/service/finalized_state/disk_format/block.rs +++ b/zebra-state/src/service/finalized_state/disk_format/block.rs @@ -314,7 +314,7 @@ impl IntoDisk for TransactionIndex { impl FromDisk for TransactionIndex { fn from_bytes(disk_bytes: impl AsRef<[u8]>) -> Self { - let disk_bytes = disk_bytes.as_ref().try_into().unwrap_or_default(); + let disk_bytes = disk_bytes.as_ref().try_into().unwrap(); TransactionIndex::from_index(u16::from_be_bytes(disk_bytes)) } @@ -331,6 +331,16 @@ impl IntoDisk for TransactionLocation { } } +impl FromDisk for Option { + fn from_bytes(disk_bytes: impl AsRef<[u8]>) -> Self { + if disk_bytes.as_ref().is_empty() { + Some(TransactionLocation::from_bytes(disk_bytes)) + } else { + None + } + } +} + impl FromDisk for TransactionLocation { fn from_bytes(disk_bytes: impl AsRef<[u8]>) -> Self { let (height_bytes, index_bytes) = disk_bytes.as_ref().split_at(HEIGHT_DISK_BYTES); diff --git a/zebra-state/src/service/finalized_state/zebra_db/shielded.rs b/zebra-state/src/service/finalized_state/zebra_db/shielded.rs index 14102c0359f..39e96d67775 100644 --- a/zebra-state/src/service/finalized_state/zebra_db/shielded.rs +++ b/zebra-state/src/service/finalized_state/zebra_db/shielded.rs @@ -62,36 +62,39 @@ impl ZebraDb { } /// Returns the [`TransactionLocation`] of the transaction that revealed - /// the given [`sprout::Nullifier`], if it is revealed in the finalized state. + /// the given [`sprout::Nullifier`], if it is revealed in the finalized state and its + /// spending transaction hash has been indexed. #[allow(clippy::unwrap_in_result)] pub fn sprout_revealing_tx_loc( &self, sprout_nullifier: &sprout::Nullifier, ) -> Option { let sprout_nullifiers = self.db.cf_handle("sprout_nullifiers").unwrap(); - self.db.zs_get(&sprout_nullifiers, &sprout_nullifier) + self.db.zs_get(&sprout_nullifiers, &sprout_nullifier)? } /// Returns the [`TransactionLocation`] of the transaction that revealed - /// the given [`sapling::Nullifier`], if it is revealed in the finalized state. + /// the given [`sapling::Nullifier`], if it is revealed in the finalized state and its + /// spending transaction hash has been indexed. #[allow(clippy::unwrap_in_result)] pub fn sapling_revealing_tx_loc( &self, sapling_nullifier: &sapling::Nullifier, ) -> Option { let sapling_nullifiers = self.db.cf_handle("sapling_nullifiers").unwrap(); - self.db.zs_get(&sapling_nullifiers, &sapling_nullifier) + self.db.zs_get(&sapling_nullifiers, &sapling_nullifier)? } /// Returns the [`TransactionLocation`] of the transaction that revealed - /// the given [`orchard::Nullifier`], if it is revealed in the finalized state. + /// the given [`orchard::Nullifier`], if it is revealed in the finalized state and its + /// spending transaction hash has been indexed. #[allow(clippy::unwrap_in_result)] pub fn orchard_revealing_tx_loc( &self, orchard_nullifier: &orchard::Nullifier, ) -> Option { let orchard_nullifiers = self.db.cf_handle("orchard_nullifiers").unwrap(); - self.db.zs_get(&orchard_nullifiers, &orchard_nullifier) + self.db.zs_get(&orchard_nullifiers, &orchard_nullifier)? } /// Returns `true` if the finalized state contains `sprout_anchor`. diff --git a/zebra-state/src/service/finalized_state/zebra_db/transparent.rs b/zebra-state/src/service/finalized_state/zebra_db/transparent.rs index 08e45981186..304f3363a52 100644 --- a/zebra-state/src/service/finalized_state/zebra_db/transparent.rs +++ b/zebra-state/src/service/finalized_state/zebra_db/transparent.rs @@ -125,7 +125,8 @@ impl ZebraDb { } /// Returns the [`TransactionLocation`] of the transaction that spent the given - /// [`transparent::OutPoint`], if it is unspent in the finalized state. + /// [`transparent::OutPoint`], if it is unspent in the finalized state and its + /// spending transaction hash has been indexed. pub fn spending_tx_loc(&self, outpoint: &transparent::OutPoint) -> Option { let output_location = self.output_location(outpoint)?; self.tx_location_by_spent_output_location(&output_location) diff --git a/zebra-state/src/service/read/block.rs b/zebra-state/src/service/read/block.rs index 6202796d936..88b1ad53da3 100644 --- a/zebra-state/src/service/read/block.rs +++ b/zebra-state/src/service/read/block.rs @@ -184,7 +184,8 @@ where /// Returns the [`Hash`](transaction::Hash) of the transaction that spent an output at /// the provided [`transparent::OutPoint`] or revealed the provided nullifier, if it exists -/// and is spent or revealed in the non-finalized `chain` or finalized `db`. +/// and is spent or revealed in the non-finalized `chain` or finalized `db` and its +/// spending transaction hash has been indexed. pub fn spending_transaction_hash( chain: Option, db: &ZebraDb,