From dfa19fc2b4e38097334f4a30e159f9bcd92909c0 Mon Sep 17 00:00:00 2001 From: Wei-Ning Huang Date: Fri, 20 Jul 2018 09:52:52 +0800 Subject: Implement simulation on a real network (#5) simulation: implement simulation on a real network --- core/blocklattice.go | 38 +++++++++++++++++++++----------------- core/blocklattice_test.go | 20 ++++---------------- core/network.go | 24 +++++++++++++----------- core/types/block.go | 16 ++++++++-------- core/types/validator.go | 14 ++------------ core/validator.go | 22 ---------------------- 6 files changed, 48 insertions(+), 86 deletions(-) delete mode 100644 core/validator.go (limited to 'core') diff --git a/core/blocklattice.go b/core/blocklattice.go index 0da09d6..f746c20 100644 --- a/core/blocklattice.go +++ b/core/blocklattice.go @@ -44,7 +44,7 @@ const ( // State. type BlockLattice struct { owner types.ValidatorID - validatorSet map[types.ValidatorID]struct{} + ValidatorSet map[types.ValidatorID]struct{} blocks map[common.Hash]*types.Block fmax int @@ -52,7 +52,6 @@ type BlockLattice struct { lastSeenTimestamps map[types.ValidatorID]time.Time blockDB blockdb.BlockDatabase - network Network app Application mutex sync.Mutex @@ -72,14 +71,12 @@ type BlockLattice struct { // NewBlockLattice returns a new empty BlockLattice instance. func NewBlockLattice( db blockdb.BlockDatabase, - network Network, app Application) *BlockLattice { return &BlockLattice{ - validatorSet: make(map[types.ValidatorID]struct{}), + ValidatorSet: make(map[types.ValidatorID]struct{}), blocks: make(map[common.Hash]*types.Block), lastSeenTimestamps: make(map[types.ValidatorID]time.Time), blockDB: db, - network: network, app: app, waitingSet: make(map[common.Hash]*types.Block), stronglyAckedSet: make(map[common.Hash]*types.Block), @@ -96,8 +93,8 @@ func NewBlockLattice( func (l *BlockLattice) AddValidator( id types.ValidatorID, genesis *types.Block) { - l.validatorSet[id] = struct{}{} - l.fmax = (len(l.validatorSet) - 1) / 3 + l.ValidatorSet[id] = struct{}{} + l.fmax = (len(l.ValidatorSet) - 1) / 3 l.phi = 2*l.fmax + 1 genesis.State = types.BlockStatusFinal @@ -106,7 +103,7 @@ func (l *BlockLattice) AddValidator( // SetOwner sets the blocklattice's owner, which is the localview of whom. func (l *BlockLattice) SetOwner(id types.ValidatorID) { - if _, exists := l.validatorSet[id]; !exists { + if _, exists := l.ValidatorSet[id]; !exists { panic("SetOnwer: owner is not a valid validator") } l.owner = id @@ -173,6 +170,9 @@ func (l *BlockLattice) processAcks(b *types.Block) { for ab := range bx.Acks { abb := l.getBlock(ab) if abb.State < types.BlockStatusFinal { + if abb.Ackeds == nil { + abb.Ackeds = make(map[common.Hash]struct{}) + } abb.Ackeds[target.Hash] = struct{}{} populateAckBy(abb, target) } @@ -186,7 +186,7 @@ func (l *BlockLattice) processAcks(b *types.Block) { func (l *BlockLattice) updateTimestamps(b *types.Block) { q := b.ProposerID l.lastSeenTimestamps[q] = b.Timestamps[q].Add(epsilon) - for vid := range l.validatorSet { + for vid := range l.ValidatorSet { if b.Timestamps[vid].After(l.lastSeenTimestamps[vid]) { l.lastSeenTimestamps[vid] = b.Timestamps[vid] } @@ -245,6 +245,12 @@ func (l *BlockLattice) ProcessBlock(b *types.Block, runTotal ...bool) { l.mutex.Lock() defer l.mutex.Unlock() + if b.Hash == b.ParentHash { + if _, exists := l.ValidatorSet[b.ProposerID]; !exists { + l.AddValidator(b.ProposerID, b) + } + } + if l.getBlock(b.Hash) != nil { return } @@ -288,8 +294,8 @@ IterateStronglyAckedSet: } } -// ProposeBlock implements the send part of DEXON reliable broadcast. -func (l *BlockLattice) ProposeBlock(b *types.Block) { +// PrepareBlock prepare a block for broadcast. +func (l *BlockLattice) PrepareBlock(b *types.Block) { l.mutex.Lock() defer l.mutex.Unlock() @@ -306,8 +312,6 @@ func (l *BlockLattice) ProposeBlock(b *types.Block) { } //l.ProcessBlock(b) - l.network.BroadcastBlock(b) - l.ackCandidateSet = make(map[types.ValidatorID]*types.Block) } @@ -358,7 +362,7 @@ func (l *BlockLattice) calculateAHVofBlock( // Calculate ABS of a block. l.AHV[b.Hash] = make(map[types.ValidatorID]uint64) - for v := range l.validatorSet { + for v := range l.ValidatorSet { gv, gExists := globalMins[v] lv, lExists := l.ABS[b.Hash][v] @@ -432,7 +436,7 @@ func (l *BlockLattice) totalOrdering(b *types.Block) { if lose >= l.phi { winAll = false break - } else if lose < l.phi-len(l.validatorSet)+len(abs) { + } else if lose < l.phi-len(l.ValidatorSet)+len(abs) { // Do nothing. } else { winAll = false @@ -477,7 +481,7 @@ func (l *BlockLattice) totalOrdering(b *types.Block) { earlyDelivery := false // Does not satisfy External stability a. - if len(abs) < len(l.validatorSet) { + if len(abs) < len(l.ValidatorSet) { earlyDelivery = true // External stability b. @@ -498,7 +502,7 @@ func (l *BlockLattice) totalOrdering(b *types.Block) { return } for precedingHash := range precedingSet { - if len(l.ABS[precedingHash]) < len(l.validatorSet)-l.phi { + if len(l.ABS[precedingHash]) < len(l.ValidatorSet)-l.phi { extBSatisfied = false } } diff --git a/core/blocklattice_test.go b/core/blocklattice_test.go index 380dc38..f43d645 100644 --- a/core/blocklattice_test.go +++ b/core/blocklattice_test.go @@ -35,17 +35,6 @@ var b01, b11, b21, b31, b02, b12, b22, b32, b03, b13, b23, b33 *types.Block -// TestNetwork. -type TestNetwork struct { -} - -func (n *TestNetwork) Join(endpoint Endpoint) chan interface{} { - return nil -} - -func (n *TestNetwork) BroadcastBlock(block *types.Block) { -} - // TestApp. type TestApp struct { Outputs []*types.Block @@ -78,13 +67,11 @@ func (s *BlockLatticeTest) SetupTest() { s.app = &TestApp{} - lattice = NewBlockLattice( - blockdb.NewMemBackedBlockDB(), - &TestNetwork{}, - s.app) + lattice = NewBlockLattice(blockdb.NewMemBackedBlockDB(), s.app) for i := 0; i < 4; i++ { - validators = append(validators, types.ValidatorID(common.NewRandomHash())) + validators = append(validators, + types.ValidatorID{Hash: common.NewRandomHash()}) Debugf("V%d: %s\n", i, validators[i]) } Debugf("\n") @@ -116,6 +103,7 @@ func (s *BlockLatticeTest) SetupTest() { genesises[3].Hash: struct{}{}, }, } + b11 = &types.Block{ ProposerID: validators[1], ParentHash: genesises[1].Hash, diff --git a/core/network.go b/core/network.go index 8de73d2..d19af51 100644 --- a/core/network.go +++ b/core/network.go @@ -1,18 +1,18 @@ -// copyright 2018 the dexon-consensus-core authors -// this file is part of the dexon-consensus-core library. +// Copyright 2018 The dexon-consensus-core Authors +// This file is part of the dexon-consensus-core library. // -// the dexon-consensus-core library is free software: you can redistribute it -// and/or modify it under the terms of the gnu lesser general public license as -// published by the free software foundation, either version 3 of the license, +// The dexon-consensus-core library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // -// the dexon-consensus-core library is distributed in the hope that it will be -// useful, but without any warranty; without even the implied warranty of -// merchantability or fitness for a particular purpose. see the gnu lesser -// general public license for more details. +// The dexon-consensus-core library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. // -// you should have received a copy of the gnu lesser general public license -// along with the dexon-consensus-core library. if not, see +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus-core library. If not, see // . package core @@ -28,6 +28,8 @@ type Endpoint interface { // Network is the interface for network related functions. type Network interface { + Start() + NumPeers() int Join(endpoint Endpoint) chan interface{} BroadcastBlock(block *types.Block) } diff --git a/core/types/block.go b/core/types/block.go index 91b71da..6762f14 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -38,15 +38,15 @@ const ( // Block represents a single event broadcasted on the network. type Block struct { - ProposerID ValidatorID - ParentHash common.Hash - Hash common.Hash - Height uint64 - Timestamps map[ValidatorID]time.Time - Acks map[common.Hash]struct{} + ProposerID ValidatorID `json:"proposer_id"` + ParentHash common.Hash `json:"parent_hash"` + Hash common.Hash `json:"hash"` + Height uint64 `json:"height"` + Timestamps map[ValidatorID]time.Time `json:"timestamps"` + Acks map[common.Hash]struct{} `json:"acks"` - Ackeds map[common.Hash]struct{} - State State + Ackeds map[common.Hash]struct{} `json:"-"` + State State `json:"-"` } func (b *Block) String() string { diff --git a/core/types/validator.go b/core/types/validator.go index 5d424e8..48ce586 100644 --- a/core/types/validator.go +++ b/core/types/validator.go @@ -18,20 +18,10 @@ package types import ( - "bytes" - "encoding/hex" - "github.com/dexon-foundation/dexon-consensus-core/common" ) // ValidatorID is the ID type for validators. -type ValidatorID common.Hash - -func (v ValidatorID) String() string { - return hex.EncodeToString([]byte(v[:]))[:6] -} - -// Equal check if two validator IDs are the same. -func (v ValidatorID) Equal(v2 ValidatorID) bool { - return bytes.Compare([]byte(v[:]), []byte(v2[:])) == 0 +type ValidatorID struct { + common.Hash } diff --git a/core/validator.go b/core/validator.go deleted file mode 100644 index 93dbbce..0000000 --- a/core/validator.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The dexon-consensus-core Authors -// This file is part of the dexon-consensus-core library. -// -// The dexon-consensus-core library is free software: you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The dexon-consensus-core library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the dexon-consensus-core library. If not, see -// . - -package core - -// Validator represents a validator in DEXON consensus algorithm. -type Validator struct { -} -- cgit v1.2.3