Allow multiple migrations to be specified for custom wallet init.

Since our migrations form a DAG, it doesn't make sense to only allow a
single migration to be specified for wallet initialization; instead,
allow multiple migrations so that one can hit all the desired leaves.
This commit is contained in:
Kris Nuttycombe 2022-10-12 12:35:24 -06:00
parent 85390cb8ce
commit e6f039d0f9
3 changed files with 25 additions and 13 deletions

View File

@ -114,13 +114,13 @@ pub fn init_wallet_db<P: consensus::Parameters + 'static>(
wdb: &mut WalletDb<P>, wdb: &mut WalletDb<P>,
seed: Option<SecretVec<u8>>, seed: Option<SecretVec<u8>>,
) -> Result<(), MigratorError<WalletMigrationError>> { ) -> Result<(), MigratorError<WalletMigrationError>> {
init_wallet_db_internal(wdb, seed, None) init_wallet_db_internal(wdb, seed, &[])
} }
fn init_wallet_db_internal<P: consensus::Parameters + 'static>( fn init_wallet_db_internal<P: consensus::Parameters + 'static>(
wdb: &mut WalletDb<P>, wdb: &mut WalletDb<P>,
seed: Option<SecretVec<u8>>, seed: Option<SecretVec<u8>>,
target_migration: Option<Uuid>, target_migrations: &[Uuid],
) -> Result<(), MigratorError<WalletMigrationError>> { ) -> Result<(), MigratorError<WalletMigrationError>> {
// Turn off foreign keys, and ensure that table replacement/modification // Turn off foreign keys, and ensure that table replacement/modification
// does not break views // does not break views
@ -137,7 +137,13 @@ fn init_wallet_db_internal<P: consensus::Parameters + 'static>(
migrator migrator
.register_multiple(migrations::all_migrations(&wdb.params, seed)) .register_multiple(migrations::all_migrations(&wdb.params, seed))
.expect("Wallet migration registration should have been successful."); .expect("Wallet migration registration should have been successful.");
migrator.up(target_migration)?; if target_migrations.is_empty() {
migrator.up(None)?;
} else {
for target_migration in target_migrations {
migrator.up(Some(*target_migration))?;
}
}
wdb.conn wdb.conn
.execute("PRAGMA foreign_keys = ON", []) .execute("PRAGMA foreign_keys = ON", [])
.map_err(|e| MigratorError::Adapter(WalletMigrationError::from(e)))?; .map_err(|e| MigratorError::Adapter(WalletMigrationError::from(e)))?;

View File

@ -34,9 +34,12 @@ impl<P> schemer::Migration for Migration<P> {
} }
fn dependencies(&self) -> HashSet<Uuid> { fn dependencies(&self) -> HashSet<Uuid> {
[add_utxo_account::MIGRATION_ID, sent_notes_to_internal::MIGRATION_ID] [
.into_iter() add_utxo_account::MIGRATION_ID,
.collect() sent_notes_to_internal::MIGRATION_ID,
]
.into_iter()
.collect()
} }
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
@ -292,7 +295,7 @@ mod tests {
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
use { use {
crate::wallet::init::migrations::ufvk_support, crate::wallet::init::migrations::{ufvk_support, utxos_table},
zcash_client_backend::encoding::AddressCodec, zcash_client_backend::encoding::AddressCodec,
zcash_primitives::{ zcash_primitives::{
consensus::{BlockHeight, BranchId}, consensus::{BlockHeight, BranchId},
@ -311,7 +314,7 @@ mod tests {
fn transaction_views() { fn transaction_views() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap();
init_wallet_db_internal(&mut db_data, None, Some(addresses_table::MIGRATION_ID)).unwrap(); init_wallet_db_internal(&mut db_data, None, &[addresses_table::MIGRATION_ID]).unwrap();
let usk = let usk =
UnifiedSpendingKey::from_seed(&tests::network(), &[0u8; 32][..], AccountId::from(0)) UnifiedSpendingKey::from_seed(&tests::network(), &[0u8; 32][..], AccountId::from(0))
.unwrap(); .unwrap();
@ -403,7 +406,12 @@ mod tests {
fn migrate_from_wm2() { fn migrate_from_wm2() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap();
init_wallet_db_internal(&mut db_data, None, Some(ufvk_support::MIGRATION_ID)).unwrap(); init_wallet_db_internal(
&mut db_data,
None,
&[utxos_table::MIGRATION_ID, ufvk_support::MIGRATION_ID],
)
.unwrap();
// create a UTXO to spend // create a UTXO to spend
let tx = TransactionData::from_parts( let tx = TransactionData::from_parts(

View File

@ -7,7 +7,7 @@ use schemer;
use schemer_rusqlite::RusqliteMigration; use schemer_rusqlite::RusqliteMigration;
use uuid::Uuid; use uuid::Uuid;
use super::{ufvk_support}; use super::ufvk_support;
use crate::wallet::init::WalletMigrationError; use crate::wallet::init::WalletMigrationError;
/// This migration adds the `to_account` field to the `sent_notes` table. /// This migration adds the `to_account` field to the `sent_notes` table.
@ -28,9 +28,7 @@ impl schemer::Migration for Migration {
} }
fn dependencies(&self) -> HashSet<Uuid> { fn dependencies(&self) -> HashSet<Uuid> {
[ufvk_support::MIGRATION_ID] [ufvk_support::MIGRATION_ID].into_iter().collect()
.into_iter()
.collect()
} }
fn description(&self) -> &'static str { fn description(&self) -> &'static str {