Skip to content

Commit

Permalink
Add Require Spend Subaddress (#989)
Browse files Browse the repository at this point in the history
* Initial pass plumbing API

Signed-off-by: sugargoat <[email protected]>

* Logic is in place

Signed-off-by: sugargoat <[email protected]>

* Update to default bool

Signed-off-by: sugargoat <[email protected]>

* Rename for brevity & clarity

Signed-off-by: sugargoat <[email protected]>

* Add e2e tests for mode/build mismatch

Signed-off-by: sugargoat <[email protected]>

* Fix up db and migrations

Signed-off-by: sugargoat <[email protected]>

* Rename for conciseness & clarity

Signed-off-by: sugargoat <[email protected]>

* Add require_spend_sudaddress for import_view_only methods

Signed-off-by: sugargoat <[email protected]>

* Update schema to include autogenerated comment

Signed-off-by: sugargoat <[email protected]>

* Whitespace

Signed-off-by: sugargoat <[email protected]>

* Address case for spend even without require, use more proper error type, and clean up tests

Signed-off-by: sugargoat <[email protected]>

* Minor cleanups

Signed-off-by: sugargoat <[email protected]>

* Update test name for accuracy

Signed-off-by: sugargoat <[email protected]>

* Add "enable/disable"

Signed-off-by: sugargoat <[email protected]>

* add require_spend_subaddress to AccountMap Account model

* update AccountSecrets model to expose require_from_subaddress when exporting

* Debugging test

Signed-off-by: sugargoat <[email protected]>

* Rather than enable/disable: set

Signed-off-by: sugargoat <[email protected]>

* Expose `import` endpoints

Signed-off-by: sugargoat <[email protected]>

* Fixup import_view_only_account request create

Signed-off-by: sugargoat <[email protected]>

* Fix clippy

Signed-off-by: sugargoat <[email protected]>

---------

Signed-off-by: sugargoat <[email protected]>
Co-authored-by: Henry Holtzman <[email protected]>
  • Loading branch information
sugargoat and holtzman authored May 23, 2024
1 parent 3f1ece3 commit a604fec
Show file tree
Hide file tree
Showing 29 changed files with 558 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
ALTER TABLE accounts DROP COLUMN require_spend_subaddress;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE accounts
ADD COLUMN require_spend_subaddress BOOLEAN NOT NULL DEFAULT FALSE;
70 changes: 69 additions & 1 deletion full-service/src/db/account.rs

Large diffs are not rendered by default.

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_subaddress: 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 require_spend_subaddress: bool,
}

/// A transaction output entity that either was received to an Account in this
Expand Down
2 changes: 2 additions & 0 deletions full-service/src/db/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ diesel::table! {
view_only -> Bool,
managed_by_hardware_wallet -> Bool,
resyncing -> Bool,
require_spend_subaddress -> Bool,
}
}

Expand Down Expand Up @@ -116,6 +117,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));
diesel::joinable!(transaction_input_txos -> txos (txo_id));
diesel::joinable!(transaction_logs -> accounts (account_id));
Expand Down
22 changes: 22 additions & 0 deletions full-service/src/db/txo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -2825,6 +2826,7 @@ mod tests {
"Bob's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -2930,6 +2932,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -3012,6 +3015,7 @@ mod tests {
"Exchange Account",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -3120,6 +3124,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3248,6 +3253,7 @@ mod tests {
"Exchange Account",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -3357,6 +3363,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3424,6 +3431,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3482,6 +3490,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3557,6 +3566,7 @@ mod tests {
"Alice",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3719,6 +3729,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3770,6 +3781,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -3861,6 +3873,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -3917,6 +3930,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -3970,6 +3984,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -4059,6 +4074,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -4159,6 +4175,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -4346,6 +4363,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -4498,6 +4516,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down Expand Up @@ -4601,6 +4620,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -4688,6 +4708,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down Expand Up @@ -4816,6 +4837,7 @@ mod tests {
"",
"".to_string(),
"".to_string(),
false,
conn,
)
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion full-service/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ pub enum WalletTransactionBuilderError {
/// Error interacting with fog: {0}
FogError(String),

/// Attempting to build a transaction from a TXO without a subaddress: {0}
/// Subaddress is required for spending on this account: {0}
NullSubaddress(String),

/// Error executing diesel transaction: {0}
Expand Down
7 changes: 5 additions & 2 deletions full-service/src/json_rpc/v1/api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ where
subaddress_index: None,
},
None,
None, // Note: Not including subaddress_to_spend_from in V1 API
None, // Note: Not including spend_subaddress in V1 API
)
.await
.map_err(format_error)?;
Expand Down Expand Up @@ -298,7 +298,7 @@ where
subaddress_index: None,
},
None,
None, // Note: not including subaddress_to_spend_from in V1 API
None, // Note: not including spend_subaddress in V1 API
)
.await
.map_err(format_error)?;
Expand Down Expand Up @@ -383,6 +383,7 @@ where
name,
fog_report_url.unwrap_or_default(),
fog_authority_spki.unwrap_or_default(),
false, // not exposed in V1 API
)
.map_err(format_error)?;
let next_subaddress_index = service
Expand Down Expand Up @@ -1005,6 +1006,7 @@ where
ns,
fog_report_url.unwrap_or_default(),
fog_authority_spki.unwrap_or_default(),
false,
)
.map_err(format_error)?;

Expand Down Expand Up @@ -1045,6 +1047,7 @@ where
ns,
fog_report_url.unwrap_or_default(),
fog_authority_spki.unwrap_or_default(),
false,
)
.map_err(format_error)?;

Expand Down
1 change: 1 addition & 0 deletions full-service/src/json_rpc/v1/models/txo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ mod tests {
"Alice's Main Account",
"".to_string(),
"".to_string(),
false,
&mut wallet_db.get_pooled_conn().unwrap(),
)
.unwrap();
Expand Down
24 changes: 19 additions & 5 deletions full-service/src/json_rpc/v2/api/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub enum JsonCommandRequest {
block_version: Option<String>,
sender_memo_credential_subaddress_index: Option<String>,
payment_request_id: Option<String>,
subaddress_to_spend_from: Option<String>,
spend_subaddress: Option<String>,
},
build_burn_transaction {
account_id: String,
Expand All @@ -69,7 +69,7 @@ pub enum JsonCommandRequest {
tombstone_block: Option<String>,
max_spendable_value: Option<String>,
block_version: Option<String>,
subaddress_to_spend_from: Option<String>,
spend_subaddress: Option<String>,
},
build_transaction {
account_id: String,
Expand All @@ -84,7 +84,7 @@ pub enum JsonCommandRequest {
block_version: Option<String>,
sender_memo_credential_subaddress_index: Option<String>,
payment_request_id: Option<String>,
subaddress_to_spend_from: Option<String>,
spend_subaddress: Option<String>,
},
build_unsigned_burn_transaction {
account_id: String,
Expand All @@ -96,7 +96,7 @@ pub enum JsonCommandRequest {
tombstone_block: Option<String>,
max_spendable_value: Option<String>,
block_version: Option<String>,
subaddress_to_spend_from: Option<String>,
spend_subaddress: Option<String>,
},
build_unsigned_transaction {
account_id: String,
Expand All @@ -109,7 +109,7 @@ pub enum JsonCommandRequest {
tombstone_block: Option<String>,
max_spendable_value: Option<String>,
block_version: Option<String>,
subaddress_to_spend_from: Option<String>,
spend_subaddress: Option<String>,
},
check_b58_type {
b58_code: String,
Expand All @@ -121,6 +121,8 @@ pub enum JsonCommandRequest {
create_account {
name: Option<String>,
fog_info: Option<FogInfo>,
#[serde(default = "bool::default")] // default is false
require_spend_subaddress: bool,
},
create_payment_request {
account_id: String,
Expand Down Expand Up @@ -226,25 +228,33 @@ pub enum JsonCommandRequest {
first_block_index: Option<String>,
next_subaddress_index: Option<String>,
fog_info: Option<FogInfo>,
#[serde(default = "bool::default")] // default is false
require_spend_subaddress: bool,
},
import_account {
mnemonic: String,
name: Option<String>,
first_block_index: Option<String>,
next_subaddress_index: Option<String>,
fog_info: Option<FogInfo>,
#[serde(default = "bool::default")] // default is false
require_spend_subaddress: bool,
},
import_view_only_account {
view_private_key: String,
spend_public_key: String,
name: Option<String>,
first_block_index: Option<String>,
next_subaddress_index: Option<String>,
#[serde(default = "bool::default")] // default is false
require_spend_subaddress: bool,
},
import_view_only_account_from_hardware_wallet {
name: Option<String>,
first_block_index: Option<String>,
fog_info: Option<FogInfo>,
#[serde(default = "bool::default")] // default is false
require_spend_subaddress: bool,
},
remove_account {
account_id: String,
Expand All @@ -259,6 +269,10 @@ pub enum JsonCommandRequest {
search_ledger {
query: String,
},
set_require_spend_subaddress {
account_id: String,
require_spend_subaddress: bool,
},
submit_transaction {
tx_proposal: TxProposal,
comment: Option<String>,
Expand Down
3 changes: 3 additions & 0 deletions full-service/src/json_rpc/v2/api/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ pub enum JsonCommandResponse {
search_ledger {
results: Vec<LedgerSearchResult>,
},
set_require_spend_subaddress {
account: Account,
},
submit_transaction {
transaction_log: Option<TransactionLog>,
},
Expand Down
Loading

0 comments on commit a604fec

Please sign in to comment.