diff --git a/beaconchain/beaconchain_handler.go b/beaconchain/beaconchain_handler.go new file mode 100644 index 000000000..add8b08a9 --- /dev/null +++ b/beaconchain/beaconchain_handler.go @@ -0,0 +1,115 @@ +package beaconchain + +import ( + "fmt" + "net" + "os" + + "github.com/simple-rules/harmony-benchmark/p2p" + "github.com/simple-rules/harmony-benchmark/proto" + proto_identity "github.com/simple-rules/harmony-benchmark/proto/identity" +) + +//BeaconChainHandler handles registration of new Identities +// This could have been its seperate package like consensus, but am avoiding creating a lot of packages. +func (IDC *BeaconChain) BeaconChainHandler(conn net.Conn) { + content, err := p2p.ReadMessageContent(conn) + if err != nil { + IDC.log.Error("Read p2p data failed") + return + } + msgCategory, err := proto.GetMessageCategory(content) + if err != nil { + IDC.log.Error("Read message category failed", "err", err) + return + } + if msgCategory != proto.Identity { + IDC.log.Error("Identity Chain Recieved incorrect protocol message") + os.Exit(1) + } else { + fmt.Println("Message category is correct") + } + msgType, err := proto.GetMessageType(content) + if err != nil { + IDC.log.Error("Read action type failed") + return + } + msgPayload, err := proto.GetMessagePayload(content) + if err != nil { + IDC.log.Error("Read message payload failed") + return + } + switch msgCategory { + case proto.Identity: + actionType := proto_identity.IdentityMessageType(msgType) + switch actionType { + case proto_identity.Identity: + idMsgType, err := proto_identity.GetIdentityMessageType(msgPayload) + if err != nil { + fmt.Println("Error finding the identity message type") + } + switch idMsgType { + case proto_identity.Register: + IDC.AcceptConnections(msgPayload) + case proto_identity.Acknowledge: + // IDC.acceptNewConnection(msgPayload) + } + + } + + } +} + +// TODO(alok): You removed pow package. +// func (IDC *IdentityChain) registerIdentity(msgPayload []byte) { +// payload, err := proto_identity.GetIdentityMessagePayload(msgPayload) +// if err != nil { +// IDC.log.Error("identity payload not read") +// } else { +// fmt.Println("identity payload read") +// } +// fmt.Println("we are now registering identities") +// offset := 0 +// proof := payload[offset : offset+32] +// offset = offset + 32 +// Node := node.DeserializeWaitNode(payload[offset:]) +// req := IDC.PowMap[Node.Self] +// ok, err := pow.Check(req, string(proof), []byte("")) +// fmt.Println(err) +// if ok { +// fmt.Println("Proof of work accepted") +// IDC.PendingIdentities = append(IDC.PendingIdentities, Node) +// fmt.Println(len(IDC.PendingIdentities)) //Fix why IDC does not have log working. +// } else { +// fmt.Println("identity proof of work not accepted") +// } +// } + +// func (IDC *IdentityChain) acceptNewConnection(msgPayload []byte) { + +// identityPayload, err := proto_identity.GetIdentityMessagePayload(msgPayload) +// if err != nil { +// fmt.Println("There was a error in reading the identity payload") +// } else { +// fmt.Println("accepted new connection") +// } +// fmt.Println("Sleeping for 2 secs ...") +// time.Sleep(2 * time.Second) +// Node := node.DeserializeWaitNode(identityPayload) +// buffer := bytes.NewBuffer([]byte{}) +// src := rand.NewSource(time.Now().UnixNano()) +// rnd := rand.New(src) +// challengeNonce := int((rnd.Int31())) +// req := pow.NewRequest(5, []byte(strconv.Itoa(challengeNonce))) +// IDC.PowMap[Node.Self] = req +// buffer.Write([]byte(req)) +// // 32 byte block hash +// // buffer.Write(prevBlockHash) +// // The message is missing previous BlockHash, this is because we don't actively maintain a identitychain +// // This canbe included in the fulfill request. +// // Message should be encrypted and then signed to follow PKE. +// //IDC should accept node publickey, encrypt the nonce and blockhash +// // Then sign the message by own private key and send the message back. +// msgToSend := proto_identity.ConstructIdentityMessage(proto_identity.Register, buffer.Bytes()) +// p2p.SendMessage(Node.Self, msgToSend) +// } diff --git a/beaconchain/identitychain.go b/beaconchain/identitychain.go new file mode 100644 index 000000000..db1f04d94 --- /dev/null +++ b/beaconchain/identitychain.go @@ -0,0 +1,98 @@ +package beaconchain + +import ( + "fmt" + "net" + "os" + "sync" + + "github.com/dedis/kyber" + "github.com/simple-rules/harmony-benchmark/crypto/pki" + "github.com/simple-rules/harmony-benchmark/log" + "github.com/simple-rules/harmony-benchmark/node" + "github.com/simple-rules/harmony-benchmark/p2p" + proto_identity "github.com/simple-rules/harmony-benchmark/proto/identity" +) + +var mutex sync.Mutex +var identityPerBlock = 100000 + +// BeaconChain (Blockchain) keeps Identities per epoch, currently centralized! +type BeaconChain struct { + //Identities []*IdentityBlock //No need to have the identity block as of now + Identities []*node.Node + log log.Logger + PeerToShardMap map[*node.Node]int + ShardLeaderMap map[int]*node.Node + PubKey kyber.Point + NumberOfShards int + NumberOfLeadersAdded int +} + +//Init +func Init(filename string) { + idc := BeaconChain{} + //idc.NumberOfShards = readConfigFile(filename) + idc.NumberOfShards = 2 + idc.PubKey = generateIDCKeys() + idc.StartServer() +} + +func readConfigFile(filename string) int { + return 2 +} + +func generateIDCKeys() kyber.Point { + priKey := pki.GetPrivateKeyFromInt(10) + pubkey := pki.GetPublicKeyFromPrivateKey(priKey) + return pubkey +} + +//AcceptConnections welcomes new connections +func (IDC *BeaconChain) AcceptConnections(b []byte) { + Node := node.DeserializeWaitNode(b) + IDC.registerNode(Node) //This copies lock value of sync.mutex, we need to have a way around it by creating auxiliary data struct. +} + +func (IDC *BeaconChain) registerNode(Node *node.Node) { + IDC.Identities = append(IDC.Identities, Node) + IDC.CommunicatePublicKeyToNode(Node.Self) + return +} + +func (IDC *BeaconChain) CommunicatePublicKeyToNode(Peer p2p.Peer) { + pbkey := pki.GetBytesFromPublicKey(IDC.PubKey) + msgToSend := proto_identity.ConstructIdentityMessage(proto_identity.Acknowledge, pbkey[:]) + p2p.SendMessage(Peer, msgToSend) +} + +//StartServer a server and process the request by a handler. +func (IDC *BeaconChain) StartServer() { + fmt.Println("Starting server...") + fmt.Println(IDC.PubKey) + IDC.log.Info("Starting IDC server...") //log.Info does nothing for me! (ak) + IDC.listenOnPort() +} + +func (IDC *BeaconChain) listenOnPort() { + addr := net.JoinHostPort("", "8081") + listen, err := net.Listen("tcp4", addr) + if err != nil { + IDC.log.Crit("Socket listen port failed") + os.Exit(1) + } else { + fmt.Println("Starting server...now listening") + IDC.log.Info("Identity chain is now listening ..") //log.Info does nothing for me! (ak) remove this + } + defer listen.Close() + for { + conn, err := listen.Accept() + if err != nil { + IDC.log.Crit("Error listening on port. Exiting", "8081") + continue + } else { + fmt.Println("I am accepting connections now") + } + go IDC.BeaconChainHandler(conn) + } +} diff --git a/proto/identity/identity.go b/proto/identity/identity.go index 6f6a4bfa4..42457ba53 100644 --- a/proto/identity/identity.go +++ b/proto/identity/identity.go @@ -38,7 +38,6 @@ func (msgType MessageType) String() string { "Register", "Acknowledge", "Leader", - "IDCKey", "Node_Info", "Peers", }