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
f2025637
Commit
f2025637
authored
Jun 18, 2015
by
Bas van Kervel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added attach over ipc command
parent
36a6b16a
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
238 additions
and
35 deletions
+238
-35
js.go
cmd/geth/js.go
+64
-25
main.go
cmd/geth/main.go
+46
-0
comms.go
rpc/comms/comms.go
+25
-2
http.go
rpc/comms/http.go
+1
-2
inproc.go
rpc/comms/inproc.go
+18
-0
ipc.go
rpc/comms/ipc.go
+64
-4
ipc_unix.go
rpc/comms/ipc_unix.go
+11
-1
ipc_windows.go
rpc/comms/ipc_windows.go
+9
-1
No files found.
cmd/geth/js.go
View file @
f2025637
...
@@ -26,6 +26,8 @@ import (
...
@@ -26,6 +26,8 @@ import (
"path/filepath"
"path/filepath"
"strings"
"strings"
"sort"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/docserver"
...
@@ -36,7 +38,6 @@ import (
...
@@ -36,7 +38,6 @@ import (
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/xeth"
"github.com/ethereum/go-ethereum/xeth"
"github.com/peterh/liner"
"github.com/peterh/liner"
"github.com/robertkrimen/otto"
"github.com/robertkrimen/otto"
...
@@ -137,6 +138,40 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
...
@@ -137,6 +138,40 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
return
begin
,
completionWords
,
end
return
begin
,
completionWords
,
end
}
}
func
newLightweightJSRE
(
libPath
string
,
client
comms
.
EthereumClient
,
interactive
bool
,
f
xeth
.
Frontend
)
*
jsre
{
js
:=
&
jsre
{
ps1
:
"> "
}
js
.
wait
=
make
(
chan
*
big
.
Int
)
js
.
client
=
client
if
f
==
nil
{
f
=
js
}
// update state in separare forever blocks
js
.
re
=
re
.
New
(
libPath
)
if
err
:=
js
.
apiBindings
(
f
);
err
!=
nil
{
utils
.
Fatalf
(
"Unable to initialize console - %v"
,
err
)
}
if
!
liner
.
TerminalSupported
()
||
!
interactive
{
js
.
prompter
=
dumbterm
{
bufio
.
NewReader
(
os
.
Stdin
)}
}
else
{
lr
:=
liner
.
NewLiner
()
//js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
lr
.
SetCtrlCAborts
(
true
)
js
.
loadAutoCompletion
()
lr
.
SetWordCompleter
(
apiWordCompleter
)
lr
.
SetTabCompletionStyle
(
liner
.
TabPrints
)
js
.
prompter
=
lr
js
.
atexit
=
func
()
{
js
.
withHistory
(
func
(
hist
*
os
.
File
)
{
hist
.
Truncate
(
0
);
lr
.
WriteHistory
(
hist
)
})
lr
.
Close
()
close
(
js
.
wait
)
}
}
return
js
}
func
newJSRE
(
ethereum
*
eth
.
Ethereum
,
libPath
,
corsDomain
string
,
client
comms
.
EthereumClient
,
interactive
bool
,
f
xeth
.
Frontend
)
*
jsre
{
func
newJSRE
(
ethereum
*
eth
.
Ethereum
,
libPath
,
corsDomain
string
,
client
comms
.
EthereumClient
,
interactive
bool
,
f
xeth
.
Frontend
)
*
jsre
{
js
:=
&
jsre
{
ethereum
:
ethereum
,
ps1
:
"> "
}
js
:=
&
jsre
{
ethereum
:
ethereum
,
ps1
:
"> "
}
// set default cors domain used by startRpc from CLI flag
// set default cors domain used by startRpc from CLI flag
...
@@ -177,7 +212,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et
...
@@ -177,7 +212,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et
}
}
func
(
self
*
jsre
)
loadAutoCompletion
()
{
func
(
self
*
jsre
)
loadAutoCompletion
()
{
if
modules
,
err
:=
self
.
suportedApis
();
err
==
nil
{
if
modules
,
err
:=
self
.
sup
p
ortedApis
();
err
==
nil
{
loadedModulesMethods
=
make
(
map
[
string
][]
string
)
loadedModulesMethods
=
make
(
map
[
string
][]
string
)
for
module
,
_
:=
range
modules
{
for
module
,
_
:=
range
modules
{
loadedModulesMethods
[
module
]
=
api
.
AutoCompletion
[
module
]
loadedModulesMethods
[
module
]
=
api
.
AutoCompletion
[
module
]
...
@@ -185,34 +220,33 @@ func (self *jsre) loadAutoCompletion() {
...
@@ -185,34 +220,33 @@ func (self *jsre) loadAutoCompletion() {
}
}
}
}
func
(
self
*
jsre
)
suportedApis
()
(
map
[
string
]
string
,
error
)
{
// show summary of current geth instance
req
:=
shared
.
Request
{
func
(
self
*
jsre
)
welcome
()
{
Id
:
1
,
self
.
re
.
Eval
(
`console.log('instance: ' + web3.version.client);`
)
Jsonrpc
:
"2.0"
,
self
.
re
.
Eval
(
`console.log(' datadir: ' + admin.datadir);`
)
Method
:
"modules"
,
self
.
re
.
Eval
(
`console.log("coinbase: " + eth.coinbase);`
)
}
self
.
re
.
Eval
(
`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`
)
self
.
re
.
Eval
(
`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`
)
err
:=
self
.
client
.
Send
(
&
req
)
if
modules
,
err
:=
self
.
supportedApis
();
err
==
nil
{
if
err
!=
nil
{
loadedModules
:=
make
([]
string
,
0
)
return
nil
,
err
for
api
,
version
:=
range
modules
{
}
loadedModules
=
append
(
loadedModules
,
fmt
.
Sprintf
(
"%s:%s"
,
api
,
version
))
res
,
err
:=
self
.
client
.
Recv
()
if
err
!=
nil
{
return
nil
,
err
}
}
sort
.
Strings
(
loadedModules
)
if
sucRes
,
ok
:=
res
.
(
map
[
string
]
string
);
ok
{
self
.
re
.
Eval
(
fmt
.
Sprintf
(
"var modules = '%s';"
,
strings
.
Join
(
loadedModules
,
" "
)))
if
err
==
nil
{
self
.
re
.
Eval
(
`console.log(" modules: " + modules);`
)
return
sucRes
,
nil
}
}
}
}
return
nil
,
fmt
.
Errorf
(
"Unable to determine supported API's"
)
func
(
self
*
jsre
)
supportedApis
()
(
map
[
string
]
string
,
error
)
{
return
self
.
client
.
SupportedModules
()
}
}
func
(
js
*
jsre
)
apiBindings
(
f
xeth
.
Frontend
)
error
{
func
(
js
*
jsre
)
apiBindings
(
f
xeth
.
Frontend
)
error
{
apis
,
err
:=
js
.
suportedApis
()
apis
,
err
:=
js
.
sup
p
ortedApis
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -366,7 +400,12 @@ func (self *jsre) interactive() {
...
@@ -366,7 +400,12 @@ func (self *jsre) interactive() {
}
}
func
(
self
*
jsre
)
withHistory
(
op
func
(
*
os
.
File
))
{
func
(
self
*
jsre
)
withHistory
(
op
func
(
*
os
.
File
))
{
hist
,
err
:=
os
.
OpenFile
(
filepath
.
Join
(
self
.
ethereum
.
DataDir
,
"history"
),
os
.
O_RDWR
|
os
.
O_CREATE
,
os
.
ModePerm
)
datadir
:=
common
.
DefaultDataDir
()
if
self
.
ethereum
!=
nil
{
datadir
=
self
.
ethereum
.
DataDir
}
hist
,
err
:=
os
.
OpenFile
(
filepath
.
Join
(
datadir
,
"history"
),
os
.
O_RDWR
|
os
.
O_CREATE
,
os
.
ModePerm
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
"unable to open history file: %v
\n
"
,
err
)
fmt
.
Printf
(
"unable to open history file: %v
\n
"
,
err
)
return
return
...
...
cmd/geth/main.go
View file @
f2025637
...
@@ -204,6 +204,16 @@ nodes.
...
@@ -204,6 +204,16 @@ nodes.
The Geth console is an interactive shell for the JavaScript runtime environment
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
which exposes a node admin interface as well as the Ðapp JavaScript API.
See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console
See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console
`
},
{
Action
:
attach
,
Name
:
"attach"
,
Usage
:
`Geth Console: interactive JavaScript environment`
,
Description
:
`
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
This command allows to open a console on a running geth node.
`
,
`
,
},
},
{
{
...
@@ -297,6 +307,40 @@ func run(ctx *cli.Context) {
...
@@ -297,6 +307,40 @@ func run(ctx *cli.Context) {
ethereum
.
WaitForShutdown
()
ethereum
.
WaitForShutdown
()
}
}
func
attach
(
ctx
*
cli
.
Context
)
{
// Wrap the standard output with a colorified stream (windows)
if
isatty
.
IsTerminal
(
os
.
Stdout
.
Fd
())
{
if
pr
,
pw
,
err
:=
os
.
Pipe
();
err
==
nil
{
go
io
.
Copy
(
colorable
.
NewColorableStdout
(),
pr
)
os
.
Stdout
=
pw
}
}
var
client
comms
.
EthereumClient
var
err
error
if
ctx
.
Args
()
.
Present
()
{
client
,
err
=
comms
.
ClientFromEndpoint
(
ctx
.
Args
()
.
First
(),
codec
.
JSON
)
}
else
{
cfg
:=
comms
.
IpcConfig
{
Endpoint
:
ctx
.
GlobalString
(
utils
.
IPCPathFlag
.
Name
),
}
client
,
err
=
comms
.
NewIpcClient
(
cfg
,
codec
.
JSON
)
}
if
err
!=
nil
{
utils
.
Fatalf
(
"Unable to attach to geth node - %v"
,
err
)
}
repl
:=
newLightweightJSRE
(
ctx
.
String
(
utils
.
JSpathFlag
.
Name
),
client
,
true
,
nil
)
repl
.
welcome
()
repl
.
interactive
()
}
func
console
(
ctx
*
cli
.
Context
)
{
func
console
(
ctx
*
cli
.
Context
)
{
// Wrap the standard output with a colorified stream (windows)
// Wrap the standard output with a colorified stream (windows)
if
isatty
.
IsTerminal
(
os
.
Stdout
.
Fd
())
{
if
isatty
.
IsTerminal
(
os
.
Stdout
.
Fd
())
{
...
@@ -323,6 +367,8 @@ func console(ctx *cli.Context) {
...
@@ -323,6 +367,8 @@ func console(ctx *cli.Context) {
true
,
true
,
nil
,
nil
,
)
)
repl
.
welcome
()
repl
.
interactive
()
repl
.
interactive
()
ethereum
.
Stop
()
ethereum
.
Stop
()
...
...
rpc/comms/comms.go
View file @
f2025637
...
@@ -4,12 +4,14 @@ import (
...
@@ -4,12 +4,14 @@ import (
"io"
"io"
"net"
"net"
"fmt"
"strings"
"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/rpc/api"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/shared"
"strings"
)
)
const
(
const
(
...
@@ -36,6 +38,8 @@ type EthereumClient interface {
...
@@ -36,6 +38,8 @@ type EthereumClient interface {
Send
(
interface
{})
error
Send
(
interface
{})
error
// Receive response
// Receive response
Recv
()
(
interface
{},
error
)
Recv
()
(
interface
{},
error
)
// List with modules this client supports
SupportedModules
()
(
map
[
string
]
string
,
error
)
}
}
func
handle
(
conn
net
.
Conn
,
api
api
.
EthereumApi
,
c
codec
.
Codec
)
{
func
handle
(
conn
net
.
Conn
,
api
api
.
EthereumApi
,
c
codec
.
Codec
)
{
...
@@ -64,3 +68,22 @@ func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) {
...
@@ -64,3 +68,22 @@ func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) {
}
}
}
}
}
}
// Endpoint must be in the form of:
// ${protocol}:${path}
// e.g. ipc:/tmp/geth.ipc
// rpc:localhost:8545
func
ClientFromEndpoint
(
endpoint
string
,
c
codec
.
Codec
)
(
EthereumClient
,
error
)
{
if
strings
.
HasPrefix
(
endpoint
,
"ipc:"
)
{
cfg
:=
IpcConfig
{
Endpoint
:
endpoint
[
4
:
],
}
return
NewIpcClient
(
cfg
,
codec
.
JSON
)
}
if
strings
.
HasPrefix
(
endpoint
,
"rpc:"
)
{
}
return
nil
,
fmt
.
Errorf
(
"Invalid endpoint"
)
}
rpc/comms/http.go
View file @
f2025637
...
@@ -64,7 +64,6 @@ func StopHttp() {
...
@@ -64,7 +64,6 @@ func StopHttp() {
}
}
}
}
type
httpClient
struct
{
type
httpClient
struct
{
codec
codec
.
ApiCoder
codec
codec
.
ApiCoder
}
}
...
...
rpc/comms/inproc.go
View file @
f2025637
...
@@ -51,3 +51,21 @@ func (self *InProcClient) Send(req interface{}) error {
...
@@ -51,3 +51,21 @@ func (self *InProcClient) Send(req interface{}) error {
func
(
self
*
InProcClient
)
Recv
()
(
interface
{},
error
)
{
func
(
self
*
InProcClient
)
Recv
()
(
interface
{},
error
)
{
return
self
.
lastRes
,
self
.
lastErr
return
self
.
lastRes
,
self
.
lastErr
}
}
func
(
self
*
InProcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
req
:=
shared
.
Request
{
Id
:
1
,
Jsonrpc
:
"2.0"
,
Method
:
"modules"
,
}
if
res
,
err
:=
self
.
api
.
Execute
(
&
req
);
err
==
nil
{
if
result
,
ok
:=
res
.
(
map
[
string
]
string
);
ok
{
return
result
,
nil
}
}
else
{
return
nil
,
err
}
return
nil
,
fmt
.
Errorf
(
"Invalid response"
)
}
rpc/comms/ipc.go
View file @
f2025637
package
comms
package
comms
import
(
import
(
"fmt"
"net"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
"encoding/json"
)
)
type
IpcConfig
struct
{
type
IpcConfig
struct
{
...
@@ -10,19 +15,74 @@ type IpcConfig struct {
...
@@ -10,19 +15,74 @@ type IpcConfig struct {
}
}
type
ipcClient
struct
{
type
ipcClient
struct
{
codec
codec
.
ApiCoder
endpoint
string
codec
codec
.
Codec
coder
codec
.
ApiCoder
}
}
func
(
self
*
ipcClient
)
Close
()
{
func
(
self
*
ipcClient
)
Close
()
{
self
.
code
c
.
Close
()
self
.
code
r
.
Close
()
}
}
func
(
self
*
ipcClient
)
Send
(
req
interface
{})
error
{
func
(
self
*
ipcClient
)
Send
(
req
interface
{})
error
{
return
self
.
codec
.
WriteResponse
(
req
)
var
err
error
if
r
,
ok
:=
req
.
(
*
shared
.
Request
);
ok
{
if
err
=
self
.
coder
.
WriteResponse
(
r
);
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
net
.
OpError
);
ok
{
// connection lost, retry once
if
err
=
self
.
reconnect
();
err
==
nil
{
err
=
self
.
coder
.
WriteResponse
(
r
)
}
}
}
return
err
}
return
fmt
.
Errorf
(
"Invalid request (%T)"
,
req
)
}
}
func
(
self
*
ipcClient
)
Recv
()
(
interface
{},
error
)
{
func
(
self
*
ipcClient
)
Recv
()
(
interface
{},
error
)
{
return
self
.
codec
.
ReadResponse
()
res
,
err
:=
self
.
coder
.
ReadResponse
()
if
err
!=
nil
{
return
nil
,
err
}
if
r
,
ok
:=
res
.
(
shared
.
SuccessResponse
);
ok
{
return
r
.
Result
,
nil
}
if
r
,
ok
:=
res
.
(
shared
.
ErrorResponse
);
ok
{
return
r
.
Error
,
nil
}
return
res
,
err
}
func
(
self
*
ipcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
req
:=
shared
.
Request
{
Id
:
1
,
Jsonrpc
:
"2.0"
,
Method
:
"modules"
,
}
if
err
:=
self
.
coder
.
WriteResponse
(
req
);
err
!=
nil
{
return
nil
,
err
}
res
,
err
:=
self
.
coder
.
ReadResponse
()
if
err
!=
nil
{
return
nil
,
err
}
if
sucRes
,
ok
:=
res
.
(
shared
.
SuccessResponse
);
ok
{
data
,
_
:=
json
.
Marshal
(
sucRes
.
Result
)
modules
:=
make
(
map
[
string
]
string
)
err
=
json
.
Unmarshal
(
data
,
&
modules
)
if
err
==
nil
{
return
modules
,
nil
}
}
return
nil
,
fmt
.
Errorf
(
"Invalid response"
)
}
}
// Create a new IPC client, UNIX domain socket on posix, named pipe on Windows
// Create a new IPC client, UNIX domain socket on posix, named pipe on Windows
...
...
rpc/comms/ipc_unix.go
View file @
f2025637
...
@@ -18,7 +18,17 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
...
@@ -18,7 +18,17 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
return
nil
,
err
return
nil
,
err
}
}
return
&
ipcClient
{
codec
.
New
(
c
)},
nil
return
&
ipcClient
{
cfg
.
Endpoint
,
codec
,
codec
.
New
(
c
)},
nil
}
func
(
self
*
ipcClient
)
reconnect
()
error
{
self
.
coder
.
Close
()
c
,
err
:=
net
.
DialUnix
(
"unix"
,
nil
,
&
net
.
UnixAddr
{
self
.
endpoint
,
"unix"
})
if
err
==
nil
{
self
.
coder
=
self
.
codec
.
New
(
c
)
}
return
err
}
}
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
api
.
EthereumApi
)
error
{
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
api
.
EthereumApi
)
error
{
...
...
rpc/comms/ipc_windows.go
View file @
f2025637
...
@@ -641,7 +641,15 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
...
@@ -641,7 +641,15 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
return
nil
,
err
return
nil
,
err
}
}
return
&
ipcClient
{
codec
.
New
(
c
)},
nil
return
&
ipcClient
{
cfg
.
Endpoint
,
codec
,
codec
.
New
(
c
)},
nil
}
func
(
self
*
ipcClient
)
reconnect
()
error
{
c
,
err
:=
Dial
(
self
.
endpoint
)
if
err
==
nil
{
self
.
coder
=
self
.
codec
.
New
(
c
)
}
return
err
}
}
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
api
.
EthereumApi
)
error
{
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
api
.
EthereumApi
)
error
{
...
...
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