Closed n8maninger closed 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
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.
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.