diff --git a/identitychain/identityblock.go b/identitychain/identityblock.go index b1f72df4f..46be703fe 100644 --- a/identitychain/identityblock.go +++ b/identitychain/identityblock.go @@ -30,6 +30,11 @@ func (b *IdentityBlock) Serialize() []byte { return result.Bytes() } +//Get Identities +func (b *IdentityBlock) GetIdentities() []*waitnode.WaitNode { + return b.Identities +} + // DeserializeBlock deserializes a block func DeserializeBlock(d []byte) *IdentityBlock { var block IdentityBlock diff --git a/identitychain/identitychain.go b/identitychain/identitychain.go index c92193d61..ffd9e1372 100644 --- a/identitychain/identitychain.go +++ b/identitychain/identitychain.go @@ -2,6 +2,8 @@ package identitychain import ( "fmt" + "math" + "math/rand" "net" "os" "sync" @@ -16,20 +18,83 @@ var identityPerBlock = 100000 // IdentityChain (Blockchain) keeps Identities per epoch, currently centralized! type IdentityChain struct { - Identities []*IdentityBlock - PendingIdentities []*waitnode.WaitNode - log log.Logger - Peer p2p.Peer + Identities []*IdentityBlock + PendingIdentities []*waitnode.WaitNode + log log.Logger + Peer p2p.Peer + SelectedIdentitites []*waitnode.WaitNode + EpochNum int + PeerToShardMap map[*waitnode.WaitNode]int + ShardLeaderMap map[int]*waitnode.WaitNode + PubKey string + CurrentEpochStartTime int64 + NumberOfShards int + NumberOfNodesInShard int +} + +func seekRandomNumber(EpochNum int, SelectedIdentitites []*waitnode.WaitNode) int { + // Broadcast message to all nodes and collect back their numbers, do consensus and get a leader. + // Use leader to generate a random number. + //all here mocked + // interact with "node" and "wait_node" + return rand.Intn(1000) + } //GlobalBlockchainConfig stores global level blockchain configurations. type GlobalBlockchainConfig struct { - NumberOfShards int - EpochTimeSecs int16 + NumberOfShards int + EpochTimeSecs int16 + MaxNodesInShard int +} + +//Shard +func (IDC *IdentityChain) Shard() { + num := seekRandomNumber(IDC.EpochNum, IDC.SelectedIdentitites) + IDC.CreateShardAssignment(num) + IDC.ElectLeaders() +} + +// +func (IDC *IdentityChain) ElectLeaders() { +} + +//CreateShardAssignment +func (IDC *IdentityChain) CreateShardAssignment(num int) { + IDC.NumberOfShards = IDC.NumberOfShards + needNewShards() + IDC.SelectedIdentitites = generateRandomPermutations(num, IDC.SelectedIdentitites) + IDC.PeerToShardMap = make(map[*waitnode.WaitNode]int) + numberInOneShard := len(IDC.SelectedIdentitites) / IDC.NumberOfShards + for peerNum := 1; peerNum <= len(IDC.SelectedIdentitites); peerNum++ { + IDC.PeerToShardMap[IDC.SelectedIdentitites[peerNum]] = peerNum / numberInOneShard + } +} + +func generateRandomPermutations(num int, SelectedIdentitites []*waitnode.WaitNode) []*waitnode.WaitNode { + src := rand.NewSource(int64(num)) + rnd := rand.New(src) + perm := rnd.Perm(len(SelectedIdentitites)) + SelectedIdentititesCopy := make([]*waitnode.WaitNode, len(SelectedIdentitites)) + for j, i := range perm { + SelectedIdentititesCopy[j] = SelectedIdentitites[i] + } + return SelectedIdentititesCopy +} + +// SelectIds +func (IDC *IdentityChain) SelectIds() { + selectNumber := IDC.NumberOfNodesInShard - len(IDC.Identities) + IB := IDC.GetLatestBlock() + currentIDS := IB.GetIdentities() + selectNumber = int(math.Min(float64(len(IDC.PendingIdentities)), float64(selectNumber))) + pending := IDC.PendingIdentities[:selectNumber] + IDC.SelectedIdentitites = append(currentIDS, pending...) + IDC.PendingIdentities = []*waitnode.WaitNode{} } -func (IDC *IdentityChain) shard() { - return +//Checks how many new shards we need. Currently we say 0. +func needNewShards() int { + return 0 } // GetLatestBlock gests the latest block at the end of the chain diff --git a/runwait/run_wait.go b/runwait/run_wait.go index 66315a8a4..b2a953adb 100644 --- a/runwait/run_wait.go +++ b/runwait/run_wait.go @@ -1,5 +1,7 @@ package main +import "fmt" + // import ( // "flag" @@ -8,6 +10,7 @@ package main // ) func main() { + fmt.Println("hello") // ip := flag.String("ip", "127.0.0.0", "IP of the node") // port := flag.String("port", "8080", "port of the node") // flag.Parse()