diff --git a/internal/beaconchain/libs/beaconchain.go b/internal/beaconchain/libs/beaconchain.go index 39cf4f78d..bc0856103 100644 --- a/internal/beaconchain/libs/beaconchain.go +++ b/internal/beaconchain/libs/beaconchain.go @@ -18,6 +18,8 @@ import ( "github.com/harmony-one/harmony/p2p/p2pimpl" ) +type BCState int + var mutex sync.Mutex var identityPerBlock = 100000 @@ -35,10 +37,16 @@ type BeaconChain struct { IP string Port string host host.Host - - rpcServer *beaconchain.Server + state BCState + rpcServer *beaconchain.Server } +// Followings are the set of states of that beaconchain can be in. +const ( + NodeInfoReceived BCState = iota + RandomInfoSent +) + // SupportRPC initializes and starts the rpc service func (bc *BeaconChain) SupportRPC() { bc.InitRPCServer() @@ -90,8 +98,8 @@ func generateBCKey() kyber.Point { return pubkey } -//AcceptConnections welcomes new connections -func (bc *BeaconChain) AcceptConnections(b []byte) { +//AcceptNodeInfo deserializes node information received via beaconchain handler +func (bc *BeaconChain) AcceptNodeInfo(b []byte) *bcconn.NodeInfo { Node := bcconn.DeserializeNodeInfo(b) bc.log.Info("New Node Connection", "IP", Node.Self.IP, "Port", Node.Self.Port) bc.NumberOfNodesAdded = bc.NumberOfNodesAdded + 1 @@ -99,11 +107,24 @@ func (bc *BeaconChain) AcceptConnections(b []byte) { if isLeader { bc.Leaders = append(bc.Leaders, Node) } + bc.state = NodeInfoReceived + return Node +} + +//RespondRandomness sends a randomness beacon to the node inorder for it process what shard it will be in +func (bc *BeaconChain) RespondRandomness(Node *bcconn.NodeInfo) { response := bcconn.ResponseRandomNumber{NumberOfShards: bc.NumberOfShards, NumberOfNodesAdded: bc.NumberOfNodesAdded, Leaders: bc.Leaders} msg := bcconn.SerializeRandomInfo(response) msgToSend := proto_identity.ConstructIdentityMessage(proto_identity.Acknowledge, msg) bc.log.Info("Sent Out Msg", "# Nodes", response.NumberOfNodesAdded) host.SendMessage(bc.host, Node.Self, msgToSend, nil) + bc.state = RandomInfoSent +} + +//AcceptConnections welcomes new connections +func (bc *BeaconChain) AcceptConnections(b []byte) { + node := bc.AcceptNodeInfo(b) + bc.RespondRandomness(node) } //StartServer a server and process the request by a handler. diff --git a/internal/beaconchain/libs/beaconchain_test.go b/internal/beaconchain/libs/beaconchain_test.go index 4322300c8..1ce95252e 100644 --- a/internal/beaconchain/libs/beaconchain_test.go +++ b/internal/beaconchain/libs/beaconchain_test.go @@ -8,6 +8,7 @@ import ( "github.com/harmony-one/harmony/api/proto/bcconn" beaconchain "github.com/harmony-one/harmony/internal/beaconchain/rpc" "github.com/harmony-one/harmony/p2p" + "github.com/stretchr/testify/assert" ) var ( @@ -71,3 +72,41 @@ func TestFetchLeaders(t *testing.T) { } } + +func TestAcceptNodeInfo(t *testing.T) { + var ip string + ip = "127.0.0.1" + beaconport := "8080" + numshards := 1 + bc := New(numshards, ip, beaconport) + b := bcconn.SerializeNodeInfo(leader1) + node := bc.AcceptNodeInfo(b) + if !reflect.DeepEqual(node, leader1) { + t.Error("Beaconchain is unable to deserialize incoming node info") + } + if len(bc.Leaders) != 1 { + t.Error("Beaconchain was unable to update the leader array") + } + +} + +func TestRespondRandomness(t *testing.T) { + var ip string + ip = "127.0.0.1" + beaconport := "8080" + numshards := 1 + bc := New(numshards, ip, beaconport) + bc.RespondRandomness(leader1) + assert.Equal(t, RandomInfoSent, bc.state) +} + +func TestAcceptConnections(t *testing.T) { + var ip string + ip = "127.0.0.1" + beaconport := "8080" + numshards := 1 + bc := New(numshards, ip, beaconport) + b := bcconn.SerializeNodeInfo(leader1) + bc.AcceptConnections(b) + assert.Equal(t, RandomInfoSent, bc.state) +}