diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index d455d4947..e54b51af2 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -25,12 +25,13 @@ import ( "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) // AddrManager provides a concurrency safe address manager for caching potential // peers on the bitcoin network. type AddrManager struct { - mtx sync.Mutex + mtx bchutil.Mutex peersFile string lookupFunc func(string) ([]net.IP, error) rand *rand.Rand @@ -44,7 +45,7 @@ type AddrManager struct { quit chan struct{} nTried int nNew int - lamtx sync.Mutex + lamtx bchutil.Mutex localAddresses map[string]*LocalAddress version int } @@ -1149,6 +1150,9 @@ func (a *AddrManager) LocalAddresses() []*LocalAddress { // Use Start to begin processing asynchronous address updates. func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager { am := AddrManager{ + mtx: bchutil.NewMutex("addrmgr.AddrManager.mtx"), + lamtx: bchutil.NewMutex("addrmgr.AddrManager.lamtx"), + peersFile: filepath.Join(dataDir, "peers.json"), lookupFunc: lookupFunc, rand: rand.New(rand.NewSource(time.Now().UnixNano())), diff --git a/bchec/ecmh.go b/bchec/ecmh.go index 9727396d8..eed82701d 100644 --- a/bchec/ecmh.go +++ b/bchec/ecmh.go @@ -18,7 +18,9 @@ type Multiset struct { curve *KoblitzCurve x *big.Int y *big.Int - mtx sync.RWMutex + + // This does not use the logging mutex to avoid cyclic dependencies + mtx sync.RWMutex } // NewMultiset returns an empty multiset. The hash of an empty set diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 87dc9c947..20ad7af9b 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -7,13 +7,13 @@ package blockchain import ( "math/big" "sort" - "sync" "time" "github.com/gcash/bchd/chaincfg" "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/database" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) // blockStatus is a bit field representing the validation state of the block. @@ -229,7 +229,7 @@ type blockIndex struct { db database.DB chainParams *chaincfg.Params - sync.RWMutex + bchutil.RWMutex index map[chainhash.Hash]*blockNode dirty map[*blockNode]struct{} } @@ -241,8 +241,10 @@ func newBlockIndex(db database.DB, chainParams *chaincfg.Params) *blockIndex { return &blockIndex{ db: db, chainParams: chainParams, - index: make(map[chainhash.Hash]*blockNode), - dirty: make(map[*blockNode]struct{}), + + RWMutex: bchutil.NewRWMutex("blockchain.blockIndex"), + index: make(map[chainhash.Hash]*blockNode), + dirty: make(map[*blockNode]struct{}), } } diff --git a/blockchain/chain.go b/blockchain/chain.go index 0db611d8d..b3398aa3d 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -10,7 +10,6 @@ import ( "container/list" "fmt" "math" - "sync" "time" "github.com/gcash/bchd/chaincfg" @@ -131,7 +130,7 @@ type BlockChain struct { // chainLock protects concurrent access to the vast majority of the // fields in this struct below this point. - chainLock sync.RWMutex + chainLock bchutil.RWMutex // These fields are related to the memory block index. They both have // their own locks, however they are often also protected by the chain @@ -153,7 +152,7 @@ type BlockChain struct { // orphanLock protects the fields related to handling of orphan blocks. // They are protected by a combination of the chain lock and the orphan lock. - orphanLock sync.RWMutex + orphanLock bchutil.RWMutex orphans map[chainhash.Hash]*orphanBlock prevOrphans map[chainhash.Hash][]*orphanBlock oldestOrphan *orphanBlock @@ -174,7 +173,7 @@ type BlockChain struct { // // In addition, some of the fields are stored in the database so the // chain state can be quickly reconstructed on load. - stateLock sync.RWMutex + stateLock bchutil.RWMutex stateSnapshot *BestState // The following caches are used to efficiently keep track of the @@ -207,7 +206,7 @@ type BlockChain struct { // The notifications field stores a slice of callbacks to be executed on // certain blockchain events. - notificationsLock sync.RWMutex + notificationsLock bchutil.RWMutex notifications []NotificationCallback // The following fields are set if the blockchain is configured to prune @@ -2272,6 +2271,11 @@ func New(config *Config) (*BlockChain, error) { pruneDepth: config.PruneDepth, fastSyncDataDir: config.FastSyncDataDir, fastSyncDone: make(chan struct{}), + + chainLock: bchutil.NewRWMutex("blockchain.BlockChain.chainLock"), + stateLock: bchutil.NewRWMutex("blockchain.BlockChain.stateLock"), + orphanLock: bchutil.NewRWMutex("blockchain.BlockChain.orphanLock"), + notificationsLock: bchutil.NewRWMutex("blockchain.BlockChain.notificationsLock"), } // Initialize the chain state from the passed database. When the db diff --git a/blockchain/chainview.go b/blockchain/chainview.go index a4c3692cd..9e92504ef 100644 --- a/blockchain/chainview.go +++ b/blockchain/chainview.go @@ -4,9 +4,7 @@ package blockchain -import ( - "sync" -) +import "github.com/gcash/bchutil" // approxNodesPerWeek is an approximation of the number of new blocks there are // in a week on average. @@ -42,7 +40,7 @@ func fastLog2Floor(n uint32) uint8 { // The chain view for the branch ending in 6a consists of: // genesis -> 1 -> 2 -> 3 -> 4a -> 5a -> 6a type chainView struct { - mtx sync.Mutex + mtx bchutil.Mutex nodes []*blockNode } @@ -51,7 +49,10 @@ type chainView struct { // can be updated at any time via the setTip function. func newChainView(tip *blockNode) *chainView { // The mutex is intentionally not held since this is a constructor. - var c chainView + c := chainView{ + mtx: bchutil.NewMutex("blockchain.chainView.mtx"), + nodes: nil, + } c.setTip(tip) return &c } diff --git a/blockchain/indexers/addrindex.go b/blockchain/indexers/addrindex.go index 4849c5e05..0fb03b697 100644 --- a/blockchain/indexers/addrindex.go +++ b/blockchain/indexers/addrindex.go @@ -7,7 +7,6 @@ package indexers import ( "errors" "fmt" - "sync" "github.com/gcash/bchd/blockchain" "github.com/gcash/bchd/chaincfg" @@ -569,7 +568,7 @@ type AddrIndex struct { // keep an index of all addresses which a given transaction involves. // This allows fairly efficient updates when transactions are removed // once they are included into a block. - unconfirmedLock sync.RWMutex + unconfirmedLock bchutil.RWMutex txnsByAddr map[[addrKeySize]byte]map[chainhash.Hash]*bchutil.Tx addrsByTx map[chainhash.Hash]map[[addrKeySize]byte]struct{} } @@ -937,6 +936,8 @@ func NewAddrIndex(db database.DB, chainParams *chaincfg.Params) *AddrIndex { chainParams: chainParams, txnsByAddr: make(map[[addrKeySize]byte]map[chainhash.Hash]*bchutil.Tx), addrsByTx: make(map[chainhash.Hash]map[[addrKeySize]byte]struct{}), + + unconfirmedLock: bchutil.NewRWMutex("blockchain/indexers.AddrIndex.unconfirmedLock"), } } diff --git a/blockchain/indexers/blocklogger.go b/blockchain/indexers/blocklogger.go index 8db87bc32..21400d53a 100644 --- a/blockchain/indexers/blocklogger.go +++ b/blockchain/indexers/blocklogger.go @@ -7,7 +7,6 @@ package indexers import ( "fmt" "math" - "sync" "time" "github.com/gcash/bchlog" @@ -24,7 +23,7 @@ type blockProgressLogger struct { subsystemLogger bchlog.Logger progressAction string - sync.Mutex + bchutil.Mutex } // newBlockProgressLogger returns a new block progress logger. @@ -36,6 +35,7 @@ func newBlockProgressLogger(progressMessage string, logger bchlog.Logger) *block lastBlockLogTime: time.Now(), progressAction: progressMessage, subsystemLogger: logger, + Mutex: bchutil.NewMutex("blockchain/indexers.blockProgressLogger"), } } diff --git a/blockchain/mediantime.go b/blockchain/mediantime.go index 141f7acb9..3aacf8482 100644 --- a/blockchain/mediantime.go +++ b/blockchain/mediantime.go @@ -7,8 +7,9 @@ package blockchain import ( "math" "sort" - "sync" "time" + + "github.com/gcash/bchutil" ) const ( @@ -75,7 +76,7 @@ func (s int64Sorter) Less(i, j int) bool { // the time offset mechanism in Bitcoin Core. This is necessary because it is // used in the consensus code. type medianTime struct { - mtx sync.Mutex + mtx bchutil.Mutex knownIDs map[string]struct{} offsets []int64 offsetSecs int64 @@ -212,6 +213,7 @@ func (m *medianTime) Offset() time.Duration { // message received from remote peers that successfully connect and negotiate. func NewMedianTime() MedianTimeSource { return &medianTime{ + mtx: bchutil.NewMutex("blockchain.mediaTime.mtx"), knownIDs: make(map[string]struct{}), offsets: make([]int64, 0, maxMedianTimeEntries), } diff --git a/blockchain/utxocache.go b/blockchain/utxocache.go index c17b68a71..31b718d9e 100644 --- a/blockchain/utxocache.go +++ b/blockchain/utxocache.go @@ -7,8 +7,8 @@ package blockchain import ( "container/list" "fmt" + "github.com/gcash/bchd/txscript" - "sync" "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/database" @@ -186,7 +186,7 @@ type utxoCache struct { // This mutex protects the internal state. // A simple mutex instead of a read-write mutex is chosen because the main // read method also possibly does a write on a cache miss. - mtx sync.Mutex + mtx bchutil.Mutex // cachedEntries keeps the internal cache of the utxo state. The tfModified // flag indicates that the state of the entry (potentially) deviates from the @@ -206,6 +206,7 @@ func newUtxoCache(db database.DB, maxTotalMemoryUsage uint64) *utxoCache { return &utxoCache{ db: db, maxTotalMemoryUsage: maxTotalMemoryUsage, + mtx: bchutil.NewMutex("blockchain.utxoCache.mtx"), cachedEntries: make(map[wire.OutPoint]*UtxoEntry), } diff --git a/btcjson/register.go b/btcjson/register.go index 10cd0f9a8..c783f84af 100644 --- a/btcjson/register.go +++ b/btcjson/register.go @@ -11,7 +11,8 @@ import ( "sort" "strconv" "strings" - "sync" + + "github.com/gcash/bchutil" ) // UsageFlag define flags that specify additional properties about the @@ -84,7 +85,7 @@ type methodInfo struct { var ( // These fields are used to map the registered types to method names. - registerLock sync.RWMutex + registerLock = bchutil.NewRWMutex("btcjson.registerLock") methodToConcreteType = make(map[string]reflect.Type) methodToInfo = make(map[string]methodInfo) concreteTypeToMethod = make(map[reflect.Type]string) diff --git a/connmgr/connmanager.go b/connmgr/connmanager.go index 6bf0cb50e..41fbd7892 100644 --- a/connmgr/connmanager.go +++ b/connmgr/connmanager.go @@ -11,6 +11,8 @@ import ( "sync" "sync/atomic" "time" + + "github.com/gcash/bchutil" ) // maxFailedAttempts is the maximum number of successive failed connection @@ -63,7 +65,7 @@ type ConnReq struct { conn net.Conn state ConnState - stateMtx sync.RWMutex + stateMtx bchutil.RWMutex retryCount uint32 } @@ -366,7 +368,7 @@ func (cm *ConnManager) NewConnReq() { return } - c := &ConnReq{} + c := &ConnReq{stateMtx: bchutil.NewRWMutex("connmgr.ConnReq.stateMtx")} atomic.StoreUint64(&c.id, atomic.AddUint64(&cm.connReqCount, 1)) // Submit a request of a pending connection attempt to the connection diff --git a/connmgr/dynamicbanscore.go b/connmgr/dynamicbanscore.go index bc3c2a458..bf84a4f92 100644 --- a/connmgr/dynamicbanscore.go +++ b/connmgr/dynamicbanscore.go @@ -7,8 +7,9 @@ package connmgr import ( "fmt" "math" - "sync" "time" + + "github.com/gcash/bchutil" ) const ( @@ -64,7 +65,11 @@ type DynamicBanScore struct { lastUnix int64 transient float64 persistent uint32 - mtx sync.Mutex + mtx bchutil.Mutex +} + +func NewDynamicBanScore() DynamicBanScore { + return DynamicBanScore{mtx: bchutil.NewMutex("connmgr.DynamicBanScore.tx")} } // String returns the ban score as a human-readable string. diff --git a/connmgr/dynamicbanscore_test.go b/connmgr/dynamicbanscore_test.go index ec3d2eae6..9248e86b6 100644 --- a/connmgr/dynamicbanscore_test.go +++ b/connmgr/dynamicbanscore_test.go @@ -13,7 +13,7 @@ import ( // TestDynamicBanScoreDecay tests the exponential decay implemented in // DynamicBanScore. func TestDynamicBanScoreDecay(t *testing.T) { - var bs DynamicBanScore + bs := NewDynamicBanScore() base := time.Now() r := bs.increase(100, 50, base) @@ -35,7 +35,7 @@ func TestDynamicBanScoreDecay(t *testing.T) { // TestDynamicBanScoreLifetime tests that DynamicBanScore properly yields zero // once the maximum age is reached. func TestDynamicBanScoreLifetime(t *testing.T) { - var bs DynamicBanScore + bs := NewDynamicBanScore() base := time.Now() bs.increase(0, math.MaxUint32, base) @@ -52,7 +52,7 @@ func TestDynamicBanScoreLifetime(t *testing.T) { // TestDynamicBanScore tests exported functions of DynamicBanScore. Exponential // decay or other time based behavior is tested by other functions. func TestDynamicBanScoreReset(t *testing.T) { - var bs DynamicBanScore + bs := NewDynamicBanScore() if bs.Int() != 0 { t.Errorf("Initial state is not zero.") } diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index 0979bfd57..c76d0f522 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -17,11 +17,11 @@ import ( "path/filepath" "strconv" "strings" - "sync" "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/database" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) const ( @@ -80,15 +80,22 @@ type filer interface { // read or read/write access. It also contains a read-write mutex to support // multiple concurrent readers. type lockableFile struct { - sync.RWMutex + bchutil.RWMutex file filer } +func newLockableFile(f filer) *lockableFile { + return &lockableFile{ + file: f, + RWMutex: bchutil.NewRWMutex("database/ffldb.lockableFile"), + } +} + // writeCursor represents the current file and offset of the block file on disk // for performing all writes. It also contains a read-write mutex to support // multiple concurrent readers which can reuse the file handle. type writeCursor struct { - sync.RWMutex + bchutil.RWMutex // curFile is the current block file that will be appended to when // writing new blocks. @@ -162,9 +169,9 @@ type blockStore struct { // // Due to the high performance and multi-read concurrency requirements, // write locks should only be held for the minimum time necessary. - obfMutex sync.RWMutex - lruMutex sync.Mutex - fbhMutex sync.RWMutex + obfMutex bchutil.RWMutex + lruMutex bchutil.Mutex + fbhMutex bchutil.RWMutex openBlocksLRU *list.List // Contains uint32 block file numbers. fileNumToLRUElem map[uint32]*list.Element openBlockFiles map[uint32]*lockableFile @@ -264,7 +271,7 @@ func (s *blockStore) openFile(fileNum uint32) (*lockableFile, error) { return nil, makeDbErr(database.ErrDriverSpecific, err.Error(), err) } - blockFile := &lockableFile{file: file} + blockFile := newLockableFile(file) // Close the least recently used file if the file exceeds the max // allowed open files. This is not done until after the file open in @@ -879,11 +886,16 @@ func newBlockStore(basePath string, network wire.BitcoinNet) (*blockStore, error fileNumToLRUElem: make(map[uint32]*list.Element), writeCursor: &writeCursor{ - curFile: &lockableFile{}, + RWMutex: bchutil.NewRWMutex("database/ffldb.blockStore.writeCursor"), + curFile: newLockableFile(nil), curFileNum: uint32(fileNum), curOffset: fileOff, }, fileBlockHeights: make(map[uint32]uint32), + + obfMutex: bchutil.NewRWMutex("database/ffldb.blockStore.obfMutex"), + lruMutex: bchutil.NewMutex("database/ffldb.blockStore.lruMutex"), + fbhMutex: bchutil.NewRWMutex("database/ffldb.blockStore.fbhMutex"), } store.openFileFunc = store.openFile store.openWriteFileFunc = store.openWriteFile diff --git a/database/ffldb/db.go b/database/ffldb/db.go index fd4492034..7975e9588 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -12,7 +12,6 @@ import ( "path/filepath" "runtime" "sort" - "sync" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/comparer" @@ -984,7 +983,7 @@ type transaction struct { // Active iterators that need to be notified when the pending keys have // been updated so the cursors can properly handle updates to the // transaction state. - activeIterLock sync.RWMutex + activeIterLock bchutil.RWMutex activeIters []*treap.Iterator } @@ -1782,11 +1781,11 @@ func (tx *transaction) Rollback() error { // the database.DB interface. All database access is performed through // transactions which are obtained through the specific Namespace. type db struct { - writeLock sync.Mutex // Limit to one write transaction at a time. - closeLock sync.RWMutex // Make database close block while txns active. - closed bool // Is the database closed? - store *blockStore // Handles read/writing blocks to flat files. - cache *dbCache // Cache layer which wraps underlying leveldb DB. + writeLock bchutil.Mutex // Limit to one write transaction at a time. + closeLock bchutil.RWMutex // Make database close block while txns active. + closed bool // Is the database closed? + store *blockStore // Handles read/writing blocks to flat files. + cache *dbCache // Cache layer which wraps underlying leveldb DB. } // Enforce db implements the database.DB interface. @@ -1866,6 +1865,8 @@ func (db *db) begin(writable bool) (*transaction, error) { snapshot: snapshot, pendingKeys: treap.NewMutable(), pendingRemove: treap.NewMutable(), + + activeIterLock: bchutil.NewRWMutex("database/ffldb.transaction.activeIterLock"), } tx.metaBucket = &bucket{tx: tx, id: metadataBucketID} tx.blockIdxBucket = &bucket{tx: tx, id: blockIdxBucketID} @@ -2099,7 +2100,13 @@ func openDB(dbPath string, network wire.BitcoinNet, create bool, cacheSize uint6 flushSecs = defaultFlushSecs } cache := newDbCache(ldb, store, cacheSize, flushSecs) - pdb := &db{store: store, cache: cache} + pdb := &db{ + store: store, + cache: cache, + + writeLock: bchutil.NewMutex("database/fldb/db.writeLock"), + closeLock: bchutil.NewRWMutex("database/fldb/db.closeLock"), + } // Perform any reconciliation needed between the block and metadata as // well as database initialization, if needed. diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index 8c26a35b2..2d2a99e3d 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -7,13 +7,13 @@ package ffldb import ( "bytes" "fmt" - "sync" "time" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/util" "github.com/gcash/bchd/database/internal/treap" + "github.com/gcash/bchutil" ) const ( @@ -386,7 +386,7 @@ type dbCache struct { // stored using immutable treaps to support O(1) MVCC snapshots against // the cached data. The cacheLock is used to protect concurrent access // for cache updates and snapshots. - cacheLock sync.RWMutex + cacheLock bchutil.RWMutex cachedKeys *treap.Immutable cachedRemove *treap.Immutable } @@ -654,7 +654,9 @@ func newDbCache(ldb *leveldb.DB, store *blockStore, maxSize uint64, flushInterva maxSize: maxSize, flushInterval: time.Second * time.Duration(flushIntervalSecs), lastFlush: time.Now(), - cachedKeys: treap.NewImmutable(), - cachedRemove: treap.NewImmutable(), + + cacheLock: bchutil.NewRWMutex("database/ffldb.dbCache.cacheLock"), + cachedKeys: treap.NewImmutable(), + cachedRemove: treap.NewImmutable(), } } diff --git a/database/ffldb/mockfile_test.go b/database/ffldb/mockfile_test.go index 15fbd6e5a..5eae76c34 100644 --- a/database/ffldb/mockfile_test.go +++ b/database/ffldb/mockfile_test.go @@ -10,7 +10,8 @@ package ffldb import ( "errors" "io" - "sync" + + "github.com/gcash/bchutil" ) // Errors used for the mock file. @@ -30,7 +31,7 @@ var ( // the database code related to reading and writing from the flat block files. // A maxSize of -1 is unlimited. type mockFile struct { - sync.RWMutex + bchutil.RWMutex maxSize int64 data []byte forceSyncErr bool diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index a1917a832..00d068a81 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -326,7 +326,7 @@ func testWriteFailures(tc *testContext) bool { store.writeCursor.Lock() oldFile := store.writeCursor.curFile store.writeCursor.curFile = &lockableFile{ - file: &mockFile{forceSyncErr: true, maxSize: -1}, + file: &mockFile{forceSyncErr: true, maxSize: -1, RWMutex: bchutil.NewRWMutex("database/ffldb.mockFile")}, } store.writeCursor.Unlock() err := tc.db.(*db).cache.flush() @@ -655,7 +655,7 @@ func TestFailureScenarios(t *testing.T) { if maxFileSize, ok := tc.maxFileSizes[fileNum]; ok { maxSize = maxFileSize } - file := &mockFile{maxSize: maxSize} + file := &mockFile{maxSize: maxSize, RWMutex: bchutil.NewRWMutex("database/ffldb.mockFile")} tc.files[fileNum] = &lockableFile{file: file} return file, nil } @@ -675,7 +675,7 @@ func TestFailureScenarios(t *testing.T) { file.Unlock() return file, nil } - file := &lockableFile{file: &mockFile{}} + file := &lockableFile{file: &mockFile{RWMutex: bchutil.NewRWMutex("database/ffldb.mockFile")}} tc.files[fileNum] = file return file, nil } diff --git a/go.mod b/go.mod index 90f91d8f7..36125f778 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/dchest/siphash v1.2.1 github.com/gcash/bchlog v0.0.0-20180913005452-b4f036f92fa6 - github.com/gcash/bchutil v0.0.0-20191012211144-98e73ec336ba + github.com/gcash/bchutil v0.0.0-20191105224616-dcc2306d4ba0 github.com/golang/protobuf v1.3.2 github.com/gorilla/websocket v1.4.1 // indirect github.com/improbable-eng/grpc-web v0.9.1 diff --git a/go.sum b/go.sum index bd9d73b0f..ad5c91696 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/gcash/bchlog v0.0.0-20180913005452-b4f036f92fa6 h1:3pZvWJ8MSfWstGrb8H github.com/gcash/bchlog v0.0.0-20180913005452-b4f036f92fa6/go.mod h1:PpfmXTLfjRp7Tf6v/DCGTRXHz+VFbiRcsoUxi7HvwlQ= github.com/gcash/bchutil v0.0.0-20190625002603-800e62fe9aff h1:QT9Muw3OooirX3cRwFuaXOPR2Lq/1P8ug9yEzW8eaRA= github.com/gcash/bchutil v0.0.0-20190625002603-800e62fe9aff/go.mod h1:zXSP0Fg2L52wpSEDApQDQMiSygnQiK5HDquDl0a5BHg= -github.com/gcash/bchutil v0.0.0-20191012211144-98e73ec336ba h1:KVa96lSrJGMYZ414NtYuAlbtCgrmW9kDnjvYXcLrr5A= -github.com/gcash/bchutil v0.0.0-20191012211144-98e73ec336ba/go.mod h1:nUIrcbbtEQdCsRwcp+j/CndDKMQE9Fi8p2F8cIZmIqI= +github.com/gcash/bchutil v0.0.0-20191105224616-dcc2306d4ba0 h1:5wg91ZnUQAVR8FzTlyCy0AP3cZaBBAQzLAbjKDn6aWw= +github.com/gcash/bchutil v0.0.0-20191105224616-dcc2306d4ba0/go.mod h1:nUIrcbbtEQdCsRwcp+j/CndDKMQE9Fi8p2F8cIZmIqI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -104,6 +104,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/integration/rpctest/bchd.go b/integration/rpctest/bchd.go index 55ae7e2c3..1619b3904 100644 --- a/integration/rpctest/bchd.go +++ b/integration/rpctest/bchd.go @@ -10,13 +10,14 @@ import ( "os/exec" "path/filepath" "runtime" - "sync" + + "github.com/gcash/bchutil" ) var ( // compileMtx guards access to the executable path so that the project is // only compiled once. - compileMtx sync.Mutex + compileMtx = bchutil.NewMutex("integration/rpcclient.compileMtx") // executablePath is the path to the compiled executable. This is the empty // string until bchd is compiled. This should not be accessed directly; diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index 062b5cd6d..2a49c7535 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/binary" "fmt" - "sync" "github.com/gcash/bchd/bchec" "github.com/gcash/bchd/blockchain" @@ -99,13 +98,13 @@ type memWallet struct { chainUpdates []*chainUpdate chainUpdateSignal chan struct{} - chainMtx sync.Mutex + chainMtx bchutil.Mutex net *chaincfg.Params rpc *rpcclient.Client - sync.RWMutex + bchutil.RWMutex } // newMemWallet creates and returns a fully initialized instance of the @@ -153,6 +152,9 @@ func newMemWallet(net *chaincfg.Params, harnessID uint32) (*memWallet, error) { utxos: make(map[wire.OutPoint]*utxo), chainUpdateSignal: make(chan struct{}), reorgJournal: make(map[int32]*undoEntry), + + RWMutex: bchutil.NewRWMutex("integration/rpctest.memWallet"), + chainMtx: bchutil.NewMutex("integration/rpctest.memWallet.chainMtx"), }, nil } diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 28e381ea7..e2530413e 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -11,7 +11,6 @@ import ( "os" "path/filepath" "strconv" - "sync" "testing" "time" @@ -57,7 +56,7 @@ var ( testInstances = make(map[string]*Harness) // Used to protest concurrent access to above declared variables. - harnessStateMtx sync.RWMutex + harnessStateMtx = bchutil.NewRWMutex("integration/rpctest.harnessStateMtx") ) // HarnessTestCase represents a test-case which utilizes an instance of the @@ -88,7 +87,7 @@ type Harness struct { maxConnRetries int nodeNum int - sync.Mutex + bchutil.Mutex } // New creates and initializes new instance of the rpc test harness. @@ -197,6 +196,7 @@ func New(activeNet *chaincfg.Params, handlers *rpcclient.NotificationHandlers, ActiveNet: activeNet, nodeNum: nodeNum, wallet: wallet, + Mutex: bchutil.NewMutex("integration/rpctest.Harness"), } // Track this newly created test instance within the package level diff --git a/mempool/estimatefee.go b/mempool/estimatefee.go index f8b27e65d..5ea8eff22 100644 --- a/mempool/estimatefee.go +++ b/mempool/estimatefee.go @@ -14,7 +14,6 @@ import ( "math/rand" "sort" "strings" - "sync" "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/mining" @@ -47,7 +46,7 @@ const ( bytePerKb = 1000 - bchPerSatoshi = 1E-8 + bchPerSatoshi = 1e-8 ) var ( @@ -168,7 +167,7 @@ type FeeEstimator struct { // The number of blocks that have been registered. numBlocksRegistered uint32 - mtx sync.RWMutex + mtx bchutil.RWMutex observed map[chainhash.Hash]*observedTransaction bin [estimateFeeDepth][]*observedTransaction @@ -192,6 +191,7 @@ func NewFeeEstimator(maxRollback, minRegisteredBlocks uint32) *FeeEstimator { maxReplacements: estimateFeeMaxReplacements, observed: make(map[chainhash.Hash]*observedTransaction), dropped: make([]*registeredBlock, 0, maxRollback), + mtx: bchutil.NewRWMutex("mempool.FeeEstimator.mtx"), } } diff --git a/mempool/mempool.go b/mempool/mempool.go index 959a65e7a..f5e48e468 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -11,12 +11,12 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/dchest/siphash" "math" - "sync" "sync/atomic" "time" + "github.com/dchest/siphash" + "github.com/gcash/bchd/blockchain" "github.com/gcash/bchd/blockchain/indexers" "github.com/gcash/bchd/btcjson" @@ -166,7 +166,7 @@ type TxPool struct { // The following variables must only be used atomically. lastUpdated int64 // last time pool was updated - mtx sync.RWMutex + mtx bchutil.RWMutex cfg Config pool map[chainhash.Hash]*TxDesc orphans map[chainhash.Hash]*orphanTx @@ -1405,6 +1405,7 @@ func (mp *TxPool) DecodeCompressedBlock(iBlock interface{}) (*wire.MsgBlock, err func New(cfg *Config) *TxPool { return &TxPool{ cfg: *cfg, + mtx: bchutil.NewRWMutex("mempool.TxPool.mtx"), pool: make(map[chainhash.Hash]*TxDesc), orphans: make(map[chainhash.Hash]*orphanTx), orphansByPrev: make(map[wire.OutPoint]map[chainhash.Hash]*bchutil.Tx), diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 1481ed53d..dacbef88b 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -6,13 +6,13 @@ package mempool import ( "encoding/hex" - "github.com/gcash/bchd/mining" "reflect" "runtime" - "sync" "testing" "time" + "github.com/gcash/bchd/mining" + "github.com/gcash/bchd/bchec" "github.com/gcash/bchd/blockchain" "github.com/gcash/bchd/chaincfg" @@ -28,7 +28,7 @@ const MockMaxUtxosPerBlock = 32000000 / wire.MinTxOutPayload // a current faked chain height to the pool callbacks. This, in turn, allows // transactions to appear as though they are spending completely valid utxos. type fakeChain struct { - sync.RWMutex + bchutil.RWMutex utxos *blockchain.UtxoViewpoint currentHeight int32 medianTimePast time.Time diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index eef73ca3d..3c61febb9 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -90,13 +90,13 @@ type Config struct { // function, but the default is based on the number of processor cores in the // system which is typically sufficient. type CPUMiner struct { - sync.Mutex + bchutil.Mutex g *mining.BlkTmplGenerator cfg Config numWorkers uint32 started bool discreteMining bool - submitBlockLock sync.Mutex + submitBlockLock bchutil.Mutex wg sync.WaitGroup workerWg sync.WaitGroup updateNumWorkers chan struct{} @@ -638,5 +638,8 @@ func New(cfg *Config) *CPUMiner { updateNumWorkers: make(chan struct{}), queryHashesPerSec: make(chan float64), updateHashes: make(chan uint64), + + Mutex: bchutil.NewMutex("mining/cpuminer.CPUMiner"), + submitBlockLock: bchutil.NewMutex("mining/cpuminer.CPUMiner.submitBlockLock"), } } diff --git a/netsync/blocklogger.go b/netsync/blocklogger.go index bf1a3600c..8921b6206 100644 --- a/netsync/blocklogger.go +++ b/netsync/blocklogger.go @@ -7,7 +7,6 @@ package netsync import ( "fmt" "math" - "sync" "time" "github.com/gcash/bchd/blockchain" @@ -25,7 +24,7 @@ type blockProgressLogger struct { subsystemLogger bchlog.Logger progressAction string - sync.Mutex + bchutil.Mutex } // newBlockProgressLogger returns a new block progress logger. @@ -34,6 +33,7 @@ type blockProgressLogger struct { // ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) func newBlockProgressLogger(progressMessage string, logger bchlog.Logger) *blockProgressLogger { return &blockProgressLogger{ + Mutex: bchutil.NewMutex("netsync.blockProgressLogger"), lastBlockLogTime: time.Now(), progressAction: progressMessage, subsystemLogger: logger, diff --git a/peer/mruinvmap.go b/peer/mruinvmap.go index 0c3275316..55a89c88d 100644 --- a/peer/mruinvmap.go +++ b/peer/mruinvmap.go @@ -8,16 +8,16 @@ import ( "bytes" "container/list" "fmt" - "sync" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) // mruInventoryMap provides a concurrency safe map that is limited to a maximum // number of items with eviction for the oldest entry when the limit is // exceeded. type mruInventoryMap struct { - invMtx sync.Mutex + invMtx bchutil.Mutex invMap map[wire.InvVect]*list.Element // nearly O(1) lookups invList *list.List // O(1) insert, update, delete limit uint @@ -124,6 +124,7 @@ func (m *mruInventoryMap) Delete(iv *wire.InvVect) { // new entry. func newMruInventoryMap(limit uint) *mruInventoryMap { m := mruInventoryMap{ + invMtx: bchutil.NewMutex("peer.mruInventoryMap.invMtx"), invMap: make(map[wire.InvVect]*list.Element), invList: list.New(), limit: limit, diff --git a/peer/mrunoncemap.go b/peer/mrunoncemap.go index 5f7c79842..73811bd4a 100644 --- a/peer/mrunoncemap.go +++ b/peer/mrunoncemap.go @@ -8,14 +8,15 @@ import ( "bytes" "container/list" "fmt" - "sync" + + "github.com/gcash/bchutil" ) // mruNonceMap provides a concurrency safe map that is limited to a maximum // number of items with eviction for the oldest entry when the limit is // exceeded. type mruNonceMap struct { - mtx sync.Mutex + mtx bchutil.Mutex nonceMap map[uint64]*list.Element // nearly O(1) lookups nonceList *list.List // O(1) insert, update, delete limit uint @@ -117,6 +118,7 @@ func (m *mruNonceMap) Delete(nonce uint64) { // new entry. func newMruNonceMap(limit uint) *mruNonceMap { m := mruNonceMap{ + mtx: bchutil.NewMutex("peer.mruNonceMap.mtx"), nonceMap: make(map[uint64]*list.Element), nonceList: list.New(), limit: limit, diff --git a/peer/peer.go b/peer/peer.go index 2dac44a79..cb9a31d2a 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -14,7 +14,6 @@ import ( "math/rand" "net" "strconv" - "sync" "sync/atomic" "time" @@ -24,6 +23,7 @@ import ( "github.com/gcash/bchd/chaincfg" "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) const ( @@ -465,7 +465,7 @@ type Peer struct { cfg Config inbound bool - flagsMtx sync.Mutex // protects the peer flags below + flagsMtx bchutil.Mutex // protects the peer flags below na *wire.NetAddress id int32 userAgent string @@ -481,16 +481,16 @@ type Peer struct { wireEncoding wire.MessageEncoding knownInventory *mruInventoryMap - prevGetBlocksMtx sync.Mutex + prevGetBlocksMtx bchutil.Mutex prevGetBlocksBegin *chainhash.Hash prevGetBlocksStop *chainhash.Hash - prevGetHdrsMtx sync.Mutex + prevGetHdrsMtx bchutil.Mutex prevGetHdrsBegin *chainhash.Hash prevGetHdrsStop *chainhash.Hash // These fields keep track of statistics for the peer and are protected // by the statsMtx mutex. - statsMtx sync.RWMutex + statsMtx bchutil.RWMutex timeOffset int64 timeConnected time.Time startingHeight int32 @@ -2360,6 +2360,11 @@ func newPeerBase(origCfg *Config, inbound bool) *Peer { services: cfg.Services, protocolVersion: cfg.ProtocolVersion, syncPeer: false, + + flagsMtx: bchutil.NewMutex("peer.Peer.flagsMtx"), + statsMtx: bchutil.NewRWMutex("peer.Peer.statsMtx"), + prevGetHdrsMtx: bchutil.NewMutex("peer.Peer.prevGetHdrsMtx"), + prevGetBlocksMtx: bchutil.NewMutex("peer.Peer.prevGetBlocksMtx"), } return &p } diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 590e09dd6..5eee4e181 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -26,6 +26,7 @@ import ( "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" "github.com/gcash/bchd/btcjson" + "github.com/gcash/bchutil" ) var ( @@ -130,7 +131,7 @@ type Client struct { httpClient *http.Client // mtx is a mutex to protect access to connection related fields. - mtx sync.Mutex + mtx bchutil.Mutex // disconnected indicated whether or not the server is disconnected. disconnected bool @@ -140,13 +141,13 @@ type Client struct { retryCount int64 // Track command and their response channels by ID. - requestLock sync.Mutex + requestLock bchutil.Mutex requestMap map[uint64]*list.Element requestList *list.List // Notifications. ntfnHandlers *NotificationHandlers - ntfnStateLock sync.Mutex + ntfnStateLock bchutil.Mutex ntfnState *notificationState // Networking infrastructure. @@ -1260,6 +1261,10 @@ func New(config *ConnConfig, ntfnHandlers *NotificationHandlers) (*Client, error connEstablished: connEstablished, disconnect: make(chan struct{}), shutdown: make(chan struct{}), + + mtx: bchutil.NewMutex("rpcclient.Client.mtx"), + requestLock: bchutil.NewMutex("rpcclient.Client.requestLock"), + ntfnStateLock: bchutil.NewMutex("rpcclient.Client.ntfnStateLock"), } if start { diff --git a/rpcserver.go b/rpcserver.go index 21b33926a..d4360297f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -345,7 +345,7 @@ func rpcNoTxInfoError(txHash *chainhash.Hash) *btcjson.RPCError { // gbtWorkState houses state that is used in between multiple RPC invocations to // getblocktemplate. type gbtWorkState struct { - sync.Mutex + bchutil.Mutex lastTxUpdate time.Time lastGenerated time.Time prevHash *chainhash.Hash @@ -361,6 +361,7 @@ type gbtWorkState struct { // fields initialized and ready to use. func newGbtWorkState(timeSource blockchain.MedianTimeSource) *gbtWorkState { return &gbtWorkState{ + Mutex: bchutil.NewMutex("gbtWorkState"), notifyMap: make(map[chainhash.Hash]map[int64]chan struct{}), timeSource: timeSource, } @@ -3983,7 +3984,7 @@ type rpcServer struct { ntfnMgr *wsNotificationManager numClients int32 statusLines map[int]string - statusLock sync.RWMutex + statusLock bchutil.RWMutex wg sync.WaitGroup gbtWorkState *gbtWorkState helpCacher *helpCacher @@ -4803,6 +4804,7 @@ func newRPCServer(config *rpcserverConfig) (*rpcServer, error) { helpCacher: newHelpCacher(), requestProcessShutdown: make(chan struct{}), quit: make(chan int), + statusLock: bchutil.NewRWMutex("rpcServer.statusLock"), } if cfg.RPCUser != "" && cfg.RPCPass != "" { login := cfg.RPCUser + ":" + cfg.RPCPass diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 872eebcf0..b166c39c0 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -9,9 +9,9 @@ import ( "errors" "sort" "strings" - "sync" "github.com/gcash/bchd/btcjson" + "github.com/gcash/bchutil" ) // helpDescsEnUS defines the English descriptions used for the help strings. @@ -790,7 +790,7 @@ var rpcResultTypes = map[string][]interface{}{ // helpCacher provides a concurrent safe type that provides help and usage for // the RPC server commands and caches the results for future calls. type helpCacher struct { - sync.Mutex + bchutil.Mutex usage string methodHelp map[string]string } @@ -865,6 +865,7 @@ func (c *helpCacher) rpcUsage(includeWebsockets bool) (string, error) { // usage for the RPC server commands and caches the results for future calls. func newHelpCacher() *helpCacher { return &helpCacher{ + Mutex: bchutil.NewMutex("helpCacher"), methodHelp: make(map[string]string), } } diff --git a/rpcwebsocket.go b/rpcwebsocket.go index f66304f7d..5b31a0801 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -252,7 +252,7 @@ func (m *wsNotificationManager) NotifyMempoolTx(tx *bchutil.Tx, isNew bool) { // // NOTE: This extension was ported from github.com/decred/dcrd type wsClientFilter struct { - mu sync.Mutex + mu bchutil.Mutex // Implemented fast paths for address lookup. pubKeyHashes map[[ripemd160.Size]byte]struct{} @@ -275,6 +275,7 @@ type wsClientFilter struct { // NOTE: This extension was ported from github.com/decred/dcrd func newWSClientFilter(addresses []string, unspentOutPoints []wire.OutPoint, params *chaincfg.Params) *wsClientFilter { filter := &wsClientFilter{ + mu: bchutil.NewMutex("wsClientFilter.mu"), pubKeyHashes: map[[ripemd160.Size]byte]struct{}{}, scriptHashes: map[[ripemd160.Size]byte]struct{}{}, compressedPubKeys: map[[33]byte]struct{}{}, @@ -1246,7 +1247,7 @@ type wsResponse struct { // subsystems can't block. Ultimately, all messages are sent via the // outHandler. type wsClient struct { - sync.Mutex + bchutil.Mutex // server is the RPC server that is servicing the client. server *rpcServer @@ -2002,6 +2003,8 @@ func newWebsocketClient(server *rpcServer, conn *websocket.Conn, } client := &wsClient{ + Mutex: bchutil.NewMutex("wsClient"), + conn: conn, addr: remoteAddr, authenticated: authenticated, diff --git a/server.go b/server.go index 2961c476c..975e47e65 100644 --- a/server.go +++ b/server.go @@ -12,7 +12,6 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/gcash/bchd/bchrpc" "math" "net" "runtime" @@ -23,6 +22,8 @@ import ( "sync/atomic" "time" + "github.com/gcash/bchd/bchrpc" + "github.com/gcash/bchutil/gcs/builder" "github.com/gcash/bchd/addrmgr" @@ -275,7 +276,7 @@ type server struct { // cfCheckptCaches stores a cached slice of filter headers for cfcheckpt // messages for each filter type. cfCheckptCaches map[wire.FilterType][]cfHeaderKV - cfCheckptCachesMtx sync.RWMutex + cfCheckptCachesMtx bchutil.RWMutex } // spMsg represents a message over the wire from a specific peer. @@ -304,13 +305,13 @@ type serverPeer struct { server *server persistent bool continueHash *chainhash.Hash - relayMtx sync.Mutex - processBlockMtx sync.Mutex + relayMtx bchutil.Mutex + processBlockMtx bchutil.Mutex disableRelayTx bool sentAddrs bool isWhitelisted bool filter *bloom.Filter - addrMtx sync.RWMutex + addrMtx bchutil.RWMutex knownAddresses map[string]struct{} banScore connmgr.DynamicBanScore quit chan struct{} @@ -319,7 +320,7 @@ type serverPeer struct { blockProcessed chan struct{} recvSubscribers map[spMsgSubscription]struct{} - mtxSubscribers sync.RWMutex + mtxSubscribers bchutil.RWMutex } // newServerPeer returns a new serverPeer instance. The peer needs to be set by @@ -334,6 +335,13 @@ func newServerPeer(s *server, isPersistent bool) *serverPeer { txProcessed: make(chan struct{}, 1), blockProcessed: make(chan struct{}, 1), recvSubscribers: make(map[spMsgSubscription]struct{}), + + banScore: connmgr.NewDynamicBanScore(), + + relayMtx: bchutil.NewMutex("serverPeer.relayMtx"), + addrMtx: bchutil.NewRWMutex("serverPeer.addrMtx"), + processBlockMtx: bchutil.NewMutex("serverPeer.processBlockMtx"), + mtxSubscribers: bchutil.NewRWMutex("serverPeer.mtxSubscribers"), } } @@ -3086,6 +3094,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param sigCache: txscript.NewSigCache(cfg.SigCacheMaxSize), hashCache: txscript.NewHashCache(cfg.SigCacheMaxSize), cfCheckptCaches: make(map[wire.FilterType][]cfHeaderKV), + cfCheckptCachesMtx: bchutil.NewRWMutex("server.cfCheckptCachesMtx"), } // Create the transaction and address indexes if needed. diff --git a/txscript/hashcache.go b/txscript/hashcache.go index 54d77df01..5092d03bb 100644 --- a/txscript/hashcache.go +++ b/txscript/hashcache.go @@ -5,10 +5,9 @@ package txscript import ( - "sync" - "github.com/gcash/bchd/chaincfg/chainhash" "github.com/gcash/bchd/wire" + "github.com/gcash/bchutil" ) // TxSigHashes houses the partial set of sighashes introduced within BIP0143. @@ -39,13 +38,14 @@ func NewTxSigHashes(tx *wire.MsgTx) *TxSigHashes { type HashCache struct { sigHashes map[chainhash.Hash]*TxSigHashes - sync.RWMutex + bchutil.RWMutex } // NewHashCache returns a new instance of the HashCache given a maximum number // of entries which may exist within it at anytime. func NewHashCache(maxSize uint) *HashCache { return &HashCache{ + RWMutex: bchutil.NewRWMutex("txscript.HashCache"), sigHashes: make(map[chainhash.Hash]*TxSigHashes, maxSize), } } diff --git a/txscript/sigcache.go b/txscript/sigcache.go index 8f456f981..c79b826df 100644 --- a/txscript/sigcache.go +++ b/txscript/sigcache.go @@ -5,10 +5,9 @@ package txscript import ( - "sync" - "github.com/gcash/bchd/bchec" "github.com/gcash/bchd/chaincfg/chainhash" + "github.com/gcash/bchutil" ) // sigCacheEntry represents an entry in the SigCache. Entries within the @@ -33,7 +32,7 @@ type sigCacheEntry struct { // optimization which speeds up the validation of transactions within a block, // if they've already been seen and verified within the mempool. type SigCache struct { - sync.RWMutex + bchutil.RWMutex validSigs map[chainhash.Hash]sigCacheEntry maxEntries uint } @@ -45,6 +44,7 @@ type SigCache struct { // cache to exceed the max. func NewSigCache(maxEntries uint) *SigCache { return &SigCache{ + RWMutex: bchutil.NewRWMutex("txscript.SigCache"), validSigs: make(map[chainhash.Hash]sigCacheEntry, maxEntries), maxEntries: maxEntries, }