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
f9cbd16f
Commit
f9cbd16f
authored
Aug 07, 2015
by
Bas van Kervel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support for user agents
parent
2fcf7f12
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
361 additions
and
88 deletions
+361
-88
js.go
cmd/geth/js.go
+3
-7
main.go
cmd/geth/main.go
+1
-1
flags.go
cmd/utils/flags.go
+16
-9
admin.go
rpc/api/admin.go
+9
-0
net.go
rpc/api/net.go
+1
-2
personal.go
rpc/api/personal.go
+11
-11
personal_args.go
rpc/api/personal_args.go
+15
-7
shh_js.go
rpc/api/shh_js.go
+0
-0
codec.go
rpc/codec/codec.go
+2
-0
json.go
rpc/codec/json.go
+23
-16
comms.go
rpc/comms/comms.go
+1
-1
inproc.go
rpc/comms/inproc.go
+1
-1
ipc.go
rpc/comms/ipc.go
+9
-26
ipc_unix.go
rpc/comms/ipc_unix.go
+8
-1
ipc_windows.go
rpc/comms/ipc_windows.go
+8
-1
jeth.go
rpc/jeth.go
+84
-5
agent.go
rpc/useragent/agent.go
+24
-0
remote_frontend.go
rpc/useragent/remote_frontend.go
+141
-0
xeth.go
xeth/xeth.go
+4
-0
No files found.
cmd/geth/js.go
View file @
f9cbd16f
...
@@ -145,19 +145,15 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
...
@@ -145,19 +145,15 @@ 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
{
func
newLightweightJSRE
(
libPath
string
,
client
comms
.
EthereumClient
,
interactive
bool
)
*
jsre
{
js
:=
&
jsre
{
ps1
:
"> "
}
js
:=
&
jsre
{
ps1
:
"> "
}
js
.
wait
=
make
(
chan
*
big
.
Int
)
js
.
wait
=
make
(
chan
*
big
.
Int
)
js
.
client
=
client
js
.
client
=
client
js
.
ds
=
docserver
.
New
(
"/"
)
js
.
ds
=
docserver
.
New
(
"/"
)
if
f
==
nil
{
f
=
js
}
// update state in separare forever blocks
// update state in separare forever blocks
js
.
re
=
re
.
New
(
libPath
)
js
.
re
=
re
.
New
(
libPath
)
if
err
:=
js
.
apiBindings
(
f
);
err
!=
nil
{
if
err
:=
js
.
apiBindings
(
js
);
err
!=
nil
{
utils
.
Fatalf
(
"Unable to initialize console - %v"
,
err
)
utils
.
Fatalf
(
"Unable to initialize console - %v"
,
err
)
}
}
...
@@ -291,7 +287,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
...
@@ -291,7 +287,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
utils
.
Fatalf
(
"Unable to determine supported api's: %v"
,
err
)
utils
.
Fatalf
(
"Unable to determine supported api's: %v"
,
err
)
}
}
jeth
:=
rpc
.
NewJeth
(
api
.
Merge
(
apiImpl
...
),
js
.
re
,
js
.
client
)
jeth
:=
rpc
.
NewJeth
(
api
.
Merge
(
apiImpl
...
),
js
.
re
,
js
.
client
,
f
)
js
.
re
.
Set
(
"jeth"
,
struct
{}{})
js
.
re
.
Set
(
"jeth"
,
struct
{}{})
t
,
_
:=
js
.
re
.
Get
(
"jeth"
)
t
,
_
:=
js
.
re
.
Get
(
"jeth"
)
jethObj
:=
t
.
Object
()
jethObj
:=
t
.
Object
()
...
...
cmd/geth/main.go
View file @
f9cbd16f
...
@@ -425,7 +425,7 @@ func attach(ctx *cli.Context) {
...
@@ -425,7 +425,7 @@ func attach(ctx *cli.Context) {
ctx
.
GlobalString
(
utils
.
JSpathFlag
.
Name
),
ctx
.
GlobalString
(
utils
.
JSpathFlag
.
Name
),
client
,
client
,
true
,
true
,
nil
)
)
if
ctx
.
GlobalString
(
utils
.
ExecFlag
.
Name
)
!=
""
{
if
ctx
.
GlobalString
(
utils
.
ExecFlag
.
Name
)
!=
""
{
repl
.
batch
(
ctx
.
GlobalString
(
utils
.
ExecFlag
.
Name
))
repl
.
batch
(
ctx
.
GlobalString
(
utils
.
ExecFlag
.
Name
))
...
...
cmd/utils/flags.go
View file @
f9cbd16f
...
@@ -21,30 +21,32 @@ import (
...
@@ -21,30 +21,32 @@ import (
"fmt"
"fmt"
"log"
"log"
"math/big"
"math/big"
"net"
"net/http"
"net/http"
"os"
"os"
"path/filepath"
"path/filepath"
"runtime"
"runtime"
"strconv"
"strconv"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/metrics"
"github.com/codegangsta/cli"
"github.com/codegangsta/cli"
"github.com/ethereum/ethash"
"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event"
"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/metrics"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/p2p/nat"
"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/rpc/useragent"
"github.com/ethereum/go-ethereum/xeth"
"github.com/ethereum/go-ethereum/xeth"
)
)
...
@@ -518,15 +520,20 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
...
@@ -518,15 +520,20 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
Endpoint
:
IpcSocketPath
(
ctx
),
Endpoint
:
IpcSocketPath
(
ctx
),
}
}
xeth
:=
xeth
.
New
(
eth
,
nil
)
initializer
:=
func
(
conn
net
.
Conn
)
(
shared
.
EthereumApi
,
error
)
{
fe
:=
useragent
.
NewRemoteFrontend
(
conn
,
eth
.
AccountManager
())
xeth
:=
xeth
.
New
(
eth
,
fe
)
codec
:=
codec
.
JSON
codec
:=
codec
.
JSON
apis
,
err
:=
api
.
ParseApiString
(
ctx
.
GlobalString
(
IPCApiFlag
.
Name
),
codec
,
xeth
,
eth
)
apis
,
err
:=
api
.
ParseApiString
(
ctx
.
GlobalString
(
IPCApiFlag
.
Name
),
codec
,
xeth
,
eth
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
return
api
.
Merge
(
apis
...
),
nil
}
}
return
comms
.
StartIpc
(
config
,
codec
,
api
.
Merge
(
apis
...
)
)
return
comms
.
StartIpc
(
config
,
codec
.
JSON
,
initializer
)
}
}
func
StartRPC
(
eth
*
eth
.
Ethereum
,
ctx
*
cli
.
Context
)
error
{
func
StartRPC
(
eth
*
eth
.
Ethereum
,
ctx
*
cli
.
Context
)
error
{
...
...
rpc/api/admin.go
View file @
f9cbd16f
...
@@ -37,6 +37,7 @@ import (
...
@@ -37,6 +37,7 @@ import (
"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/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/useragent"
"github.com/ethereum/go-ethereum/xeth"
"github.com/ethereum/go-ethereum/xeth"
)
)
...
@@ -71,6 +72,7 @@ var (
...
@@ -71,6 +72,7 @@ var (
"admin_httpGet"
:
(
*
adminApi
)
.
HttpGet
,
"admin_httpGet"
:
(
*
adminApi
)
.
HttpGet
,
"admin_sleepBlocks"
:
(
*
adminApi
)
.
SleepBlocks
,
"admin_sleepBlocks"
:
(
*
adminApi
)
.
SleepBlocks
,
"admin_sleep"
:
(
*
adminApi
)
.
Sleep
,
"admin_sleep"
:
(
*
adminApi
)
.
Sleep
,
"admin_enableUserAgent"
:
(
*
adminApi
)
.
EnableUserAgent
,
}
}
)
)
...
@@ -474,3 +476,10 @@ func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) {
...
@@ -474,3 +476,10 @@ func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) {
return
string
(
resp
),
nil
return
string
(
resp
),
nil
}
}
func
(
self
*
adminApi
)
EnableUserAgent
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
if
fe
,
ok
:=
self
.
xeth
.
Frontend
()
.
(
*
useragent
.
RemoteFrontend
);
ok
{
fe
.
Enable
()
}
return
true
,
nil
}
rpc/api/net.go
View file @
f9cbd16f
...
@@ -97,4 +97,3 @@ func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
...
@@ -97,4 +97,3 @@ func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
func
(
self
*
netApi
)
Version
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
func
(
self
*
netApi
)
Version
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
return
self
.
xeth
.
NetworkVersion
(),
nil
return
self
.
xeth
.
NetworkVersion
(),
nil
}
}
rpc/api/personal.go
View file @
f9cbd16f
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
package
api
package
api
import
(
import
(
"fmt"
"time"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
...
@@ -125,18 +126,17 @@ func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error)
...
@@ -125,18 +126,17 @@ func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error)
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
}
var
err
error
if
len
(
args
.
Passphrase
)
==
0
{
fe
:=
self
.
xeth
.
Frontend
()
if
fe
==
nil
{
return
false
,
fmt
.
Errorf
(
"No password provided"
)
}
return
fe
.
UnlockAccount
(
common
.
HexToAddress
(
args
.
Address
)
.
Bytes
()),
nil
}
am
:=
self
.
ethereum
.
AccountManager
()
am
:=
self
.
ethereum
.
AccountManager
()
addr
:=
common
.
HexToAddress
(
args
.
Address
)
addr
:=
common
.
HexToAddress
(
args
.
Address
)
if
args
.
Duration
==
-
1
{
err
:=
am
.
TimedUnlock
(
addr
,
args
.
Passphrase
,
time
.
Duration
(
args
.
Duration
)
*
time
.
Second
)
err
=
am
.
Unlock
(
addr
,
args
.
Passphrase
)
return
err
==
nil
,
err
}
else
{
err
=
am
.
TimedUnlock
(
addr
,
args
.
Passphrase
,
time
.
Duration
(
args
.
Duration
)
*
time
.
Second
)
}
if
err
==
nil
{
return
true
,
nil
}
return
false
,
err
}
}
rpc/api/personal_args.go
View file @
f9cbd16f
...
@@ -86,10 +86,10 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -86,10 +86,10 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
return
shared
.
NewDecodeParamError
(
err
.
Error
())
return
shared
.
NewDecodeParamError
(
err
.
Error
())
}
}
args
.
Duration
=
-
1
args
.
Duration
=
0
if
len
(
obj
)
<
2
{
if
len
(
obj
)
<
1
{
return
shared
.
NewInsufficientParamsError
(
len
(
obj
),
2
)
return
shared
.
NewInsufficientParamsError
(
len
(
obj
),
1
)
}
}
if
addrstr
,
ok
:=
obj
[
0
]
.
(
string
);
ok
{
if
addrstr
,
ok
:=
obj
[
0
]
.
(
string
);
ok
{
...
@@ -98,11 +98,19 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -98,11 +98,19 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
return
shared
.
NewInvalidTypeError
(
"address"
,
"not a string"
)
return
shared
.
NewInvalidTypeError
(
"address"
,
"not a string"
)
}
}
if
len
(
obj
)
>=
2
&&
obj
[
1
]
!=
nil
{
if
passphrasestr
,
ok
:=
obj
[
1
]
.
(
string
);
ok
{
if
passphrasestr
,
ok
:=
obj
[
1
]
.
(
string
);
ok
{
args
.
Passphrase
=
passphrasestr
args
.
Passphrase
=
passphrasestr
}
else
{
}
else
{
return
shared
.
NewInvalidTypeError
(
"passphrase"
,
"not a string"
)
return
shared
.
NewInvalidTypeError
(
"passphrase"
,
"not a string"
)
}
}
}
if
len
(
obj
)
>=
3
&&
obj
[
2
]
!=
nil
{
if
duration
,
ok
:=
obj
[
2
]
.
(
float64
);
ok
{
args
.
Duration
=
int
(
duration
)
}
}
return
nil
return
nil
}
}
rpc/api/s
s
h_js.go
→
rpc/api/s
h
h_js.go
View file @
f9cbd16f
File moved
rpc/codec/codec.go
View file @
f9cbd16f
...
@@ -31,6 +31,8 @@ type ApiCoder interface {
...
@@ -31,6 +31,8 @@ type ApiCoder interface {
ReadRequest
()
([]
*
shared
.
Request
,
bool
,
error
)
ReadRequest
()
([]
*
shared
.
Request
,
bool
,
error
)
// Parse response message from underlying stream
// Parse response message from underlying stream
ReadResponse
()
(
interface
{},
error
)
ReadResponse
()
(
interface
{},
error
)
// Read raw message from underlying stream
Recv
()
(
interface
{},
error
)
// Encode response to encoded form in underlying stream
// Encode response to encoded form in underlying stream
WriteResponse
(
interface
{})
error
WriteResponse
(
interface
{})
error
// Decode single message from data
// Decode single message from data
...
...
rpc/codec/json.go
View file @
f9cbd16f
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"fmt"
"fmt"
"net"
"net"
"time"
"time"
"strings"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/shared"
)
)
...
@@ -73,35 +74,41 @@ func (self *JsonCodec) ReadRequest() (requests []*shared.Request, isBatch bool,
...
@@ -73,35 +74,41 @@ func (self *JsonCodec) ReadRequest() (requests []*shared.Request, isBatch bool,
return
nil
,
false
,
err
return
nil
,
false
,
err
}
}
func
(
self
*
JsonCodec
)
ReadResponse
()
(
interface
{},
error
)
{
func
(
self
*
JsonCodec
)
Recv
()
(
interface
{},
error
)
{
bytesInBuffer
:=
0
var
msg
json
.
RawMessage
buf
:=
make
([]
byte
,
MAX_RESPONSE_SIZE
)
err
:=
self
.
d
.
Decode
(
&
msg
)
if
err
!=
nil
{
deadline
:=
time
.
Now
()
.
Add
(
READ_TIMEOUT
*
time
.
Second
)
self
.
c
.
Close
()
if
err
:=
self
.
c
.
SetDeadline
(
deadline
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
for
{
return
msg
,
err
n
,
err
:=
self
.
c
.
Read
(
buf
[
bytesInBuffer
:
])
}
func
(
self
*
JsonCodec
)
ReadResponse
()
(
interface
{},
error
)
{
in
,
err
:=
self
.
Recv
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
bytesInBuffer
+=
n
var
failure
shared
.
ErrorResponse
if
msg
,
ok
:=
in
.
(
json
.
RawMessage
);
ok
{
if
err
=
json
.
Unmarshal
(
buf
[
:
bytesInBuffer
],
&
failure
);
err
==
nil
&&
failure
.
Error
!=
nil
{
var
req
*
shared
.
Request
if
err
=
json
.
Unmarshal
(
msg
,
&
req
);
err
==
nil
&&
strings
.
HasPrefix
(
req
.
Method
,
"agent_"
)
{
return
req
,
nil
}
var
failure
*
shared
.
ErrorResponse
if
err
=
json
.
Unmarshal
(
msg
,
&
failure
);
err
==
nil
&&
failure
.
Error
!=
nil
{
return
failure
,
fmt
.
Errorf
(
failure
.
Error
.
Message
)
return
failure
,
fmt
.
Errorf
(
failure
.
Error
.
Message
)
}
}
var
success
shared
.
SuccessResponse
var
success
*
shared
.
SuccessResponse
if
err
=
json
.
Unmarshal
(
buf
[
:
bytesInBuffer
]
,
&
success
);
err
==
nil
{
if
err
=
json
.
Unmarshal
(
msg
,
&
success
);
err
==
nil
{
return
success
,
nil
return
success
,
nil
}
}
}
}
self
.
c
.
Close
()
return
in
,
err
return
nil
,
fmt
.
Errorf
(
"Unable to read response"
)
}
}
// Decode data
// Decode data
...
...
rpc/comms/comms.go
View file @
f9cbd16f
...
@@ -49,7 +49,7 @@ var (
...
@@ -49,7 +49,7 @@ var (
)
)
type
EthereumClient
interface
{
type
EthereumClient
interface
{
// Close underl
a
ying connection
// Close underlying connection
Close
()
Close
()
// Send request
// Send request
Send
(
interface
{})
error
Send
(
interface
{})
error
...
...
rpc/comms/inproc.go
View file @
f9cbd16f
...
@@ -60,7 +60,7 @@ func (self *InProcClient) Send(req interface{}) error {
...
@@ -60,7 +60,7 @@ 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
*
shared
.
NewRpcResponse
(
self
.
lastId
,
self
.
lastJsonrpc
,
self
.
lastRes
,
self
.
lastErr
),
nil
}
}
func
(
self
*
InProcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
func
(
self
*
InProcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
...
...
rpc/comms/ipc.go
View file @
f9cbd16f
...
@@ -44,35 +44,18 @@ func (self *ipcClient) Close() {
...
@@ -44,35 +44,18 @@ func (self *ipcClient) Close() {
func
(
self
*
ipcClient
)
Send
(
req
interface
{})
error
{
func
(
self
*
ipcClient
)
Send
(
req
interface
{})
error
{
var
err
error
var
err
error
if
r
,
ok
:=
req
.
(
*
shared
.
Request
);
ok
{
if
err
=
self
.
coder
.
WriteResponse
(
req
);
err
!=
nil
{
if
err
=
self
.
coder
.
WriteResponse
(
r
);
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
net
.
OpError
);
ok
{
// connection lost, retry once
if
_
,
ok
:=
err
.
(
*
net
.
OpError
);
ok
{
// connection lost, retry once
if
err
=
self
.
reconnect
();
err
==
nil
{
if
err
=
self
.
reconnect
();
err
==
nil
{
err
=
self
.
coder
.
WriteResponse
(
r
)
err
=
self
.
coder
.
WriteResponse
(
req
)
}
}
}
}
}
}
return
err
return
err
}
return
fmt
.
Errorf
(
"Invalid request (%T)"
,
req
)
}
}
func
(
self
*
ipcClient
)
Recv
()
(
interface
{},
error
)
{
func
(
self
*
ipcClient
)
Recv
()
(
interface
{},
error
)
{
res
,
err
:=
self
.
coder
.
ReadResponse
()
return
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
)
{
func
(
self
*
ipcClient
)
SupportedModules
()
(
map
[
string
]
string
,
error
)
{
...
@@ -91,7 +74,7 @@ func (self *ipcClient) SupportedModules() (map[string]string, error) {
...
@@ -91,7 +74,7 @@ func (self *ipcClient) SupportedModules() (map[string]string, error) {
return
nil
,
err
return
nil
,
err
}
}
if
sucRes
,
ok
:=
res
.
(
shared
.
SuccessResponse
);
ok
{
if
sucRes
,
ok
:=
res
.
(
*
shared
.
SuccessResponse
);
ok
{
data
,
_
:=
json
.
Marshal
(
sucRes
.
Result
)
data
,
_
:=
json
.
Marshal
(
sucRes
.
Result
)
modules
:=
make
(
map
[
string
]
string
)
modules
:=
make
(
map
[
string
]
string
)
err
=
json
.
Unmarshal
(
data
,
&
modules
)
err
=
json
.
Unmarshal
(
data
,
&
modules
)
...
@@ -109,8 +92,8 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
...
@@ -109,8 +92,8 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
}
}
// Start IPC server
// Start IPC server
func
StartIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
offeredApi
shared
.
EthereumApi
)
error
{
func
StartIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
initializer
func
(
conn
net
.
Conn
)
(
shared
.
EthereumApi
,
error
)
)
error
{
return
startIpc
(
cfg
,
codec
,
offeredApi
)
return
startIpc
(
cfg
,
codec
,
initializer
)
}
}
func
newIpcConnId
()
int
{
func
newIpcConnId
()
int
{
...
...
rpc/comms/ipc_unix.go
View file @
f9cbd16f
...
@@ -48,7 +48,7 @@ func (self *ipcClient) reconnect() error {
...
@@ -48,7 +48,7 @@ func (self *ipcClient) reconnect() error {
return
err
return
err
}
}
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
shared
.
EthereumApi
)
error
{
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
initializer
func
(
conn
net
.
Conn
)
(
shared
.
EthereumApi
,
error
)
)
error
{
os
.
Remove
(
cfg
.
Endpoint
)
// in case it still exists from a previous run
os
.
Remove
(
cfg
.
Endpoint
)
// in case it still exists from a previous run
l
,
err
:=
net
.
Listen
(
"unix"
,
cfg
.
Endpoint
)
l
,
err
:=
net
.
Listen
(
"unix"
,
cfg
.
Endpoint
)
...
@@ -69,6 +69,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
...
@@ -69,6 +69,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
id
:=
newIpcConnId
()
id
:=
newIpcConnId
()
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"New IPC connection with id %06d started
\n
"
,
id
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"New IPC connection with id %06d started
\n
"
,
id
)
api
,
err
:=
initializer
(
conn
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to initialize IPC connection - %v
\n
"
,
err
)
conn
.
Close
()
continue
}
go
handle
(
id
,
conn
,
api
,
codec
)
go
handle
(
id
,
conn
,
api
,
codec
)
}
}
...
...
rpc/comms/ipc_windows.go
View file @
f9cbd16f
...
@@ -667,7 +667,7 @@ func (self *ipcClient) reconnect() error {
...
@@ -667,7 +667,7 @@ func (self *ipcClient) reconnect() error {
return
err
return
err
}
}
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
api
shared
.
EthereumApi
)
error
{
func
startIpc
(
cfg
IpcConfig
,
codec
codec
.
Codec
,
initializer
func
(
conn
net
.
Conn
)
(
shared
.
EthereumApi
,
error
)
)
error
{
os
.
Remove
(
cfg
.
Endpoint
)
// in case it still exists from a previous run
os
.
Remove
(
cfg
.
Endpoint
)
// in case it still exists from a previous run
l
,
err
:=
Listen
(
cfg
.
Endpoint
)
l
,
err
:=
Listen
(
cfg
.
Endpoint
)
...
@@ -687,6 +687,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
...
@@ -687,6 +687,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
id
:=
newIpcConnId
()
id
:=
newIpcConnId
()
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"New IPC connection with id %06d started
\n
"
,
id
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"New IPC connection with id %06d started
\n
"
,
id
)
api
,
err
:=
initializer
(
conn
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to initialize IPC connection - %v
\n
"
,
err
)
conn
.
Close
()
continue
}
go
handle
(
id
,
conn
,
api
,
codec
)
go
handle
(
id
,
conn
,
api
,
codec
)
}
}
...
...
rpc/jeth.go
View file @
f9cbd16f
...
@@ -18,12 +18,17 @@ package rpc
...
@@ -18,12 +18,17 @@ package rpc
import
(
import
(
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/jsre"
"github.com/ethereum/go-ethereum/jsre"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"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/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/useragent"
"github.com/ethereum/go-ethereum/xeth"
"github.com/robertkrimen/otto"
"github.com/robertkrimen/otto"
)
)
...
@@ -31,10 +36,21 @@ type Jeth struct {
...
@@ -31,10 +36,21 @@ type Jeth struct {
ethApi
shared
.
EthereumApi
ethApi
shared
.
EthereumApi
re
*
jsre
.
JSRE
re
*
jsre
.
JSRE
client
comms
.
EthereumClient
client
comms
.
EthereumClient
fe
xeth
.
Frontend
}
}
func
NewJeth
(
ethApi
shared
.
EthereumApi
,
re
*
jsre
.
JSRE
,
client
comms
.
EthereumClient
)
*
Jeth
{
func
NewJeth
(
ethApi
shared
.
EthereumApi
,
re
*
jsre
.
JSRE
,
client
comms
.
EthereumClient
,
fe
xeth
.
Frontend
)
*
Jeth
{
return
&
Jeth
{
ethApi
,
re
,
client
}
// enable the jeth as the user agent
req
:=
shared
.
Request
{
Id
:
0
,
Method
:
useragent
.
EnableUserAgentMethod
,
Jsonrpc
:
shared
.
JsonRpcVersion
,
Params
:
[]
byte
(
"[]"
),
}
client
.
Send
(
&
req
)
client
.
Recv
()
return
&
Jeth
{
ethApi
,
re
,
client
,
fe
}
}
}
func
(
self
*
Jeth
)
err
(
call
otto
.
FunctionCall
,
code
int
,
msg
string
,
id
interface
{})
(
response
otto
.
Value
)
{
func
(
self
*
Jeth
)
err
(
call
otto
.
FunctionCall
,
code
int
,
msg
string
,
id
interface
{})
(
response
otto
.
Value
)
{
...
@@ -72,16 +88,34 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
...
@@ -72,16 +88,34 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
if
err
!=
nil
{
if
err
!=
nil
{
return
self
.
err
(
call
,
-
32603
,
err
.
Error
(),
req
.
Id
)
return
self
.
err
(
call
,
-
32603
,
err
.
Error
(),
req
.
Id
)
}
}
respif
,
err
=
self
.
client
.
Recv
()
recv
:
respif
,
err
=
self
.
client
.
Recv
()
if
err
!=
nil
{
if
err
!=
nil
{
return
self
.
err
(
call
,
-
32603
,
err
.
Error
(),
req
.
Id
)
return
self
.
err
(
call
,
-
32603
,
err
.
Error
(),
req
.
Id
)
}
}
agentreq
,
isRequest
:=
respif
.
(
*
shared
.
Request
)
if
isRequest
{
self
.
handleRequest
(
agentreq
)
goto
recv
// receive response after agent interaction
}
sucres
,
isSuccessResponse
:=
respif
.
(
*
shared
.
SuccessResponse
)
errres
,
isErrorResponse
:=
respif
.
(
*
shared
.
ErrorResponse
)
if
!
isSuccessResponse
&&
!
isErrorResponse
{
return
self
.
err
(
call
,
-
32603
,
fmt
.
Sprintf
(
"Invalid response type (%T)"
,
respif
),
req
.
Id
)
}
call
.
Otto
.
Set
(
"ret_jsonrpc"
,
shared
.
JsonRpcVersion
)
call
.
Otto
.
Set
(
"ret_jsonrpc"
,
shared
.
JsonRpcVersion
)
call
.
Otto
.
Set
(
"ret_id"
,
req
.
Id
)
call
.
Otto
.
Set
(
"ret_id"
,
req
.
Id
)
res
,
_
:=
json
.
Marshal
(
respif
)
var
res
[]
byte
if
isSuccessResponse
{
res
,
err
=
json
.
Marshal
(
sucres
.
Result
)
}
else
if
isErrorResponse
{
res
,
err
=
json
.
Marshal
(
errres
.
Error
)
}
call
.
Otto
.
Set
(
"ret_result"
,
string
(
res
))
call
.
Otto
.
Set
(
"ret_result"
,
string
(
res
))
call
.
Otto
.
Set
(
"response_idx"
,
i
)
call
.
Otto
.
Set
(
"response_idx"
,
i
)
...
@@ -105,3 +139,48 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
...
@@ -105,3 +139,48 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
return
return
}
}
// handleRequest will handle user agent requests by interacting with the user and sending
// the user response back to the geth service
func
(
self
*
Jeth
)
handleRequest
(
req
*
shared
.
Request
)
bool
{
var
err
error
var
args
[]
interface
{}
if
err
=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Unable to parse agent request - %v
\n
"
,
err
)
return
false
}
switch
req
.
Method
{
case
useragent
.
AskPasswordMethod
:
return
self
.
askPassword
(
req
.
Id
,
req
.
Jsonrpc
,
args
)
case
useragent
.
ConfirmTransactionMethod
:
return
self
.
confirmTransaction
(
req
.
Id
,
req
.
Jsonrpc
,
args
)
}
return
false
}
// askPassword will ask the user to supply the password for a given account
func
(
self
*
Jeth
)
askPassword
(
id
interface
{},
jsonrpc
string
,
args
[]
interface
{})
bool
{
var
err
error
var
passwd
string
if
len
(
args
)
>=
1
{
if
account
,
ok
:=
args
[
0
]
.
(
string
);
ok
{
fmt
.
Printf
(
"Unlock account %s
\n
"
,
account
)
passwd
,
err
=
utils
.
PromptPassword
(
"Passphrase: "
,
true
)
}
else
{
return
false
}
}
if
err
=
self
.
client
.
Send
(
shared
.
NewRpcResponse
(
id
,
jsonrpc
,
passwd
,
err
));
err
!=
nil
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Unable to send user agent ask password response - %v
\n
"
,
err
)
}
return
err
==
nil
}
func
(
self
*
Jeth
)
confirmTransaction
(
id
interface
{},
jsonrpc
string
,
args
[]
interface
{})
bool
{
// Accept all tx which are send from this console
return
self
.
client
.
Send
(
shared
.
NewRpcResponse
(
id
,
jsonrpc
,
true
,
nil
))
==
nil
}
rpc/useragent/agent.go
0 → 100644
View file @
f9cbd16f
// Copyright 2015 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 user agent provides frontends and agents which can interact with the user
package
useragent
var
(
AskPasswordMethod
=
"agent_askPassword"
ConfirmTransactionMethod
=
"agent_confirmTransaction"
EnableUserAgentMethod
=
"admin_enableUserAgent"
)
rpc/useragent/remote_frontend.go
0 → 100644
View file @
f9cbd16f
// Copyright 2015 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
useragent
import
(
"encoding/json"
"fmt"
"net"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rpc/shared"
)
// remoteFrontend implements xeth.Frontend and will communicate with an external
// user agent over a connection
type
RemoteFrontend
struct
{
enabled
bool
mgr
*
accounts
.
Manager
d
*
json
.
Decoder
e
*
json
.
Encoder
n
int
}
// NewRemoteFrontend creates a new frontend which will interact with an user agent
// over the given connection
func
NewRemoteFrontend
(
conn
net
.
Conn
,
mgr
*
accounts
.
Manager
)
*
RemoteFrontend
{
return
&
RemoteFrontend
{
false
,
mgr
,
json
.
NewDecoder
(
conn
),
json
.
NewEncoder
(
conn
),
0
}
}
// Enable will enable user interaction
func
(
fe
*
RemoteFrontend
)
Enable
()
{
fe
.
enabled
=
true
}
// UnlockAccount asks the user agent for the user password and tries to unlock the account.
// It will try 3 attempts before giving up.
func
(
fe
*
RemoteFrontend
)
UnlockAccount
(
address
[]
byte
)
bool
{
if
!
fe
.
enabled
{
return
false
}
err
:=
fe
.
send
(
AskPasswordMethod
,
common
.
Bytes2Hex
(
address
))
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to send password request to agent - %v
\n
"
,
err
)
return
false
}
passwdRes
,
err
:=
fe
.
recv
()
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to recv password response from agent - %v
\n
"
,
err
)
return
false
}
if
passwd
,
ok
:=
passwdRes
.
Result
.
(
string
);
ok
{
err
=
fe
.
mgr
.
Unlock
(
common
.
BytesToAddress
(
address
),
passwd
)
}
if
err
==
nil
{
return
true
}
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
"3 invalid account unlock attempts"
)
return
false
}
// ConfirmTransaction asks the user for approval
func
(
fe
*
RemoteFrontend
)
ConfirmTransaction
(
tx
string
)
bool
{
if
!
fe
.
enabled
{
return
true
// backwards compatibility
}
err
:=
fe
.
send
(
ConfirmTransactionMethod
,
tx
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to send tx confirmation request to agent - %v
\n
"
,
err
)
return
false
}
confirmResponse
,
err
:=
fe
.
recv
()
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Unable to recv tx confirmation response from agent - %v
\n
"
,
err
)
return
false
}
if
confirmed
,
ok
:=
confirmResponse
.
Result
.
(
bool
);
ok
{
return
confirmed
}
return
false
}
// send request to the agent
func
(
fe
*
RemoteFrontend
)
send
(
method
string
,
params
...
interface
{})
error
{
fe
.
n
+=
1
p
,
err
:=
json
.
Marshal
(
params
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Unable to send agent request %v
\n
"
,
err
)
return
err
}
req
:=
shared
.
Request
{
Method
:
method
,
Jsonrpc
:
shared
.
JsonRpcVersion
,
Id
:
fe
.
n
,
Params
:
p
,
}
return
fe
.
e
.
Encode
(
&
req
)
}
// recv user response from agent
func
(
fe
*
RemoteFrontend
)
recv
()
(
*
shared
.
SuccessResponse
,
error
)
{
var
res
json
.
RawMessage
if
err
:=
fe
.
d
.
Decode
(
&
res
);
err
!=
nil
{
return
nil
,
err
}
var
response
shared
.
SuccessResponse
if
err
:=
json
.
Unmarshal
(
res
,
&
response
);
err
==
nil
{
return
&
response
,
nil
}
return
nil
,
fmt
.
Errorf
(
"Invalid user agent response"
)
}
xeth/xeth.go
View file @
f9cbd16f
...
@@ -885,6 +885,10 @@ func isAddress(addr string) bool {
...
@@ -885,6 +885,10 @@ func isAddress(addr string) bool {
return
addrReg
.
MatchString
(
addr
)
return
addrReg
.
MatchString
(
addr
)
}
}
func
(
self
*
XEth
)
Frontend
()
Frontend
{
return
self
.
frontend
}
func
(
self
*
XEth
)
Transact
(
fromStr
,
toStr
,
nonceStr
,
valueStr
,
gasStr
,
gasPriceStr
,
codeStr
string
)
(
string
,
error
)
{
func
(
self
*
XEth
)
Transact
(
fromStr
,
toStr
,
nonceStr
,
valueStr
,
gasStr
,
gasPriceStr
,
codeStr
string
)
(
string
,
error
)
{
// this minimalistic recoding is enough (works for natspec.js)
// this minimalistic recoding is enough (works for natspec.js)
...
...
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