p2p/simulations: add mocker functionality (#15207)
This commit adds mocker functionality to p2p/simulations. A mocker allows to starting/stopping of nodes via the HTTP API.
This commit is contained in:
@ -27,6 +27,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
@ -263,8 +264,10 @@ func (c *Client) Send(method, path string, in, out interface{}) error {
|
||||
|
||||
// Server is an HTTP server providing an API to manage a simulation network
|
||||
type Server struct {
|
||||
router *httprouter.Router
|
||||
network *Network
|
||||
router *httprouter.Router
|
||||
network *Network
|
||||
mockerStop chan struct{} // when set, stops the current mocker
|
||||
mockerMtx sync.Mutex // synchronises access to the mockerStop field
|
||||
}
|
||||
|
||||
// NewServer returns a new simulation API server
|
||||
@ -278,6 +281,10 @@ func NewServer(network *Network) *Server {
|
||||
s.GET("/", s.GetNetwork)
|
||||
s.POST("/start", s.StartNetwork)
|
||||
s.POST("/stop", s.StopNetwork)
|
||||
s.POST("/mocker/start", s.StartMocker)
|
||||
s.POST("/mocker/stop", s.StopMocker)
|
||||
s.GET("/mocker", s.GetMockers)
|
||||
s.POST("/reset", s.ResetNetwork)
|
||||
s.GET("/events", s.StreamNetworkEvents)
|
||||
s.GET("/snapshot", s.CreateSnapshot)
|
||||
s.POST("/snapshot", s.LoadSnapshot)
|
||||
@ -318,6 +325,59 @@ func (s *Server) StopNetwork(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// StartMocker starts the mocker node simulation
|
||||
func (s *Server) StartMocker(w http.ResponseWriter, req *http.Request) {
|
||||
s.mockerMtx.Lock()
|
||||
defer s.mockerMtx.Unlock()
|
||||
if s.mockerStop != nil {
|
||||
http.Error(w, "mocker already running", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
mockerType := req.FormValue("mocker-type")
|
||||
mockerFn := LookupMocker(mockerType)
|
||||
if mockerFn == nil {
|
||||
http.Error(w, fmt.Sprintf("unknown mocker type %q", mockerType), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
nodeCount, err := strconv.Atoi(req.FormValue("node-count"))
|
||||
if err != nil {
|
||||
http.Error(w, "invalid node-count provided", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
s.mockerStop = make(chan struct{})
|
||||
go mockerFn(s.network, s.mockerStop, nodeCount)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// StopMocker stops the mocker node simulation
|
||||
func (s *Server) StopMocker(w http.ResponseWriter, req *http.Request) {
|
||||
s.mockerMtx.Lock()
|
||||
defer s.mockerMtx.Unlock()
|
||||
if s.mockerStop == nil {
|
||||
http.Error(w, "stop channel not initialized", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
close(s.mockerStop)
|
||||
s.mockerStop = nil
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// GetMockerList returns a list of available mockers
|
||||
func (s *Server) GetMockers(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
list := GetMockerList()
|
||||
s.JSON(w, http.StatusOK, list)
|
||||
}
|
||||
|
||||
// ResetNetwork resets all properties of a network to its initial (empty) state
|
||||
func (s *Server) ResetNetwork(w http.ResponseWriter, req *http.Request) {
|
||||
s.network.Reset()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// StreamNetworkEvents streams network events as a server-sent-events stream
|
||||
func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
|
||||
events := make(chan *Event)
|
||||
|
Reference in New Issue
Block a user