Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
df75dbfd
Commit
df75dbfd
authored
Feb 09, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd, node, rpc: readd inproc RPC client, expose via node
parent
900e124b
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
178 additions
and
25 deletions
+178
-25
js_test.go
cmd/geth/js_test.go
+2
-4
main.go
cmd/geth/main.go
+2
-2
client.go
cmd/utils/client.go
+0
-1
api.go
node/api.go
+1
-1
node.go
node/node.go
+54
-1
node_test.go
node/node_test.go
+5
-7
http.go
rpc/http.go
+1
-1
inproc.go
rpc/inproc.go
+111
-0
ipc.go
rpc/ipc.go
+1
-1
ipc_windows.go
rpc/ipc_windows.go
+0
-6
websocket.go
rpc/websocket.go
+1
-1
No files found.
cmd/geth/js_test.go
View file @
df75dbfd
...
...
@@ -20,7 +20,6 @@ import (
"fmt"
"io/ioutil"
"math/big"
"math/rand"
"os"
"path/filepath"
"regexp"
...
...
@@ -30,7 +29,6 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/common/httpclient"
...
...
@@ -96,7 +94,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *nod
t
.
Fatal
(
err
)
}
// Create a networkless protocol stack
stack
,
err
:=
node
.
New
(
&
node
.
Config
{
PrivateKey
:
testNodeKey
,
Name
:
"test"
,
NoDiscovery
:
true
,
IPCPath
:
fmt
.
Sprintf
(
"geth-test-%d.ipc"
,
rand
.
Int63
())
})
stack
,
err
:=
node
.
New
(
&
node
.
Config
{
PrivateKey
:
testNodeKey
,
Name
:
"test"
,
NoDiscovery
:
true
})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create node: %v"
,
err
)
}
...
...
@@ -142,7 +140,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *nod
stack
.
Service
(
&
ethereum
)
assetPath
:=
filepath
.
Join
(
os
.
Getenv
(
"GOPATH"
),
"src"
,
"github.com"
,
"ethereum"
,
"go-ethereum"
,
"cmd"
,
"mist"
,
"assets"
,
"ext"
)
client
,
err
:=
utils
.
NewRemoteRPCClientFromString
(
"ipc:"
+
stack
.
IPCEndpoint
()
)
client
,
err
:=
stack
.
Attach
(
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to attach to node: %v"
,
err
)
}
...
...
cmd/geth/main.go
View file @
df75dbfd
...
...
@@ -425,7 +425,7 @@ func console(ctx *cli.Context) {
startNode
(
ctx
,
node
)
// Attach to the newly started node, and either execute script or become interactive
client
,
err
:=
utils
.
NewRemoteRPCClientFromString
(
"ipc:"
+
node
.
IPCEndpoint
()
)
client
,
err
:=
node
.
Attach
(
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Failed to attach to the inproc geth: %v"
,
err
)
}
...
...
@@ -451,7 +451,7 @@ func execScripts(ctx *cli.Context) {
startNode
(
ctx
,
node
)
// Attach to the newly started node and execute the given scripts
client
,
err
:=
utils
.
NewRemoteRPCClientFromString
(
"ipc:"
+
node
.
IPCEndpoint
()
)
client
,
err
:=
node
.
Attach
(
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Failed to attach to the inproc geth: %v"
,
err
)
}
...
...
cmd/utils/client.go
View file @
df75dbfd
...
...
@@ -51,6 +51,5 @@ func NewRemoteRPCClientFromString(endpoint string) (rpc.Client, error) {
if
strings
.
HasPrefix
(
endpoint
,
"ws:"
)
{
return
rpc
.
NewWSClient
(
endpoint
)
}
return
nil
,
fmt
.
Errorf
(
"invalid endpoint"
)
}
node/api.go
View file @
df75dbfd
...
...
@@ -89,7 +89,7 @@ func (api *PrivateAdminAPI) StartWS(host string, port int, cors string, apis str
defer
api
.
node
.
lock
.
Unlock
()
if
api
.
node
.
wsHandler
!=
nil
{
return
false
,
fmt
.
Errorf
(
"WebSocke
r
RPC already running on %s"
,
api
.
node
.
wsEndpoint
)
return
false
,
fmt
.
Errorf
(
"WebSocke
t
RPC already running on %s"
,
api
.
node
.
wsEndpoint
)
}
if
err
:=
api
.
node
.
startWS
(
fmt
.
Sprintf
(
"%s:%d"
,
host
,
port
),
api
.
node
.
rpcAPIs
,
strings
.
Split
(
apis
,
","
),
cors
);
err
!=
nil
{
return
false
,
err
...
...
node/node.go
View file @
df75dbfd
...
...
@@ -55,7 +55,9 @@ type Node struct {
serviceFuncs
[]
ServiceConstructor
// Service constructors (in dependency order)
services
map
[
reflect
.
Type
]
Service
// Currently running services
rpcAPIs
[]
rpc
.
API
// List of APIs currently provided by the node
rpcAPIs
[]
rpc
.
API
// List of APIs currently provided by the node
inprocHandler
*
rpc
.
Server
// In-process RPC request handler to process the API requests
ipcEndpoint
string
// IPC endpoint to listen at (empty = IPC disabled)
ipcListener
net
.
Listener
// IPC RPC listener socket to serve API requests
ipcHandler
*
rpc
.
Server
// IPC RPC request handler to process the API requests
...
...
@@ -217,16 +219,22 @@ func (n *Node) startRPC(services map[reflect.Type]Service) error {
apis
=
append
(
apis
,
service
.
APIs
()
...
)
}
// Start the various API endpoints, terminating all in case of errors
if
err
:=
n
.
startInProc
(
apis
);
err
!=
nil
{
return
err
}
if
err
:=
n
.
startIPC
(
apis
);
err
!=
nil
{
n
.
stopInProc
()
return
err
}
if
err
:=
n
.
startHTTP
(
n
.
httpEndpoint
,
apis
,
n
.
httpWhitelist
,
n
.
httpCors
);
err
!=
nil
{
n
.
stopIPC
()
n
.
stopInProc
()
return
err
}
if
err
:=
n
.
startWS
(
n
.
wsEndpoint
,
apis
,
n
.
wsWhitelist
,
n
.
wsDomains
);
err
!=
nil
{
n
.
stopHTTP
()
n
.
stopIPC
()
n
.
stopInProc
()
return
err
}
// All API endpoints started successfully
...
...
@@ -234,6 +242,28 @@ func (n *Node) startRPC(services map[reflect.Type]Service) error {
return
nil
}
// startInProc initializes an in-process RPC endpoint.
func
(
n
*
Node
)
startInProc
(
apis
[]
rpc
.
API
)
error
{
// Register all the APIs exposed by the services
handler
:=
rpc
.
NewServer
()
for
_
,
api
:=
range
apis
{
if
err
:=
handler
.
RegisterName
(
api
.
Namespace
,
api
.
Service
);
err
!=
nil
{
return
err
}
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"InProc registered %T under '%s'"
,
api
.
Service
,
api
.
Namespace
)
}
n
.
inprocHandler
=
handler
return
nil
}
// stopInProc terminates the in-process RPC endpoint.
func
(
n
*
Node
)
stopInProc
()
{
if
n
.
inprocHandler
!=
nil
{
n
.
inprocHandler
.
Stop
()
n
.
inprocHandler
=
nil
}
}
// startIPC initializes and starts the IPC RPC endpoint.
func
(
n
*
Node
)
startIPC
(
apis
[]
rpc
.
API
)
error
{
// Short circuit if the IPC endpoint isn't being exposed
...
...
@@ -468,6 +498,19 @@ func (n *Node) Restart() error {
return
nil
}
// Attach creates an RPC client attached to an in-process API handler.
func
(
n
*
Node
)
Attach
()
(
rpc
.
Client
,
error
)
{
n
.
lock
.
RLock
()
defer
n
.
lock
.
RUnlock
()
// Short circuit if the node's not running
if
n
.
server
==
nil
{
return
nil
,
ErrNodeStopped
}
// Otherwise attach to the API and return
return
rpc
.
NewInProcRPCClient
(
n
.
inprocHandler
),
nil
}
// Server retrieves the currently running P2P network layer. This method is meant
// only to inspect fields of the currently running server, life cycle management
// should be left to this Node entity.
...
...
@@ -506,6 +549,16 @@ func (n *Node) IPCEndpoint() string {
return
n
.
ipcEndpoint
}
// HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack.
func
(
n
*
Node
)
HTTPEndpoint
()
string
{
return
n
.
httpEndpoint
}
// WSEndpoint retrieves the current WS endpoint used by the protocol stack.
func
(
n
*
Node
)
WSEndpoint
()
string
{
return
n
.
wsEndpoint
}
// EventMux retrieves the event multiplexer used by all the network services in
// the current protocol stack.
func
(
n
*
Node
)
EventMux
()
*
event
.
TypeMux
{
...
...
node/node_test.go
View file @
df75dbfd
...
...
@@ -18,9 +18,7 @@ package node
import
(
"errors"
"fmt"
"io/ioutil"
"math/rand"
"os"
"reflect"
"testing"
...
...
@@ -37,7 +35,6 @@ var (
func
testNodeConfig
()
*
Config
{
return
&
Config
{
IPCPath
:
fmt
.
Sprintf
(
"test-%d.ipc"
,
rand
.
Int63
()),
PrivateKey
:
testNodeKey
,
Name
:
"test node"
,
}
...
...
@@ -541,10 +538,11 @@ func TestAPIGather(t *testing.T) {
defer
stack
.
Stop
()
// Connect to the RPC server and verify the various registered endpoints
ipcClient
,
err
:=
rpc
.
NewIPCClient
(
stack
.
IPCEndpoint
()
)
client
,
err
:=
stack
.
Attach
(
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to connect to the
IPC
API server: %v"
,
err
)
t
.
Fatalf
(
"failed to connect to the
inproc
API server: %v"
,
err
)
}
defer
client
.
Close
()
tests
:=
[]
struct
{
Method
string
...
...
@@ -556,11 +554,11 @@ func TestAPIGather(t *testing.T) {
{
"multi.v2.nested_theOneMethod"
,
"multi.v2.nested"
},
}
for
i
,
test
:=
range
tests
{
if
err
:=
ipcC
lient
.
Send
(
rpc
.
JSONRequest
{
Id
:
new
(
int64
),
Version
:
"2.0"
,
Method
:
test
.
Method
});
err
!=
nil
{
if
err
:=
c
lient
.
Send
(
rpc
.
JSONRequest
{
Id
:
new
(
int64
),
Version
:
"2.0"
,
Method
:
test
.
Method
});
err
!=
nil
{
t
.
Fatalf
(
"test %d: failed to send API request: %v"
,
i
,
err
)
}
reply
:=
new
(
rpc
.
JSONSuccessResponse
)
if
err
:=
ipcC
lient
.
Recv
(
reply
);
err
!=
nil
{
if
err
:=
c
lient
.
Recv
(
reply
);
err
!=
nil
{
t
.
Fatalf
(
"test %d: failed to read API reply: %v"
,
i
,
err
)
}
select
{
...
...
rpc/http.go
View file @
df75dbfd
...
...
@@ -259,7 +259,7 @@ type httpClient struct {
// NewHTTPClient create a new RPC clients that connection to a geth RPC server
// over HTTP.
func
NewHTTPClient
(
endpoint
string
)
(
*
http
Client
,
error
)
{
func
NewHTTPClient
(
endpoint
string
)
(
Client
,
error
)
{
url
,
err
:=
url
.
Parse
(
endpoint
)
if
err
!=
nil
{
return
nil
,
err
...
...
rpc/inproc.go
0 → 100644
View file @
df75dbfd
// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
rpc
import
"encoding/json"
// NewInProcRPCClient creates an in-process buffer stream attachment to a given
// RPC server.
func
NewInProcRPCClient
(
handler
*
Server
)
Client
{
buffer
:=
&
inprocBuffer
{
requests
:
make
(
chan
[]
byte
,
16
),
responses
:
make
(
chan
[]
byte
,
16
),
}
client
:=
&
inProcClient
{
server
:
handler
,
buffer
:
buffer
,
}
go
handler
.
ServeCodec
(
NewJSONCodec
(
client
.
buffer
))
return
client
}
// inProcClient is an in-process buffer stream attached to an RPC server.
type
inProcClient
struct
{
server
*
Server
buffer
*
inprocBuffer
}
// Close tears down the request channel of the in-proc client.
func
(
c
*
inProcClient
)
Close
()
{
c
.
buffer
.
Close
()
}
// Send marshals a message into a json format and injects in into the client
// request channel.
func
(
c
*
inProcClient
)
Send
(
msg
interface
{})
error
{
d
,
err
:=
json
.
Marshal
(
msg
)
if
err
!=
nil
{
return
err
}
c
.
buffer
.
requests
<-
d
return
nil
}
// Recv reads a message from the response channel and tries to parse it into the
// given msg interface.
func
(
c
*
inProcClient
)
Recv
(
msg
interface
{})
error
{
data
:=
<-
c
.
buffer
.
responses
return
json
.
Unmarshal
(
data
,
&
msg
)
}
// Returns the collection of modules the RPC server offers.
func
(
c
*
inProcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
return
SupportedModules
(
c
)
}
// inprocBuffer represents the connection between the RPC server and console
type
inprocBuffer
struct
{
readBuf
[]
byte
// store remaining request bytes after a partial read
requests
chan
[]
byte
// list with raw serialized requests
responses
chan
[]
byte
// list with raw serialized responses
}
// Read will read the next request in json format.
func
(
b
*
inprocBuffer
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
// last read didn't read entire request, return remaining bytes
if
len
(
b
.
readBuf
)
>
0
{
n
:=
copy
(
p
,
b
.
readBuf
)
if
n
<
len
(
b
.
readBuf
)
{
b
.
readBuf
=
b
.
readBuf
[
:
n
]
}
else
{
b
.
readBuf
=
b
.
readBuf
[
:
0
]
}
return
n
,
nil
}
// read next request
req
:=
<-
b
.
requests
n
:=
copy
(
p
,
req
)
if
n
<
len
(
req
)
{
// inprocBuffer too small, store remaining chunk for next read
b
.
readBuf
=
req
[
n
:
]
}
return
n
,
nil
}
// Write sends the given buffer to the backend.
func
(
b
*
inprocBuffer
)
Write
(
p
[]
byte
)
(
n
int
,
err
error
)
{
b
.
responses
<-
p
return
len
(
p
),
nil
}
// Close cleans up obtained resources.
func
(
b
*
inprocBuffer
)
Close
()
error
{
close
(
b
.
requests
)
close
(
b
.
responses
)
return
nil
}
rpc/ipc.go
View file @
df75dbfd
...
...
@@ -38,7 +38,7 @@ type ipcClient struct {
// NewIPCClient create a new IPC client that will connect on the given endpoint. Messages are JSON encoded and encoded.
// On Unix it assumes the endpoint is the full path to a unix socket, and Windows the endpoint is an identifier for a
// named pipe.
func
NewIPCClient
(
endpoint
string
)
(
*
ipc
Client
,
error
)
{
func
NewIPCClient
(
endpoint
string
)
(
Client
,
error
)
{
conn
,
err
:=
newIPCConnection
(
endpoint
)
if
err
!=
nil
{
return
nil
,
err
...
...
rpc/ipc_windows.go
View file @
df75dbfd
...
...
@@ -239,9 +239,6 @@ func Dial(address string) (*PipeConn, error) {
for
{
conn
,
err
:=
dial
(
address
,
nmpwait_wait_forever
)
if
err
==
nil
{
// Ugly hack working around some async connectivity issues
time
.
Sleep
(
100
*
time
.
Millisecond
)
return
conn
,
nil
}
if
isPipeNotReady
(
err
)
{
...
...
@@ -363,9 +360,6 @@ func Listen(address string) (*PipeListener, error) {
if
err
!=
nil
{
return
nil
,
err
}
// Ugly hack working around some async connectivity issues
time
.
Sleep
(
100
*
time
.
Millisecond
)
return
&
PipeListener
{
addr
:
PipeAddr
(
address
),
handle
:
handle
,
...
...
rpc/websocket.go
View file @
df75dbfd
...
...
@@ -109,7 +109,7 @@ type wsClient struct {
// NewWSClientj creates a new RPC client that communicates with a RPC server
// that is listening on the given endpoint using JSON encoding.
func
NewWSClient
(
endpoint
string
)
(
*
ws
Client
,
error
)
{
func
NewWSClient
(
endpoint
string
)
(
Client
,
error
)
{
return
&
wsClient
{
endpoint
:
endpoint
},
nil
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment