notary: control start/stop state

Don't start/stop twice, don't do anything in callbacks if not started.
This commit is contained in:
Roman Khimov 2022-07-02 15:48:35 +03:00
parent 73e34514a5
commit 0d627c947f

View file

@ -22,6 +22,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"go.uber.org/atomic"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -47,6 +48,8 @@ type (
// newTxs is a channel where new transactions are sent // newTxs is a channel where new transactions are sent
// to be processed in an `onTransaction` callback. // to be processed in an `onTransaction` callback.
newTxs chan txHashPair newTxs chan txHashPair
// started is a status bool to protect from double start/shutdown.
started *atomic.Bool
// reqMtx protects requests list. // reqMtx protects requests list.
reqMtx sync.RWMutex reqMtx sync.RWMutex
@ -142,6 +145,7 @@ func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction fu
requests: make(map[util.Uint256]*request), requests: make(map[util.Uint256]*request),
Config: cfg, Config: cfg,
Network: net, Network: net,
started: atomic.NewBool(false),
wallet: wallet, wallet: wallet,
onTransaction: onTransaction, onTransaction: onTransaction,
newTxs: make(chan txHashPair, defaultTxChannelCapacity), newTxs: make(chan txHashPair, defaultTxChannelCapacity),
@ -159,6 +163,9 @@ func (n *Notary) Name() string {
// Start runs a Notary module in a separate goroutine. // Start runs a Notary module in a separate goroutine.
func (n *Notary) Start() { func (n *Notary) Start() {
if !n.started.CAS(false, true) {
return
}
n.Config.Log.Info("starting notary service") n.Config.Log.Info("starting notary service")
n.Config.Chain.SubscribeForBlocks(n.blocksCh) n.Config.Chain.SubscribeForBlocks(n.blocksCh)
n.mp.SubscribeForTransactions(n.reqCh) n.mp.SubscribeForTransactions(n.reqCh)
@ -203,11 +210,17 @@ drainLoop:
// Shutdown stops the Notary module. // Shutdown stops the Notary module.
func (n *Notary) Shutdown() { func (n *Notary) Shutdown() {
if !n.started.CAS(true, false) {
return
}
close(n.stopCh) close(n.stopCh)
} }
// OnNewRequest is a callback method which is called after a new notary request is added to the notary request pool. // OnNewRequest is a callback method which is called after a new notary request is added to the notary request pool.
func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) { func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) {
if !n.started.Load() {
return
}
acc := n.getAccount() acc := n.getAccount()
if acc == nil { if acc == nil {
return return
@ -314,7 +327,7 @@ func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) {
// OnRequestRemoval is a callback which is called after fallback transaction is removed // OnRequestRemoval is a callback which is called after fallback transaction is removed
// from the notary payload pool due to expiration, main tx appliance or any other reason. // from the notary payload pool due to expiration, main tx appliance or any other reason.
func (n *Notary) OnRequestRemoval(pld *payload.P2PNotaryRequest) { func (n *Notary) OnRequestRemoval(pld *payload.P2PNotaryRequest) {
if n.getAccount() == nil { if !n.started.Load() || n.getAccount() == nil {
return return
} }
@ -338,6 +351,9 @@ func (n *Notary) OnRequestRemoval(pld *payload.P2PNotaryRequest) {
// PostPersist is a callback which is called after a new block event is received. // PostPersist is a callback which is called after a new block event is received.
// PostPersist must not be called under the blockchain lock, because it uses finalization function. // PostPersist must not be called under the blockchain lock, because it uses finalization function.
func (n *Notary) PostPersist() { func (n *Notary) PostPersist() {
if !n.started.Load() {
return
}
acc := n.getAccount() acc := n.getAccount()
if acc == nil { if acc == nil {
return return