|
|
@ -26,6 +26,7 @@ import ( |
|
|
|
proto_node "github.com/harmony-one/harmony/api/proto/node" |
|
|
|
proto_node "github.com/harmony-one/harmony/api/proto/node" |
|
|
|
service_manager "github.com/harmony-one/harmony/api/service" |
|
|
|
service_manager "github.com/harmony-one/harmony/api/service" |
|
|
|
blockproposal "github.com/harmony-one/harmony/api/service/blockproposal" |
|
|
|
blockproposal "github.com/harmony-one/harmony/api/service/blockproposal" |
|
|
|
|
|
|
|
"github.com/harmony-one/harmony/api/service/clientsupport" |
|
|
|
consensus_service "github.com/harmony-one/harmony/api/service/consensus" |
|
|
|
consensus_service "github.com/harmony-one/harmony/api/service/consensus" |
|
|
|
"github.com/harmony-one/harmony/api/service/explorer" |
|
|
|
"github.com/harmony-one/harmony/api/service/explorer" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing" |
|
|
@ -91,7 +92,7 @@ func (state State) String() string { |
|
|
|
// Constants related to doing syncing.
|
|
|
|
// Constants related to doing syncing.
|
|
|
|
const ( |
|
|
|
const ( |
|
|
|
lastMileThreshold = 4 |
|
|
|
lastMileThreshold = 4 |
|
|
|
inSyncThreshold = 2 |
|
|
|
inSyncThreshold = 1 |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
const ( |
|
|
@ -280,7 +281,7 @@ func New(host p2p.Host, consensus *bft.Consensus, db ethdb.Database) *Node { |
|
|
|
node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey), node.Consensus.ShardID) |
|
|
|
node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey), node.Consensus.ShardID) |
|
|
|
|
|
|
|
|
|
|
|
node.AddSmartContractsToPendingTransactions() |
|
|
|
node.AddSmartContractsToPendingTransactions() |
|
|
|
node.Consensus.ConsensusBlock = make(chan *types.Block) |
|
|
|
node.Consensus.ConsensusBlock = make(chan *bft.BFTBlockInfo) |
|
|
|
node.Consensus.VerifiedNewBlock = make(chan *types.Block) |
|
|
|
node.Consensus.VerifiedNewBlock = make(chan *types.Block) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -301,11 +302,16 @@ func New(host p2p.Host, consensus *bft.Consensus, db ethdb.Database) *Node { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// IsOutOfSync checks whether the node is out of sync by comparing latest block with consensus block
|
|
|
|
// IsOutOfSync checks whether the node is out of sync by comparing latest block with consensus block
|
|
|
|
func (node *Node) IsOutOfSync(consensusBlock *types.Block) bool { |
|
|
|
func (node *Node) IsOutOfSync(consensusBlockInfo *bft.BFTBlockInfo) bool { |
|
|
|
|
|
|
|
consensusBlock := consensusBlockInfo.Block |
|
|
|
|
|
|
|
consensusID := consensusBlockInfo.ConsensusID |
|
|
|
|
|
|
|
|
|
|
|
myHeight := node.blockchain.CurrentBlock().NumberU64() |
|
|
|
myHeight := node.blockchain.CurrentBlock().NumberU64() |
|
|
|
newHeight := consensusBlock.NumberU64() |
|
|
|
newHeight := consensusBlock.NumberU64() |
|
|
|
utils.GetLogInstance().Debug("[SYNC]", "myHeight", myHeight, "newHeight", newHeight) |
|
|
|
utils.GetLogInstance().Debug("[SYNC]", "myHeight", myHeight, "newHeight", newHeight) |
|
|
|
if newHeight-myHeight <= inSyncThreshold { |
|
|
|
if newHeight-myHeight <= inSyncThreshold { |
|
|
|
|
|
|
|
node.stateSync.AddLastMileBlock(consensusBlock) |
|
|
|
|
|
|
|
node.Consensus.UpdateConsensusID(consensusID + 1) |
|
|
|
return false |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
// cache latest blocks for last mile catch up
|
|
|
|
// cache latest blocks for last mile catch up
|
|
|
@ -321,21 +327,24 @@ func (node *Node) DoSyncing() { |
|
|
|
select { |
|
|
|
select { |
|
|
|
// in current implementation logic, timeout means in sync
|
|
|
|
// in current implementation logic, timeout means in sync
|
|
|
|
case <-time.After(5 * time.Second): |
|
|
|
case <-time.After(5 * time.Second): |
|
|
|
|
|
|
|
//myHeight := node.blockchain.CurrentBlock().NumberU64()
|
|
|
|
|
|
|
|
//utils.GetLogInstance().Debug("[SYNC]", "currentHeight", myHeight)
|
|
|
|
node.stateMutex.Lock() |
|
|
|
node.stateMutex.Lock() |
|
|
|
node.State = NodeReadyForConsensus |
|
|
|
node.State = NodeReadyForConsensus |
|
|
|
node.stateMutex.Unlock() |
|
|
|
node.stateMutex.Unlock() |
|
|
|
continue |
|
|
|
continue |
|
|
|
case consensusBlock := <-node.Consensus.ConsensusBlock: |
|
|
|
case consensusBlockInfo := <-node.Consensus.ConsensusBlock: |
|
|
|
// never reached from chao
|
|
|
|
if !node.IsOutOfSync(consensusBlockInfo) { |
|
|
|
if !node.IsOutOfSync(consensusBlock) { |
|
|
|
|
|
|
|
if node.State == NodeNotInSync { |
|
|
|
if node.State == NodeNotInSync { |
|
|
|
utils.GetLogInstance().Info("[SYNC] Node is now IN SYNC!") |
|
|
|
utils.GetLogInstance().Info("[SYNC] Node is now IN SYNC!") |
|
|
|
node.stateSync.CloseConnections() |
|
|
|
|
|
|
|
node.stateSync = nil |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
node.stateMutex.Lock() |
|
|
|
node.stateMutex.Lock() |
|
|
|
node.State = NodeReadyForConsensus |
|
|
|
node.State = NodeReadyForConsensus |
|
|
|
node.stateMutex.Unlock() |
|
|
|
node.stateMutex.Unlock() |
|
|
|
|
|
|
|
// wait for last mile block finish; think a better way
|
|
|
|
|
|
|
|
time.Sleep(200 * time.Millisecond) |
|
|
|
|
|
|
|
node.stateSync.CloseConnections() |
|
|
|
|
|
|
|
node.stateSync = nil |
|
|
|
continue |
|
|
|
continue |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
utils.GetLogInstance().Debug("[SYNC] node is out of sync") |
|
|
|
utils.GetLogInstance().Debug("[SYNC] node is out of sync") |
|
|
@ -642,6 +651,8 @@ func (node *Node) setupForShardLeader() { |
|
|
|
node.serviceManager.RegisterService(service_manager.Consensus, consensus_service.NewService(node.BlockChannel, node.Consensus)) |
|
|
|
node.serviceManager.RegisterService(service_manager.Consensus, consensus_service.NewService(node.BlockChannel, node.Consensus)) |
|
|
|
// Register new block service.
|
|
|
|
// Register new block service.
|
|
|
|
node.serviceManager.RegisterService(service_manager.BlockProposal, blockproposal.NewService(node.Consensus.ReadySignal, node.WaitForConsensusReady)) |
|
|
|
node.serviceManager.RegisterService(service_manager.BlockProposal, blockproposal.NewService(node.Consensus.ReadySignal, node.WaitForConsensusReady)) |
|
|
|
|
|
|
|
// Register client support service.
|
|
|
|
|
|
|
|
node.serviceManager.RegisterService(service_manager.ClientSupport, clientsupport.NewService(node.blockchain.State, node.CallFaucetContract, node.SelfPeer.IP, node.SelfPeer.Port)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (node *Node) setupForShardValidator() { |
|
|
|
func (node *Node) setupForShardValidator() { |
|
|
|