Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet): adds contract_id to outputs db #4222

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base_layer/wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This usually increases compile time by a large amount. Can we drop a column maybe to fit into 32?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI didn't seem to take too long, so maybe not so bad

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we can drop parent_pk and/or unique_id later and remove this feature.

diesel_migrations = "1.4.0"
digest = "0.9.0"
fs2 = "0.3.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP INDEX outputs_contract_id_index;
ALTER TABLE outputs DROP COLUMN contract_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE outputs
ADD contract_id blob NULL;

CREATE INDEX outputs_contract_id_index ON outputs (contract_id);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE outputs
RENAME COLUMN output_type TO flags;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE outputs
RENAME COLUMN flags TO output_type;
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,12 @@ impl OutputManagerBackend for OutputManagerSqliteDatabase {
Ok(result)
}

fn fetch_with_features(&self, flags: OutputType) -> Result<Vec<DbUnblindedOutput>, OutputManagerStorageError> {
fn fetch_with_features(
&self,
output_type: OutputType,
) -> Result<Vec<DbUnblindedOutput>, 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)?;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct NewOutputSql {
#[derivative(Debug = "ignore")]
pub spending_key: Vec<u8>,
pub value: i64,
pub flags: i32,
pub output_type: i32,
pub maturity: i64,
pub recovery_byte: i32,
pub status: i32,
Expand All @@ -65,6 +65,7 @@ pub struct NewOutputSql {
pub features_json: String,
pub covenant: Vec<u8>,
pub encrypted_value: Vec<u8>,
pub contract_id: Option<Vec<u8>>,
}

impl NewOutputSql {
Expand All @@ -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,
Expand Down Expand Up @@ -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()),
})
}

Expand Down Expand Up @@ -138,7 +140,7 @@ impl From<OutputSql> 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,
Expand All @@ -158,6 +160,7 @@ impl From<OutputSql> for NewOutputSql {
features_json: o.features_json,
covenant: o.covenant,
encrypted_value: o.encrypted_value,
contract_id: o.contract_id,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ pub struct OutputSql {
#[derivative(Debug = "ignore")]
pub spending_key: Vec<u8>,
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,
Expand Down Expand Up @@ -101,6 +100,7 @@ pub struct OutputSql {
pub spending_priority: i32,
pub covenant: Vec<u8>,
pub encrypted_value: Vec<u8>,
pub contract_id: Option<Vec<u8>>,
}

impl OutputSql {
Expand Down Expand Up @@ -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)
Expand All @@ -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 => {
Expand Down Expand Up @@ -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<Vec<OutputSql>, OutputManagerStorageError> {
let res = diesel::sql_query("SELECT * FROM outputs where flags & $1 = $1 ORDER BY id;")
.bind::<diesel::sql_types::Integer, _>(i32::from(flags.as_byte()))
let res = diesel::sql_query("SELECT * FROM outputs where output_type & $1 = $1 ORDER BY id;")
.bind::<diesel::sql_types::Integer, _>(i32::from(output_type.as_byte()))
.load(conn)?;
Ok(res)
}
Expand Down Expand Up @@ -569,15 +577,16 @@ impl TryFrom<OutputSql> 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
Expand Down
26 changes: 23 additions & 3 deletions base_layer/wallet/src/schema.rs
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -108,7 +127,7 @@ table! {
commitment -> Nullable<Binary>,
spending_key -> Binary,
value -> BigInt,
flags -> Integer,
output_type -> Integer,
maturity -> BigInt,
recovery_byte -> Integer,
status -> Integer,
Expand Down Expand Up @@ -136,6 +155,7 @@ table! {
spending_priority -> Integer,
covenant -> Binary,
encrypted_value -> Binary,
contract_id -> Nullable<Binary>,
}
}

Expand Down