Skip to content
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

node: add spv mode with 5pi fallback #409

Merged
merged 4 commits into from
Oct 10, 2021
Merged

node: add spv mode with 5pi fallback #409

merged 4 commits into from
Oct 10, 2021

Conversation

chikeichan
Copy link
Contributor

@chikeichan chikeichan commented Sep 10, 2021

Adding SPV mode with a fallback to 5pi for all calls that requires full node (getTX, getCoin, getNameInfo, etc). Code include a proxy boolean flag to execRPC to tell Bob to proxy to 5pi when on spv.

Also copied implementation of verifymessagewithname so that we dont have to send message to a hosted node to verify.

Storage comparison: 31MB vs 9GB 😮

When syncing in spv mode, the node seem to be stucked at around 65%. Closing and reopening Bob a few times (3 times is the charm for me) seems to resume syncing for some reason.

To enable SPV mode, simply click enable and wait for node to restart

Screen Shot 2021-09-10 at 11 42 58 PM

@chikeichan chikeichan marked this pull request as ready for review September 10, 2021 15:35
@chikeichan
Copy link
Contributor Author

ready for review and feel free to pull down for testing.

however, i wont merge until i deploy the better version of 5pi by @kurumiimari :D

async verifyMessageWithName(name, signature, str) {
if (await this.getSpvMode()) {
const result = await this.getNameInfo(name);
const owner = result?.info?.owner;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this syntax requires nodejs v16 (or is it 14?) Dunno if you've already mentioned that in the readme or set "engines" in package.json ? I guess it's be electron version anyway not nodejs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be enabled with a webpack configurations. Forgot what the exact option is but our configs already supports it.

if (addr.version !== 0 || addr.hash.length !== 20)
return false;

const MAGIC_STRING = `${pkg.currency} signed message:\n`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of re-implementing this here, you should be able to call a regular verifymessage command once you obtain the address.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing I want to avoid tho is sending the signature to hosted node. It seems better to be able to verify signature locally, instead of relying on a hosted node to tell me. Perhaps we can make it an exportable util function in hsd?

Copy link
Contributor

@pinheadmz pinheadmz Sep 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPV nodes still have rpc verifymessage, it just takes an addres as input instead of the name. So once you get the corresponding address from the API you can just call that locally.

Also, why not send the signature to the API server? We're trusting that node for lots of other stuff already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trust but verify is the general model. We are trusting the hosted node for things that we could verify locally.

For verifymessage, doing it locally means that we only need to trust the node to send us the correct name owner (which could be independently verify) and then verify signature locally. If we rely on the node, we would only get a boolean of whether or not the message is valid, but no ways to verify independently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPV nodes still have rpc verifymessage

Ah, I will do this

Copy link
Contributor

@pinheadmz pinheadmz Sep 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually - even trusting the full node to return the owner coin should technically be provable - using Urkel. I don't think we have this in hsd quite yet, but an SPV node could use the same pool.resolve() function it uses to resolve TLDs with Urkel Proofs, but instead of returning the dns resource, it could return the owner. (The entire Namestate object is included in urkel, including owner). If you want to explore this route, maybe start with a PR to hsd instead of trying to implement in the UI layer ;-)

}

async _execRPC(method, args, proxy) {
if (proxy) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we ever use the proxy if not in SPV mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I will rename variable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm maybe i misunderstand. im not asking about the variabel name but why you need to check BOTH proxy AND this.getSpvMode() ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh! this is actually for the rpc method that we DONT want to proxy to hosted node on SPV, such as verifymessage, sendrawtransactions, sendrawairdrop, etc.

method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + Buffer.from(`x:775f8ca39e1748a7b47ff16ad4b1b9ad`).toString('base64'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL why bother? ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too lazy to change code in old 5pi 😂
New 5pi is gonna public to all by default after we switch

@pinheadmz
Copy link
Contributor

Looks pretty simple! Left some comments, have not tested yet. Looks like you caught estimatefee already which is an important thing SPV can't do. 👍

@pinheadmz
Copy link
Contributor

I think we should also think about overall available network resources when we deploy. We've already seen a ton of hnsd nodes come online with Fingertip release! I think we should consider setting max-outbound: 4 (default is 8) in Bob wallet, across the board full node and spv mode. I know Kyokan is supporting Bob with the 5pi service, maybe Kyokan could also host one or two full nodes with bip37 enabled, and set those peers as seed nodes in the Bob Wallet configuration.

@chikeichan
Copy link
Contributor Author

I think we should also think about overall available network resources when we deploy. We've already seen a ton of hnsd nodes come online with Fingertip release! I think we should consider setting max-outbound: 4 (default is 8) in Bob wallet, across the board full node and spv mode. I know Kyokan is supporting Bob with the 5pi service, maybe Kyokan could also host one or two full nodes with bip37 enabled, and set those peers as seed nodes in the Bob Wallet configuration.

Will add max outbound in a separate PR

put(prefixHash(hash), name);
return name;
}

async getAuctionInfo(name) {
return this._execRPC('getauctioninfo', [name]);
return this._execRPC('getauctioninfo', [name], true);
Copy link
Contributor

@pinheadmz pinheadmz Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, isn't this a wallet RPC? If this RPC called from the full node? Looks like its duplicated from the wallet RPC where it is actually used. I think this can be pulled from node/service.js

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea this method is actually not being used by UI - will remove

@rithvikvibhu rithvikvibhu deleted the spv branch February 1, 2022 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants