Merge pull request #78 from farazdagi/feature/restart-rpc
node_manager: start/stop RPC server methods added
This commit is contained in:
commit
4322d71714
|
@ -216,6 +216,20 @@ func StartNode(datadir *C.char) *C.char {
|
||||||
return C.CString(string(outBytes))
|
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
|
//export InitJail
|
||||||
func InitJail(js *C.char) {
|
func InitJail(js *C.char) {
|
||||||
jail.Init(C.GoString(js))
|
jail.Init(C.GoString(js))
|
||||||
|
@ -287,3 +301,18 @@ func RemoveWhisperFilter(idFilter int) {
|
||||||
func ClearWhisperFilters() {
|
func ClearWhisperFilters() {
|
||||||
geth.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
|
name string
|
||||||
fn func(t *testing.T) bool
|
fn func(t *testing.T) bool
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
"restart node RPC",
|
||||||
|
testRestartNodeRPC,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"create main and child accounts",
|
"create main and child accounts",
|
||||||
testCreateChildAccount,
|
testCreateChildAccount,
|
||||||
|
@ -86,6 +90,50 @@ func testExportedAPI(t *testing.T, done chan struct{}) {
|
||||||
done <- 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 {
|
func testCreateChildAccount(t *testing.T) bool {
|
||||||
geth.Logout() // to make sure that we start with empty account (which might get populated during previous tests)
|
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 {
|
type Node struct {
|
||||||
geth *node.Node // reference to the running Geth node
|
geth *node.Node // reference to the running Geth node
|
||||||
started chan struct{} // channel to wait for node to start
|
started chan struct{} // channel to wait for node to start
|
||||||
|
config *node.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inited checks whether status node has been properly initialized
|
// Inited checks whether status node has been properly initialized
|
||||||
|
@ -135,6 +136,7 @@ func MakeNode(dataDir string, rpcPort int) *Node {
|
||||||
return &Node{
|
return &Node{
|
||||||
geth: stack,
|
geth: stack,
|
||||||
started: make(chan struct{}),
|
started: make(chan struct{}),
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
@ -21,6 +22,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/les"
|
"github.com/ethereum/go-ethereum/les"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"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/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||||
|
@ -35,9 +37,10 @@ type SelectedExtKey struct {
|
||||||
|
|
||||||
// NodeManager manages Status node (which abstracts contained geth node)
|
// NodeManager manages Status node (which abstracts contained geth node)
|
||||||
type NodeManager struct {
|
type NodeManager struct {
|
||||||
node *Node // reference to Status node
|
node *Node // reference to Status node
|
||||||
services *NodeServiceStack // default stack of services running on geth node
|
services *NodeServiceStack // default stack of services running on geth node
|
||||||
SelectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
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)
|
// NodeServiceStack contains "standard" node services (which are always available)
|
||||||
|
@ -58,6 +61,7 @@ var (
|
||||||
ErrInvalidJailedRequestQueue = errors.New("jailed request queue is not properly initialized")
|
ErrInvalidJailedRequestQueue = errors.New("jailed request queue is not properly initialized")
|
||||||
ErrNodeMakeFailure = errors.New("error creating p2p node")
|
ErrNodeMakeFailure = errors.New("error creating p2p node")
|
||||||
ErrNodeStartFailure = errors.New("error starting p2p node")
|
ErrNodeStartFailure = errors.New("error starting p2p node")
|
||||||
|
ErrInvalidNodeAPI = errors.New("no node API connected")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -128,7 +132,9 @@ func (m *NodeManager) RunNode() {
|
||||||
glog.V(logger.Warn).Infoln("cannot get RPC client service:", ErrInvalidClient)
|
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.populateStaticPeers()
|
||||||
|
|
||||||
m.onNodeStarted() // node started, notify listeners
|
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
|
// HasNode checks whether manager has initialized node attached
|
||||||
func (m *NodeManager) NodeInited() bool {
|
func (m *NodeManager) NodeInited() bool {
|
||||||
if m == nil || !m.node.Inited() {
|
if m == nil || !m.node.Inited() {
|
||||||
|
|
|
@ -193,7 +193,7 @@ func TestJailRPCSend(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if balance < 90 || balance > 100 {
|
if balance < 100 {
|
||||||
t.Error("wrong balance (there should be lots of test Ether on that account)")
|
t.Error("wrong balance (there should be lots of test Ether on that account)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue