diff --git a/network/dag/consistency.go b/network/dag/consistency.go index 1a1f7a24b..5e0dd847f 100644 --- a/network/dag/consistency.go +++ b/network/dag/consistency.go @@ -119,6 +119,10 @@ func (f *xorTreeRepair) checkPage() { if err != nil { return err } + err = f.state.xorTree.writeWithoutLock(txn) + if err != nil { + return err + } log.Logger().Warnf("detected XOR tree mismatch for page %d, fixed using recalculated values", f.currentPage) } diff --git a/network/dag/treestore.go b/network/dag/treestore.go index 515bc4b98..0b0b3a828 100644 --- a/network/dag/treestore.go +++ b/network/dag/treestore.go @@ -63,12 +63,18 @@ func (store *treeStore) write(tx stoabs.WriteTx, transaction Transaction) error store.mutex.Lock() defer store.mutex.Unlock() - writer := tx.GetShelfWriter(store.bucketName) - store.tree.Insert(transaction.Ref(), transaction.Clock()) + return store.writeWithoutLock(tx) +} + +// writeWithoutLock writes all current changes in the treeStore to disk. +// It is the callers responsibility to prevent race conditions on treeStore. Use treeStore.mutex if needed. +func (store *treeStore) writeWithoutLock(tx stoabs.WriteTx) error { dirties, orphaned := store.tree.Updates() store.tree.ResetUpdates() // failure after this point results in rollback anyway + writer := tx.GetShelfWriter(store.bucketName) + // delete orphaned leaves for _, orphan := range orphaned { // always zero err := writer.Delete(clockToKey(orphan))