Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Feat/verify mainstay inclusion - #78

Closed
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion
Closed

Feat/verify mainstay inclusion#78
DhananjayPurohit wants to merge 11 commits into
civkit:mainfrom
DhananjayPurohit:feat/verify-mainstay-inclusion

Conversation

@DhananjayPurohit

Copy link
Copy Markdown
Contributor

No description provided.

@ariard

Copy link
Copy Markdown
Contributor

see #79 with functional RPC calls on bitcoind

with following config details

# Password for JSON-RPC connections
rpcpassword=hello_world
# Username for JSON-RPC connections
rpcuser=civkitd_client
# Use the chain <chain> (default: main). Allowed values: main, test,
# signet, regtest
chain=regtest

implementing verifytxoutproof passthrough, that way civkit sample should be able to verify proofs by relying on a civkitd node, alternatively.

will review more this one.

@DhananjayPurohit

Copy link
Copy Markdown
ContributorAuthor

So, this verifytxoutproof should be called using the command from civkit-cli, right? Also the files having .proto extension need to be modified or its auto-generated?

Comment threadCargo.toml Outdated
base64 = "0.21.4"
jsonrpc = "0.14.0"
rs_merkle = "1.4.1"
bitcoincore-rpc = "0.17.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can remove the usage of this crate. Latest branch introduce a functional RPC client, gives us more flexibility on parameters formatting.

Comment threadsrc/bitcoind_client.rs Outdated
}

pub async fn verifytxoutproof() {
pub async fn verifytxoutproof(txid: String, slot: usize, mut inclusion_proof: InclusionProof) -> bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is where we’re out-of-sync:

verifytxoutproof is a RPC method in Bitcoin Core: https://github.com/bitcoin/bitcoin/blob/master/src/rpc/txoutproof.cpp#L123

This method takes a CMerkleBlock and then return a result if the pointed to txid has been included in the chain. CMerkleBlock contains a CPartialMerkleTree (which internally points to a txid).

Here verifytxoutproof should be just a call to self.rpc_client.call(“verifytxoutproof”, &[merkle_block]) to realize the latest step of mainstay proof verification, namely that the txid has been included in the chain.

Now in term of API, we have two options (at least):

  • a) move this verification code (commitment, slot proof, merkle root inclusion) in the client-side (i.e into civkit-sample)
  • b) have just the client with a method verifiyinclusionproof and a given txid

As the ultimate step of the verification flow is dependent on chain access and txidindex (which takes some server ressource), mobile clients will most of the time rely on a server. So I think we can have this code here, just wrapping verify_commitments / verify_slot_proof and verify_merkle_root_inclusion in a dedicated mainstay method and have this in notaryd calling back verifytxoutproof for the latest step).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Want to clarify what we want to do here and how.

In order to verify the merkle root inclusion in the mainstay transaction we need to get the scriptPubKey of the tx and to verify it's confirmation. The current method is that the mainstay proof just contains the merkle root (and path) and the TxID, and the verification process consists of using getrawtransaction to confirm the txid is confirmed AND get the scriptPubKey from the raw/deserialised tx returned (then verify scriptPubKey is tweaked with the merkle root).

This is the simplest approach as it only means the mainstay 'proof' object needs the TxID and merke root, however it also requires a node with txindex=1.

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

gettxoutproof requires txindex=1 so a a pruned node would only suffice for verification, you would need a full node for generating proofs.

Does this make sense - we should go with this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to enable verification of proofs with a pruned node (with txindex=0) then we can use verifytxoutproof . But for this to work, we need to know the a) The full raw transaction and b) The proof generated by gettxoutproof . These would have to be included in the 'proof' object.

I think we’re in sync here - Note to call verifytxoutproof you only need the merkle block generated by gettxoutproof, the full raw transaction isn’t a requirement, see the tests in rpc_txoutproof.py.

That said, of course better to use getrawtransaction if this fits the current usage of verifying the merkle root inclusion in a mainstay transaction. Note you can use getrawtransaction with the current civkitd rpc framework with Client::call().

Note my feedback was mostly on the resource trade-offs and verification responsibility between client and server. As both alternatives are requiring txindex=1, I don’t think it matters. I can see a new verifyinclusionproof with the scriptpubkey, the txid and the merkle root, the commitment and the merkle path. What is unclear to me is how the user learns the scriptpubkey, from our conversation here: #64 (comment)

I think we should go with this, even if the high-level API we should introduce for the civkit user at the client-level (i.e currently civkit-sample is unclear to me, we can address this in a follow-up PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The user can only learn the scriptPubKey from the raw (deserialised) tx - that's why it needs to be included in the proof if can't be retrieved with getrawtransaction .

@ariard

Copy link
Copy Markdown
Contributor

So, this verifytxoutproof should be called using the command from civkit-cli, right?

This is bottom interface servicing all the civkit components that need themselves access to bitcoind state, so CredentialGateway and mainstay to verify inclusion proof for now (in the future maybe to serve some on-chain payment proof).

Also the files having .proto extension need to be modified or its auto-generated?

The .proto are manually edited and then auto-generated by the tonic framework in rust code which is itself compiled to binary.

Architecturally, I think it could be valuable to start using mainstay proof generation and verification in notaryd, for now just using as a front-end for mainstay server, then we can add more functionalities with time, e.g announcing mainstay as a service over ln gossips or nostr.

@ariard

Copy link
Copy Markdown
Contributor

Will review more this one, we can add the good API for civkit clients matching the underlying mainstay operations in future PR.

@ariardariard mentioned this pull request Dec 13, 2023
@ariard

Copy link
Copy Markdown
Contributor

Thanks for the work here - Rather to review when to manually fix the issues, see #109.
You should be credited in the commit message. I’ll land it, we can do follow-up PRs after.

@ariardariard closed this Dec 13, 2023
Sign up for freeto 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.

3 participants

@DhananjayPurohit@ariard@tomt1664