-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Public node with accounts and signing in Frontend #5304
Conversation
While throttling the amount of requests the UI can make to the web node is definitely important, we should also be able to throttle the amount (and intensity) of RPC requests in general. It's fair to assume that any publicly-available RPC will be pummeled mercilessly sometimes by malicious actors. |
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 good! I love the way you handled unsupported requests with AccountProvider
, very clean!
Most important issue is that only a whitelist of APIs should be enabled, listed them in comment. Not sure how well GUI will work without those APIs.
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; | ||
const LOCAL_STORAGE_KEY = '_parity::localAccounts'; | ||
|
||
function fromLocalStorage () { |
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 think UI code uses store
library exactly for that.
|
||
const account = this._store.find((account) => account.address === address); | ||
|
||
if (account == null) { |
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.
=== null
? Should be caught by linter anyway.
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 tend to use == null
as an existence check, since the only values it can coerce to are null
and undefined
. if (!account)
would also work. Is there a specific way to catch existence of a value that fits the code style?
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 think if (!account) {
is used everywhere.
return false; | ||
} | ||
|
||
if (address === this._last) { |
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.
Is there a guarantee that this._last
will be lowercased? I think it would be safer to do: address === this._last.toLowerCase()
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.
It should be guaranteed to be lowercase as any inputs where address is passed are forced to lowercase before anything is done with it. That said, I'll add a setter to make it clearer it's an expected behavior.
clearTimeout(this._persistTimer); | ||
|
||
// Throttle persisting the accounts | ||
this._persistTimer = setTimeout(() => { |
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.
_.debounce
?
@@ -0,0 +1,7778 @@ | |||
export default [ |
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.
Can we push the dictionary as a separate library (JS and Rust?) It's already duplicated in native-signer
and parity
.
Will prepare a repo.
js/src/api/local/middleware.js
Outdated
|
||
// Maps transaction requests to transaction hashes. | ||
// This allows the locally-signed transactions to emulate the signer. | ||
const transactionHashes = {}; |
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.
Why is it not part of the instance? Or at least static
fields if we want to share it between instances.
const middleware = this.parity | ||
.nodeKind() | ||
.then((nodeKind) => { | ||
if (nodeKind.availability === 'public') { |
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.
What if nodeKind
is changed during lifetime of the UI (e.g. Parity being restarted without closing tab window)?
rpc/src/v1/helpers/accounts.rs
Outdated
match *provider { | ||
Some(ref weak) => weak.upgrade().ok_or_else(Error::internal_error), | ||
None => Err(Error { | ||
code: ErrorCode::InvalidRequest, |
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 tried to use helpers::errors::codes::UNSUPPORTED_REQUEST
for such stuff in the past, might be good to stay consistent with the error codes.
rpc/src/v1/helpers/accounts.rs
Outdated
use ethcore::account_provider::AccountProvider; | ||
use jsonrpc_core::{Error, ErrorCode}; | ||
|
||
pub fn unwrap_provider(provider: &Option<Weak<AccountProvider>>) -> Result<Arc<AccountProvider>, Error> { |
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.
That's pretty clever solution! :) Loving it 👍
@@ -128,6 +128,7 @@ impl Configuration { | |||
Some(true) if pruning == Pruning::Specific(Algorithm::Archive) => writeln!(&mut stderr(), "Warning: Warp Sync is disabled because pruning mode is set to archive").expect("Error writing to stderr"), | |||
_ => {}, | |||
}; | |||
let public_node = self.args.flag_public_node; |
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.
Public node should have only subset of APIs enabled:
eth,net,parity,rpc,web3
Some of the disabled APIs are already useless because AccountProvider
is missing, but stuff like parity_stopNetwork
should also be disabled.
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.
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.
Just a grumble regarding nodeKind
being changed during the lifetime of a website.
tests failing. |
Yeah, not sure what's up with the tests:
@tomusdrw I talked about this with Jaco, will bundle it with network change in the FE, which triggers a full reload. UX shouldn't really be an issue as that's pretty far from standard behavior. |
fc31fdf
to
a64cb9c
Compare
a64cb9c
to
9bd3f10
Compare
Disclaimer: The PR includes a copy of the dictionary for the frontend, hence the crazy diff. It's not that big.
Start parity with
--public-node
(suggestions for a better flag open):Some concerns and general notes: