SiaFoundation / walletd

A new Sia wallet
https://sia.tech/software/walletd
MIT License
15 stars 6 forks source link

Remove orphaned blocks during rescan #104

Closed n8maninger closed 2 months ago

n8maninger commented 2 months ago

When a scan is interrupted, orphaned blocks will never be reverted from the wallet store. This adds a check for orphans when scanning and reverts their state from the store.

n8maninger commented 2 months ago

@lukechampine chaindb is occasionally triggering the race detector in getBucket. Do we know how it behaves when it tries to read from an already committed transaction? Does the chain manager just panic?

WARNING: DATA RACE
Read at 0x00c0004d4cc0 by goroutine 306913:
  runtime.mapdelete()
      /Users/n8maninger/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.8.darwin-arm64/src/runtime/map.go:696 +0x45c
  go.etcd.io/bbolt.(*Bucket).rebalance()
      /Users/n8maninger/go/pkg/mod/go.etcd.io/bbolt@v1.3.9/bucket.go:659 +0xdc
  go.etcd.io/bbolt.(*Tx).Commit()
      /Users/n8maninger/go/pkg/mod/go.etcd.io/bbolt@v1.3.9/tx.go:154 +0x90
  go.sia.tech/coreutils.(*BoltChainDB).Flush()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/db.go:50 +0x4c
  go.sia.tech/coreutils.(*BoltChainDB).Close()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/db.go:66 +0x2c
  go.sia.tech/walletd/wallet_test.TestWalletAddresses.func8()
      /Users/n8maninger/Projects/github.com/SiaFoundation/walletd/wallet/wallet_test.go:508 +0x34
  runtime.deferreturn()
      /Users/n8maninger/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.8.darwin-arm64/src/runtime/panic.go:477 +0x34
  testing.tRunner()
      /Users/n8maninger/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.8.darwin-arm64/src/testing/testing.go:1595 +0x1b0
  testing.(*T).Run.func1()
      /Users/n8maninger/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.8.darwin-arm64/src/testing/testing.go:1648 +0x40

Previous write at 0x00c0004d4cc0 by goroutine 306916:
  runtime.mapaccess2_faststr()
      /Users/n8maninger/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.8.darwin-arm64/src/runtime/map_faststr.go:108 +0x42c
  go.etcd.io/bbolt.(*Bucket).Bucket()
      /Users/n8maninger/go/pkg/mod/go.etcd.io/bbolt@v1.3.9/bucket.go:115 +0x1d4
  go.etcd.io/bbolt.(*Tx).Bucket()
      /Users/n8maninger/go/pkg/mod/go.etcd.io/bbolt@v1.3.9/tx.go:102 +0xe4
  go.sia.tech/coreutils.(*BoltChainDB).Bucket()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/db.go:28 +0xc4
  go.sia.tech/coreutils/chain.(*DBStore).bucket()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/chain/db.go:269 +0x124
  go.sia.tech/coreutils/chain.(*DBStore).getBlock()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/chain/db.go:309 +0xbc
  go.sia.tech/coreutils/chain.(*DBStore).Block()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/chain/db.go:634 +0x78
  go.sia.tech/coreutils/chain.blockAndParent()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/chain/manager.go:60 +0xc0
  go.sia.tech/coreutils/chain.(*Manager).UpdatesSince()
      /Users/n8maninger/go/pkg/mod/go.sia.tech/coreutils@v0.0.4-0.20240318195004-c73e571336f7/chain/manager.go:427 +0x4a4
  go.sia.tech/walletd/wallet.syncStore()
      /Users/n8maninger/Projects/github.com/SiaFoundation/walletd/wallet/manager.go:186 +0x110
  go.sia.tech/walletd/wallet.NewManager.func1()
      /Users/n8maninger/Projects/github.com/SiaFoundation/walletd/wallet/manager.go:218 +0x238
lukechampine commented 2 months ago

Seems to me like this is caused by db.Close being called concurrently with a read (via UpdatesSince). So we need to ensure that UpdatesSince isn't called after Close, i.e. that syncStore shuts down properly.