Skip to content

Commit

Permalink
Check consistency of account id, name index on open
Browse files Browse the repository at this point in the history
  • Loading branch information
tuxcanfly committed May 4, 2015
1 parent c820c8a commit ba2ced7
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions waddrmgr/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,11 @@ func upgradeManager(namespace walletdb.Namespace, pubPassPhrase []byte, chainPar
version = 4
}

// Ensure that the account indexes are up-to-date and consistent
if err := updateAccountIndexes(namespace); err != nil {
return err
}

// Ensure the manager is upraded to the latest version. This check is
// to intentionally cause a failure if the manager version is updated
// without writing code to handle the upgrade.
Expand Down Expand Up @@ -1970,3 +1975,61 @@ func upgradeToVersion4(namespace walletdb.Namespace, pubPassPhrase []byte) error
}
return nil
}

// updateAccountIndexes checks for any missing entries in the account id
// and name indexes and rebuils them, if required, to make sure that the
// indexes are consistent
func updateAccountIndexes(namespace walletdb.Namespace) error {
err := namespace.Update(func(tx walletdb.Tx) error {
bucket := tx.RootBucket().Bucket(acctBucketName)

nameIdxbucket := tx.RootBucket().Bucket(acctNameIdxBucketName)
idIdxbucket := tx.RootBucket().Bucket(acctIDIdxBucketName)

err := bucket.ForEach(func(k, v []byte) error {
// Skip buckets.
if v == nil {
return nil
}

// Fetch the name from the account row
account := binary.LittleEndian.Uint32(k)
acctInfoIface, err := fetchAccountInfo(tx, account)
if err != nil {
return err
}
acctInfo, ok := acctInfoIface.(*dbBIP0044AccountRow)
if !ok {
str := fmt.Sprintf("unsupported account type %T", acctInfoIface)
return managerError(ErrDatabase, str, nil)
}
name := acctInfo.name

// Check that the bidirectional index exists for this (id, name)
// pair and rebuild entries if required
val := idIdxbucket.Get(k)
if !bytes.Equal(val, stringToBytes(name)) {
if err := putAccountIDIndex(tx, account, name); err != nil {
return err
}
fmt.Printf("fixed invalid account id index: %d -> %s\n",
account, name)
}

val = nameIdxbucket.Get(stringToBytes(name))
if !bytes.Equal(val, k) {
if err := putAccountNameIndex(tx, account, name); err != nil {
return err
}
fmt.Printf("fixed missing account name index: %s -> %d\n", name,
account)
}
return nil
})
return err
})
if err != nil {
return maybeConvertDbError(err)
}
return nil
}

0 comments on commit ba2ced7

Please sign in to comment.