Skip to content

Commit ab7f1b9

Browse files
committed
Make ephemeral_addresses.address non-null & unique
We should never construct an ephemeral address from an invalid index, and therefore the address column need not be nullable.
1 parent 24b6d50 commit ab7f1b9

File tree

4 files changed

+14
-19
lines changed

4 files changed

+14
-19
lines changed

zcash_client_sqlite/src/wallet/db.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,14 @@ pub(super) const TABLE_EPHEMERAL_ADDRESSES: &str = r#"
116116
CREATE TABLE ephemeral_addresses (
117117
account_id INTEGER NOT NULL,
118118
address_index INTEGER NOT NULL,
119-
address TEXT,
119+
address TEXT NOT NULL,
120120
used_in_tx INTEGER,
121121
seen_in_tx INTEGER,
122122
FOREIGN KEY (account_id) REFERENCES accounts(id),
123123
FOREIGN KEY (used_in_tx) REFERENCES transactions(id_tx),
124124
FOREIGN KEY (seen_in_tx) REFERENCES transactions(id_tx),
125125
PRIMARY KEY (account_id, address_index),
126+
CONSTRAINT ephemeral_addr_uniq UNIQUE (address),
126127
CONSTRAINT used_implies_seen CHECK (
127128
used_in_tx IS NULL OR seen_in_tx IS NOT NULL
128129
),
@@ -135,10 +136,6 @@ CREATE TABLE ephemeral_addresses (
135136
// libsqlite3-sys requires at least version 3.14.0.
136137
// "WITHOUT ROWID" tells SQLite to use a clustered index on the (composite) primary key.
137138
const_assert_eq!(GAP_LIMIT, 20);
138-
pub(super) const INDEX_EPHEMERAL_ADDRESSES_ADDRESS: &str = r#"
139-
CREATE INDEX ephemeral_addresses_address ON ephemeral_addresses (
140-
address ASC
141-
)"#;
142139

143140
/// Stores information about every block that the wallet has scanned.
144141
///

zcash_client_sqlite/src/wallet/init.rs

-1
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ mod tests {
422422
db::INDEX_ACCOUNTS_UIVK,
423423
db::INDEX_HD_ACCOUNT,
424424
db::INDEX_ADDRESSES_ACCOUNTS,
425-
db::INDEX_EPHEMERAL_ADDRESSES_ADDRESS,
426425
db::INDEX_NF_MAP_LOCATOR_IDX,
427426
db::INDEX_ORCHARD_RECEIVED_NOTES_ACCOUNT,
428427
db::INDEX_ORCHARD_RECEIVED_NOTES_TX,

zcash_client_sqlite/src/wallet/init/migrations/ephemeral_addresses.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,22 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
4545
"CREATE TABLE ephemeral_addresses (
4646
account_id INTEGER NOT NULL,
4747
address_index INTEGER NOT NULL,
48-
address TEXT,
48+
address TEXT NOT NULL,
4949
used_in_tx INTEGER,
5050
seen_in_tx INTEGER,
5151
FOREIGN KEY (account_id) REFERENCES accounts(id),
5252
FOREIGN KEY (used_in_tx) REFERENCES transactions(id_tx),
5353
FOREIGN KEY (seen_in_tx) REFERENCES transactions(id_tx),
5454
PRIMARY KEY (account_id, address_index),
55+
CONSTRAINT ephemeral_addr_uniq UNIQUE (address),
5556
CONSTRAINT used_implies_seen CHECK (
5657
used_in_tx IS NULL OR seen_in_tx IS NOT NULL
5758
),
5859
CONSTRAINT index_range_and_address_nullity CHECK (
5960
(address_index BETWEEN 0 AND 0x7FFFFFFF AND address IS NOT NULL) OR
6061
(address_index BETWEEN 0x80000000 AND 0x7FFFFFFF + 20 AND address IS NULL AND used_in_tx IS NULL AND seen_in_tx IS NULL)
6162
)
62-
) WITHOUT ROWID;
63-
CREATE INDEX ephemeral_addresses_address ON ephemeral_addresses (
64-
address ASC
65-
);",
63+
) WITHOUT ROWID;"
6664
)?;
6765

6866
// Make sure that at least `GAP_LIMIT` ephemeral transparent addresses are

zcash_client_sqlite/src/wallet/transparent/ephemeral.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,19 @@ fn reserve_until<P: consensus::Parameters>(
282282
)?;
283283

284284
for raw_index in range_to_store {
285-
let address_str_opt = match NonHardenedChildIndex::from_index(raw_index) {
286-
Some(address_index) => Some(
285+
let address_str = NonHardenedChildIndex::from_index(raw_index)
286+
.map(|address_index| {
287287
ephemeral_ivk
288-
.derive_ephemeral_address(address_index)?
289-
.encode(params),
290-
),
291-
None => None,
292-
};
288+
.derive_ephemeral_address(address_index)
289+
.map(|addr| addr.encode(params))
290+
})
291+
.transpose()?
292+
.expect("we do not attempt to generate addresses outside the non-hardened index range");
293+
293294
stmt_insert_ephemeral_address.execute(named_params![
294295
":account_id": account_id.0,
295296
":address_index": raw_index,
296-
":address": address_str_opt,
297+
":address": address_str,
297298
])?;
298299
}
299300
Ok(())

0 commit comments

Comments
 (0)