Skip to content

Commit 2e0b56a

Browse files
author
Bas van Kervel
committed
added RPC start/stop support
1 parent 2737baa commit 2e0b56a

31 files changed

+224
-130
lines changed

cmd/geth/js.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/ethereum/go-ethereum/xeth"
4242
"github.com/peterh/liner"
4343
"github.com/robertkrimen/otto"
44+
"github.com/ethereum/go-ethereum/rpc/shared"
4445
)
4546

4647
type prompter interface {
@@ -183,7 +184,9 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et
183184
js.wait = js.xeth.UpdateState()
184185
js.client = client
185186
if clt, ok := js.client.(*comms.InProcClient); ok {
186-
clt.Initialize(js.xeth, ethereum)
187+
if offeredApis, err := api.ParseApiString(shared.AllApis, codec.JSON, js.xeth, ethereum); err == nil {
188+
clt.Initialize(api.Merge(offeredApis...))
189+
}
187190
}
188191

189192
// update state in separare forever blocks
@@ -311,7 +314,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
311314
// load only supported API's in javascript runtime
312315
shortcuts := "var eth = web3.eth; "
313316
for _, apiName := range apiNames {
314-
if apiName == api.Web3ApiName || apiName == api.EthApiName {
317+
if apiName == shared.Web3ApiName || apiName == shared.EthApiName {
315318
continue // manually mapped
316319
}
317320

cmd/geth/js_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func TestRPC(t *testing.T) {
210210
defer ethereum.Stop()
211211
defer os.RemoveAll(tmp)
212212

213-
checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004)`, `true`)
213+
checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004, "*", "web3,eth,net")`, `true`)
214214
}
215215

216216
func TestCheckTestAccountBalance(t *testing.T) {

cmd/utils/flags.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
461461
return err
462462
}
463463

464-
return comms.StartIpc(config, codec, apis...)
464+
return comms.StartIpc(config, codec, api.Merge(apis...))
465465
}
466466

467467
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
@@ -479,7 +479,7 @@ func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
479479
return err
480480
}
481481

482-
return comms.StartHttp(config, codec, apis...)
482+
return comms.StartHttp(config, codec, api.Merge(apis...))
483483
}
484484

485485
func StartPProf(ctx *cli.Context) {

rpc/api/admin.go

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/ethereum/go-ethereum/logger/glog"
1212
"github.com/ethereum/go-ethereum/rlp"
1313
"github.com/ethereum/go-ethereum/rpc/codec"
14+
"github.com/ethereum/go-ethereum/rpc/comms"
1415
"github.com/ethereum/go-ethereum/rpc/shared"
1516
"github.com/ethereum/go-ethereum/xeth"
1617
)
@@ -32,6 +33,8 @@ var (
3233
"admin_chainSyncStatus": (*adminApi).ChainSyncStatus,
3334
"admin_setSolc": (*adminApi).SetSolc,
3435
"admin_datadir": (*adminApi).DataDir,
36+
"admin_startRPC": (*adminApi).StartRPC,
37+
"admin_stopRPC": (*adminApi).StopRPC,
3538
}
3639
)
3740

@@ -42,25 +45,25 @@ type adminhandler func(*adminApi, *shared.Request) (interface{}, error)
4245
type adminApi struct {
4346
xeth *xeth.XEth
4447
ethereum *eth.Ethereum
45-
methods map[string]adminhandler
46-
codec codec.ApiCoder
48+
codec codec.Codec
49+
coder codec.ApiCoder
4750
}
4851

4952
// create a new admin api instance
50-
func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi {
53+
func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi {
5154
return &adminApi{
5255
xeth: xeth,
5356
ethereum: ethereum,
54-
methods: AdminMapping,
55-
codec: coder.New(nil),
57+
codec: codec,
58+
coder: codec.New(nil),
5659
}
5760
}
5861

5962
// collection with supported methods
6063
func (self *adminApi) Methods() []string {
61-
methods := make([]string, len(self.methods))
64+
methods := make([]string, len(AdminMapping))
6265
i := 0
63-
for k := range self.methods {
66+
for k := range AdminMapping {
6467
methods[i] = k
6568
i++
6669
}
@@ -69,15 +72,15 @@ func (self *adminApi) Methods() []string {
6972

7073
// Execute given request
7174
func (self *adminApi) Execute(req *shared.Request) (interface{}, error) {
72-
if callback, ok := self.methods[req.Method]; ok {
75+
if callback, ok := AdminMapping[req.Method]; ok {
7376
return callback(self, req)
7477
}
7578

7679
return nil, &shared.NotImplementedError{req.Method}
7780
}
7881

7982
func (self *adminApi) Name() string {
80-
return AdminApiName
83+
return shared.AdminApiName
8184
}
8285

8386
func (self *adminApi) ApiVersion() string {
@@ -86,7 +89,7 @@ func (self *adminApi) ApiVersion() string {
8689

8790
func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) {
8891
args := new(AddPeerArgs)
89-
if err := self.codec.Decode(req.Params, &args); err != nil {
92+
if err := self.coder.Decode(req.Params, &args); err != nil {
9093
return nil, shared.NewDecodeParamError(err.Error())
9194
}
9295

@@ -120,7 +123,7 @@ func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool {
120123

121124
func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
122125
args := new(ImportExportChainArgs)
123-
if err := self.codec.Decode(req.Params, &args); err != nil {
126+
if err := self.coder.Decode(req.Params, &args); err != nil {
124127
return nil, shared.NewDecodeParamError(err.Error())
125128
}
126129

@@ -163,7 +166,7 @@ func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
163166

164167
func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
165168
args := new(ImportExportChainArgs)
166-
if err := self.codec.Decode(req.Params, &args); err != nil {
169+
if err := self.coder.Decode(req.Params, &args); err != nil {
167170
return nil, shared.NewDecodeParamError(err.Error())
168171
}
169172

@@ -181,7 +184,7 @@ func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
181184

182185
func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) {
183186
args := new(VerbosityArgs)
184-
if err := self.codec.Decode(req.Params, &args); err != nil {
187+
if err := self.coder.Decode(req.Params, &args); err != nil {
185188
return nil, shared.NewDecodeParamError(err.Error())
186189
}
187190

@@ -202,7 +205,7 @@ func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error)
202205

203206
func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
204207
args := new(SetSolcArgs)
205-
if err := self.codec.Decode(req.Params, &args); err != nil {
208+
if err := self.coder.Decode(req.Params, &args); err != nil {
206209
return nil, shared.NewDecodeParamError(err.Error())
207210
}
208211

@@ -212,3 +215,32 @@ func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
212215
}
213216
return solc.Info(), nil
214217
}
218+
219+
func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) {
220+
var err error
221+
args := new(StartRPCArgs)
222+
if err := self.coder.Decode(req.Params, &args); err != nil {
223+
return nil, shared.NewDecodeParamError(err.Error())
224+
}
225+
226+
cfg := comms.HttpConfig{
227+
ListenAddress: args.ListenAddress,
228+
ListenPort: args.ListenPort,
229+
CorsDomain: args.CorsDomain,
230+
}
231+
232+
if apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum); err == nil {
233+
err = comms.StartHttp(cfg, self.codec, Merge(apis...))
234+
}
235+
236+
if err == nil {
237+
return true, nil
238+
}
239+
240+
return false, err
241+
}
242+
243+
func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) {
244+
comms.StopHttp()
245+
return true, nil
246+
}

rpc/api/admin_args.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,55 @@ func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) {
9595

9696
return shared.NewInvalidTypeError("path", "not a string")
9797
}
98+
99+
type StartRPCArgs struct {
100+
ListenAddress string
101+
ListenPort uint
102+
CorsDomain string
103+
Apis string
104+
}
105+
106+
func (args *StartRPCArgs) UnmarshalJSON(b []byte) (err error) {
107+
var obj []interface{}
108+
if err := json.Unmarshal(b, &obj); err != nil {
109+
return shared.NewDecodeParamError(err.Error())
110+
}
111+
112+
args.ListenAddress = "127.0.0.1"
113+
args.ListenPort = 8545
114+
args.Apis = "net,eth,web3"
115+
116+
if len(obj) >= 1 {
117+
if addr, ok := obj[0].(string); ok {
118+
args.ListenAddress = addr
119+
} else {
120+
return shared.NewInvalidTypeError("listenAddress", "not a string")
121+
}
122+
}
123+
124+
if len(obj) >= 2 {
125+
if port, ok := obj[1].(float64); ok && port >= 0 && port <= 64*1024 {
126+
args.ListenPort = uint(port)
127+
} else {
128+
return shared.NewInvalidTypeError("listenPort", "not a valid port number")
129+
}
130+
}
131+
132+
if len(obj) >= 3 {
133+
if corsDomain, ok := obj[2].(string); ok {
134+
args.CorsDomain = corsDomain
135+
} else {
136+
return shared.NewInvalidTypeError("corsDomain", "not a string")
137+
}
138+
}
139+
140+
if len(obj) >= 4 {
141+
if apis, ok := obj[3].(string); ok {
142+
args.Apis = apis
143+
} else {
144+
return shared.NewInvalidTypeError("apis", "not a string")
145+
}
146+
}
147+
148+
return nil
149+
}

rpc/api/admin_js.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ web3._extend({
3939
params: 1,
4040
inputFormatter: [web3._extend.utils.formatInputString],
4141
outputFormatter: web3._extend.formatters.formatOutputString
42+
}),
43+
new web3._extend.Method({
44+
name: 'startRPC',
45+
call: 'admin_startRPC',
46+
params: 4,
47+
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputInteger,web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
48+
outputFormatter: web3._extend.formatters.formatOutputBool
49+
}),
50+
new web3._extend.Method({
51+
name: 'stopRPC',
52+
call: 'admin_stopRPC',
53+
params: 0,
54+
inputFormatter: [],
55+
outputFormatter: web3._extend.formatters.formatOutputBool
4256
})
4357
],
4458
properties:

rpc/api/api.go

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,10 @@
11
package api
22

33
import (
4-
"strings"
5-
64
"github.com/ethereum/go-ethereum/rpc/shared"
75
)
86

9-
const (
10-
AdminApiName = "admin"
11-
EthApiName = "eth"
12-
DbApiName = "db"
13-
DebugApiName = "debug"
14-
MergedApiName = "merged"
15-
MinerApiName = "miner"
16-
NetApiName = "net"
17-
ShhApiName = "shh"
18-
TxPoolApiName = "txpool"
19-
PersonalApiName = "personal"
20-
Web3ApiName = "web3"
21-
22-
JsonRpcVersion = "2.0"
23-
)
24-
25-
var (
26-
// All API's
27-
AllApis = strings.Join([]string{
28-
AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName,
29-
ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName,
30-
}, ",")
31-
)
32-
33-
// Ethereum RPC API interface
34-
type EthereumApi interface {
35-
// API identifier
36-
Name() string
37-
38-
// API version
39-
ApiVersion() string
40-
41-
// Execute the given request and returns the response or an error
42-
Execute(*shared.Request) (interface{}, error)
43-
44-
// List of supported RCP methods this API provides
45-
Methods() []string
46-
}
47-
487
// Merge multiple API's to a single API instance
49-
func Merge(apis ...EthereumApi) EthereumApi {
8+
func Merge(apis ...shared.EthereumApi) shared.EthereumApi {
509
return newMergedApi(apis...)
5110
}

rpc/api/args.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"encoding/json"
5+
56
"github.com/ethereum/go-ethereum/rpc/shared"
67
)
78

@@ -54,4 +55,4 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
5455
}
5556
args.Word = argstr
5657
return nil
57-
}
58+
}

rpc/api/args_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"math/big"
88
"testing"
9+
910
"github.com/ethereum/go-ethereum/rpc/shared"
1011
)
1112

rpc/api/db.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (self *dbApi) Execute(req *shared.Request) (interface{}, error) {
6363
}
6464

6565
func (self *dbApi) Name() string {
66-
return DbApiName
66+
return shared.DbApiName
6767
}
6868

6969
func (self *dbApi) ApiVersion() string {

0 commit comments

Comments
 (0)