From 000d939a2c8fcb1d0fa229acb2ca3c21dfa037e3 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Wed, 3 Aug 2022 12:36:25 +0100 Subject: [PATCH 1/9] clear pending coinbase transactions now rely on utxo hashes --- base_layer/core/src/transactions/coinbase_builder.rs | 2 +- .../wallet/src/output_manager_service/service.rs | 4 ++-- .../output_manager_service/storage/database/backend.rs | 4 ++-- .../src/output_manager_service/storage/database/mod.rs | 6 +++--- .../output_manager_service/storage/sqlite_db/mod.rs | 8 ++++---- .../storage/sqlite_db/output_sql.rs | 10 ++++++++++ 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index 6363831374..ecdce58e26 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -203,7 +203,7 @@ impl CoinbaseBuilder { let sig = Signature::sign(spending_key.clone(), nonce, &challenge) .map_err(|_| CoinbaseBuildError::BuildError("Challenge could not be represented as a scalar".into()))?; - let sender_offset_private_key = PrivateKey::random(&mut OsRng); + let sender_offset_private_key = PrivateKey::from_bytes(Blake256::digest(spending_key)); // H(spending_key) <- Blake256 let sender_offset_public_key = PublicKey::from_secret_key(&sender_offset_private_key); let covenant = self.covenant; diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index cc16d39468..c50c7da0aa 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -1012,12 +1012,12 @@ where match self .resources .db - .clear_pending_coinbase_transaction_at_block_height(block_height) + .clear_pending_coinbase_transaction_with_hash(output.hash.as_slice()) { Ok(_) => { debug!( target: LOG_TARGET, - "An existing pending coinbase was cleared for block height {}", block_height + "An existing pending coinbase was cleared with hash {}", output.hash.to_hex() ) }, Err(e) => match e { diff --git a/base_layer/wallet/src/output_manager_service/storage/database/backend.rs b/base_layer/wallet/src/output_manager_service/storage/database/backend.rs index 4527e1b561..e3a7cad923 100644 --- a/base_layer/wallet/src/output_manager_service/storage/database/backend.rs +++ b/base_layer/wallet/src/output_manager_service/storage/database/backend.rs @@ -97,9 +97,9 @@ pub trait OutputManagerBackend: Send + Sync + Clone { /// Get the output that was most recently spent, ordered descending by mined height fn get_last_spent_output(&self) -> Result, OutputManagerStorageError>; /// Check if there is a pending coinbase transaction at this block height, if there is clear it. - fn clear_pending_coinbase_transaction_at_block_height( + fn clear_pending_coinbase_transaction_with_hash( &self, - block_height: u64, + hash: &[u8], ) -> Result<(), OutputManagerStorageError>; /// Set if a coinbase output is abandoned or not fn set_coinbase_abandoned(&self, tx_id: TxId, abandoned: bool) -> Result<(), OutputManagerStorageError>; diff --git a/base_layer/wallet/src/output_manager_service/storage/database/mod.rs b/base_layer/wallet/src/output_manager_service/storage/database/mod.rs index 91c15e1bbb..d5af1bcbae 100644 --- a/base_layer/wallet/src/output_manager_service/storage/database/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/database/mod.rs @@ -220,11 +220,11 @@ where T: OutputManagerBackend + 'static } /// Check if there is a pending coinbase transaction at this block height, if there is clear it. - pub fn clear_pending_coinbase_transaction_at_block_height( + pub fn clear_pending_coinbase_transaction_with_hash( &self, - block_height: u64, + hash: &[u8], ) -> Result<(), OutputManagerStorageError> { - self.db.clear_pending_coinbase_transaction_at_block_height(block_height) + self.db.clear_pending_coinbase_transaction_with_hash(hash) } pub fn fetch_all_unspent_outputs(&self) -> Result, OutputManagerStorageError> { diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs index 09fdafe15d..f2d0a21e03 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs @@ -1074,21 +1074,21 @@ impl OutputManagerBackend for OutputManagerSqliteDatabase { Ok(()) } - fn clear_pending_coinbase_transaction_at_block_height( + fn clear_pending_coinbase_transaction_with_hash( &self, - block_height: u64, + hash: &[u8], ) -> Result<(), OutputManagerStorageError> { let start = Instant::now(); let conn = self.database_connection.get_pooled_connection()?; let acquire_lock = start.elapsed(); - let output = OutputSql::find_pending_coinbase_at_block_height(block_height, &conn)?; + let output = OutputSql::find_pending_coinbase_with_hash(hash, &conn)?; output.delete(&conn)?; if start.elapsed().as_millis() > 0 { trace!( target: LOG_TARGET, - "sqlite profile - clear_pending_coinbase_transaction_at_block_height: lock {} + db_op {} = {} ms", + "sqlite profile - clear_pending_coinbase_transaction_with_hash: lock {} + db_op {} = {} ms", acquire_lock.as_millis(), (start.elapsed() - acquire_lock).as_millis(), start.elapsed().as_millis() diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs index 63480ee86c..804681ab59 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs @@ -576,6 +576,16 @@ impl OutputSql { .first::(conn)?) } + pub fn find_pending_coinbase_with_hash( + hash: &[u8], + conn: &SqliteConnection, + ) -> Result { + Ok(outputs::table + .filter(outputs::status.ne(OutputStatus::Unspent as i32)) + .filter(outputs::hash.eq(Some(hash))) + .first::(conn)?) + } + /// Find a particular Output, if it exists and is in the specified Spent state pub fn find_pending_coinbase_at_block_height( block_height: u64, From aa225a474a69c0cf0ad02f203c1de853063742b2 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Mon, 8 Aug 2022 12:15:51 +0100 Subject: [PATCH 2/9] sync with dev --- base_layer/core/src/transactions/coinbase_builder.rs | 2 +- .../wallet/src/output_manager_service/service.rs | 4 ++-- .../output_manager_service/storage/database/backend.rs | 4 ++-- .../src/output_manager_service/storage/database/mod.rs | 6 +++--- .../output_manager_service/storage/sqlite_db/mod.rs | 8 ++++---- .../storage/sqlite_db/output_sql.rs | 10 ---------- 6 files changed, 12 insertions(+), 22 deletions(-) diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index 5b984352cf..0b55b78e6d 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -205,7 +205,7 @@ impl CoinbaseBuilder { let sig = Signature::sign(spending_key.clone(), nonce, &challenge) .map_err(|_| CoinbaseBuildError::BuildError("Challenge could not be represented as a scalar".into()))?; - let sender_offset_private_key = PrivateKey::from_bytes(Blake256::digest(spending_key)); // H(spending_key) <- Blake256 + let sender_offset_private_key = PrivateKey::random(&mut OsRng); let sender_offset_public_key = PublicKey::from_secret_key(&sender_offset_private_key); let covenant = self.covenant; diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index 9e8395c57a..97bdfd64a3 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -1014,12 +1014,12 @@ where match self .resources .db - .clear_pending_coinbase_transaction_with_hash(output.hash.as_slice()) + .clear_pending_coinbase_transaction_at_block_height(block_height) { Ok(_) => { debug!( target: LOG_TARGET, - "An existing pending coinbase was cleared with hash {}", output.hash.to_hex() + "An existing pending coinbase was cleared for block height {}", block_height ) }, Err(e) => match e { diff --git a/base_layer/wallet/src/output_manager_service/storage/database/backend.rs b/base_layer/wallet/src/output_manager_service/storage/database/backend.rs index e3a7cad923..4527e1b561 100644 --- a/base_layer/wallet/src/output_manager_service/storage/database/backend.rs +++ b/base_layer/wallet/src/output_manager_service/storage/database/backend.rs @@ -97,9 +97,9 @@ pub trait OutputManagerBackend: Send + Sync + Clone { /// Get the output that was most recently spent, ordered descending by mined height fn get_last_spent_output(&self) -> Result, OutputManagerStorageError>; /// Check if there is a pending coinbase transaction at this block height, if there is clear it. - fn clear_pending_coinbase_transaction_with_hash( + fn clear_pending_coinbase_transaction_at_block_height( &self, - hash: &[u8], + block_height: u64, ) -> Result<(), OutputManagerStorageError>; /// Set if a coinbase output is abandoned or not fn set_coinbase_abandoned(&self, tx_id: TxId, abandoned: bool) -> Result<(), OutputManagerStorageError>; diff --git a/base_layer/wallet/src/output_manager_service/storage/database/mod.rs b/base_layer/wallet/src/output_manager_service/storage/database/mod.rs index d5af1bcbae..91c15e1bbb 100644 --- a/base_layer/wallet/src/output_manager_service/storage/database/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/database/mod.rs @@ -220,11 +220,11 @@ where T: OutputManagerBackend + 'static } /// Check if there is a pending coinbase transaction at this block height, if there is clear it. - pub fn clear_pending_coinbase_transaction_with_hash( + pub fn clear_pending_coinbase_transaction_at_block_height( &self, - hash: &[u8], + block_height: u64, ) -> Result<(), OutputManagerStorageError> { - self.db.clear_pending_coinbase_transaction_with_hash(hash) + self.db.clear_pending_coinbase_transaction_at_block_height(block_height) } pub fn fetch_all_unspent_outputs(&self) -> Result, OutputManagerStorageError> { diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs index 9fab53d2d1..73af04cd9c 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs @@ -1074,21 +1074,21 @@ impl OutputManagerBackend for OutputManagerSqliteDatabase { Ok(()) } - fn clear_pending_coinbase_transaction_with_hash( + fn clear_pending_coinbase_transaction_at_block_height( &self, - hash: &[u8], + block_height: u64, ) -> Result<(), OutputManagerStorageError> { let start = Instant::now(); let conn = self.database_connection.get_pooled_connection()?; let acquire_lock = start.elapsed(); - let output = OutputSql::find_pending_coinbase_with_hash(hash, &conn)?; + let output = OutputSql::find_pending_coinbase_at_block_height(block_height, &conn)?; output.delete(&conn)?; if start.elapsed().as_millis() > 0 { trace!( target: LOG_TARGET, - "sqlite profile - clear_pending_coinbase_transaction_with_hash: lock {} + db_op {} = {} ms", + "sqlite profile - clear_pending_coinbase_transaction_at_block_height: lock {} + db_op {} = {} ms", acquire_lock.as_millis(), (start.elapsed() - acquire_lock).as_millis(), start.elapsed().as_millis() diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs index cfedab1288..8e6cbdd476 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs @@ -576,16 +576,6 @@ impl OutputSql { .first::(conn)?) } - pub fn find_pending_coinbase_with_hash( - hash: &[u8], - conn: &SqliteConnection, - ) -> Result { - Ok(outputs::table - .filter(outputs::status.ne(OutputStatus::Unspent as i32)) - .filter(outputs::hash.eq(Some(hash))) - .first::(conn)?) - } - /// Find a particular Output, if it exists and is in the specified Spent state pub fn find_pending_coinbase_at_block_height( block_height: u64, From 22e3cfae31e1a54f2a4aea1c97249457e0a6d174 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 16:16:31 +0100 Subject: [PATCH 3/9] add domain separation, with hashing api, for dan layer --- dan_layer/core/src/models/hashing.rs | 42 +++++++++++++++++++ .../core/src/models/hot_stuff_message.rs | 6 ++- dan_layer/core/src/models/mod.rs | 2 + dan_layer/core/src/models/tari_dan_payload.rs | 4 +- dan_layer/core/src/templates/hashing.rs | 41 ++++++++++++++++++ dan_layer/core/src/templates/mod.rs | 1 + .../core/src/templates/tip004_template.rs | 12 +++++- dan_layer/engine/src/instructions/hashing.rs | 41 ++++++++++++++++++ .../engine/src/instructions/instruction.rs | 6 ++- dan_layer/engine/src/instructions/mod.rs | 2 + 10 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 dan_layer/core/src/models/hashing.rs create mode 100644 dan_layer/core/src/templates/hashing.rs create mode 100644 dan_layer/engine/src/instructions/hashing.rs diff --git a/dan_layer/core/src/models/hashing.rs b/dan_layer/core/src/models/hashing.rs new file mode 100644 index 0000000000..7b30efefdd --- /dev/null +++ b/dan_layer/core/src/models/hashing.rs @@ -0,0 +1,42 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerCoreModelsDomain, + "com.tari.tari_project.dan_layer.core.models", + 1 +); + +pub(crate) const HOT_STUFF_MESSAGE_LABEL: &str = "hot_stuff_message"; +pub(crate) const TARI_DAN_PAYLOAD_LABEL: &str = "tari_dan_payload"; + +pub(crate) fn dan_layer_models_hasher( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/core/src/models/hot_stuff_message.rs b/dan_layer/core/src/models/hot_stuff_message.rs index 784658a62d..f401ddd0fb 100644 --- a/dan_layer/core/src/models/hot_stuff_message.rs +++ b/dan_layer/core/src/models/hot_stuff_message.rs @@ -25,7 +25,9 @@ use tari_common_types::types::FixedHash; use tari_core::transactions::transaction_components::SignerSignature; use tari_crypto::hash::blake2::Blake256; +use super::HOT_STUFF_MESSAGE_LABEL; use crate::models::{ + dan_layer_core_hasher, HotStuffMessageType, HotStuffTreeNode, Payload, @@ -200,7 +202,7 @@ impl HotStuffMessage { } pub fn create_signature_challenge(&self) -> Vec { - let mut b = Blake256::new() + let mut b = dan_layer_core_hasher::(HOT_STUFF_MESSAGE_LABEL) .chain(&[self.message_type.as_u8()]) .chain(self.view_number.as_u64().to_le_bytes()); if let Some(ref node) = self.node { @@ -209,7 +211,7 @@ impl HotStuffMessage { b = b.chain(node_hash.as_bytes()); } else { } - b.finalize().to_vec() + b.finalize().as_ref().to_vec() } pub fn view_number(&self) -> ViewId { diff --git a/dan_layer/core/src/models/mod.rs b/dan_layer/core/src/models/mod.rs index 70d346b560..852a81b949 100644 --- a/dan_layer/core/src/models/mod.rs +++ b/dan_layer/core/src/models/mod.rs @@ -28,6 +28,7 @@ mod base_layer_output; mod committee; pub mod domain_events; mod error; +mod hashing; mod hot_stuff_message; mod hot_stuff_tree_node; mod instruction_set; @@ -46,6 +47,7 @@ pub use base_layer_metadata::BaseLayerMetadata; pub use base_layer_output::{BaseLayerOutput, CheckpointOutput, CommitteeOutput}; pub use committee::Committee; pub use error::ModelError; +pub(crate) use hashing::{dan_layer_models_hasher, HOT_STUFF_MESSAGE_LABEL}; pub use hot_stuff_message::HotStuffMessage; pub use hot_stuff_tree_node::HotStuffTreeNode; pub use instruction_set::InstructionSet; diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 40df6810ec..1c35f00d25 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -27,6 +27,7 @@ use tari_common_types::types::FixedHash; use tari_crypto::hash::blake2::Blake256; use tari_dan_engine::instructions::Instruction; +use super::{dan_layer_models_hasher, hashing::TARI_DAN_PAYLOAD_LABEL}; use crate::models::{ConsensusHash, InstructionSet, Payload}; #[derive(Debug, Clone)] @@ -56,7 +57,8 @@ impl TariDanPayload { } fn calculate_hash(&self) -> FixedHash { - let result = Blake256::new().chain(self.instruction_set.consensus_hash()); + let result = + dan_layer_models_hasher::(TARI_DAN_PAYLOAD_LABEL).chain(self.instruction_set.consensus_hash()); if let Some(ref ck) = self.checkpoint { result.chain(ck.consensus_hash()).finalize().into() } else { diff --git a/dan_layer/core/src/templates/hashing.rs b/dan_layer/core/src/templates/hashing.rs new file mode 100644 index 0000000000..5b5972d096 --- /dev/null +++ b/dan_layer/core/src/templates/hashing.rs @@ -0,0 +1,41 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerCoreTemplatesDomain, + "com.tari.tari_project.dan_layer.core.templates", + 1 +); + +pub(crate) const TIP004_TEMPLATE_LABEL: &str = "tip004_template"; + +pub(crate) fn dan_layer_templates_hasher( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/core/src/templates/mod.rs b/dan_layer/core/src/templates/mod.rs index 5a94462230..66b350a3e1 100644 --- a/dan_layer/core/src/templates/mod.rs +++ b/dan_layer/core/src/templates/mod.rs @@ -20,6 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +pub mod hashing; pub mod tip002_template; pub mod tip004_template; pub mod tip721_template; diff --git a/dan_layer/core/src/templates/tip004_template.rs b/dan_layer/core/src/templates/tip004_template.rs index 17d1d5f4cd..20201df0d1 100644 --- a/dan_layer/core/src/templates/tip004_template.rs +++ b/dan_layer/core/src/templates/tip004_template.rs @@ -29,7 +29,11 @@ use tari_dan_common_types::proto::tips::tip004; use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}; use tari_utilities::hex::Hex; -use crate::{models::InstructionSet, DigitalAssetError}; +use crate::{ + hashing::{dan_layer_templates_hasher, TIP004_TEMPLATE_LABEL}, + models::InstructionSet, + DigitalAssetError, +}; const LOG_TARGET: &str = "tari::dan_layer::core::templates::tip004_template"; @@ -95,7 +99,11 @@ fn mint(args: &[u8], state_db: &mut TUnitOfWork) } fn hash_of(s: &str) -> Vec { - Blake256::new().chain(s).finalize().to_vec() + dan_layer_templates_hasher::(TIP004_TEMPLATE_LABEL) + .chain(s) + .finalize() + .as_ref() + .to_vec() } fn balance_of( diff --git a/dan_layer/engine/src/instructions/hashing.rs b/dan_layer/engine/src/instructions/hashing.rs new file mode 100644 index 0000000000..aa480ed46d --- /dev/null +++ b/dan_layer/engine/src/instructions/hashing.rs @@ -0,0 +1,41 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerEngineInstructionsDomain, + "com.tari.tari_project.dan_layer.engine.instructions", + 1 +); + +pub(crate) const INSTRUCTION_LABEL: &str = "instruction"; + +pub(crate) fn dan_layer_engine_instructions( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/engine/src/instructions/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs index dd1a632ed2..331e92aaf0 100644 --- a/dan_layer/engine/src/instructions/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -9,6 +9,8 @@ use tari_crypto::hash::blake2::Blake256; use tari_dan_common_types::TemplateId; use tari_utilities::hex::Hex; +use super::hashing::{dan_layer_engine_instructions, INSTRUCTION_LABEL}; + #[derive(Clone, Debug)] pub struct Instruction { template_id: TemplateId, @@ -79,7 +81,9 @@ impl Instruction { } pub fn calculate_hash(&self) -> FixedHash { - let b = Blake256::new().chain(self.method.as_bytes()).chain(&self.args); + let b = dan_layer_engine_instructions(INSTRUCTION_LABEL) + .chain(self.method.as_bytes()) + .chain(&self.args); // b.chain(self.from.as_bytes()) // .chain(com_sig_to_bytes(&self.signature)) b.finalize().into() diff --git a/dan_layer/engine/src/instructions/mod.rs b/dan_layer/engine/src/instructions/mod.rs index e7dc0b50e9..311446d253 100644 --- a/dan_layer/engine/src/instructions/mod.rs +++ b/dan_layer/engine/src/instructions/mod.rs @@ -1,6 +1,8 @@ // Copyright 2022 The Tari Project // SPDX-License-Identifier: BSD-3-Clause +mod hashing; mod instruction; +pub(crate) use hashing::dan_layer_engine; pub use instruction::Instruction; From 6dc8edb8c88d7bfb135c2687b8fd0fa150713254 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 16:40:40 +0100 Subject: [PATCH 4/9] refactor clippy --- dan_layer/engine/src/instructions/hashing.rs | 2 +- dan_layer/engine/src/instructions/instruction.rs | 15 +++++++++------ dan_layer/engine/src/instructions/mod.rs | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/dan_layer/engine/src/instructions/hashing.rs b/dan_layer/engine/src/instructions/hashing.rs index aa480ed46d..2602d3ddc5 100644 --- a/dan_layer/engine/src/instructions/hashing.rs +++ b/dan_layer/engine/src/instructions/hashing.rs @@ -37,5 +37,5 @@ pub(crate) const INSTRUCTION_LABEL: &str = "instruction"; pub(crate) fn dan_layer_engine_instructions( label: &'static str, ) -> DomainSeparatedHasher { - DomainSeparatedHasher::::new_with_label(label) + DomainSeparatedHasher::::new_with_label(label) } diff --git a/dan_layer/engine/src/instructions/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs index 331e92aaf0..cc0edadd99 100644 --- a/dan_layer/engine/src/instructions/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -3,7 +3,6 @@ use std::fmt::{Display, Formatter}; -use digest::Digest; use tari_common_types::types::{FixedHash, PublicKey}; use tari_crypto::hash::blake2::Blake256; use tari_dan_common_types::TemplateId; @@ -81,12 +80,16 @@ impl Instruction { } pub fn calculate_hash(&self) -> FixedHash { - let b = dan_layer_engine_instructions(INSTRUCTION_LABEL) + // Blake256 has 32-byte output + let b = dan_layer_engine_instructions::(INSTRUCTION_LABEL) .chain(self.method.as_bytes()) - .chain(&self.args); - // b.chain(self.from.as_bytes()) - // .chain(com_sig_to_bytes(&self.signature)) - b.finalize().into() + .chain(&self.args) + .finalize(); + + let mut out = [0u8; 32]; + out.clone_from_slice(b.as_ref()); + + out.into() } } diff --git a/dan_layer/engine/src/instructions/mod.rs b/dan_layer/engine/src/instructions/mod.rs index 311446d253..bb63dfbafa 100644 --- a/dan_layer/engine/src/instructions/mod.rs +++ b/dan_layer/engine/src/instructions/mod.rs @@ -4,5 +4,5 @@ mod hashing; mod instruction; -pub(crate) use hashing::dan_layer_engine; +pub(crate) use hashing::dan_layer_engine_instructions; pub use instruction::Instruction; From 94da098b0d90a9fd839b0e964e012d6022a27833 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 17:12:49 +0100 Subject: [PATCH 5/9] cargo checks --- dan_layer/core/src/models/hot_stuff_message.rs | 3 +-- dan_layer/core/src/models/tari_dan_payload.rs | 11 ++++++++--- dan_layer/core/src/templates/hashing.rs | 4 ++-- dan_layer/core/src/templates/tip004_template.rs | 8 ++------ dan_layer/engine/src/instructions/instruction.rs | 2 +- dan_layer/engine/src/instructions/mod.rs | 1 - 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dan_layer/core/src/models/hot_stuff_message.rs b/dan_layer/core/src/models/hot_stuff_message.rs index f401ddd0fb..3c2b39313e 100644 --- a/dan_layer/core/src/models/hot_stuff_message.rs +++ b/dan_layer/core/src/models/hot_stuff_message.rs @@ -20,14 +20,13 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use digest::Digest; use tari_common_types::types::FixedHash; use tari_core::transactions::transaction_components::SignerSignature; use tari_crypto::hash::blake2::Blake256; use super::HOT_STUFF_MESSAGE_LABEL; use crate::models::{ - dan_layer_core_hasher, + dan_layer_models_hasher, HotStuffMessageType, HotStuffTreeNode, Payload, diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 1c35f00d25..b0df5b223f 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -22,7 +22,6 @@ use std::fmt::Debug; -use digest::Digest; use tari_common_types::types::FixedHash; use tari_crypto::hash::blake2::Blake256; use tari_dan_engine::instructions::Instruction; @@ -59,11 +58,17 @@ impl TariDanPayload { fn calculate_hash(&self) -> FixedHash { let result = dan_layer_models_hasher::(TARI_DAN_PAYLOAD_LABEL).chain(self.instruction_set.consensus_hash()); + + let mut out = [0u8; 32]; + if let Some(ref ck) = self.checkpoint { - result.chain(ck.consensus_hash()).finalize().into() + let result = result.chain(ck.consensus_hash()).finalize(); } else { - result.finalize().into() + let result = result.finalize(); } + + out.copy_from_slice(result.as_ref()); + out.into() } } diff --git a/dan_layer/core/src/templates/hashing.rs b/dan_layer/core/src/templates/hashing.rs index 5b5972d096..abe1b7a535 100644 --- a/dan_layer/core/src/templates/hashing.rs +++ b/dan_layer/core/src/templates/hashing.rs @@ -36,6 +36,6 @@ pub(crate) const TIP004_TEMPLATE_LABEL: &str = "tip004_template"; pub(crate) fn dan_layer_templates_hasher( label: &'static str, -) -> DomainSeparatedHasher { - DomainSeparatedHasher::::new_with_label(label) +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) } diff --git a/dan_layer/core/src/templates/tip004_template.rs b/dan_layer/core/src/templates/tip004_template.rs index 20201df0d1..4f14661fa2 100644 --- a/dan_layer/core/src/templates/tip004_template.rs +++ b/dan_layer/core/src/templates/tip004_template.rs @@ -20,7 +20,6 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use digest::Digest; use log::*; use prost::Message; use tari_core::transactions::transaction_components::TemplateParameter; @@ -29,11 +28,8 @@ use tari_dan_common_types::proto::tips::tip004; use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}; use tari_utilities::hex::Hex; -use crate::{ - hashing::{dan_layer_templates_hasher, TIP004_TEMPLATE_LABEL}, - models::InstructionSet, - DigitalAssetError, -}; +use super::hashing::{dan_layer_templates_hasher, TIP004_TEMPLATE_LABEL}; +use crate::{models::InstructionSet, DigitalAssetError}; const LOG_TARGET: &str = "tari::dan_layer::core::templates::tip004_template"; diff --git a/dan_layer/engine/src/instructions/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs index cc0edadd99..a2ea180aeb 100644 --- a/dan_layer/engine/src/instructions/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -87,7 +87,7 @@ impl Instruction { .finalize(); let mut out = [0u8; 32]; - out.clone_from_slice(b.as_ref()); + out.copy_from_slice(b.as_ref()); out.into() } diff --git a/dan_layer/engine/src/instructions/mod.rs b/dan_layer/engine/src/instructions/mod.rs index bb63dfbafa..614a8ed58b 100644 --- a/dan_layer/engine/src/instructions/mod.rs +++ b/dan_layer/engine/src/instructions/mod.rs @@ -4,5 +4,4 @@ mod hashing; mod instruction; -pub(crate) use hashing::dan_layer_engine_instructions; pub use instruction::Instruction; From 25ba0bbb39694889dd280e65aa32321dcfca5200 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 17:26:56 +0100 Subject: [PATCH 6/9] refactor cargo checks --- dan_layer/core/src/models/hot_stuff_message.rs | 2 +- dan_layer/core/src/models/tari_dan_payload.rs | 6 +++--- dan_layer/engine/src/instructions/instruction.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dan_layer/core/src/models/hot_stuff_message.rs b/dan_layer/core/src/models/hot_stuff_message.rs index 3c2b39313e..5ee81adce8 100644 --- a/dan_layer/core/src/models/hot_stuff_message.rs +++ b/dan_layer/core/src/models/hot_stuff_message.rs @@ -201,7 +201,7 @@ impl HotStuffMessage { } pub fn create_signature_challenge(&self) -> Vec { - let mut b = dan_layer_core_hasher::(HOT_STUFF_MESSAGE_LABEL) + let mut b = dan_layer_models_hasher::(HOT_STUFF_MESSAGE_LABEL) .chain(&[self.message_type.as_u8()]) .chain(self.view_number.as_u64().to_le_bytes()); if let Some(ref node) = self.node { diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index b0df5b223f..37e633fa1d 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -62,11 +62,11 @@ impl TariDanPayload { let mut out = [0u8; 32]; if let Some(ref ck) = self.checkpoint { - let result = result.chain(ck.consensus_hash()).finalize(); - } else { - let result = result.finalize(); + let result = result.chain(ck.consensus_hash()); } + let result = result.finalize(); + out.copy_from_slice(result.as_ref()); out.into() } diff --git a/dan_layer/engine/src/instructions/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs index a2ea180aeb..4e71c7f2cd 100644 --- a/dan_layer/engine/src/instructions/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -85,7 +85,7 @@ impl Instruction { .chain(self.method.as_bytes()) .chain(&self.args) .finalize(); - + let mut out = [0u8; 32]; out.copy_from_slice(b.as_ref()); From bee9ab5050bfa4a693f0c3ecc86e3147c46f5c48 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 17:42:18 +0100 Subject: [PATCH 7/9] refactor code --- dan_layer/core/src/models/tari_dan_payload.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 37e633fa1d..b823e2b122 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -36,7 +36,7 @@ pub struct TariDanPayload { checkpoint: Option, } -impl TariDanPayload { +impl TariDanPaconstruct_challengeyload { pub fn new(instruction_set: InstructionSet, checkpoint: Option) -> Self { let mut result = Self { hash: FixedHash::zero(), @@ -61,9 +61,9 @@ impl TariDanPayload { let mut out = [0u8; 32]; - if let Some(ref ck) = self.checkpoint { - let result = result.chain(ck.consensus_hash()); - } + let result = if let Some(ref ck) = self.checkpoint { + result.chain(ck.consensus_hash()) + }; let result = result.finalize(); From 53fe3dbcdb9a230f5901f77d5ea35b598b93b26b Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 17:51:53 +0100 Subject: [PATCH 8/9] rename tari dan payload impl --- dan_layer/core/src/models/tari_dan_payload.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index b823e2b122..c6e6c17d01 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -36,7 +36,7 @@ pub struct TariDanPayload { checkpoint: Option, } -impl TariDanPaconstruct_challengeyload { +impl TariDanPayload { pub fn new(instruction_set: InstructionSet, checkpoint: Option) -> Self { let mut result = Self { hash: FixedHash::zero(), From 5d7abb1d8333895c438e4a0af2edb60f0119145f Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Tue, 9 Aug 2022 17:59:14 +0100 Subject: [PATCH 9/9] finalize hasher --- dan_layer/core/src/models/tari_dan_payload.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index c6e6c17d01..c4567c4702 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -62,11 +62,11 @@ impl TariDanPayload { let mut out = [0u8; 32]; let result = if let Some(ref ck) = self.checkpoint { - result.chain(ck.consensus_hash()) + result.chain(ck.consensus_hash()).finalize() + } else { + result.finalize() }; - let result = result.finalize(); - out.copy_from_slice(result.as_ref()); out.into() }