network: fix race in TestHandleGetMPTData

Init server config before server start. Fixes the following data race:

```
WARNING: DATA RACE
Write at 0x00c00032ef20 by goroutine 26:
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData.func2()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:755 +0x10a
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202

Previous read at 0x00c00032ef20 by goroutine 24:
  github.com/nspcc-dev/neo-go/internal/fakechain.(*FakeChain).GetConfig()
      /go/src/github.com/nspcc-dev/neo-go/internal/fakechain/fakechain.go:167 +0x6f
  github.com/nspcc-dev/neo-go/pkg/network.(*Server).initStaleMemPools()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server.go:1433 +0x89
  github.com/nspcc-dev/neo-go/pkg/network.(*Server).Start()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server.go:284 +0x288
  github.com/nspcc-dev/neo-go/pkg/network.startWithChannel.func1()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:91 +0x44

Goroutine 26 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:1238 +0x5d7
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:752 +0x8c
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202

Goroutine 24 (running) created at:
  github.com/nspcc-dev/neo-go/pkg/network.startWithChannel()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:90 +0x78
  github.com/nspcc-dev/neo-go/pkg/network.startTestServer()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:384 +0xbd
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData.func2()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:753 +0x55
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202
```
This commit is contained in:
Anna Shaleva 2021-09-13 11:41:54 +03:00
parent 29ef076f4b
commit 6357af0bb0
3 changed files with 31 additions and 9 deletions

View file

@ -55,6 +55,15 @@ type FakeStateSync struct {
// NewFakeChain returns new FakeChain structure. // NewFakeChain returns new FakeChain structure.
func NewFakeChain() *FakeChain { func NewFakeChain() *FakeChain {
return NewFakeChainWithCustomCfg(nil)
}
// NewFakeChainWithCustomCfg returns new FakeChain structure with specified protocol configuration.
func NewFakeChainWithCustomCfg(protocolCfg func(c *config.ProtocolConfiguration)) *FakeChain {
cfg := config.ProtocolConfiguration{Magic: netmode.UnitTestNet, P2PNotaryRequestPayloadPoolSize: 10}
if protocolCfg != nil {
protocolCfg(&cfg)
}
return &FakeChain{ return &FakeChain{
Pool: mempool.New(10, 0, false), Pool: mempool.New(10, 0, false),
PoolTxF: func(*transaction.Transaction) error { return nil }, PoolTxF: func(*transaction.Transaction) error { return nil },
@ -62,7 +71,7 @@ func NewFakeChain() *FakeChain {
blocks: make(map[util.Uint256]*block.Block), blocks: make(map[util.Uint256]*block.Block),
hdrHashes: make(map[uint32]util.Uint256), hdrHashes: make(map[uint32]util.Uint256),
txs: make(map[util.Uint256]*transaction.Transaction), txs: make(map[util.Uint256]*transaction.Transaction),
ProtocolConfiguration: config.ProtocolConfiguration{Magic: netmode.UnitTestNet, P2PNotaryRequestPayloadPoolSize: 10}, ProtocolConfiguration: cfg,
} }
} }

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/internal/fakechain" "github.com/nspcc-dev/neo-go/internal/fakechain"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/network/capability" "github.com/nspcc-dev/neo-go/pkg/network/capability"
"github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
@ -187,7 +188,11 @@ func (p *localPeer) CanProcessAddr() bool {
} }
func newTestServer(t *testing.T, serverConfig ServerConfig) *Server { func newTestServer(t *testing.T, serverConfig ServerConfig) *Server {
s, err := newServerFromConstructors(serverConfig, fakechain.NewFakeChain(), zaptest.NewLogger(t), return newTestServerWithCustomCfg(t, serverConfig, nil)
}
func newTestServerWithCustomCfg(t *testing.T, serverConfig ServerConfig, protocolCfg func(*config.ProtocolConfiguration)) *Server {
s, err := newServerFromConstructors(serverConfig, fakechain.NewFakeChainWithCustomCfg(protocolCfg), zaptest.NewLogger(t),
newFakeTransp, newFakeConsensus, newTestDiscovery) newFakeTransp, newFakeConsensus, newTestDiscovery)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(s.discovery.Close) t.Cleanup(s.discovery.Close)

View file

@ -379,8 +379,14 @@ func (s *Server) testHandleMessage(t *testing.T, p Peer, cmd CommandType, pl pay
return s return s
} }
func startTestServer(t *testing.T) *Server { func startTestServer(t *testing.T, protocolCfg ...func(*config.ProtocolConfiguration)) *Server {
s := newTestServer(t, ServerConfig{Port: 0, UserAgent: "/test/"}) var s *Server
srvCfg := ServerConfig{Port: 0, UserAgent: "/test/"}
if protocolCfg != nil {
s = newTestServerWithCustomCfg(t, srvCfg, protocolCfg[0])
} else {
s = newTestServer(t, srvCfg)
}
ch := startWithChannel(s) ch := startWithChannel(s)
t.Cleanup(func() { t.Cleanup(func() {
s.Shutdown() s.Shutdown()
@ -750,9 +756,10 @@ func TestHandleGetMPTData(t *testing.T) {
}) })
t.Run("KeepOnlyLatestState on", func(t *testing.T) { t.Run("KeepOnlyLatestState on", func(t *testing.T) {
s := startTestServer(t) s := startTestServer(t, func(c *config.ProtocolConfiguration) {
s.chain.(*fakechain.FakeChain).P2PStateExchangeExtensions = true c.P2PStateExchangeExtensions = true
s.chain.(*fakechain.FakeChain).KeepOnlyLatestState = true c.KeepOnlyLatestState = true
})
p := newLocalPeer(t, s) p := newLocalPeer(t, s)
p.handshaked = true p.handshaked = true
msg := NewMessage(CMDGetMPTData, &payload.MPTInventory{ msg := NewMessage(CMDGetMPTData, &payload.MPTInventory{
@ -762,8 +769,9 @@ func TestHandleGetMPTData(t *testing.T) {
}) })
t.Run("good", func(t *testing.T) { t.Run("good", func(t *testing.T) {
s := startTestServer(t) s := startTestServer(t, func(c *config.ProtocolConfiguration) {
s.chain.(*fakechain.FakeChain).P2PStateExchangeExtensions = true c.P2PStateExchangeExtensions = true
})
var recvResponse atomic.Bool var recvResponse atomic.Bool
r1 := random.Uint256() r1 := random.Uint256()
r2 := random.Uint256() r2 := random.Uint256()