-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relocate personal RPC endpoints to parity and geth class #1211
Relocate personal RPC endpoints to parity and geth class #1211
Conversation
7053617
to
5c3fc71
Compare
@pipermerriam @carver Here's a first stab at relocating the I'm not sure if I like the pattern in this PR, but I had trouble finding something I liked better since there are going to be shared endpoints b/w geth&parity as well as endpoints unique to either geth&parity. Also, what about other clients? If someone wanted to use the trinity client, it might be confusing to use a https://docs.google.com/spreadsheets/d/1rNvszb2hbYrzUbZj0v4oPnSwyJezYYHhgcpiqdVf7Bk/edit?usp=sharing |
Combined with the new way module methods are being done in #1166 this might be a little cleaner since we'd be able to re-use the method definitions for any commonly shaped endpoints. |
web3/geth.py
Outdated
https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal | ||
""" | ||
def __init__(self, w3): | ||
self.w3 = w3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will override the inherited Module __init__, which could cause a bug in the future.
web3/geth.py
Outdated
class Geth(Module): | ||
@property | ||
def personal(self): | ||
return GethPersonal(self.web3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im not sure if it is better, but submodules could be configured in Web3 along with the modules.
Something to the effect of this in web3.Web3:
def get_default_modules():
return [
{"name": "eth", "module": Eth},
{"name": "net", "module": Net},
{"name": "geth", "module": Geth, "submodules": {"personal": Personal}}
{"name": "personal", "module": Personal},
{"name": "version", "module": Version},
{"name": "txpool", "module": TxPool},
{"name": "miner", "module": Miner},
{"name": "admin", "module": Admin},
{"name": "parity", "module": Parity},
{"name": "testing", "module": Testing},
]
class Web3:
[...]
def __init__(self, provider=None, middlewares=None, modules=None, ens=empty):
self.manager = self.RequestManager(self, provider, middlewares)
if modules is None:
modules = get_default_modules()
for module in modules:
module['module'].attach(self, module.get('name'))
if 'submodules' in module:
for subname, submodule in module['submodules'].items():
submodule.attach(getattr(self, module['name']), submodule)
self.ens = ens
The Module.attach method appears to work with modules 2 levels deep. Im leaning toward having 1 way modules are attached.
With #1166 way of defining methods, the personal module methods could all be written in one place and the partiy/geth personal modules could compose the methods they support. Then the not implemented methods could just be absent. |
b5f468e
to
02977cc
Compare
92534c6
to
282ba94
Compare
unlockable_account_dual_type, | ||
'bad-password', | ||
None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot figure this out for the life of me why parity insists on returning True
if there is a failure to the personal_unlockAccount
call.
https://wiki.parity.io/JSONRPC-personal-module#personal_unlockaccount
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could a comment to the code explaining that this is the actual expected output at the moment, since its pretty weird. Maybe open an issue with Parity?
also pinging @dylanjw if you don't mind taking another look over this |
dbec384
to
7ca37c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just a couple small changes.
unlockable_account_dual_type, | ||
'bad-password', | ||
None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could a comment to the code explaining that this is the actual expected output at the moment, since its pretty weird. Maybe open an issue with Parity?
web3/personal.py
Outdated
return Method( | ||
"personal_importRawKey", | ||
mungers=[default_root_munger], | ||
formatter_lookup_fn=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Seeing the new Method class used, I think I need to make Method
's arguments more intuitive. I prefer omitting formatter_lookup_fn
here rather than setting it to None. Setting it to None looks like it would not have formatters applied, but it actually will have the default formatters applied. I will make changes to Method
to either remove formatter_lookup_fn
from the arguments, or have it override the default formatters when set to None or a custom lookup function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I would expect:
- "
formatter_lookup_fn
kwarg missing": default formatting - "
formatter_lookup_fn=None
": no formatting - "
formatter_lookup_fn=my_formatter
": onlymy_formatter
runs
ValueError, | ||
) | ||
|
||
# Test overridden here since eth-tester returns False rather than None for failed unlock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of changing eth-tester
's behavior to match geth
@@ -78,9 +142,9 @@ The following methods are available on the ``web3.personal`` namespace. | |||
|
|||
.. code-block:: python | |||
|
|||
>>> web3.personal.unlockAccount('0xd3cda913deb6f67967b99d67acdfa1712c293601', 'wrong-passphrase') | |||
>>> web3.parity.personal.unlockAccount('0xd3cda913deb6f67967b99d67acdfa1712c293601', 'wrong-passphrase') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this example result needs to switch to True
and almost certainly an explanation that that is not a typo in the docs.
web3/main.py
Outdated
{"name": "txpool", "module": TxPool}, | ||
{"name": "miner", "module": Miner}, | ||
{"name": "admin", "module": Admin}, | ||
{"name": "parity", "module": Parity, 'submodules': {'personal': ParityPersonal}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may like this format better:
return {
...
"admin": Admin,
"parity": (Parity, {"personal": ParityPersonal}),
...
}
One nice thing about this is that the submodule format is the same as the supermodule format, which makes for easier extension to multiple layers if desired. It also means less special casing when stitching the modules togother. Plus I think it's a little nicer to read.
Here's an example with 3 layers:
return {
...
"admin": Admin,
"parity": (Parity, {
"personal": ParityPersonal,
"test": (TestModule, {
"eth": ParityEthTest,
"bzz": ParitySwarmTest,
...
}),
}),
...
}
web3/personal.py
Outdated
return Method( | ||
"personal_importRawKey", | ||
mungers=[default_root_munger], | ||
formatter_lookup_fn=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I would expect:
- "
formatter_lookup_fn
kwarg missing": default formatting - "
formatter_lookup_fn=None
": no formatting - "
formatter_lookup_fn=my_formatter
": onlymy_formatter
runs
3f614e7
to
a770663
Compare
a770663
to
e912bec
Compare
module_class.attach(self, module) | ||
if submodules: | ||
for subname, subclasses in submodules[0].items(): | ||
subclasses[0].attach(getattr(self, module), subname) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carver Thoughts on this setup? Maybe there's a cleaner way to achieve the attaching of subclasses?
web3/main.py
Outdated
module_class, *submodules = modules[module] | ||
module_class.attach(self, module) | ||
if submodules: | ||
for subname, subclasses in submodules[0].items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this submodules[0]
looks surprising, I think. Also, if we're going to go with a recursive definition, might as well implement with a recursive solution, so it can go arbitrarily (well stack-limit) deep.
Something like a new utility method:
def attach_modules(parent_module, module_definitions)
for module_name, module_info in module_definitions.items():
module_class = module_info[0]
module_class.attach(parent_module, module_name)
if len(module_info) == 2:
submodule_definitions = module_info[1]
module = getattr(parent_module, module_name)
attach_modules(module, submodule_definitions)
elif len(module_info) != 1:
raise ValidationError("Module definition can only have 1 or 2 elements")
Then the web3 init just uses it, like:
attach_modules(self, modules)
e912bec
to
d78e187
Compare
What was wrong?
Updated
web3.personal
namespace toweb3.geth.personal
andweb3.parity.personal
which each reflect the personal jsonrpc endpoints supported by the respective client. Made the same update toPersonalModuleTest
->GoEthereumPersonalModuleTest
andParityPersonalModuleTest
for integration testing.Cute Animal Picture