mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
151 lines
3.5 KiB
Go
151 lines
3.5 KiB
Go
package simulations
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/ethereum/go-ethereum/p2p/adapters"
|
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
|
)
|
|
|
|
const lablen = 4
|
|
|
|
// func NewMockNetworkController(n *Network, parent *ResourceController) Controller {
|
|
func NewMockNetworkController(journal *Journal, closef func()) Controller {
|
|
self := NewResourceContoller(
|
|
&ResourceHandlers{
|
|
Destroy: &ResourceHandler{
|
|
Handle: func(msg interface{}, parent *ResourceController) (interface{}, error) {
|
|
journal.Close()
|
|
closef()
|
|
return nil, nil
|
|
},
|
|
},
|
|
// Create: n.StartNode, NodeConfig
|
|
// Update: n.Setup, NodeConfig
|
|
// Retrieve: n.Retrieve,
|
|
Retrieve: &ResourceHandler{
|
|
Handle: func(msg interface{}, parent *ResourceController) (interface{}, error) {
|
|
u := UpdateCy(journal)
|
|
return u, nil
|
|
},
|
|
},
|
|
},
|
|
)
|
|
return Controller(self)
|
|
}
|
|
|
|
// Network
|
|
// this can be the hook for uptime
|
|
type Network struct {
|
|
adapters.Messenger
|
|
lock sync.RWMutex
|
|
NodeMap map[discover.NodeID]int
|
|
Nodes []*SimNode
|
|
Journal []*Entry
|
|
// Journals map[string]*Journal
|
|
// Events events.Mux
|
|
}
|
|
|
|
func NewNetwork(m adapters.Messenger) *Network {
|
|
return &Network{
|
|
Messenger: m,
|
|
NodeMap: make(map[discover.NodeID]int),
|
|
}
|
|
}
|
|
|
|
type SimNode struct {
|
|
ID *discover.NodeID
|
|
config *NodeConfig
|
|
NetAdapter adapters.NetAdapter
|
|
}
|
|
|
|
func (self *SimNode) String() string {
|
|
return fmt.Sprintf("SimNode %v", self.ID.String()[0:lablen])
|
|
}
|
|
|
|
func (self *SimConn) String() string {
|
|
return fmt.Sprintf("SimConn %v->%v", self.Caller.String()[0:lablen], self.Callee.String()[0:lablen])
|
|
}
|
|
|
|
// active connections are represented by the SimNode entry object so that
|
|
// you journal updates could filter if passive knowledge about peers is
|
|
// irrelevant
|
|
type SimConn struct {
|
|
Caller *discover.NodeID `json:"caller"`
|
|
Callee *discover.NodeID `json:"callee"`
|
|
caller, callee *SimNode
|
|
// Info
|
|
// active connection
|
|
// average throughput, recent average throughput
|
|
}
|
|
|
|
type NodeConfig struct {
|
|
ID *discover.NodeID
|
|
Run func(adapters.NetAdapter, adapters.Messenger) adapters.ProtoCall
|
|
}
|
|
|
|
func (self *Network) Protocol(id *discover.NodeID) adapters.ProtoCall {
|
|
self.lock.Lock()
|
|
defer self.lock.Unlock()
|
|
node := self.getNode(id)
|
|
if node == nil {
|
|
return nil
|
|
}
|
|
na := node.NetAdapter.(*adapters.SimNet)
|
|
return na.Run
|
|
}
|
|
|
|
// TODO: ignored for now
|
|
type QueryConfig struct {
|
|
Format string // "cy.update", "journal",
|
|
}
|
|
|
|
func (n *Network) AppendEntries(entries ...*Entry) {
|
|
n.lock.Lock()
|
|
n.Journal = append(n.Journal, entries...)
|
|
n.lock.Unlock()
|
|
}
|
|
|
|
type Know struct {
|
|
Subject *discover.NodeID `json:"subject"`
|
|
Object *discover.NodeID `json:"object"`
|
|
// Into
|
|
// number of attempted connections
|
|
// time of attempted connections
|
|
// number of active connections during the session
|
|
// number of active connections since records began
|
|
// swap balance
|
|
}
|
|
|
|
func (self *Network) StartNode(conf *NodeConfig) error {
|
|
self.lock.Lock()
|
|
defer self.lock.Unlock()
|
|
id := conf.ID
|
|
|
|
_, found := self.NodeMap[*id]
|
|
if found {
|
|
return fmt.Errorf("node %v already running", id)
|
|
}
|
|
simnet := adapters.NewSimNet(id, self, self)
|
|
if conf.Run != nil {
|
|
simnet.Run = conf.Run(simnet, self.Messenger)
|
|
}
|
|
self.NodeMap[*id] = len(self.Nodes)
|
|
self.Nodes = append(self.Nodes, &SimNode{id, conf, adapters.NetAdapter(simnet)})
|
|
return nil
|
|
}
|
|
|
|
func (self *Network) GetNode(id *discover.NodeID) *SimNode {
|
|
self.lock.Lock()
|
|
defer self.lock.Unlock()
|
|
return self.getNode(id)
|
|
}
|
|
|
|
func (self *Network) getNode(id *discover.NodeID) *SimNode {
|
|
i, found := self.NodeMap[*id]
|
|
if !found {
|
|
return nil
|
|
}
|
|
return self.Nodes[i]
|
|
}
|