diff --git a/base_layer/wallet/Cargo.toml b/base_layer/wallet/Cargo.toml index 5e47070a72..a11428d36e 100644 --- a/base_layer/wallet/Cargo.toml +++ b/base_layer/wallet/Cargo.toml @@ -37,7 +37,7 @@ chrono = { version = "0.4.19", default-features = false, features = ["serde"] } clear_on_drop = "=0.2.4" crossbeam-channel = "0.5.4" derivative = "2.2.0" -diesel = { version = "1.4.8", features = ["sqlite", "serde_json", "chrono"] } +diesel = { version = "1.4.8", features = ["sqlite", "serde_json", "chrono", "64-column-tables"] } diesel_migrations = "1.4.0" digest = "0.9.0" fs2 = "0.3.0" diff --git a/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/down.sql b/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/down.sql new file mode 100644 index 0000000000..83e26d0a29 --- /dev/null +++ b/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/down.sql @@ -0,0 +1,2 @@ +DROP INDEX outputs_contract_id_index; +ALTER TABLE outputs DROP COLUMN contract_id; diff --git a/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/up.sql b/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/up.sql new file mode 100644 index 0000000000..1dea687f5b --- /dev/null +++ b/base_layer/wallet/migrations/2022-06-22-133735_add_contract_id/up.sql @@ -0,0 +1,4 @@ +ALTER TABLE outputs + ADD contract_id blob NULL; + +CREATE INDEX outputs_contract_id_index ON outputs (contract_id); \ No newline at end of file diff --git a/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/down.sql b/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/down.sql new file mode 100644 index 0000000000..7d6184acc0 --- /dev/null +++ b/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/down.sql @@ -0,0 +1,2 @@ +ALTER TABLE outputs + RENAME COLUMN output_type TO flags; diff --git a/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/up.sql b/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/up.sql new file mode 100644 index 0000000000..7dd8171c09 --- /dev/null +++ b/base_layer/wallet/migrations/2022-06-22-153811_rename_flags_to_output_type/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE outputs + RENAME COLUMN flags TO output_type; \ No newline at end of file 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 2c6a94a40c..ab6eb5d2c7 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 @@ -296,9 +296,12 @@ impl OutputManagerBackend for OutputManagerSqliteDatabase { Ok(result) } - fn fetch_with_features(&self, flags: OutputType) -> Result, OutputManagerStorageError> { + fn fetch_with_features( + &self, + output_type: OutputType, + ) -> Result, OutputManagerStorageError> { let conn = self.database_connection.get_pooled_connection()?; - let mut outputs = OutputSql::index_by_feature_flags(flags, &conn)?; + let mut outputs = OutputSql::index_by_output_type(output_type, &conn)?; for o in &mut outputs { self.decrypt_if_necessary(o)?; } diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs index 6b4024ffc1..884d1a5367 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs @@ -44,7 +44,7 @@ pub struct NewOutputSql { #[derivative(Debug = "ignore")] pub spending_key: Vec, pub value: i64, - pub flags: i32, + pub output_type: i32, pub maturity: i64, pub recovery_byte: i32, pub status: i32, @@ -65,6 +65,7 @@ pub struct NewOutputSql { pub features_json: String, pub covenant: Vec, pub encrypted_value: Vec, + pub contract_id: Option>, } impl NewOutputSql { @@ -79,7 +80,7 @@ impl NewOutputSql { commitment: Some(output.commitment.to_vec()), spending_key: output.unblinded_output.spending_key.to_vec(), value: output.unblinded_output.value.as_u64() as i64, - flags: i32::from(output.unblinded_output.features.output_type.as_byte()), + output_type: i32::from(output.unblinded_output.features.output_type.as_byte()), maturity: output.unblinded_output.features.maturity as i64, recovery_byte: i32::from(output.unblinded_output.features.recovery_byte), status: status as i32, @@ -108,6 +109,7 @@ impl NewOutputSql { })?, covenant: output.unblinded_output.covenant.to_bytes(), encrypted_value: output.unblinded_output.encrypted_value.to_vec(), + contract_id: output.unblinded_output.features.contract_id().map(|h| h.to_vec()), }) } @@ -138,7 +140,7 @@ impl From for NewOutputSql { commitment: o.commitment, spending_key: o.spending_key, value: o.value, - flags: o.flags, + output_type: o.output_type, maturity: o.maturity, recovery_byte: o.recovery_byte, status: o.status, @@ -158,6 +160,7 @@ impl From for NewOutputSql { features_json: o.features_json, covenant: o.covenant, encrypted_value: o.encrypted_value, + contract_id: o.contract_id, } } } 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 fc16e08555..2161db7e07 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 @@ -71,8 +71,7 @@ pub struct OutputSql { #[derivative(Debug = "ignore")] pub spending_key: Vec, pub value: i64, - // TODO: Rename this to output_type - pub flags: i32, + pub output_type: i32, pub maturity: i64, pub recovery_byte: i32, pub status: i32, @@ -101,6 +100,7 @@ pub struct OutputSql { pub spending_priority: i32, pub covenant: Vec, pub encrypted_value: Vec, + pub contract_id: Option>, } impl OutputSql { @@ -196,7 +196,11 @@ impl OutputSql { .filter(outputs::maturity.le(tip_height)) .filter(outputs::features_unique_id.is_null()) .filter(outputs::features_parent_public_key.is_null()) - .filter(outputs::flags.eq(no_flags).or(outputs::flags.eq(coinbase_flag))) + .filter( + outputs::output_type + .eq(no_flags) + .or(outputs::output_type.eq(coinbase_flag)), + ) .order(outputs::value.desc()) .select(outputs::value) .limit(1) @@ -217,7 +221,11 @@ impl OutputSql { .filter(outputs::maturity.le(tip_height)) .filter(outputs::features_unique_id.is_null()) .filter(outputs::features_parent_public_key.is_null()) - .filter(outputs::flags.eq(no_flags).or(outputs::flags.eq(coinbase_flag))) + .filter( + outputs::output_type + .eq(no_flags) + .or(outputs::output_type.eq(coinbase_flag)), + ) .order_by(outputs::spending_priority.desc()); match strategy { UTXOSelectionStrategy::Smallest => { @@ -256,12 +264,12 @@ impl OutputSql { .load(conn)?) } - pub fn index_by_feature_flags( - flags: OutputType, + pub fn index_by_output_type( + output_type: OutputType, conn: &SqliteConnection, ) -> Result, OutputManagerStorageError> { - let res = diesel::sql_query("SELECT * FROM outputs where flags & $1 = $1 ORDER BY id;") - .bind::(i32::from(flags.as_byte())) + let res = diesel::sql_query("SELECT * FROM outputs where output_type & $1 = $1 ORDER BY id;") + .bind::(i32::from(output_type.as_byte())) .load(conn)?; Ok(res) } @@ -569,15 +577,16 @@ impl TryFrom for DbUnblindedOutput { reason: format!("Could not convert json into OutputFeatures:{}", s), })?; - let flags = o - .flags + let output_type = o + .output_type .try_into() .map_err(|_| OutputManagerStorageError::ConversionError { - reason: format!("Unable to convert flag bits with value {} to OutputType", o.flags), + reason: format!("Unable to convert flag bits with value {} to OutputType", o.output_type), + })?; + features.output_type = + OutputType::from_byte(output_type).ok_or(OutputManagerStorageError::ConversionError { + reason: "Flags could not be converted from bits".to_string(), })?; - features.output_type = OutputType::from_byte(flags).ok_or(OutputManagerStorageError::ConversionError { - reason: "Flags could not be converted from bits".to_string(), - })?; features.maturity = o.maturity as u64; features.metadata = o.metadata.unwrap_or_default(); features.sidechain_features = o diff --git a/base_layer/wallet/src/schema.rs b/base_layer/wallet/src/schema.rs index b746e3d5b6..7027274c95 100644 --- a/base_layer/wallet/src/schema.rs +++ b/base_layer/wallet/src/schema.rs @@ -1,5 +1,24 @@ -// Copyright 2022 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause +// Copyright 2020. 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. table! { client_key_values (key) { @@ -108,7 +127,7 @@ table! { commitment -> Nullable, spending_key -> Binary, value -> BigInt, - flags -> Integer, + output_type -> Integer, maturity -> BigInt, recovery_byte -> Integer, status -> Integer, @@ -136,6 +155,7 @@ table! { spending_priority -> Integer, covenant -> Binary, encrypted_value -> Binary, + contract_id -> Nullable, } }