mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-24 09:25:21 +00:00
network: introduce (*Server).IsInSync, start consensus in synced state
We define synchronized state as a combination of minimum number of peers and chain height being not behind of more than 2/3 of these peers.
This commit is contained in:
parent
a2616cfafe
commit
c5d54e9992
1 changed files with 51 additions and 15 deletions
|
@ -64,7 +64,7 @@ type (
|
||||||
unregister chan peerDrop
|
unregister chan peerDrop
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
|
|
||||||
connected *atomic.Bool
|
consensusStarted *atomic.Bool
|
||||||
|
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,13 @@ func NewServer(config ServerConfig, chain core.Blockchainer, log *zap.Logger) (*
|
||||||
register: make(chan Peer),
|
register: make(chan Peer),
|
||||||
unregister: make(chan peerDrop),
|
unregister: make(chan peerDrop),
|
||||||
peers: make(map[Peer]bool),
|
peers: make(map[Peer]bool),
|
||||||
connected: atomic.NewBool(false),
|
consensusStarted: atomic.NewBool(false),
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
s.bQueue = newBlockQueue(maxBlockBatch, chain, log, s.relayBlock)
|
s.bQueue = newBlockQueue(maxBlockBatch, chain, log, func(b *block.Block) {
|
||||||
|
s.tryStartConsensus()
|
||||||
|
s.relayBlock(b)
|
||||||
|
})
|
||||||
|
|
||||||
srv, err := consensus.NewService(consensus.Config{
|
srv, err := consensus.NewService(consensus.Config{
|
||||||
Logger: log,
|
Logger: log,
|
||||||
|
@ -274,13 +277,13 @@ func (s *Server) runProto() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) tryStartConsensus() {
|
func (s *Server) tryStartConsensus() {
|
||||||
if s.Wallet == nil || s.connected.Load() {
|
if s.Wallet == nil || s.consensusStarted.Load() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.HandshakedPeersCount() >= s.MinPeers {
|
if s.IsInSync() {
|
||||||
s.log.Info("minimum amount of peers were connected to")
|
s.log.Info("node reached synchronized state, starting consensus")
|
||||||
if s.connected.CAS(false, true) {
|
if s.consensusStarted.CAS(false, true) {
|
||||||
s.consensus.Start()
|
s.consensus.Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,6 +339,39 @@ func (s *Server) getVersionMsg() *Message {
|
||||||
return s.MkMsg(CMDVersion, payload)
|
return s.MkMsg(CMDVersion, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInSync answers the question of whether the server is in sync with the
|
||||||
|
// network or not (at least how the server itself sees it). The server operates
|
||||||
|
// with the data that it has, the number of peers (that has to be more than
|
||||||
|
// minimum number) and height of these peers (our chain has to be not lower
|
||||||
|
// than 2/3 of our peers have). Ideally we would check for the highest of the
|
||||||
|
// peers, but the problem is that they can lie to us and send whatever height
|
||||||
|
// they want to.
|
||||||
|
func (s *Server) IsInSync() bool {
|
||||||
|
var peersNumber int
|
||||||
|
var notHigher int
|
||||||
|
|
||||||
|
if s.MinPeers == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLastBlock := s.chain.BlockHeight()
|
||||||
|
|
||||||
|
s.lock.RLock()
|
||||||
|
for p := range s.peers {
|
||||||
|
if p.Handshaked() {
|
||||||
|
peersNumber++
|
||||||
|
if ourLastBlock >= p.LastBlockIndex() {
|
||||||
|
notHigher++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.lock.RUnlock()
|
||||||
|
|
||||||
|
// Checking bQueue would also be nice, but it can be filled with garbage
|
||||||
|
// easily at the moment.
|
||||||
|
return peersNumber >= s.MinPeers && (3*notHigher > 2*peersNumber) // && s.bQueue.length() == 0
|
||||||
|
}
|
||||||
|
|
||||||
// When a peer sends out his version we reply with verack after validating
|
// When a peer sends out his version we reply with verack after validating
|
||||||
// the version.
|
// the version.
|
||||||
func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
|
func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
|
||||||
|
|
Loading…
Reference in a new issue