wallet: refactor ImportAccountDryRun to use walletdb.Update

To make sure we don't create any manual DB transactions, we refactor the
ImportAccountDryRun method to use walletdb.Update and the new
walletdb.ErrDryRunRollBack error for making sure a rollback is issued.
This commit is contained in:
Oliver Gugger 2021-07-19 13:30:40 +02:00
parent 9c839caddf
commit 178152bcd0
No known key found for this signature in database
GPG key ID: 8E4256593F177720

View file

@ -245,57 +245,70 @@ func (w *Wallet) ImportAccountDryRun(name string,
*waddrmgr.AccountProperties, []waddrmgr.ManagedAddress,
[]waddrmgr.ManagedAddress, error) {
var (
accountProps *waddrmgr.AccountProperties
externalAddrs []waddrmgr.ManagedAddress
internalAddrs []waddrmgr.ManagedAddress
)
// Start a database transaction that we'll never commit and always
// rollback.
tx, err := w.db.BeginReadWriteTx()
if err != nil {
return nil, nil, nil, err
}
defer func() {
_ = tx.Rollback()
}()
// rollback because we'll return a specific error in the end.
err := walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
// Import the account as usual.
accountProps, err := w.importAccount(
var err error
accountProps, err = w.importAccount(
ns, name, accountPubKey, masterKeyFingerprint, addrType,
)
if err != nil {
return nil, nil, nil, err
return err
}
// Derive the external and internal addresses. Note that we could do
// this based on the provided accountPubKey alone, but we go through the
// ScopedKeyManager instead to ensure addresses will be derived as
// expected from the wallet's point-of-view.
manager, err := w.Manager.FetchScopedKeyManager(accountProps.KeyScope)
// Derive the external and internal addresses. Note that we
// could do this based on the provided accountPubKey alone, but
// we go through the ScopedKeyManager instead to ensure
// addresses will be derived as expected from the wallet's
// point-of-view.
manager, err := w.Manager.FetchScopedKeyManager(
accountProps.KeyScope,
)
if err != nil {
return nil, nil, nil, err
return err
}
// The importAccount method above will cache the imported account within
// the scoped manager. Since this is a dry-run attempt, we'll want to
// invalidate the cache for it.
// The importAccount method above will cache the imported
// account within the scoped manager. Since this is a dry-run
// attempt, we'll want to invalidate the cache for it.
defer manager.InvalidateAccountCache(accountProps.AccountNumber)
externalAddrs, err := manager.NextExternalAddresses(
externalAddrs, err = manager.NextExternalAddresses(
ns, accountProps.AccountNumber, numAddrs,
)
if err != nil {
return nil, nil, nil, err
return err
}
internalAddrs, err := manager.NextInternalAddresses(
internalAddrs, err = manager.NextInternalAddresses(
ns, accountProps.AccountNumber, numAddrs,
)
if err != nil {
return nil, nil, nil, err
return err
}
// Refresh the account's properties after generating the addresses.
// Refresh the account's properties after generating the
// addresses.
accountProps, err = manager.AccountProperties(
ns, accountProps.AccountNumber,
)
if err != nil {
return err
}
// Make sure we always roll back the dry-run transaction by
// returning an error here.
return walletdb.ErrDryRunRollBack
})
if err != nil && err != walletdb.ErrDryRunRollBack {
return nil, nil, nil, err
}