|
|
|
@ -8,6 +8,8 @@ import ( |
|
|
|
|
"math/big" |
|
|
|
|
"math/rand" |
|
|
|
|
"net" |
|
|
|
|
"os" |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
"sync" |
|
|
|
|
"time" |
|
|
|
@ -31,17 +33,26 @@ import ( |
|
|
|
|
downloader_pb "github.com/harmony-one/harmony/syncing/downloader/proto" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type NodeState byte |
|
|
|
|
// State is a state of a node.
|
|
|
|
|
type State byte |
|
|
|
|
|
|
|
|
|
// All constants except the NodeLeader below are for validators only.
|
|
|
|
|
const ( |
|
|
|
|
NodeInit NodeState = iota // Node just started, before contacting BeaconChain
|
|
|
|
|
NodeInit State = iota // Node just started, before contacting BeaconChain
|
|
|
|
|
NodeWaitToJoin // Node contacted BeaconChain, wait to join Shard
|
|
|
|
|
NodeJoinedShard // Node joined Shard, ready for consensus
|
|
|
|
|
NodeOffline // Node is offline
|
|
|
|
|
NodeReadyForConsensus // Node is ready to do consensus
|
|
|
|
|
NodeDoingConsensus // Node is already doing consensus
|
|
|
|
|
NodeLeader // Node is the leader of some shard.
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
// TimeToSleepForSyncing is the time waiting for node transformed into NodeDoingConsensus
|
|
|
|
|
TimeToSleepForSyncing = time.Second * 30 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// NetworkNode ...
|
|
|
|
|
type NetworkNode struct { |
|
|
|
|
SelfPeer p2p.Peer |
|
|
|
|
IDCPeer p2p.Peer |
|
|
|
@ -64,14 +75,13 @@ type Node struct { |
|
|
|
|
crossTxToReturnMutex sync.Mutex |
|
|
|
|
ClientPeer *p2p.Peer // The peer for the benchmark tx generator client, used for leaders to return proof-of-accept
|
|
|
|
|
Client *client.Client // The presence of a client object means this node will also act as a client
|
|
|
|
|
IsWaiting bool |
|
|
|
|
SelfPeer p2p.Peer // TODO(minhdoan): it could be duplicated with Self below whose is Alok work.
|
|
|
|
|
IDCPeer p2p.Peer |
|
|
|
|
|
|
|
|
|
SyncNode bool // TODO(minhdoan): Remove it later.
|
|
|
|
|
chain *core.BlockChain // Account Model
|
|
|
|
|
Neighbors sync.Map // All the neighbor nodes, key is the sha256 of Peer IP/Port, value is the p2p.Peer
|
|
|
|
|
State NodeState // State of the Node
|
|
|
|
|
State State // State of the Node
|
|
|
|
|
|
|
|
|
|
// Account Model
|
|
|
|
|
pendingTransactionsAccount types.Transactions // TODO: replace with txPool
|
|
|
|
@ -150,6 +160,7 @@ func (node *Node) StartServer(port string) { |
|
|
|
|
node.listenOnPort(port) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetLog sets log for Node.
|
|
|
|
|
func (node *Node) SetLog() *Node { |
|
|
|
|
node.log = log.New() |
|
|
|
|
return node |
|
|
|
@ -205,7 +216,7 @@ func (node *Node) countNumTransactionsInBlockchainAccount() int { |
|
|
|
|
return count |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//ConnectIdentityChain connects to identity chain
|
|
|
|
|
//ConnectBeaconChain connects to identity chain
|
|
|
|
|
func (node *Node) ConnectBeaconChain() { |
|
|
|
|
Nnode := &NetworkNode{SelfPeer: node.SelfPeer, IDCPeer: node.IDCPeer} |
|
|
|
|
msg := node.SerializeNode(Nnode) |
|
|
|
@ -298,12 +309,16 @@ func New(consensus *bft.Consensus, db *hdb.LDBDatabase) *Node { |
|
|
|
|
} |
|
|
|
|
// Logger
|
|
|
|
|
node.log = log.New() |
|
|
|
|
if consensus.IsLeader { |
|
|
|
|
node.State = NodeLeader |
|
|
|
|
} else { |
|
|
|
|
node.State = NodeInit |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return &node |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add neighbors nodes
|
|
|
|
|
// AddPeers adds neighbors nodes
|
|
|
|
|
func (node *Node) AddPeers(peers []p2p.Peer) int { |
|
|
|
|
count := 0 |
|
|
|
|
for _, p := range peers { |
|
|
|
@ -332,14 +347,28 @@ func (node *Node) JoinShard(leader p2p.Peer) { |
|
|
|
|
buffer := ping.ConstructPingMessage() |
|
|
|
|
|
|
|
|
|
p2p.SendMessage(leader, buffer) |
|
|
|
|
node.log.Debug("Sent ping message") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// StartDownloaderServer starts downloader server.
|
|
|
|
|
func (node *Node) StartDownloaderServer() { |
|
|
|
|
// SupportSyncing keeps sleeping until it's doing consensus or it's a leader.
|
|
|
|
|
func (node *Node) SupportSyncing() { |
|
|
|
|
node.InitSyncingServer() |
|
|
|
|
node.StartSyncingServer() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// InitSyncingServer starts downloader server.
|
|
|
|
|
func (node *Node) InitSyncingServer() { |
|
|
|
|
node.downloaderServer = downloader.NewServer(node) |
|
|
|
|
// node.downloaderServer.Start(node.)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// StartSyncingServer starts syncing server.
|
|
|
|
|
func (node *Node) StartSyncingServer() { |
|
|
|
|
if port, err := strconv.Atoi(node.SelfPeer.Port); err == nil { |
|
|
|
|
node.downloaderServer.Start(node.SelfPeer.Ip, fmt.Sprintf("%d", port-1000)) |
|
|
|
|
} else { |
|
|
|
|
node.log.Error("Wrong port format provided") |
|
|
|
|
os.Exit(1) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CalculateResponse implements DownloadInterface on Node object.
|
|
|
|
|