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