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

Add Require Spend Subaddress #989

Merged
merged 21 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
sugargoat marked this conversation as resolved.
Show resolved Hide resolved
ALTER TABLE accounts DROP COLUMN spend_only_from_subaddress;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE accounts
ADD COLUMN spend_only_from_subaddress BOOLEAN NOT NULL DEFAULT FALSE;
31 changes: 31 additions & 0 deletions full-service/src/db/account.rs
sugargoat marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub trait AccountModel {
///| `name` | The display name for the account. | A label can have duplicates, but it is not recommended. |
///| `fog_report_url` | Fog Report server url. | Applicable only if user has Fog service, empty string otherwise. |
///| `fog_authority_spki` | Fog Authority Subject Public Key Info. | Applicable only if user has Fog service, empty string otherwise. |
///| `require_spend_subaddresses` | If enabled, this mode requires all transactions to spend from a provided subaddress | |
///
/// # Returns:
/// * (account_id, main_subaddress_b58)
Expand All @@ -94,6 +95,7 @@ pub trait AccountModel {
name: &str,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError>;

Expand All @@ -110,6 +112,7 @@ pub trait AccountModel {
///| `name` | The display name for the account. | A label can have duplicates, but it is not recommended. |
///| `fog_report_url` | Fog Report server url. | Applicable only if user has Fog service, empty string otherwise. |
///| `fog_authority_spki` | Fog Authority Subject Public Key Info. | Applicable only if user has Fog service, empty string otherwise. |
///| `require_spend_subaddresses` | If enabled, this mode requires all transactions to spend from a provided subaddress | |
///| `conn` | An reference to the pool connection of wallet database | |
///
/// # Returns:
Expand All @@ -123,6 +126,7 @@ pub trait AccountModel {
name: &str,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError>;

Expand All @@ -140,6 +144,7 @@ pub trait AccountModel {
///| `next_subaddress_index` | This index represents the next subaddress to be assigned as an address. | This is useful information in case the account is imported elsewhere. |
///| `name` | The display name for the account. | A label can have duplicates, but it is not recommended. |
///| `fog_enabled` | Indicate if fog server is enabled or disabled | |
///| `require_spend_subaddresses` | If enabled, this mode requires all transactions to spend from a provided subaddress | |
///| `conn` | An reference to the pool connection of wallet database | |
///
/// # Returns:
Expand All @@ -154,6 +159,7 @@ pub trait AccountModel {
next_subaddress_index: Option<u64>,
name: &str,
fog_enabled: bool,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError>;

Expand All @@ -170,6 +176,7 @@ pub trait AccountModel {
///| `next_subaddress_index` | This index represents the next subaddress to be assigned as an address. | This is useful information in case the account is imported elsewhere. |
///| `fog_report_url` | Fog Report server url. | Applicable only if user has Fog service, empty string otherwise. |
///| `fog_authority_spki` | Fog Authority Subject Public Key Info. | Applicable only if user has Fog service, empty string otherwise. |
///| `require_spend_subaddresses` | If enabled, this mode requires all transactions to spend from a provided subaddress | |
///| `conn` | An reference to the pool connection of wallet database | |
///
/// # Returns:
Expand All @@ -183,6 +190,7 @@ pub trait AccountModel {
next_subaddress_index: Option<u64>,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<Account, WalletDbError>;

Expand All @@ -199,6 +207,7 @@ pub trait AccountModel {
///| `next_subaddress_index` | This index represents the next subaddress to be assigned as an address. | This is useful information in case the account is imported elsewhere. |
///| `fog_report_url` | Fog Report server url. | Applicable only if user has Fog service, empty string otherwise. |
///| `fog_authority_spki` | Fog Authority Subject Public Key Info. | Applicable only if user has Fog service, empty string otherwise. |
///| `require_spend_subaddresses` | If enabled, this mode requires all transactions to spend from a provided subaddress | |
///| `conn` | An reference to the pool connection of wallet database | |
///
/// # Returns:
Expand All @@ -212,6 +221,7 @@ pub trait AccountModel {
next_subaddress_index: Option<u64>,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
sugargoat marked this conversation as resolved.
Show resolved Hide resolved
conn: Conn,
) -> Result<Account, WalletDbError>;

Expand Down Expand Up @@ -453,6 +463,7 @@ impl AccountModel for Account {
name: &str,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError> {
let fog_enabled = !fog_report_url.is_empty();
Expand All @@ -474,6 +485,7 @@ impl AccountModel for Account {
next_subaddress_index,
name,
fog_enabled,
require_spend_subaddresses,
conn,
)
}
Expand All @@ -486,6 +498,7 @@ impl AccountModel for Account {
name: &str,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError> {
let fog_enabled = !fog_report_url.is_empty();
Expand All @@ -507,6 +520,7 @@ impl AccountModel for Account {
next_subaddress_index,
name,
fog_enabled,
require_spend_subaddresses,
conn,
)
}
Expand All @@ -520,6 +534,7 @@ impl AccountModel for Account {
next_subaddress_index: Option<u64>,
name: &str,
fog_enabled: bool,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<(AccountID, String), WalletDbError> {
use crate::db::schema::accounts;
Expand Down Expand Up @@ -548,6 +563,7 @@ impl AccountModel for Account {
fog_enabled,
view_only: false,
managed_by_hardware_wallet: false,
spend_only_from_subaddress: require_spend_subaddresses,
};

diesel::insert_into(accounts::table)
Expand Down Expand Up @@ -583,6 +599,7 @@ impl AccountModel for Account {
next_subaddress_index: Option<u64>,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<Account, WalletDbError> {
let (account_id, _public_address_b58) = Account::create_from_mnemonic(
Expand All @@ -593,6 +610,7 @@ impl AccountModel for Account {
&name.unwrap_or_default(),
fog_report_url,
fog_authority_spki,
require_spend_subaddresses,
conn,
)?;
Account::get(&account_id, conn)
Expand All @@ -606,6 +624,7 @@ impl AccountModel for Account {
next_subaddress_index: Option<u64>,
fog_report_url: String,
fog_authority_spki: String,
require_spend_subaddresses: bool,
conn: Conn,
) -> Result<Account, WalletDbError> {
let (account_id, _public_address_b58) = Account::create_from_root_entropy(
Expand All @@ -616,6 +635,7 @@ impl AccountModel for Account {
&name.unwrap_or_default(),
fog_report_url,
fog_authority_spki,
require_spend_subaddresses,
conn,
)?;
Account::get(&account_id, conn)
Expand Down Expand Up @@ -656,6 +676,7 @@ impl AccountModel for Account {
fog_enabled: false,
view_only: true,
managed_by_hardware_wallet,
spend_only_from_subaddress: false,
};

diesel::insert_into(accounts::table)
Expand Down Expand Up @@ -726,6 +747,7 @@ impl AccountModel for Account {
fog_enabled: true,
view_only: true,
managed_by_hardware_wallet: true,
spend_only_from_subaddress: false,
};

diesel::insert_into(accounts::table)
Expand Down Expand Up @@ -964,6 +986,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -995,6 +1018,7 @@ mod tests {
view_only: false,
managed_by_hardware_wallet: false,
resyncing: false,
require_spend_subaddresses: false,
};
assert_eq!(expected_account, acc);

Expand Down Expand Up @@ -1037,6 +1061,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
wallet_db.get_pooled_conn().unwrap().deref_mut(),
)
.unwrap();
Expand All @@ -1062,6 +1087,7 @@ mod tests {
view_only: false,
managed_by_hardware_wallet: false,
resyncing: false,
require_spend_subaddresses: false,
};
assert_eq!(expected_account_secondary, acc_secondary);

Expand Down Expand Up @@ -1125,6 +1151,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -1160,6 +1187,7 @@ mod tests {
"Alice's FOG Account",
"fog//some.fog.url".to_string(),
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvnB9wTbTOT5uoizRYaYbw7XIEkInl8E7MGOAQj+xnC+F1rIXiCnc/t1+5IIWjbRGhWzo7RAwI5sRajn2sT4rRn9NXbOzZMvIqE4hmhmEzy1YQNDnfALAWNQ+WBbYGW+Vqm3IlQvAFFjVN1YYIdYhbLjAPdkgeVsWfcLDforHn6rR3QBZYZIlSBQSKRMY/tywTxeTCvK2zWcS0kbbFPtBcVth7VFFVPAZXhPi9yy1AvnldO6n7KLiupVmojlEMtv4FQkk604nal+j/dOplTATV8a9AJBbPRBZ/yQg57EG2Y2MRiHOQifJx0S5VbNyMm9bkS8TD7Goi59aCW6OT1gyeotWwLg60JRZTfyJ7lYWBSOzh0OnaCytRpSWtNZ6barPUeOnftbnJtE8rFhF7M4F66et0LI/cuvXYecwVwykovEVBKRF4HOK9GgSm17mQMtzrD7c558TbaucOWabYR04uhdAc3s10MkuONWG0wIQhgIChYVAGnFLvSpp2/aQEq3xrRSETxsixUIjsZyWWROkuA0IFnc8d7AmcnUBvRW7FT/5thWyk5agdYUGZ+7C1o69ihR1YxmoGh69fLMPIEOhYh572+3ckgl2SaV4uo9Gvkz8MMGRBcMIMlRirSwhCfozV2RyT5Wn1NgPpyc8zJL7QdOhL7Qxb+5WjnCVrQYHI2cCAwEAAQ==".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -1229,6 +1257,7 @@ mod tests {
view_only: false,
managed_by_hardware_wallet: false,
resyncing: false,
require_spend_subaddresses: false,
};
assert_eq!(expected_account, acc);
}
Expand Down Expand Up @@ -1287,6 +1316,7 @@ mod tests {
view_only: true,
managed_by_hardware_wallet: false,
resyncing: false,
require_spend_subaddresses: false,
};
assert_eq!(expected_account, account);
}
Expand Down Expand Up @@ -1347,6 +1377,7 @@ mod tests {
view_only: true,
managed_by_hardware_wallet: true,
resyncing: false,
require_spend_subaddresses: false,
};

// Check to make sure the account in the database is correct
Expand Down
3 changes: 3 additions & 0 deletions full-service/src/db/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub struct Account {
/// account.
pub managed_by_hardware_wallet: bool,
pub resyncing: bool,
/// If true, this account is only allowed to spend from subaddresses.
pub require_spend_subaddresses: bool,
}

/// A structure that can be inserted to create a new entity in the `accounts`
Expand All @@ -58,6 +60,7 @@ pub struct NewAccount<'a> {
pub fog_enabled: bool,
pub view_only: bool,
pub managed_by_hardware_wallet: bool,
pub spend_only_from_subaddress: bool,
}

/// A transaction output entity that either was received to an Account in this
Expand Down
4 changes: 2 additions & 2 deletions full-service/src/db/schema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @generated automatically by Diesel CLI.

sugargoat marked this conversation as resolved.
Show resolved Hide resolved
diesel::table! {
accounts (id) {
id -> Text,
Expand All @@ -14,6 +12,7 @@ diesel::table! {
view_only -> Bool,
managed_by_hardware_wallet -> Bool,
resyncing -> Bool,
spend_only_from_subaddress -> Bool,
}
}

Expand Down Expand Up @@ -116,6 +115,7 @@ diesel::table! {

diesel::joinable!(assigned_subaddresses -> accounts (account_id));
diesel::joinable!(authenticated_sender_memos -> txos (txo_id));
diesel::joinable!(destination_memos -> txos (txo_id));
diesel::joinable!(transaction_input_txos -> transaction_logs (transaction_log_id));
sugargoat marked this conversation as resolved.
Show resolved Hide resolved
diesel::joinable!(transaction_input_txos -> txos (txo_id));
diesel::joinable!(transaction_logs -> accounts (account_id));
Expand Down
Loading
Loading