core: protect (*Blockchain).keyCache with a lock
Avoid failures like this: fatal error: concurrent map writes goroutine 103 [running]: runtime.throw(0xca6fe3, 0x15) /usr/lib64/go/1.12/src/runtime/panic.go:617 +0x72 fp=0xc000687988 sp=0xc000687958 pc=0x42d8d2 runtime.mapassign(0xb9d4a0, 0xc0000b1f80, 0xc000687a6c, 0x13bd940) /usr/lib64/go/1.12/src/runtime/map.go:590 +0x5e3 fp=0xc000687a10 sp=0xc000687988 pc=0x40e2a3 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHashAgainstScript(0xc0000f8000, 0x1300d1f5a3d348be, 0x78607089e4fe9fab, 0xc0a21e4f71, 0xc000d16070, 0x1e2b8881f8178e92, 0xd589cfa965287bb8, 0x24a4e4f292ebc797, 0xb90d3120d878e619, 0xc0001d01e0, ...) /home/rik/dev/neo-go/pkg/core/blockchain.go:1866 +0x371 fp=0xc000687ad8 sp=0xc000687a10 pc=0x984ed1 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHeaderWitnesses(0xc0000f8000, 0xc000d16000, 0xc00042d950, 0x1, 0xc00008a6c0) /home/rik/dev/neo-go/pkg/core/blockchain.go:1914 +0x209 fp=0xc000687c90 sp=0xc000687ad8 pc=0x985999 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHeader(0xc0000f8000, 0xc000d16000, 0xc00042d950, 0xf0ee0049d611101f, 0xf8967398a8f9351b) /home/rik/dev/neo-go/pkg/core/blockchain.go:1254 +0x235 fp=0xc000687d70 sp=0xc000687c90 pc=0x97e4e5 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).addHeaders(0xc0000f8000, 0x1, 0xc000d12000, 0x7d0, 0x7d0, 0x0, 0x1) /home/rik/dev/neo-go/pkg/core/blockchain.go:369 +0x266 fp=0xc000687e68 sp=0xc000687d70 pc=0x973f46 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddHeaders(0xc0000f8000, 0xc000d12000, 0x7d0, 0x7d0, 0x0, 0xc0003640c0) /home/rik/dev/neo-go/pkg/core/blockchain.go:338 +0x51 fp=0xc000687eb0 sp=0xc000687e68 pc=0x973cb1 github.com/nspcc-dev/neo-go/pkg/network.(*Server).handleHeadersCmd(0xc00022c140, 0xdd0ca0, 0xc000374000, 0xc00000c020) /home/rik/dev/neo-go/pkg/network/server.go:431 +0x74 fp=0xc000687fc0 sp=0xc000687eb0 pc=0x9ce5e4 runtime.goexit() /usr/lib64/go/1.12/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000687fc8 sp=0xc000687fc0 pc=0x45ca51 created by github.com/nspcc-dev/neo-go/pkg/network.(*Server).handleMessage /home/rik/dev/neo-go/pkg/network/server.go:705 +0xa4a ...
This commit is contained in:
parent
9b04623edf
commit
9ac8001c7d
1 changed files with 17 additions and 4 deletions
|
@ -110,6 +110,8 @@ type Blockchain struct {
|
||||||
|
|
||||||
memPool mempool.Pool
|
memPool mempool.Pool
|
||||||
|
|
||||||
|
// This lock protects concurrent access to keyCache.
|
||||||
|
keyCacheLock sync.RWMutex
|
||||||
// cache for block verification keys.
|
// cache for block verification keys.
|
||||||
keyCache map[util.Uint160]map[string]*keys.PublicKey
|
keyCache map[util.Uint160]map[string]*keys.PublicKey
|
||||||
|
|
||||||
|
@ -1846,8 +1848,12 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
vm.SetCheckedHash(checkedHash.BytesBE())
|
vm.SetCheckedHash(checkedHash.BytesBE())
|
||||||
vm.LoadScript(verification)
|
vm.LoadScript(verification)
|
||||||
vm.LoadScript(witness.InvocationScript)
|
vm.LoadScript(witness.InvocationScript)
|
||||||
if useKeys && bc.keyCache[hash] != nil {
|
if useKeys {
|
||||||
vm.SetPublicKeys(bc.keyCache[hash])
|
bc.keyCacheLock.RLock()
|
||||||
|
if bc.keyCache[hash] != nil {
|
||||||
|
vm.SetPublicKeys(bc.keyCache[hash])
|
||||||
|
}
|
||||||
|
bc.keyCacheLock.RUnlock()
|
||||||
}
|
}
|
||||||
err = vm.Run()
|
err = vm.Run()
|
||||||
if vm.HasFailed() {
|
if vm.HasFailed() {
|
||||||
|
@ -1862,8 +1868,15 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
if !res {
|
if !res {
|
||||||
return errors.Errorf("signature check failed")
|
return errors.Errorf("signature check failed")
|
||||||
}
|
}
|
||||||
if useKeys && bc.keyCache[hash] == nil {
|
if useKeys {
|
||||||
bc.keyCache[hash] = vm.GetPublicKeys()
|
bc.keyCacheLock.RLock()
|
||||||
|
_, ok := bc.keyCache[hash]
|
||||||
|
bc.keyCacheLock.RUnlock()
|
||||||
|
if !ok {
|
||||||
|
bc.keyCacheLock.Lock()
|
||||||
|
bc.keyCache[hash] = vm.GetPublicKeys()
|
||||||
|
bc.keyCacheLock.Unlock()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.Errorf("no result returned from the script")
|
return errors.Errorf("no result returned from the script")
|
||||||
|
|
Loading…
Reference in a new issue