|
|
|
@ -1,17 +1,18 @@ |
|
|
|
|
package beaconchain |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"math/rand" |
|
|
|
|
"net" |
|
|
|
|
"os" |
|
|
|
|
"sync" |
|
|
|
|
|
|
|
|
|
"github.com/dedis/kyber" |
|
|
|
|
"github.com/harmony-one/harmony/bcconn" |
|
|
|
|
"github.com/harmony-one/harmony/crypto/pki" |
|
|
|
|
"github.com/harmony-one/harmony/log" |
|
|
|
|
"github.com/harmony-one/harmony/node" |
|
|
|
|
"github.com/harmony-one/harmony/p2p" |
|
|
|
|
proto_identity "github.com/harmony-one/harmony/proto/identity" |
|
|
|
|
"github.com/harmony-one/harmony/utils" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var mutex sync.Mutex |
|
|
|
@ -19,83 +20,79 @@ 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 |
|
|
|
|
Leaders []*bcconn.NodeInfo |
|
|
|
|
log log.Logger |
|
|
|
|
PeerToShardMap map[*node.Node]int |
|
|
|
|
ShardLeaderMap map[int]*node.Node |
|
|
|
|
ShardLeaderMap map[int]*bcconn.NodeInfo |
|
|
|
|
PubKey kyber.Point |
|
|
|
|
NumberOfShards int |
|
|
|
|
NumberOfLeadersAdded int |
|
|
|
|
NumberOfNodesAdded int |
|
|
|
|
IP string |
|
|
|
|
Port string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// New return BeaconChain.
|
|
|
|
|
func New(filename string) *BeaconChain { |
|
|
|
|
idc := BeaconChain{} |
|
|
|
|
//idc.NumberOfShards = readConfigFile(filename)
|
|
|
|
|
idc.log = log.New() |
|
|
|
|
idc.NumberOfShards = 2 |
|
|
|
|
idc.PubKey = generateIDCKeys() |
|
|
|
|
return &idc |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func readConfigFile(filename string) int { |
|
|
|
|
return 2 |
|
|
|
|
//Init
|
|
|
|
|
func New(numShards int, ip, port string) *BeaconChain { |
|
|
|
|
bc := BeaconChain{} |
|
|
|
|
bc.log = log.New() |
|
|
|
|
bc.NumberOfShards = numShards |
|
|
|
|
bc.PubKey = generateIDCKeys() |
|
|
|
|
bc.NumberOfNodesAdded = 0 |
|
|
|
|
bc.Port = port |
|
|
|
|
bc.IP = ip |
|
|
|
|
return &bc |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func generateIDCKeys() kyber.Point { |
|
|
|
|
priKey := pki.GetPrivateKeyFromInt(10) |
|
|
|
|
r := rand.Intn(1000) |
|
|
|
|
priKey := pki.GetPrivateKeyFromInt(r) |
|
|
|
|
pubkey := pki.GetPublicKeyFromPrivateKey(priKey) |
|
|
|
|
return pubkey |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// AcceptConnections welcomes new connections
|
|
|
|
|
func (IDC *BeaconChain) AcceptConnections(b []byte) { |
|
|
|
|
NewNode := node.DeserializeNode(b) |
|
|
|
|
fmt.Println(NewNode) |
|
|
|
|
} |
|
|
|
|
//AcceptConnections welcomes new connections
|
|
|
|
|
func (bc *BeaconChain) AcceptConnections(b []byte) { |
|
|
|
|
Node := bcconn.DeserializeNodeInfo(b) |
|
|
|
|
bc.log.Info("Obtained node information, updating local information") |
|
|
|
|
bc.NumberOfNodesAdded = bc.NumberOfNodesAdded + 1 |
|
|
|
|
_, isLeader := utils.AllocateShard(bc.NumberOfNodesAdded, bc.NumberOfShards) |
|
|
|
|
if isLeader { |
|
|
|
|
bc.Leaders = append(bc.Leaders, Node) |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
|
|
|
|
|
func (IDC *BeaconChain) registerNode(Node *node.Node) { |
|
|
|
|
IDC.Identities = append(IDC.Identities, Node) |
|
|
|
|
fmt.Println(IDC.Identities) |
|
|
|
|
//IDC.CommunicatePublicKeyToNode(Node.SelfPeer)
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
**IMPORTANT** |
|
|
|
|
|
|
|
|
|
// CommunicatePublicKeyToNode communicates public key to node.
|
|
|
|
|
func (IDC *BeaconChain) CommunicatePublicKeyToNode(peer p2p.Peer) { |
|
|
|
|
pbkey := pki.GetBytesFromPublicKey(IDC.PubKey) |
|
|
|
|
msgToSend := proto_identity.ConstructIdentityMessage(proto_identity.Acknowledge, pbkey[:]) |
|
|
|
|
p2p.SendMessage(peer, msgToSend) |
|
|
|
|
} |
|
|
|
|
Note that public key is not in kyber.Scalar form it is in byte form. |
|
|
|
|
Use following conversion to get back the actual key |
|
|
|
|
//peer.PubKey = crypto.Ed25519Curve.Point()
|
|
|
|
|
//err = peer.PubKey.UnmarshalBinary(p.PubKey[:])
|
|
|
|
|
|
|
|
|
|
//StartServer a server and process the request by a handler.
|
|
|
|
|
func (IDC *BeaconChain) StartServer() { |
|
|
|
|
IDC.log.Info("Starting IDC server...") //log.Info does nothing for me! (ak)
|
|
|
|
|
IDC.listenOnPort() |
|
|
|
|
**/ |
|
|
|
|
response := bcconn.ResponseRandomNumber{NumberOfShards: bc.NumberOfShards, NumberOfNodesAdded: bc.NumberOfNodesAdded, Leaders: bc.Leaders} |
|
|
|
|
msg := bcconn.SerializeRandomInfo(response) |
|
|
|
|
msgToSend := proto_identity.ConstructIdentityMessage(proto_identity.Acknowledge, msg) |
|
|
|
|
p2p.SendMessage(Node.Self, msgToSend) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (IDC *BeaconChain) listenOnPort() { |
|
|
|
|
addr := net.JoinHostPort("127.0.0.1", "8081") |
|
|
|
|
//StartServer a server and process the request by a handler.
|
|
|
|
|
func (bc *BeaconChain) StartServer() { |
|
|
|
|
bc.log.Info("Starting Beaconchain server ...") |
|
|
|
|
ip := bc.IP |
|
|
|
|
port := bc.Port |
|
|
|
|
addr := net.JoinHostPort(ip, port) |
|
|
|
|
listen, err := net.Listen("tcp", addr) |
|
|
|
|
if err != nil { |
|
|
|
|
IDC.log.Crit("Socket listen port failed") |
|
|
|
|
bc.log.Crit("Socket listen port failed") |
|
|
|
|
os.Exit(1) |
|
|
|
|
} else { |
|
|
|
|
IDC.log.Info("Identity chain is now listening ..") |
|
|
|
|
} |
|
|
|
|
defer listen.Close() |
|
|
|
|
for { |
|
|
|
|
IDC.log.Info("I am accepting connections now") |
|
|
|
|
bc.log.Info("beacon chain is now listening ..") |
|
|
|
|
conn, err := listen.Accept() |
|
|
|
|
fmt.Println(conn) |
|
|
|
|
if err != nil { |
|
|
|
|
IDC.log.Crit("Error listening on port. Exiting", "8081") |
|
|
|
|
bc.log.Crit("Error listening on port. Exiting", "8081") |
|
|
|
|
continue |
|
|
|
|
} else { |
|
|
|
|
IDC.log.Info("I am accepting connections now") |
|
|
|
|
} |
|
|
|
|
go IDC.BeaconChainHandler(conn) |
|
|
|
|
go bc.BeaconChainHandler(conn) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|