From cc690fac2b49d5b0ab7618a1e506ba7d29ebec0a Mon Sep 17 00:00:00 2001 From: Hans Moog <hm@mkjc.net> Date: Tue, 17 Sep 2019 20:10:35 +0200 Subject: [PATCH] Feat: added society and elders + refactored some code --- .../unbreakable_consensus/consensus_test.go | 55 +++++++++++++++++++ packages/unbreakable_consensus/epoch.go | 24 ++++++++ .../unbreakable_consensus/epoch_register.go | 17 +++++- .../social_consensus/elder_mask.go | 19 +++++++ .../social_consensus/node.go | 48 ++++++++++++++++ .../social_consensus/society.go | 50 +++++++++++++++++ packages/unbreakable_consensus/transaction.go | 31 +++++++++++ 7 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 packages/unbreakable_consensus/consensus_test.go create mode 100644 packages/unbreakable_consensus/social_consensus/elder_mask.go create mode 100644 packages/unbreakable_consensus/social_consensus/node.go create mode 100644 packages/unbreakable_consensus/social_consensus/society.go create mode 100644 packages/unbreakable_consensus/transaction.go diff --git a/packages/unbreakable_consensus/consensus_test.go b/packages/unbreakable_consensus/consensus_test.go new file mode 100644 index 00000000..8c0703c3 --- /dev/null +++ b/packages/unbreakable_consensus/consensus_test.go @@ -0,0 +1,55 @@ +package unbreakable_consensus + +import ( + "fmt" + "math/rand" + "strconv" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/unbreakable_consensus/social_consensus" +) + +func generateElders(totalMana int, nodeCount int) []*social_consensus.Node { + result := make([]*social_consensus.Node, nodeCount) + + for i := 0; i < nodeCount; i++ { + newNode := social_consensus.NewNode("elder" + strconv.Itoa(i)) + newNode.SetReputation(uint64(totalMana / nodeCount)) + + result[i] = newNode + } + + return result +} + +func TestConsensus(t *testing.T) { + rand.Seed(time.Now().Unix()) + + elders := generateElders(100, 10) + + society := social_consensus.NewSociety(elders) + + fmt.Println(society.GetReferencedElderReputation(social_consensus.ElderMask(1).Union(social_consensus.ElderMask(1)))) + + fmt.Println(society.GetRandomElder().GetElderMask()) + + /* + + selectRandomElder := func() elder.Elder { + return nodes[rand.Intn(len(nodes))] + } + + epochRegister := NewEpochRegister() + + genesis := NewTransaction("GENESIS") + + //selectRandomNode().Attach(genesis) + + fmt.Println(selectRandomElder()) + + fmt.Println(genesis) + + fmt.Println(epochRegister.GetEpoch(0)) + */ +} diff --git a/packages/unbreakable_consensus/epoch.go b/packages/unbreakable_consensus/epoch.go index 48c5440c..e60d5042 100644 --- a/packages/unbreakable_consensus/epoch.go +++ b/packages/unbreakable_consensus/epoch.go @@ -1,4 +1,28 @@ package unbreakable_consensus +import ( + "github.com/iotaledger/goshimmer/packages/stringify" + "github.com/iotaledger/goshimmer/packages/unbreakable_consensus/social_consensus" +) + type Epoch struct { + onlineMana map[string]*social_consensus.Node + number int +} + +func NewEpoch(number int) *Epoch { + return &Epoch{ + onlineMana: make(map[string]*social_consensus.Node), + number: number, + } +} + +func (epoch *Epoch) GetNumber() int { + return epoch.number +} + +func (epoch *Epoch) String() string { + return stringify.Struct("Epoch", + stringify.StructField("number", epoch.number), + ) } diff --git a/packages/unbreakable_consensus/epoch_register.go b/packages/unbreakable_consensus/epoch_register.go index 5a62dd9a..9a52dbab 100644 --- a/packages/unbreakable_consensus/epoch_register.go +++ b/packages/unbreakable_consensus/epoch_register.go @@ -1,8 +1,23 @@ package unbreakable_consensus type EpochRegister struct { + epochs map[int]*Epoch } func NewEpochRegister() *EpochRegister { - return &EpochRegister{} + return &EpochRegister{ + epochs: make(map[int]*Epoch), + } +} + +func (epochRegister *EpochRegister) GetEpoch(number int) *Epoch { + if epoch, exists := epochRegister.epochs[number]; exists { + return epoch + } else { + epoch := NewEpoch(number) + + epochRegister.epochs[number] = epoch + + return epoch + } } diff --git a/packages/unbreakable_consensus/social_consensus/elder_mask.go b/packages/unbreakable_consensus/social_consensus/elder_mask.go new file mode 100644 index 00000000..8a251de0 --- /dev/null +++ b/packages/unbreakable_consensus/social_consensus/elder_mask.go @@ -0,0 +1,19 @@ +package social_consensus + +import ( + "fmt" +) + +type ElderMask uint64 + +func (elderMask ElderMask) Union(otherElderMask ElderMask) ElderMask { + return elderMask | otherElderMask +} + +func (elderMask ElderMask) Contains(otherMask ElderMask) bool { + return elderMask&otherMask != 0 +} + +func (elderMask ElderMask) String() string { + return "ElderMask(" + fmt.Sprintf("%064b", elderMask) + ")" +} diff --git a/packages/unbreakable_consensus/social_consensus/node.go b/packages/unbreakable_consensus/social_consensus/node.go new file mode 100644 index 00000000..baff5910 --- /dev/null +++ b/packages/unbreakable_consensus/social_consensus/node.go @@ -0,0 +1,48 @@ +package social_consensus + +import ( + "github.com/iotaledger/goshimmer/packages/stringify" +) + +type Node struct { + id string + reputation uint64 + elderMask ElderMask +} + +func NewNode(id string) *Node { + return &Node{ + id: id, + } +} + +func (node *Node) GetElderMask() ElderMask { + return node.elderMask +} + +func (node *Node) SetElderMask(mask ElderMask) { + node.elderMask = mask +} + +func (node *Node) IsElder() bool { + return node.elderMask != 0 +} + +func (node *Node) GetId() string { + return node.id +} + +func (node *Node) GetReputation() uint64 { + return node.reputation +} + +func (node *Node) SetReputation(reputation uint64) { + node.reputation = reputation +} + +func (node *Node) String() string { + return stringify.Struct("Node", + stringify.StructField("id", node.id), + stringify.StructField("reputation", node.reputation), + ) +} diff --git a/packages/unbreakable_consensus/social_consensus/society.go b/packages/unbreakable_consensus/social_consensus/society.go new file mode 100644 index 00000000..0fa24d24 --- /dev/null +++ b/packages/unbreakable_consensus/social_consensus/society.go @@ -0,0 +1,50 @@ +package social_consensus + +import ( + "math/rand" +) + +type Society struct { + elders []*Node + totalElderReputation uint64 +} + +func NewSociety(elders []*Node) (result *Society) { + result = &Society{} + result.SetElders(elders) + + return +} + +func (society *Society) GetElders() []*Node { + return society.elders +} + +func (society *Society) SetElders(newElders []*Node) { + society.elders = newElders + + society.totalElderReputation = 0 + for i, elder := range newElders { + elder.SetElderMask(1 << uint(i)) + + society.totalElderReputation += elder.GetReputation() + } +} + +func (society *Society) GetReferencedElderReputation(elderMask ElderMask) (result uint64) { + for i, elder := range society.GetElders() { + if elderMask&(1<<uint(i)) > 0 { + result += elder.GetReputation() + } + } + + return +} + +func (society *Society) GetTotalElderReputation() uint64 { + return society.totalElderReputation +} + +func (society *Society) GetRandomElder() *Node { + return society.elders[rand.Intn(len(society.elders))] +} diff --git a/packages/unbreakable_consensus/transaction.go b/packages/unbreakable_consensus/transaction.go new file mode 100644 index 00000000..2367a21a --- /dev/null +++ b/packages/unbreakable_consensus/transaction.go @@ -0,0 +1,31 @@ +package unbreakable_consensus + +import ( + "github.com/iotaledger/goshimmer/packages/stringify" +) + +type Transaction struct { + id string + claimedEpoch int +} + +func NewTransaction(id string) *Transaction { + return &Transaction{ + id: id, + } +} + +func (transaction *Transaction) GetId() string { + return transaction.id +} + +func (transaction *Transaction) GetClaimedEpoch() int { + return transaction.claimedEpoch +} + +func (transaction *Transaction) String() string { + return stringify.Struct("Transaction", + stringify.StructField("id", transaction.id), + stringify.StructField("claimedEpoch", transaction.claimedEpoch), + ) +} -- GitLab