node_manager: start/stop RPC server methods added
This commit is contained in:
parent
3832c457d8
commit
0057d8f4cd
|
@ -216,6 +216,20 @@ func StartNode(datadir *C.char) *C.char {
|
|||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
//export StopNodeRPCServer
|
||||
func StopNodeRPCServer() *C.char {
|
||||
_, err := geth.NodeManagerInstance().StopNodeRPCServer()
|
||||
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
//export StartNodeRPCServer
|
||||
func StartNodeRPCServer() *C.char {
|
||||
_, err := geth.NodeManagerInstance().StartNodeRPCServer()
|
||||
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
//export InitJail
|
||||
func InitJail(js *C.char) {
|
||||
jail.Init(C.GoString(js))
|
||||
|
@ -287,3 +301,18 @@ func RemoveWhisperFilter(idFilter int) {
|
|||
func ClearWhisperFilters() {
|
||||
geth.ClearWhisperFilters()
|
||||
}
|
||||
|
||||
func makeJSONErrorResponse(err error) *C.char {
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := geth.JSONError{
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@ func testExportedAPI(t *testing.T, done chan struct{}) {
|
|||
name string
|
||||
fn func(t *testing.T) bool
|
||||
}{
|
||||
{
|
||||
"restart node RPC",
|
||||
testRestartNodeRPC,
|
||||
},
|
||||
{
|
||||
"create main and child accounts",
|
||||
testCreateChildAccount,
|
||||
|
@ -86,6 +90,50 @@ func testExportedAPI(t *testing.T, done chan struct{}) {
|
|||
done <- struct{}{}
|
||||
}
|
||||
|
||||
func testRestartNodeRPC(t *testing.T) bool {
|
||||
// stop RPC
|
||||
stopNodeRPCServerResponse := geth.JSONError{}
|
||||
rawResponse := StopNodeRPCServer()
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &stopNodeRPCServerResponse); err != nil {
|
||||
t.Errorf("cannot decode StopNodeRPCServer reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
if stopNodeRPCServerResponse.Error != "" {
|
||||
t.Errorf("unexpected error: %s", stopNodeRPCServerResponse.Error)
|
||||
return false
|
||||
}
|
||||
|
||||
// start again RPC
|
||||
startNodeRPCServerResponse := geth.JSONError{}
|
||||
rawResponse = StartNodeRPCServer()
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &startNodeRPCServerResponse); err != nil {
|
||||
t.Errorf("cannot decode StartNodeRPCServer reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
if startNodeRPCServerResponse.Error != "" {
|
||||
t.Errorf("unexpected error: %s", startNodeRPCServerResponse.Error)
|
||||
return false
|
||||
}
|
||||
|
||||
// start when we have RPC already running
|
||||
startNodeRPCServerResponse = geth.JSONError{}
|
||||
rawResponse = StartNodeRPCServer()
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &startNodeRPCServerResponse); err != nil {
|
||||
t.Errorf("cannot decode StartNodeRPCServer reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
expectedError := "HTTP RPC already running on localhost:8545"
|
||||
if startNodeRPCServerResponse.Error != expectedError {
|
||||
t.Errorf("expected error not thrown: %s", expectedError)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func testCreateChildAccount(t *testing.T) bool {
|
||||
geth.Logout() // to make sure that we start with empty account (which might get populated during previous tests)
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ var (
|
|||
type Node struct {
|
||||
geth *node.Node // reference to the running Geth node
|
||||
started chan struct{} // channel to wait for node to start
|
||||
config *node.Config
|
||||
}
|
||||
|
||||
// Inited checks whether status node has been properly initialized
|
||||
|
@ -135,6 +136,7 @@ func MakeNode(dataDir string, rpcPort int) *Node {
|
|||
return &Node{
|
||||
geth: stack,
|
||||
started: make(chan struct{}),
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
|
@ -21,6 +22,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/les"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
|
@ -35,9 +37,10 @@ type SelectedExtKey struct {
|
|||
|
||||
// NodeManager manages Status node (which abstracts contained geth node)
|
||||
type NodeManager struct {
|
||||
node *Node // reference to Status node
|
||||
services *NodeServiceStack // default stack of services running on geth node
|
||||
SelectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
||||
node *Node // reference to Status node
|
||||
services *NodeServiceStack // default stack of services running on geth node
|
||||
api *node.PrivateAdminAPI // exposes collection of administrative API methods
|
||||
SelectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
||||
}
|
||||
|
||||
// NodeServiceStack contains "standard" node services (which are always available)
|
||||
|
@ -58,6 +61,7 @@ var (
|
|||
ErrInvalidJailedRequestQueue = errors.New("jailed request queue is not properly initialized")
|
||||
ErrNodeMakeFailure = errors.New("error creating p2p node")
|
||||
ErrNodeStartFailure = errors.New("error starting p2p node")
|
||||
ErrInvalidNodeAPI = errors.New("no node API connected")
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -128,7 +132,9 @@ func (m *NodeManager) RunNode() {
|
|||
glog.V(logger.Warn).Infoln("cannot get RPC client service:", ErrInvalidClient)
|
||||
}
|
||||
|
||||
// @TODO Remove after LES supports discover out of box
|
||||
// expose API
|
||||
m.api = node.NewPrivateAdminAPI(m.node.geth)
|
||||
|
||||
m.populateStaticPeers()
|
||||
|
||||
m.onNodeStarted() // node started, notify listeners
|
||||
|
@ -164,6 +170,42 @@ func (m *NodeManager) StartNode() {
|
|||
}()
|
||||
}
|
||||
|
||||
func (m *NodeManager) RestartNode() error {
|
||||
if m == nil || !m.NodeInited() {
|
||||
return ErrInvalidGethNode
|
||||
}
|
||||
|
||||
return m.node.geth.Restart()
|
||||
}
|
||||
|
||||
func (m *NodeManager) StartNodeRPCServer() (bool, error) {
|
||||
if m == nil || !m.NodeInited() {
|
||||
return false, ErrInvalidGethNode
|
||||
}
|
||||
|
||||
if m.api == nil {
|
||||
return false, ErrInvalidNodeAPI
|
||||
}
|
||||
|
||||
config := m.node.config
|
||||
modules := strings.Join(config.HTTPModules, ",")
|
||||
|
||||
return m.api.StartRPC(&config.HTTPHost, rpc.NewHexNumber(config.HTTPPort), &config.HTTPCors, &modules)
|
||||
}
|
||||
|
||||
// StopNodeRPCServer stops HTTP RPC service attached to node
|
||||
func (m *NodeManager) StopNodeRPCServer() (bool, error) {
|
||||
if m == nil || !m.NodeInited() {
|
||||
return false, ErrInvalidGethNode
|
||||
}
|
||||
|
||||
if m.api == nil {
|
||||
return false, ErrInvalidNodeAPI
|
||||
}
|
||||
|
||||
return m.api.StopRPC()
|
||||
}
|
||||
|
||||
// HasNode checks whether manager has initialized node attached
|
||||
func (m *NodeManager) NodeInited() bool {
|
||||
if m == nil || !m.node.Inited() {
|
||||
|
|
|
@ -193,7 +193,7 @@ func TestJailRPCSend(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
if balance < 90 || balance > 100 {
|
||||
if balance < 100 {
|
||||
t.Error("wrong balance (there should be lots of test Ether on that account)")
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue