diff options
Diffstat (limited to 'simulation/fake-network.go')
-rw-r--r-- | simulation/fake-network.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/simulation/fake-network.go b/simulation/fake-network.go new file mode 100644 index 0000000..923fab4 --- /dev/null +++ b/simulation/fake-network.go @@ -0,0 +1,95 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +package simulation + +import ( + "math/rand" + "sync" + "time" + + "github.com/dexon-foundation/dexon-consensus-core/core" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +// FakeNetwork implements the core.Network interface. +type FakeNetwork struct { + model Model + + endpointMutex sync.RWMutex + endpoints map[types.ValidatorID]chan interface{} +} + +// NewFakeNetwork returns pointer to a new Network instance. +func NewFakeNetwork(model Model) *FakeNetwork { + return &FakeNetwork{ + model: model, + endpoints: make(map[types.ValidatorID]chan interface{}), + } +} + +// Start starts the network. +func (n *FakeNetwork) Start() { +} + +// NumPeers returns the number of peers in the network. +func (n *FakeNetwork) NumPeers() int { + n.endpointMutex.Lock() + defer n.endpointMutex.Unlock() + return len(n.endpoints) +} + +// Join allow a client to join the network. It reutnrs a interface{} channel for +// the client to recieve information. +func (n *FakeNetwork) Join(endpoint core.Endpoint) chan interface{} { + n.endpointMutex.Lock() + defer n.endpointMutex.Unlock() + + if x, exists := n.endpoints[endpoint.GetID()]; exists { + return x + } + recivingChannel := make(chan interface{}, msgBufferSize) + + n.endpoints[endpoint.GetID()] = recivingChannel + return recivingChannel +} + +// Send sends a msg to another client. +func (n *FakeNetwork) Send(destID types.ValidatorID, msg interface{}) { + clientChannel, exists := n.endpoints[destID] + if !exists { + return + } + + go func() { + if rand.Float64() > n.model.LossRate() { + time.Sleep(n.model.Delay()) + + clientChannel <- msg + } + }() +} + +// BroadcastBlock broadcast blocks into the network. +func (n *FakeNetwork) BroadcastBlock(block *types.Block) { + n.endpointMutex.Lock() + defer n.endpointMutex.Unlock() + + for endpoint := range n.endpoints { + n.Send(endpoint, block.Clone()) + } +} |