mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-01-10 15:54:05 +00:00
core: fix race during native cache persist
Fixes the following race: ``` 2022-05-06T06:51:33.3980029Z WARNING: DATA RACE 2022-05-06T06:51:33.3980178Z Read at 0x00c0007e02a0 by goroutine 96: 2022-05-06T06:51:33.3980338Z runtime.mapaccess2_fast32() 2022-05-06T06:51:33.3980863Z /opt/hostedtoolcache/go/1.17.9/x64/src/runtime/map_fast32.go:52 +0x0 2022-05-06T06:51:33.3981249Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).getCache() 2022-05-06T06:51:33.3982707Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:905 +0x64 2022-05-06T06:51:33.3983443Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).GetROCache() 2022-05-06T06:51:33.3983900Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:889 +0xd4 2022-05-06T06:51:33.3984231Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).getCache() 2022-05-06T06:51:33.3984869Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:913 +0x196 2022-05-06T06:51:33.3985254Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).GetROCache() 2022-05-06T06:51:33.3985756Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:889 +0xd4 2022-05-06T06:51:33.3986167Z github.com/nspcc-dev/neo-go/pkg/core/native.(*Policy).isBlockedInternal() 2022-05-06T06:51:33.3986824Z /home/runner/work/neo-go/neo-go/pkg/core/native/policy.go:258 +0x6a 2022-05-06T06:51:33.3987264Z github.com/nspcc-dev/neo-go/pkg/core/native.(*Policy).IsBlocked() 2022-05-06T06:51:33.3987743Z /home/runner/work/neo-go/neo-go/pkg/core/native/policy.go:250 +0x2f7 2022-05-06T06:51:33.3988155Z github.com/nspcc-dev/neo-go/pkg/core/native.(*NEO).getAllCandidatesCall.func1() 2022-05-06T06:51:33.3988645Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_neo.go:948 +0x109 2022-05-06T06:51:33.3989053Z github.com/nspcc-dev/neo-go/pkg/core/native.(*NEO).getAllCandidatesCall.func2() 2022-05-06T06:51:33.3989550Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_neo.go:959 +0x137 2022-05-06T06:51:33.3989561Z 2022-05-06T06:51:33.3989735Z Previous write at 0x00c0007e02a0 by goroutine 40: 2022-05-06T06:51:33.3989891Z runtime.mapassign_fast32() 2022-05-06T06:51:33.3990260Z /opt/hostedtoolcache/go/1.17.9/x64/src/runtime/map_fast32.go:92 +0x0 2022-05-06T06:51:33.3990640Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).persistNativeCache() 2022-05-06T06:51:33.3991084Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:876 +0x12d 2022-05-06T06:51:33.3991411Z github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).Persist() 2022-05-06T06:51:33.3991852Z /home/runner/work/neo-go/neo-go/pkg/core/dao/dao.go:850 +0x1d4 2022-05-06T06:51:33.3992186Z github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).runPersist() 2022-05-06T06:51:33.3992650Z /home/runner/work/neo-go/neo-go/pkg/core/blockchain.go:1285 +0x28a 2022-05-06T06:51:33.3992971Z github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).storeBlock() 2022-05-06T06:51:33.3993845Z /home/runner/work/neo-go/neo-go/pkg/core/blockchain.go:1143 +0x1b9c 2022-05-06T06:51:33.3994241Z github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddBlock() 2022-05-06T06:51:33.3994707Z /home/runner/work/neo-go/neo-go/pkg/core/blockchain.go:910 +0x791 2022-05-06T06:51:33.3995053Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).AddNewBlock() 2022-05-06T06:51:33.3995492Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:334 +0xa7 2022-05-06T06:51:33.3995842Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).InvokeScript() 2022-05-06T06:51:33.3996288Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:178 +0x169 2022-05-06T06:51:33.3996725Z github.com/nspcc-dev/neo-go/pkg/core/native/native_test_test.TestNEO_GetCandidates.func2() 2022-05-06T06:51:33.3997253Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_test/neo_test.go:549 +0x4cb 2022-05-06T06:51:33.3997672Z github.com/nspcc-dev/neo-go/pkg/core/native/native_test_test.TestNEO_GetCandidates() 2022-05-06T06:51:33.3998404Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_test/neo_test.go:574 +0x2103 2022-05-06T06:51:33.3998751Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).AddNewBlock() 2022-05-06T06:51:33.3999193Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:334 +0xa7 2022-05-06T06:51:33.3999541Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).InvokeScript() 2022-05-06T06:51:33.3999988Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:178 +0x169 2022-05-06T06:51:33.4000305Z github.com/nspcc-dev/neo-go/pkg/neotest.AddSystemFee() 2022-05-06T06:51:33.4000733Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:291 +0x85 2022-05-06T06:51:33.4001062Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).SignTx() 2022-05-06T06:51:33.4001509Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:111 +0x109 2022-05-06T06:51:33.4001885Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).PrepareInvocation() 2022-05-06T06:51:33.4002435Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:191 +0x1b2 2022-05-06T06:51:33.4002808Z github.com/nspcc-dev/neo-go/pkg/neotest.(*Executor).InvokeScript() 2022-05-06T06:51:33.4003249Z /home/runner/work/neo-go/neo-go/pkg/neotest/basic.go:177 +0xed 2022-05-06T06:51:33.4003685Z github.com/nspcc-dev/neo-go/pkg/core/native/native_test_test.TestNEO_GetCandidates.func2() 2022-05-06T06:51:33.4004216Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_test/neo_test.go:549 +0x4cb 2022-05-06T06:51:33.4004634Z github.com/nspcc-dev/neo-go/pkg/core/native/native_test_test.TestNEO_GetCandidates() 2022-05-06T06:51:33.4005165Z /home/runner/work/neo-go/neo-go/pkg/core/native/native_test/neo_test.go:558 +0x1bbb 2022-05-06T06:51:33.4005298Z testing.tRunner() 2022-05-06T06:51:33.4005674Z /opt/hostedtoolcache/go/1.17.9/x64/src/testing/testing.go:1259 +0x22f 2022-05-06T06:51:33.4005916Z testing.(*T).Run·dwrap·21() 2022-05-06T06:51:33.4006298Z /opt/hostedtoolcache/go/1.17.9/x64/src/testing/testing.go:1306 +0x47 ... ```
This commit is contained in:
parent
ce35e69460
commit
a427411a57
1 changed files with 11 additions and 16 deletions
|
@ -839,14 +839,13 @@ func (dao *Simple) getDataBuf() *io.BufBinWriter {
|
|||
// underlying store. It doesn't block accesses to DAO from other threads.
|
||||
func (dao *Simple) Persist() (int, error) {
|
||||
if dao.nativeCachePS != nil {
|
||||
if !dao.private {
|
||||
dao.nativeCacheLock.Lock()
|
||||
defer dao.nativeCacheLock.Unlock()
|
||||
}
|
||||
if !dao.nativeCachePS.private {
|
||||
dao.nativeCachePS.nativeCacheLock.Lock()
|
||||
defer dao.nativeCachePS.nativeCacheLock.Unlock()
|
||||
}
|
||||
dao.nativeCacheLock.Lock()
|
||||
dao.nativeCachePS.nativeCacheLock.Lock()
|
||||
defer func() {
|
||||
dao.nativeCachePS.nativeCacheLock.Unlock()
|
||||
dao.nativeCacheLock.Unlock()
|
||||
}()
|
||||
|
||||
dao.persistNativeCache()
|
||||
}
|
||||
return dao.Store.Persist()
|
||||
|
@ -881,10 +880,8 @@ func (dao *Simple) persistNativeCache() {
|
|||
// GetROCache returns native contact cache. The cache CAN NOT be modified by
|
||||
// the caller. It's the caller's duty to keep it unmodified.
|
||||
func (dao *Simple) GetROCache(id int32) NativeContractCache {
|
||||
if !dao.private {
|
||||
dao.nativeCacheLock.RLock()
|
||||
defer dao.nativeCacheLock.RUnlock()
|
||||
}
|
||||
dao.nativeCacheLock.RLock()
|
||||
defer dao.nativeCacheLock.RUnlock()
|
||||
|
||||
return dao.getCache(id, true)
|
||||
}
|
||||
|
@ -892,10 +889,8 @@ func (dao *Simple) GetROCache(id int32) NativeContractCache {
|
|||
// GetRWCache returns native contact cache. The cache CAN BE safely modified
|
||||
// by the caller.
|
||||
func (dao *Simple) GetRWCache(id int32) NativeContractCache {
|
||||
if !dao.private {
|
||||
dao.nativeCacheLock.Lock()
|
||||
defer dao.nativeCacheLock.Unlock()
|
||||
}
|
||||
dao.nativeCacheLock.Lock()
|
||||
defer dao.nativeCacheLock.Unlock()
|
||||
|
||||
return dao.getCache(id, false)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue