@ -88,9 +88,7 @@ var (
// networkType indicates the type of the network
networkType = flag . String ( "network_type" , "mainnet" , "type of the network: mainnet, testnet, devnet, localnet" )
// blockPeriod indicates the how long the leader waits to propose a new block.
blockPeriod = flag . Int ( "block_period" , 8 , "how long in second the leader waits to propose a new block." )
// isNewNode indicates this node is a new node
isNewNode = flag . Bool ( "is_newnode" , false , "true means this node is a new node" )
blockPeriod = flag . Int ( "block_period" , 8 , "how long in second the leader waits to propose a new block." )
leaderOverride = flag . Bool ( "leader_override" , false , "true means override the default leader role and acts as validator" )
// shardID indicates the shard ID of this node
shardID = flag . Int ( "shard_id" , - 1 , "the shard ID of this node" )
@ -110,7 +108,7 @@ var (
keystoreDir = flag . String ( "keystore" , hmykey . DefaultKeyStoreDir , "The default keystore directory" )
genesis Account = & genesis . DeployAccount { }
initial Account = & genesis . DeployAccount { }
// logging verbosity
verbosity = flag . Int ( "verbosity" , 5 , "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 5)" )
@ -176,34 +174,34 @@ func passphraseForBls() {
blsPassphrase = passphrase
}
func setupGenesis Account ( ) ( isLeader bool ) {
func setupInitial Account ( ) ( isLeader bool ) {
genesisShardingConfig := core . ShardingSchedule . InstanceForEpoch ( big . NewInt ( core . GenesisEpoch ) )
pubKey := setU pConsensusKey ( nodeconfig . GetDefaultConfig ( ) )
pubKey := setu pConsensusKey ( nodeconfig . GetDefaultConfig ( ) )
reshardingEpoch := genesisShardingConfig . ReshardingEpoch ( )
if reshardingEpoch != nil && len ( reshardingEpoch ) > 0 {
for _ , epoch := range reshardingEpoch {
config := core . ShardingSchedule . InstanceForEpoch ( epoch )
isLeader , genesis Account = config . FindAccount ( pubKey . SerializeToHexStr ( ) )
if genesis Account != nil {
isLeader , initial Account = config . FindAccount ( pubKey . SerializeToHexStr ( ) )
if initial Account != nil {
break
}
}
} else {
isLeader , genesis Account = genesisShardingConfig . FindAccount ( pubKey . SerializeToHexStr ( ) )
isLeader , initial Account = genesisShardingConfig . FindAccount ( pubKey . SerializeToHexStr ( ) )
}
if genesis Account == nil {
if initial Account == nil {
fmt . Printf ( "cannot find your BLS key in the genesis/FN tables: %s\n" , pubKey . SerializeToHexStr ( ) )
os . Exit ( 100 )
}
fmt . Printf ( "My Genesis Account: %v\n" , * genesis Account)
fmt . Printf ( "My Genesis Account: %v\n" , * initial Account)
return isLeader
}
func setU pConsensusKey ( nodeConfig * nodeconfig . ConfigType ) * bls . PublicKey {
func setu pConsensusKey ( nodeConfig * nodeconfig . ConfigType ) * bls . PublicKey {
consensusPriKey , err := blsgen . LoadBlsKeyWithPassPhrase ( * blsKeyFile , blsPassphrase )
if err != nil {
fmt . Printf ( "error when loading bls key, err :%v\n" , err )
@ -220,13 +218,13 @@ func setUpConsensusKey(nodeConfig *nodeconfig.ConfigType) *bls.PublicKey {
return pubKey
}
func createGlobalConfig ( isLeader bool ) * nodeconfig . ConfigType {
func createGlobalConfig ( ) * nodeconfig . ConfigType {
var err error
nodeConfig := nodeconfig . GetShardConfig ( genesis Account. ShardID )
nodeConfig := nodeconfig . GetShardConfig ( initial Account. ShardID )
if ! * isExplorer {
// Set up consensus keys.
setU pConsensusKey ( nodeConfig )
setu pConsensusKey ( nodeConfig )
} else {
nodeConfig . ConsensusPriKey = & bls . SecretKey { } // set dummy bls key for consensus object
}
@ -252,13 +250,6 @@ func createGlobalConfig(isLeader bool) *nodeconfig.ConfigType {
}
nodeConfig . SelfPeer = p2p . Peer { IP : * ip , Port : * port , ConsensusPubKey : nodeConfig . ConsensusPubKey }
if isLeader && ! * isExplorer && ! * leaderOverride { // The first node in a shard is the leader at genesis
nodeConfig . Leader = nodeConfig . SelfPeer
nodeConfig . StringRole = "leader"
} else {
nodeConfig . StringRole = "validator"
}
nodeConfig . Host , err = p2pimpl . NewHost ( & nodeConfig . SelfPeer , nodeConfig . P2pPriKey )
if * logConn && nodeConfig . GetNetworkType ( ) != nodeconfig . Mainnet {
nodeConfig . Host . GetP2PHost ( ) . Network ( ) . Notify ( utils . NewConnLogger ( utils . GetLogInstance ( ) ) )
@ -267,22 +258,17 @@ func createGlobalConfig(isLeader bool) *nodeconfig.ConfigType {
panic ( "unable to new host in harmony" )
}
if err := nodeConfig . Host . AddPeer ( & nodeConfig . Leader ) ; err != nil {
ctxerror . Warn ( utils . GetLogger ( ) , err , "(*p2p.Host).AddPeer failed" ,
"peer" , & nodeConfig . Leader )
}
nodeConfig . DBDir = * dbDir
return nodeConfig
}
func setU pConsensusAndNode ( nodeConfig * nodeconfig . ConfigType ) * node . Node {
func setu pConsensusAndNode ( nodeConfig * nodeconfig . ConfigType ) * node . Node {
// Consensus object.
// TODO: consensus object shouldn't start here
// TODO(minhdoan): During refactoring, found out that the peers list is actually empty. Need to clean up the logic of consensus later.
currentConsensus , err := consensus . New ( nodeConfig . Host , nodeConfig . ShardID , nodeConfig . Leader , nodeConfig . ConsensusPriKey )
currentConsensus . SelfAddress = common . ParseAddr ( genesis Account. Address )
currentConsensus . SelfAddress = common . ParseAddr ( initial Account. Address )
if err != nil {
fmt . Fprintf ( os . Stderr , "Error :%v \n" , err )
@ -296,10 +282,6 @@ func setUpConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
currentConsensus . SetCommitDelay ( commitDelay )
currentConsensus . MinPeers = * minPeers
if * isNewNode {
currentConsensus . SetMode ( consensus . Listening )
}
if * disableViewChange {
currentConsensus . DisableViewChangeForTestingOnly ( )
}
@ -312,7 +294,6 @@ func setUpConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
} else if * dnsFlag {
currentNode . SetDNSZone ( "t.hmny.io" )
}
currentNode . NodeConfig . SetRole ( nodeconfig . NewNode )
// TODO: add staking support
// currentNode.StakingAccount = myAccount
utils . GetLogInstance ( ) . Info ( "node account set" ,
@ -321,45 +302,21 @@ func setUpConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
// TODO: refactor the creation of blockchain out of node.New()
currentConsensus . ChainReader = currentNode . Blockchain ( )
// TODO: the setup should only based on shard state
if * isGenesis {
// TODO: need change config file and use switch instead of complicated "if else" condition
if nodeConfig . ShardID == 0 { // Beacon chain
nodeConfig . SetIsBeacon ( true )
if nodeConfig . StringRole == "leader" {
currentNode . NodeConfig . SetRole ( nodeconfig . BeaconLeader )
} else {
currentNode . NodeConfig . SetRole ( nodeconfig . BeaconValidator )
}
if * isExplorer {
currentNode . NodeConfig . SetRole ( nodeconfig . ExplorerNode )
currentNode . NodeConfig . SetShardGroupID ( p2p . NewGroupIDByShardID ( p2p . ShardID ( * shardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( p2p . NewClientGroupIDByShardID ( p2p . ShardID ( * shardID ) ) )
} else {
if nodeConfig . ShardID == 0 {
currentNode . NodeConfig . SetRole ( nodeconfig . Validator )
currentNode . NodeConfig . SetShardGroupID ( p2p . GroupIDBeacon )
currentNode . NodeConfig . SetClientGroupID ( p2p . GroupIDBeaconClient )
} else {
if nodeConfig . StringRole == "leader" {
currentNode . NodeConfig . SetRole ( nodeconfig . ShardLeader )
} else {
currentNode . NodeConfig . SetRole ( nodeconfig . ShardValidator )
}
currentNode . NodeConfig . SetRole ( nodeconfig . Validator )
currentNode . NodeConfig . SetShardGroupID ( p2p . NewGroupIDByShardID ( p2p . ShardID ( nodeConfig . ShardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( p2p . NewClientGroupIDByShardID ( p2p . ShardID ( nodeConfig . ShardID ) ) )
}
} else {
if * isNewNode {
if nodeConfig . ShardID == 0 { // Beacon chain
nodeConfig . SetIsBeacon ( true )
currentNode . NodeConfig . SetRole ( nodeconfig . BeaconValidator )
currentNode . NodeConfig . SetShardGroupID ( p2p . GroupIDBeacon )
currentNode . NodeConfig . SetClientGroupID ( p2p . GroupIDBeaconClient )
} else {
currentNode . NodeConfig . SetRole ( nodeconfig . ShardValidator )
currentNode . NodeConfig . SetShardGroupID ( p2p . NewGroupIDByShardID ( p2p . ShardID ( nodeConfig . ShardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( p2p . NewClientGroupIDByShardID ( p2p . ShardID ( nodeConfig . ShardID ) ) )
}
}
if * isExplorer {
currentNode . NodeConfig . SetRole ( nodeconfig . ExplorerNode )
currentNode . NodeConfig . SetShardGroupID ( p2p . NewGroupIDByShardID ( p2p . ShardID ( * shardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( p2p . NewClientGroupIDByShardID ( p2p . ShardID ( * shardID ) ) )
}
}
currentNode . NodeConfig . ConsensusPubKey = nodeConfig . ConsensusPubKey
currentNode . NodeConfig . ConsensusPriKey = nodeConfig . ConsensusPriKey
@ -375,12 +332,9 @@ func setUpConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
// currentNode.DRand = dRand
// This needs to be executed after consensus and drand are setup
if ! * isNewNode || * shardID > - 1 { // initial staking new node doesn't need to initialize shard state
// TODO: Have a better way to distinguish non-genesis node
if err := currentNode . InitShardState ( * shardID == - 1 && ! * isNewNode ) ; err != nil {
ctxerror . Crit ( utils . GetLogger ( ) , err , "InitShardState failed" ,
"shardID" , * shardID , "isNewNode" , * isNewNode )
}
if err := currentNode . InitShardState ( ) ; err != nil {
ctxerror . Crit ( utils . GetLogger ( ) , err , "InitShardState failed" ,
"shardID" , * shardID )
}
// Set the consensus ID to be the current block number
@ -438,17 +392,17 @@ func main() {
memprofiling . MaybeCallGCPeriodically ( )
}
isLeader := false
if ! * isExplorer { // Explorer node doesn't need the following setup
isLeader = setupGenesisAccount ( )
if ! * isExplorer {
setupInitialAccount ( )
}
if * shardID >= 0 {
utils . GetLogInstance ( ) . Info ( "ShardID Override" , "original" , genesis Account. ShardID , "override" , * shardID )
genesis Account. ShardID = uint32 ( * shardID )
utils . GetLogInstance ( ) . Info ( "ShardID Override" , "original" , initial Account. ShardID , "override" , * shardID )
initial Account. ShardID = uint32 ( * shardID )
}
nodeConfig := createGlobalConfig ( isLeader )
currentNode := setU pConsensusAndNode ( nodeConfig )
nodeConfig := createGlobalConfig ( )
currentNode := setu pConsensusAndNode ( nodeConfig )
//if consensus.ShardID != 0 {
// go currentNode.SupportBeaconSyncing()