mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
swarm: migrated overlay sim to rewrite
This commit is contained in:
parent
166c3e7e5b
commit
9e1aeac485
3 changed files with 29 additions and 145 deletions
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
|
@ -380,6 +381,13 @@ func (s *Server) ResetNetwork(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
// StreamNetworkEvents streams network events as a server-sent-events stream
|
// StreamNetworkEvents streams network events as a server-sent-events stream
|
||||||
func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
|
||||||
|
var throttle <-chan time.Time
|
||||||
|
//When running a sim, the frontend may "choke to death" depending on params (node count)
|
||||||
|
//due to overwhelming event rate. It is therefore important to be able to throttle
|
||||||
|
//the rate at which the events are emitted, in order for the frontend to have time
|
||||||
|
//to terminate rendering before the next event arrives.
|
||||||
|
throttling := false
|
||||||
|
|
||||||
events := make(chan *Event)
|
events := make(chan *Event)
|
||||||
sub := s.network.events.Subscribe(events)
|
sub := s.network.events.Subscribe(events)
|
||||||
defer sub.Unsubscribe()
|
defer sub.Unsubscribe()
|
||||||
|
|
@ -455,9 +463,21 @@ func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Only do throttling if requested
|
||||||
|
if req.URL.Query().Get("throttling") == "true" {
|
||||||
|
throttling = true
|
||||||
|
//rate at which we allow events to be emitted on the server-side event stream
|
||||||
|
rate := time.Second / 40
|
||||||
|
throttle = time.Tick(rate)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case event := <-events:
|
case event := <-events:
|
||||||
|
//if throttling, wait for the next throttle tick before emitting event
|
||||||
|
if throttling {
|
||||||
|
<-throttle
|
||||||
|
}
|
||||||
// only send message events which match the filters
|
// only send message events which match the filters
|
||||||
if event.Msg != nil && !filters.Match(event.Msg) {
|
if event.Msg != nil && !filters.Match(event.Msg) {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,11 @@ func startStop(net *Network, quit chan struct{}, nodeCount int) {
|
||||||
func probabilistic(net *Network, quit chan struct{}, nodeCount int) {
|
func probabilistic(net *Network, quit chan struct{}, nodeCount int) {
|
||||||
nodes, err := connectNodesInRing(net, nodeCount)
|
nodes, err := connectNodesInRing(net, nodeCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error(fmt.Sprintf("%s", err))
|
||||||
|
if _, ok := <-quit; ok == false {
|
||||||
|
//error may be due to abortion of mocking; so the quit channel is closed
|
||||||
|
return
|
||||||
|
}
|
||||||
panic("Could not startup node network for mocker")
|
panic("Could not startup node network for mocker")
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
|
|
@ -169,7 +174,7 @@ func connectNodesInRing(net *Network, nodeCount int) ([]discover.NodeID, error)
|
||||||
conf := adapters.RandomNodeConfig()
|
conf := adapters.RandomNodeConfig()
|
||||||
node, err := net.NewNodeWithConfig(conf)
|
node, err := net.NewNodeWithConfig(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error creating a node! %s", err)
|
log.Error(fmt.Sprintf("Error creating a node! %s", err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ids[i] = node.ID()
|
ids[i] = node.ID()
|
||||||
|
|
@ -185,7 +190,7 @@ func connectNodesInRing(net *Network, nodeCount int) ([]discover.NodeID, error)
|
||||||
for i, id := range ids {
|
for i, id := range ids {
|
||||||
peerID := ids[(i+1)%len(ids)]
|
peerID := ids[(i+1)%len(ids)]
|
||||||
if err := net.Connect(id, peerID); err != nil {
|
if err := net.Connect(id, peerID); err != nil {
|
||||||
log.Error("Error connecting a node to a peer! %s", err)
|
log.Error(fmt.Sprintf("Error connecting a node to a peer! %s", err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
@ -72,162 +70,23 @@ func (s *Simulation) NewService(ctx *adapters.ServiceContext) (node.Service, err
|
||||||
return network.NewBzz(config, kad, store, nil, nil), nil
|
return network.NewBzz(config, kad, store, nil, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMockers() map[string]*simulations.MockerConfig {
|
|
||||||
configs := make(map[string]*simulations.MockerConfig)
|
|
||||||
|
|
||||||
defaultCfg := simulations.DefaultMockerConfig()
|
|
||||||
defaultCfg.ID = "start-stop"
|
|
||||||
defaultCfg.Description = "Starts and Stops nodes in go routines"
|
|
||||||
defaultCfg.Mocker = startStopMocker
|
|
||||||
|
|
||||||
bootNetworkCfg := simulations.DefaultMockerConfig()
|
|
||||||
bootNetworkCfg.ID = "bootNet"
|
|
||||||
bootNetworkCfg.Description = "Only boots up all nodes in the config"
|
|
||||||
bootNetworkCfg.Mocker = bootMocker
|
|
||||||
|
|
||||||
randomNodesCfg := simulations.DefaultMockerConfig()
|
|
||||||
randomNodesCfg.ID = "randomNodes"
|
|
||||||
randomNodesCfg.Description = "Boots nodes and then starts and stops some picking randomly"
|
|
||||||
randomNodesCfg.Mocker = randomMocker
|
|
||||||
|
|
||||||
configs[defaultCfg.ID] = defaultCfg
|
|
||||||
configs[bootNetworkCfg.ID] = bootNetworkCfg
|
|
||||||
configs[randomNodesCfg.ID] = randomNodesCfg
|
|
||||||
|
|
||||||
return configs
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupMocker(net *simulations.Network) []discover.NodeID {
|
|
||||||
nodeCount := 30
|
|
||||||
ids := make([]discover.NodeID, nodeCount)
|
|
||||||
for i := 0; i < nodeCount; i++ {
|
|
||||||
node, err := net.NewNode()
|
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
ids[i] = node.ID()
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, id := range ids {
|
|
||||||
if err := net.Start(id); err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, id := range ids {
|
|
||||||
log.Trace(fmt.Sprintf("setup mocker: register a peer on node %x", id[:4]))
|
|
||||||
var peerID discover.NodeID
|
|
||||||
if i == 0 {
|
|
||||||
peerID = ids[len(ids)-1]
|
|
||||||
} else {
|
|
||||||
peerID = ids[i-1]
|
|
||||||
}
|
|
||||||
ch := make(chan network.OverlayAddr)
|
|
||||||
go func() {
|
|
||||||
defer close(ch)
|
|
||||||
ch <- network.NewAddrFromNodeID(peerID)
|
|
||||||
}()
|
|
||||||
log.Trace(fmt.Sprintf("%x registers peer %x", id[:4], peerID[:4]))
|
|
||||||
if err := net.GetNode(id).Node.(*adapters.SimNode).Services()[0].(*network.Bzz).Hive.Register(ch); err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ids
|
|
||||||
}
|
|
||||||
|
|
||||||
func bootMocker(net *simulations.Network) {
|
|
||||||
setupMocker(net)
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomMocker(net *simulations.Network) {
|
|
||||||
ids := setupMocker(net)
|
|
||||||
|
|
||||||
for {
|
|
||||||
var lowid, highid int
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
randWait := rand.Intn(5000) + 1000
|
|
||||||
rand1 := rand.Intn(9)
|
|
||||||
rand2 := rand.Intn(9)
|
|
||||||
if rand1 < rand2 {
|
|
||||||
lowid = rand1
|
|
||||||
highid = rand2
|
|
||||||
} else if rand1 > rand2 {
|
|
||||||
highid = rand1
|
|
||||||
lowid = rand2
|
|
||||||
} else {
|
|
||||||
if rand1 == 0 {
|
|
||||||
rand2 = 9
|
|
||||||
} else if rand1 == 9 {
|
|
||||||
rand1 = 0
|
|
||||||
}
|
|
||||||
lowid = rand1
|
|
||||||
highid = rand2
|
|
||||||
}
|
|
||||||
var steps = highid - lowid
|
|
||||||
wg.Add(steps)
|
|
||||||
for i := lowid; i < highid; i++ {
|
|
||||||
log.Info(fmt.Sprintf("node %v shutting down", ids[i]))
|
|
||||||
net.Stop(ids[i])
|
|
||||||
go func(id discover.NodeID) {
|
|
||||||
time.Sleep(time.Duration(randWait) * time.Millisecond)
|
|
||||||
net.Start(id)
|
|
||||||
wg.Done()
|
|
||||||
}(ids[i])
|
|
||||||
time.Sleep(time.Duration(randWait) * time.Millisecond)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func startStopMocker(net *simulations.Network) {
|
|
||||||
ids := setupMocker(net)
|
|
||||||
|
|
||||||
for range time.Tick(10 * time.Second) {
|
|
||||||
id := ids[rand.Intn(len(ids))]
|
|
||||||
go func() {
|
|
||||||
log.Error("stopping node", "id", id)
|
|
||||||
if err := net.Stop(id); err != nil {
|
|
||||||
log.Error("error stopping node", "id", id, "err", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
log.Error("starting node", "id", id)
|
|
||||||
if err := net.Start(id); err != nil {
|
|
||||||
log.Error("error starting node", "id", id, "err", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// var server
|
// var server
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
||||||
log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
|
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
|
||||||
|
|
||||||
s := NewSimulation()
|
s := NewSimulation()
|
||||||
services := adapters.Services{
|
services := adapters.Services{
|
||||||
"overlay": s.NewService,
|
"overlay": s.NewService,
|
||||||
}
|
}
|
||||||
adapter := adapters.NewSimAdapter(services)
|
adapter := adapters.NewSimAdapter(services)
|
||||||
|
|
||||||
network := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
|
network := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
|
||||||
DefaultService: "overlay",
|
DefaultService: "overlay",
|
||||||
})
|
})
|
||||||
|
|
||||||
mockers := createMockers()
|
|
||||||
|
|
||||||
config := simulations.ServerConfig{
|
|
||||||
DefaultMockerID: "randomNodes",
|
|
||||||
// DefaultMockerID: "bootNet",
|
|
||||||
Mockers: mockers,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("starting simulation server on 0.0.0.0:8888...")
|
log.Info("starting simulation server on 0.0.0.0:8888...")
|
||||||
http.ListenAndServe(":8888", simulations.NewServer(network, config))
|
http.ListenAndServe(":8888", simulations.NewServer(network))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue