diff options
author | zelig <viktor.tron@gmail.com> | 2015-09-22 16:34:58 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2015-10-22 06:22:39 +0800 |
commit | 8b81ad1fc40080af441c0c6df94f0b2ea46e320b (patch) | |
tree | 7d8817ec84be38b911f967f1ecd5618d02e4caa9 /rpc | |
parent | 58d0752fdd1c7363fb1a127cd7e0a86d7602be02 (diff) | |
download | dexon-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.gz dexon-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.zst dexon-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.zip |
console:
* lines with leading space are ommitted from history
* exit processed even with whitespace around
* all whitespace lines (not only empty ones) are ignored
add 7 missing commands to admin api autocomplete
registrar: methods now return proper error if reg addresses are not set. fixes #1457
rpc/console: fix personal.newAccount() regression. Now all comms accept interactive password
registrar: add registrar tests for errors
crypto: catch AES decryption error on presale wallet import + fix error msg format. fixes #1580
CLI: improve error message when starting a second instance of geth. fixes #1564
cli/accounts: unlock multiple accounts. fixes #1785
* make unlocking multiple accounts work with inline <() fd
* passwdfile now correctly read only once
* improve logs
* fix CLI help text for unlocking
fix regression with docRoot / admin API
* docRoot/jspath passed to rpc/api ParseApis, which passes onto adminApi
* docRoot field for JS console in order to pass when RPC is (re)started
* improve flag desc for jspath
common/docserver: catch http errors from response
fix rpc/api tests
common/natspec: fix end to end test (skipped because takes 8s)
registrar: fix major regression:
* deploy registrars on frontier
* register HashsReg and UrlHint in GlobalRegistrar.
* set all 3 contract addresses in code
* zero out addresses first in tests
Diffstat (limited to 'rpc')
-rw-r--r-- | rpc/api/admin.go | 8 | ||||
-rw-r--r-- | rpc/api/api_test.go | 8 | ||||
-rw-r--r-- | rpc/api/personal.go | 17 | ||||
-rw-r--r-- | rpc/api/personal_args.go | 17 | ||||
-rw-r--r-- | rpc/api/utils.go | 11 | ||||
-rw-r--r-- | rpc/jeth.go | 2 | ||||
-rw-r--r-- | rpc/useragent/remote_frontend.go | 25 |
7 files changed, 67 insertions, 21 deletions
diff --git a/rpc/api/admin.go b/rpc/api/admin.go index 6aa04e667..eed8d8366 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -84,17 +84,19 @@ type adminApi struct { ethereum *eth.Ethereum codec codec.Codec coder codec.ApiCoder + docRoot string ds *docserver.DocServer } // create a new admin api instance -func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi { +func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec, docRoot string) *adminApi { return &adminApi{ xeth: xeth, ethereum: ethereum, codec: codec, coder: codec.New(nil), - ds: docserver.New("/"), + docRoot: docRoot, + ds: docserver.New(docRoot), } } @@ -256,7 +258,7 @@ func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { CorsDomain: args.CorsDomain, } - apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum) + apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum, self.docRoot) if err != nil { return false, err } diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go index 131ef68f8..a4efb09c1 100644 --- a/rpc/api/api_test.go +++ b/rpc/api/api_test.go @@ -30,7 +30,7 @@ import ( ) func TestParseApiString(t *testing.T) { - apis, err := ParseApiString("", codec.JSON, nil, nil) + apis, err := ParseApiString("", codec.JSON, nil, nil, "") if err == nil { t.Errorf("Expected an err from parsing empty API string but got nil") } @@ -39,7 +39,7 @@ func TestParseApiString(t *testing.T) { t.Errorf("Expected 0 apis from empty API string") } - apis, err = ParseApiString("eth", codec.JSON, nil, nil) + apis, err = ParseApiString("eth", codec.JSON, nil, nil, "") if err != nil { t.Errorf("Expected nil err from parsing empty API string but got %v", err) } @@ -48,7 +48,7 @@ func TestParseApiString(t *testing.T) { t.Errorf("Expected 1 apis but got %d - %v", apis, apis) } - apis, err = ParseApiString("eth,eth", codec.JSON, nil, nil) + apis, err = ParseApiString("eth,eth", codec.JSON, nil, nil, "") if err != nil { t.Errorf("Expected nil err from parsing empty API string but got \"%v\"", err) } @@ -57,7 +57,7 @@ func TestParseApiString(t *testing.T) { t.Errorf("Expected 2 apis but got %d - %v", apis, apis) } - apis, err = ParseApiString("eth,invalid", codec.JSON, nil, nil) + apis, err = ParseApiString("eth,invalid", codec.JSON, nil, nil, "") if err == nil { t.Errorf("Expected an err but got no err") } diff --git a/rpc/api/personal.go b/rpc/api/personal.go index 1fb412612..4f347c610 100644 --- a/rpc/api/personal.go +++ b/rpc/api/personal.go @@ -98,9 +98,22 @@ func (self *personalApi) NewAccount(req *shared.Request) (interface{}, error) { if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } - + var passwd string + if args.Passphrase == nil { + fe := self.xeth.Frontend() + if fe == nil { + return false, fmt.Errorf("unable to create account: unable to interact with user") + } + var ok bool + passwd, ok = fe.AskPassword() + if !ok { + return false, fmt.Errorf("unable to create account: no password given") + } + } else { + passwd = *args.Passphrase + } am := self.ethereum.AccountManager() - acc, err := am.NewAccount(args.Passphrase) + acc, err := am.NewAccount(passwd) return acc.Address.Hex(), err } diff --git a/rpc/api/personal_args.go b/rpc/api/personal_args.go index 73dc6285e..5d215c71d 100644 --- a/rpc/api/personal_args.go +++ b/rpc/api/personal_args.go @@ -23,7 +23,7 @@ import ( ) type NewAccountArgs struct { - Passphrase string + Passphrase *string } func (args *NewAccountArgs) UnmarshalJSON(b []byte) (err error) { @@ -32,16 +32,15 @@ func (args *NewAccountArgs) UnmarshalJSON(b []byte) (err error) { return shared.NewDecodeParamError(err.Error()) } - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if passhrase, ok := obj[0].(string); ok { - args.Passphrase = passhrase - return nil + if len(obj) >= 1 && obj[0] != nil { + if passphrasestr, ok := obj[0].(string); ok { + args.Passphrase = &passphrasestr + } else { + return shared.NewInvalidTypeError("passphrase", "not a string") + } } - return shared.NewInvalidTypeError("passhrase", "not a string") + return nil } type UnlockAccountArgs struct { diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 76b2c531d..719cb8074 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -33,14 +33,21 @@ var ( "admin": []string{ "addPeer", "datadir", + "enableUserAgent", "exportChain", "getContractInfo", + "httpGet", "importChain", "nodeInfo", "peers", "register", "registerUrl", + "saveInfo", + "setGlobalRegistrar", + "setHashReg", + "setUrlHint", "setSolc", + "sleep", "sleepBlocks", "startNatSpec", "startRPC", @@ -146,7 +153,7 @@ var ( ) // Parse a comma separated API string to individual api's -func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]shared.EthereumApi, error) { +func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum, docRoot string) ([]shared.EthereumApi, error) { if len(strings.TrimSpace(apistr)) == 0 { return nil, fmt.Errorf("Empty apistr provided") } @@ -157,7 +164,7 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth. for i, name := range names { switch strings.ToLower(strings.TrimSpace(name)) { case shared.AdminApiName: - apis[i] = NewAdminApi(xeth, eth, codec) + apis[i] = NewAdminApi(xeth, eth, codec, docRoot) case shared.DebugApiName: apis[i] = NewDebugApi(xeth, eth, codec) case shared.DbApiName: diff --git a/rpc/jeth.go b/rpc/jeth.go index ae2603ae4..1260a3404 100644 --- a/rpc/jeth.go +++ b/rpc/jeth.go @@ -158,11 +158,11 @@ func (self *Jeth) askPassword(id interface{}, jsonrpc string, args []interface{} 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 } } + passwd, err = utils.PromptPassword("Passphrase: ", true) 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) diff --git a/rpc/useragent/remote_frontend.go b/rpc/useragent/remote_frontend.go index 0dd4a6049..944ab287a 100644 --- a/rpc/useragent/remote_frontend.go +++ b/rpc/useragent/remote_frontend.go @@ -49,6 +49,31 @@ func (fe *RemoteFrontend) Enable() { fe.enabled = true } +func (fe *RemoteFrontend) AskPassword() (string, bool) { + if !fe.enabled { + return "", false + } + + err := fe.send(AskPasswordMethod) + 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 { + return passwd, true + } + + return "", false + +} + // 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 { |