Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
a13bc9d7
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a13bc9d7
编写于
2月 05, 2016
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cmd, common, node, rpc: move HTTP RPC into node, drop singletone aspect
上级
ba7c1251
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
274 addition
and
215 deletion
+274
-215
cmd/geth/main.go
cmd/geth/main.go
+0
-5
cmd/gethrpctest/main.go
cmd/gethrpctest/main.go
+8
-29
cmd/utils/flags.go
cmd/utils/flags.go
+20
-28
common/defaults.go
common/defaults.go
+48
-0
common/path.go
common/path.go
+0
-22
node/api.go
node/api.go
+16
-30
node/config.go
node/config.go
+36
-1
node/node.go
node/node.go
+138
-44
rpc/http.go
rpc/http.go
+7
-54
rpc/utils.go
rpc/utils.go
+1
-2
未找到文件。
cmd/geth/main.go
浏览文件 @
a13bc9d7
...
...
@@ -503,11 +503,6 @@ func startNode(ctx *cli.Context, stack *node.Node) {
}
}
// Start auxiliary services if enabled
if
ctx
.
GlobalBool
(
utils
.
RPCEnabledFlag
.
Name
)
{
if
err
:=
utils
.
StartRPC
(
stack
,
ctx
);
err
!=
nil
{
utils
.
Fatalf
(
"Failed to start RPC: %v"
,
err
)
}
}
if
ctx
.
GlobalBool
(
utils
.
WSEnabledFlag
.
Name
)
{
if
err
:=
utils
.
StartWS
(
stack
,
ctx
);
err
!=
nil
{
utils
.
Fatalf
(
"Failed to start WS: %v"
,
err
)
...
...
cmd/gethrpctest/main.go
浏览文件 @
a13bc9d7
...
...
@@ -18,7 +18,6 @@
package
main
import
(
"errors"
"flag"
"io/ioutil"
"log"
...
...
@@ -26,10 +25,10 @@ import (
"os/signal"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/tests"
...
...
@@ -84,12 +83,6 @@ func main() {
}
log
.
Println
(
"Initial test suite passed..."
)
// Start the RPC interface and wait until terminated
if
err
:=
StartRPC
(
stack
);
err
!=
nil
{
log
.
Fatalf
(
"Failed to start RPC interface: %v"
,
err
)
}
log
.
Println
(
"RPC Interface started, accepting requests..."
)
quit
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
quit
,
os
.
Interrupt
)
<-
quit
...
...
@@ -99,7 +92,13 @@ func main() {
// keystore path and initial pre-state.
func
MakeSystemNode
(
keydir
string
,
privkey
string
,
test
*
tests
.
BlockTest
)
(
*
node
.
Node
,
error
)
{
// Create a networkless protocol stack
stack
,
err
:=
node
.
New
(
&
node
.
Config
{
IpcPath
:
node
.
DefaultIpcEndpoint
(),
NoDiscovery
:
true
})
stack
,
err
:=
node
.
New
(
&
node
.
Config
{
IpcPath
:
node
.
DefaultIpcEndpoint
(),
HttpHost
:
common
.
DefaultHttpHost
,
HttpPort
:
common
.
DefaultHttpPort
,
HttpModules
:
[]
string
{
"admin"
,
"db"
,
"eth"
,
"debug"
,
"miner"
,
"net"
,
"shh"
,
"txpool"
,
"personal"
,
"web3"
},
NoDiscovery
:
true
,
})
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -164,23 +163,3 @@ func RunTest(stack *node.Node, test *tests.BlockTest) error {
}
return
nil
}
// StartRPC initializes an RPC interface to the given protocol stack.
func
StartRPC
(
stack
*
node
.
Node
)
error
{
/*
web3 := NewPublicWeb3API(stack)
server.RegisterName("web3", web3)
net := NewPublicNetAPI(stack.Server(), ethereum.NetVersion())
server.RegisterName("net", net)
*/
for
_
,
api
:=
range
stack
.
APIs
()
{
if
adminApi
,
ok
:=
api
.
Service
.
(
*
node
.
PrivateAdminAPI
);
ok
{
_
,
err
:=
adminApi
.
StartRPC
(
"127.0.0.1"
,
8545
,
""
,
"admin,db,eth,debug,miner,net,shh,txpool,personal,web3"
)
return
err
}
}
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to start RPC-HTTP interface, could not find admin API"
)
return
errors
.
New
(
"Unable to start RPC-HTTP interface"
)
}
cmd/utils/flags.go
浏览文件 @
a13bc9d7
...
...
@@ -233,12 +233,12 @@ var (
RPCListenAddrFlag
=
cli
.
StringFlag
{
Name
:
"rpcaddr"
,
Usage
:
"HTTP-RPC server listening interface"
,
Value
:
"127.0.0.1"
,
Value
:
common
.
DefaultHttpHost
,
}
RPCPortFlag
=
cli
.
IntFlag
{
Name
:
"rpcport"
,
Usage
:
"HTTP-RPC server listening port"
,
Value
:
8545
,
Value
:
common
.
DefaultHttpPort
,
}
RPCCORSDomainFlag
=
cli
.
StringFlag
{
Name
:
"rpccorsdomain"
,
...
...
@@ -262,7 +262,7 @@ var (
IPCPathFlag
=
DirectoryFlag
{
Name
:
"ipcpath"
,
Usage
:
"Filename for IPC socket/pipe within the datadir (explicit paths escape it)"
,
Value
:
DirectoryString
{
common
.
DefaultIpcSocket
()
},
Value
:
DirectoryString
{
common
.
DefaultIpcSocket
},
}
WSEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"ws"
,
...
...
@@ -271,12 +271,12 @@ var (
WSListenAddrFlag
=
cli
.
StringFlag
{
Name
:
"wsaddr"
,
Usage
:
"WS-RPC server listening interface"
,
Value
:
"127.0.0.1"
,
Value
:
common
.
DefaultWsHost
,
}
WSPortFlag
=
cli
.
IntFlag
{
Name
:
"wsport"
,
Usage
:
"WS-RPC server listening port"
,
Value
:
8546
,
Value
:
common
.
DefaultWsPort
,
}
WSApiFlag
=
cli
.
StringFlag
{
Name
:
"wsapi"
,
...
...
@@ -284,7 +284,7 @@ var (
Value
:
rpc
.
DefaultHttpRpcApis
,
}
WSAllowedDomainsFlag
=
cli
.
StringFlag
{
Name
:
"ws
domain
s"
,
Name
:
"ws
cor
s"
,
Usage
:
"Domains from which to accept websockets requests"
,
Value
:
""
,
}
...
...
@@ -482,6 +482,15 @@ func MakeNAT(ctx *cli.Context) nat.Interface {
return
natif
}
// MakeHttpRpcHost creates the HTTP RPC listener interface string from the set
// command line flags, returning empty if the HTTP endpoint is disabled.
func
MakeHttpRpcHost
(
ctx
*
cli
.
Context
)
string
{
if
!
ctx
.
GlobalBool
(
RPCEnabledFlag
.
Name
)
{
return
""
}
return
ctx
.
GlobalString
(
RPCListenAddrFlag
.
Name
)
}
// MakeGenesisBlock loads up a genesis block from an input file specified in the
// command line, or returns the empty string if none set.
func
MakeGenesisBlock
(
ctx
*
cli
.
Context
)
string
{
...
...
@@ -591,7 +600,6 @@ func MakeSystemNode(name, version string, extra []byte, ctx *cli.Context) *node.
// Configure the node's service container
stackConf
:=
&
node
.
Config
{
DataDir
:
MustMakeDataDir
(
ctx
),
IpcPath
:
MakeIpcPath
(
ctx
),
PrivateKey
:
MakeNodeKey
(
ctx
),
Name
:
MakeNodeName
(
name
,
version
,
ctx
),
NoDiscovery
:
ctx
.
GlobalBool
(
NoDiscoverFlag
.
Name
),
...
...
@@ -600,6 +608,11 @@ func MakeSystemNode(name, version string, extra []byte, ctx *cli.Context) *node.
NAT
:
MakeNAT
(
ctx
),
MaxPeers
:
ctx
.
GlobalInt
(
MaxPeersFlag
.
Name
),
MaxPendingPeers
:
ctx
.
GlobalInt
(
MaxPendingPeersFlag
.
Name
),
IpcPath
:
MakeIpcPath
(
ctx
),
HttpHost
:
MakeHttpRpcHost
(
ctx
),
HttpPort
:
ctx
.
GlobalInt
(
RPCPortFlag
.
Name
),
HttpCors
:
ctx
.
GlobalString
(
RPCCORSDomainFlag
.
Name
),
HttpModules
:
strings
.
Split
(
ctx
.
GlobalString
(
RPCApiFlag
.
Name
),
","
),
}
// Configure the Ethereum service
accman
:=
MakeAccountManager
(
ctx
)
...
...
@@ -744,27 +757,6 @@ func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database
return
chain
,
chainDb
}
// StartRPC starts a HTTP JSON-RPC API server.
func
StartRPC
(
stack
*
node
.
Node
,
ctx
*
cli
.
Context
)
error
{
for
_
,
api
:=
range
stack
.
APIs
()
{
if
adminApi
,
ok
:=
api
.
Service
.
(
*
node
.
PrivateAdminAPI
);
ok
{
address
:=
ctx
.
GlobalString
(
RPCListenAddrFlag
.
Name
)
port
:=
ctx
.
GlobalInt
(
RPCPortFlag
.
Name
)
cors
:=
ctx
.
GlobalString
(
RPCCORSDomainFlag
.
Name
)
apiStr
:=
""
if
ctx
.
GlobalIsSet
(
RPCApiFlag
.
Name
)
{
apiStr
=
ctx
.
GlobalString
(
RPCApiFlag
.
Name
)
}
_
,
err
:=
adminApi
.
StartRPC
(
address
,
port
,
cors
,
apiStr
)
return
err
}
}
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to start RPC-HTTP interface, could not find admin API"
)
return
errors
.
New
(
"Unable to start RPC-HTTP interface"
)
}
// StartWS starts a websocket JSON-RPC API server.
func
StartWS
(
stack
*
node
.
Node
,
ctx
*
cli
.
Context
)
error
{
for
_
,
api
:=
range
stack
.
APIs
()
{
...
...
common/defaults.go
0 → 100644
浏览文件 @
a13bc9d7
// 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
common
import
(
"path/filepath"
"runtime"
)
const
(
DefaultIpcSocket
=
"geth.ipc"
// Default (relative) name of the IPC RPC socket
DefaultHttpHost
=
"localhost"
// Default host interface for the HTTP RPC server
DefaultHttpPort
=
8545
// Default TCP port for the HTTP RPC server
DefaultWsHost
=
"localhost"
// Default host interface for the websocket RPC server
DefaultWsPort
=
8546
// Default TCP port for the websocket RPC server
)
// DefaultDataDir is the default data directory to use for the databases and other
// persistence requirements.
func
DefaultDataDir
()
string
{
// Try to place the data folder in the user's home dir
home
:=
HomeDir
()
if
home
!=
""
{
if
runtime
.
GOOS
==
"darwin"
{
return
filepath
.
Join
(
home
,
"Library"
,
"Ethereum"
)
}
else
if
runtime
.
GOOS
==
"windows"
{
return
filepath
.
Join
(
home
,
"AppData"
,
"Roaming"
,
"Ethereum"
)
}
else
{
return
filepath
.
Join
(
home
,
".ethereum"
)
}
}
// As we cannot guess a stable location, return empty and handle later
return
""
}
common/path.go
浏览文件 @
a13bc9d7
...
...
@@ -72,25 +72,3 @@ func HomeDir() string {
}
return
""
}
func
DefaultDataDir
()
string
{
// Try to place the data folder in the user's home dir
home
:=
HomeDir
()
if
home
!=
""
{
if
runtime
.
GOOS
==
"darwin"
{
return
filepath
.
Join
(
home
,
"Library"
,
"Ethereum"
)
}
else
if
runtime
.
GOOS
==
"windows"
{
return
filepath
.
Join
(
home
,
"AppData"
,
"Roaming"
,
"Ethereum"
)
}
else
{
return
filepath
.
Join
(
home
,
".ethereum"
)
}
}
// As we cannot guess a stable location, return empty and handle later
return
""
}
// DefaultIpcSocket returns the relative name of the default IPC socket. The path
// resolution is done by a node with other contextual infos.
func
DefaultIpcSocket
()
string
{
return
"geth.ipc"
}
node/api.go
浏览文件 @
a13bc9d7
...
...
@@ -27,7 +27,6 @@ import (
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/rpc"
"github.com/rcrowley/go-metrics"
"gopkg.in/fatih/set.v0"
)
...
...
@@ -61,42 +60,29 @@ func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
}
// StartRPC starts the HTTP RPC API server.
func
(
api
*
PrivateAdminAPI
)
StartRPC
(
address
string
,
port
int
,
cors
string
,
apis
string
)
(
bool
,
error
)
{
var
offeredAPIs
[]
rpc
.
API
if
len
(
apis
)
>
0
{
namespaces
:=
set
.
New
()
for
_
,
a
:=
range
strings
.
Split
(
apis
,
","
)
{
namespaces
.
Add
(
strings
.
TrimSpace
(
a
))
}
for
_
,
api
:=
range
api
.
node
.
APIs
()
{
if
namespaces
.
Has
(
api
.
Namespace
)
{
offeredAPIs
=
append
(
offeredAPIs
,
api
)
}
}
}
else
{
// use by default all public API's
for
_
,
api
:=
range
api
.
node
.
APIs
()
{
if
api
.
Public
{
offeredAPIs
=
append
(
offeredAPIs
,
api
)
}
}
}
func
(
api
*
PrivateAdminAPI
)
StartRPC
(
host
string
,
port
int
,
cors
string
,
apis
string
)
(
bool
,
error
)
{
api
.
node
.
lock
.
Lock
()
defer
api
.
node
.
lock
.
Unlock
()
if
a
ddress
==
""
{
address
=
"127.0.0.1"
if
a
pi
.
node
.
httpHandler
!=
nil
{
return
false
,
fmt
.
Errorf
(
"HTTP RPC already running on %s"
,
api
.
node
.
httpEndpoint
)
}
if
port
==
0
{
port
=
8545
if
err
:=
api
.
node
.
startHTTP
(
fmt
.
Sprintf
(
"%s:%d"
,
host
,
port
),
api
.
node
.
rpcAPIs
,
strings
.
Split
(
apis
,
","
),
cors
);
err
!=
nil
{
return
false
,
err
}
corsDomains
:=
strings
.
Split
(
cors
,
" "
)
err
:=
rpc
.
StartHTTP
(
address
,
port
,
corsDomains
,
offeredAPIs
)
return
err
==
nil
,
err
return
true
,
nil
}
// StopRPC terminates an already running HTTP RPC API endpoint.
func
(
api
*
PrivateAdminAPI
)
StopRPC
()
(
bool
,
error
)
{
err
:=
rpc
.
StopHTTP
()
return
err
==
nil
,
err
api
.
node
.
lock
.
Lock
()
defer
api
.
node
.
lock
.
Unlock
()
if
api
.
node
.
httpHandler
==
nil
{
return
false
,
fmt
.
Errorf
(
"HTTP RPC not running"
)
}
api
.
node
.
stopHTTP
()
return
true
,
nil
}
// StartWS starts the websocket RPC API server.
...
...
node/config.go
浏览文件 @
a13bc9d7
...
...
@@ -19,6 +19,7 @@ package node
import
(
"crypto/ecdsa"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
...
...
@@ -97,6 +98,25 @@ type Config struct {
// handshake phase, counted separately for inbound and outbound connections.
// Zero defaults to preset values.
MaxPendingPeers
int
// HttpHost is the host interface on which to start the HTTP RPC server. If this
// field is empty, no HTTP API endpoint will be started.
HttpHost
string
// HttpPort is the TCP port number on which to start the HTTP RPC server. The
// default zero value is/ valid and will pick a port number randomly (useful
// for ephemeral nodes).
HttpPort
int
// HttpCors is the Cross-Origin Resource Sharing header to send to requesting
// clients. Please be aware that CORS is a browser enforced security, it's fully
// useless for custom HTTP clients.
HttpCors
string
// HttpModules is a list of API modules to expose via the HTTP RPC interface.
// If the module list is empty, all RPC API endpoints designated public will be
// exposed.
HttpModules
[]
string
}
// IpcEndpoint resolves an IPC endpoint based on a configured value, taking into
...
...
@@ -126,10 +146,25 @@ func (c *Config) IpcEndpoint() string {
// DefaultIpcEndpoint returns the IPC path used by default.
func
DefaultIpcEndpoint
()
string
{
config
:=
&
Config
{
DataDir
:
common
.
DefaultDataDir
(),
IpcPath
:
common
.
DefaultIpcSocket
()
}
config
:=
&
Config
{
DataDir
:
common
.
DefaultDataDir
(),
IpcPath
:
common
.
DefaultIpcSocket
}
return
config
.
IpcEndpoint
()
}
// HttpEndpoint resolves an HTTP endpoint based on the configured host interface
// and port parameters.
func
(
c
*
Config
)
HttpEndpoint
()
string
{
if
c
.
HttpHost
==
""
{
return
""
}
return
fmt
.
Sprintf
(
"%s:%d"
,
c
.
HttpHost
,
c
.
HttpPort
)
}
// DefaultHttpEndpoint returns the HTTP endpoint used by default.
func
DefaultHttpEndpoint
()
string
{
config
:=
&
Config
{
HttpHost
:
common
.
DefaultHttpHost
,
HttpPort
:
common
.
DefaultHttpPort
}
return
config
.
HttpEndpoint
()
}
// NodeKey retrieves the currently configured private key of the node, checking
// first any manually set key, falling back to the one found in the configured
// data folder. If no key can be found, a new one is generated.
...
...
node/node.go
浏览文件 @
a13bc9d7
...
...
@@ -55,10 +55,17 @@ 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
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
httpEndpoint
string
// HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
httpWhitelist
[]
string
// HTTP RPC modules to allow through this endpoint
httpCors
string
// HTTP RPC Cross-Origin Resource Sharing header
httpListener
net
.
Listener
// HTTP RPC listener socket to server API requests
httpHandler
*
rpc
.
Server
// HTTP RPC request handler to process the API requests
stop
chan
struct
{}
// Channel to wait for termination notifications
lock
sync
.
RWMutex
}
...
...
@@ -93,9 +100,12 @@ func New(conf *Config) (*Node, error) {
MaxPeers
:
conf
.
MaxPeers
,
MaxPendingPeers
:
conf
.
MaxPendingPeers
,
},
serviceFuncs
:
[]
ServiceConstructor
{},
ipcEndpoint
:
conf
.
IpcEndpoint
(),
eventmux
:
new
(
event
.
TypeMux
),
serviceFuncs
:
[]
ServiceConstructor
{},
ipcEndpoint
:
conf
.
IpcEndpoint
(),
httpEndpoint
:
conf
.
HttpEndpoint
(),
httpWhitelist
:
conf
.
HttpModules
,
httpCors
:
conf
.
HttpCors
,
eventmux
:
new
(
event
.
TypeMux
),
},
nil
}
...
...
@@ -188,58 +198,146 @@ func (n *Node) Start() error {
return
nil
}
// startRPC initializes and starts the IPC RPC endpoints.
// startRPC is a helper method to start all the various RPC endpoint during node
// startup. It's not meant to be called at any time afterwards as it makes certain
// assumptions about the state of the node.
func
(
n
*
Node
)
startRPC
(
services
map
[
reflect
.
Type
]
Service
)
error
{
// Gather a
nd register all the APIs exposed by the services
// Gather a
ll the possible APIs to surface
apis
:=
n
.
apis
()
for
_
,
service
:=
range
services
{
apis
=
append
(
apis
,
service
.
APIs
()
...
)
}
ipcHandler
:=
rpc
.
NewServer
()
// Start the various API endpoints, terminating all in case of errors
if
err
:=
n
.
startIPC
(
apis
);
err
!=
nil
{
return
err
}
if
err
:=
n
.
startHTTP
(
n
.
httpEndpoint
,
apis
,
n
.
httpWhitelist
,
n
.
httpCors
);
err
!=
nil
{
n
.
stopIPC
()
return
err
}
// All API endpoints started successfully
n
.
rpcAPIs
=
apis
return
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
if
n
.
ipcEndpoint
==
""
{
return
nil
}
// Register all the APIs exposed by the services
handler
:=
rpc
.
NewServer
()
for
_
,
api
:=
range
apis
{
if
err
:=
ipcH
andler
.
RegisterName
(
api
.
Namespace
,
api
.
Service
);
err
!=
nil
{
if
err
:=
h
andler
.
RegisterName
(
api
.
Namespace
,
api
.
Service
);
err
!=
nil
{
return
err
}
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"
Register %T under namespace
'%s'"
,
api
.
Service
,
api
.
Namespace
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"
IPC registered %T under
'%s'"
,
api
.
Service
,
api
.
Namespace
)
}
// All APIs registered, start the IPC
and HTTP listeners
// All APIs registered, start the IPC
listener
var
(
ipcL
istener
net
.
Listener
err
error
l
istener
net
.
Listener
err
error
)
if
n
.
ipcEndpoint
!=
""
{
if
ipcListener
,
err
=
rpc
.
CreateIPCListener
(
n
.
ipcEndpoint
);
err
!=
nil
{
return
err
}
go
func
()
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"IPC endpoint opened: %s"
,
n
.
ipcEndpoint
)
defer
glog
.
V
(
logger
.
Info
)
.
Infof
(
"IPC endpoint closed: %s"
,
n
.
ipcEndpoint
)
for
{
conn
,
err
:=
ipcListener
.
Accept
()
if
err
!=
nil
{
// Terminate if the listener was closed
n
.
lock
.
RLock
()
closed
:=
n
.
ipcListener
==
nil
n
.
lock
.
RUnlock
()
if
closed
{
return
}
// Not closed, just some error; report and continue
glog
.
V
(
logger
.
Error
)
.
Infof
(
"IPC accept failed: %v"
,
err
)
continue
if
listener
,
err
=
rpc
.
CreateIPCListener
(
n
.
ipcEndpoint
);
err
!=
nil
{
return
err
}
go
func
()
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"IPC endpoint opened: %s"
,
n
.
ipcEndpoint
)
for
{
conn
,
err
:=
listener
.
Accept
()
if
err
!=
nil
{
// Terminate if the listener was closed
n
.
lock
.
RLock
()
closed
:=
n
.
ipcListener
==
nil
n
.
lock
.
RUnlock
()
if
closed
{
return
}
go
ipcHandler
.
ServeCodec
(
rpc
.
NewJSONCodec
(
conn
))
// Not closed, just some error; report and continue
glog
.
V
(
logger
.
Error
)
.
Infof
(
"IPC accept failed: %v"
,
err
)
continue
}
go
handler
.
ServeCodec
(
rpc
.
NewJSONCodec
(
conn
))
}
}()
// All listeners booted successfully
n
.
ipcListener
=
listener
n
.
ipcHandler
=
handler
return
nil
}
// stopIPC terminates the IPC RPC endpoint.
func
(
n
*
Node
)
stopIPC
()
{
if
n
.
ipcListener
!=
nil
{
n
.
ipcListener
.
Close
()
n
.
ipcListener
=
nil
glog
.
V
(
logger
.
Info
)
.
Infof
(
"IPC endpoint closed: %s"
,
n
.
ipcEndpoint
)
}
if
n
.
ipcHandler
!=
nil
{
n
.
ipcHandler
.
Stop
()
n
.
ipcHandler
=
nil
}
}
// startHTTP initializes and starts the HTTP RPC endpoint.
func
(
n
*
Node
)
startHTTP
(
endpoint
string
,
apis
[]
rpc
.
API
,
modules
[]
string
,
cors
string
)
error
{
// Short circuit if the IPC endpoint isn't being exposed
if
endpoint
==
""
{
return
nil
}
// Generate the whitelist based on the allowed modules
whitelist
:=
make
(
map
[
string
]
bool
)
for
_
,
module
:=
range
modules
{
whitelist
[
module
]
=
true
}
// Register all the APIs exposed by the services
handler
:=
rpc
.
NewServer
()
for
_
,
api
:=
range
apis
{
if
whitelist
[
api
.
Namespace
]
||
(
len
(
whitelist
)
==
0
&&
api
.
Public
)
{
if
err
:=
handler
.
RegisterName
(
api
.
Namespace
,
api
.
Service
);
err
!=
nil
{
return
err
}
}()
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"HTTP registered %T under '%s'"
,
api
.
Service
,
api
.
Namespace
)
}
}
// All APIs registered, start the HTTP listener
var
(
listener
net
.
Listener
err
error
)
if
listener
,
err
=
net
.
Listen
(
"tcp"
,
endpoint
);
err
!=
nil
{
return
err
}
go
rpc
.
NewHTTPServer
(
cors
,
handler
)
.
Serve
(
listener
)
glog
.
V
(
logger
.
Info
)
.
Infof
(
"HTTP endpoint opened: http://%s"
,
endpoint
)
// All listeners booted successfully
n
.
ipcListener
=
ipcListener
n
.
ipcHandler
=
ipcHandler
n
.
httpEndpoint
=
endpoint
n
.
httpListener
=
listener
n
.
httpHandler
=
handler
n
.
httpCors
=
cors
return
nil
}
// stopHTTP terminates the HTTP RPC endpoint.
func
(
n
*
Node
)
stopHTTP
()
{
if
n
.
httpListener
!=
nil
{
n
.
httpListener
.
Close
()
n
.
httpListener
=
nil
glog
.
V
(
logger
.
Info
)
.
Infof
(
"HTTP endpoint closed: http://%s"
,
n
.
httpEndpoint
)
}
if
n
.
httpHandler
!=
nil
{
n
.
httpHandler
.
Stop
()
n
.
httpHandler
=
nil
}
}
// Stop terminates a running node along with all it's services. In the node was
// not started, an error is returned.
func
(
n
*
Node
)
Stop
()
error
{
...
...
@@ -251,14 +349,10 @@ func (n *Node) Stop() error {
return
ErrNodeStopped
}
// Otherwise terminate the API, all services and the P2P server too
if
n
.
ipcListener
!=
nil
{
n
.
ipcListener
.
Close
()
n
.
ipcListener
=
nil
}
if
n
.
ipcHandler
!=
nil
{
n
.
ipcHandler
.
Stop
()
n
.
ipcHandler
=
nil
}
n
.
stopIPC
()
n
.
stopHTTP
()
n
.
rpcAPIs
=
nil
failure
:=
&
StopError
{
Services
:
make
(
map
[
reflect
.
Type
]
error
),
}
...
...
rpc/http.go
浏览文件 @
a13bc9d7
...
...
@@ -20,7 +20,6 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
...
...
@@ -29,7 +28,6 @@ import (
"net/url"
"strconv"
"strings"
"sync"
"time"
"github.com/ethereum/go-ethereum/logger"
...
...
@@ -41,12 +39,6 @@ const (
httpReadDeadLine
=
60
*
time
.
Second
// wait max httpReadDeadeline for next request
)
var
(
httpServerMu
sync
.
Mutex
// prevent concurrent access to the httpListener and httpServer
httpListener
net
.
Listener
// listener for the http server
httpRPCServer
*
Server
// the node can only start 1 HTTP RPC server instance
)
// httpMessageStream is the glue between a HTTP connection which is message based
// and the RPC codecs that expect json requests to be read from a stream. It will
// parse HTTP messages and offer the bodies of these requests as a stream through
...
...
@@ -249,53 +241,14 @@ func (h *httpConnHijacker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
go
h
.
rpcServer
.
ServeCodec
(
codec
)
}
// StartHTTP will start the JSONRPC HTTP RPC interface when its not yet running.
func
StartHTTP
(
address
string
,
port
int
,
corsdomains
[]
string
,
apis
[]
API
)
error
{
httpServerMu
.
Lock
()
defer
httpServerMu
.
Unlock
()
if
httpRPCServer
!=
nil
{
return
fmt
.
Errorf
(
"HTTP RPC interface already started on %s"
,
httpListener
.
Addr
())
}
rpcServer
:=
NewServer
()
for
_
,
api
:=
range
apis
{
if
err
:=
rpcServer
.
RegisterName
(
api
.
Namespace
,
api
.
Service
);
err
!=
nil
{
return
err
}
}
listener
,
err
:=
net
.
Listen
(
"tcp"
,
fmt
.
Sprintf
(
"%s:%d"
,
address
,
port
))
if
err
!=
nil
{
return
err
// NewHTTPServer creates a new HTTP RPC server around an API provider.
func
NewHTTPServer
(
cors
string
,
handler
*
Server
)
*
http
.
Server
{
return
&
http
.
Server
{
Handler
:
&
httpConnHijacker
{
corsdomains
:
strings
.
Split
(
cors
,
","
),
rpcServer
:
handler
,
},
}
httpServer
:=
http
.
Server
{
Handler
:
&
httpConnHijacker
{
corsdomains
,
rpcServer
}}
go
httpServer
.
Serve
(
listener
)
httpListener
=
listener
httpRPCServer
=
rpcServer
return
nil
}
// StopHTTP will stop the running HTTP interface. If it is not running an error will be returned.
func
StopHTTP
()
error
{
httpServerMu
.
Lock
()
defer
httpServerMu
.
Unlock
()
if
httpRPCServer
==
nil
{
return
errors
.
New
(
"HTTP RPC interface not started"
)
}
httpListener
.
Close
()
httpRPCServer
.
Stop
()
httpRPCServer
=
nil
httpListener
=
nil
return
nil
}
// httpClient connects to a geth RPC server over HTTP.
...
...
rpc/utils.go
浏览文件 @
a13bc9d7
...
...
@@ -20,13 +20,12 @@ import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"math/big"
"reflect"
"unicode"
"unicode/utf8"
"fmt"
"golang.org/x/net/context"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录