8000 [Rpcsaga] add blockhash to gettxoutproof by jaoleal · Pull Request #472 · vinteumorg/Floresta · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[Rpcsaga] add blockhash to gettxoutproof #472

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jaoleal
Copy link
Contributor
@jaoleal jaoleal commented May 5, 2025

What is the purpose of this pull request?

  • Bug fix
  • Documentation update
  • New feature
  • Test
  • Other:

Which crates are being modified?

  • floresta-chain
  • floresta-cli
  • floresta-common
  • floresta-compact-filters
  • floresta-electrum
  • floresta-watch-only
  • floresta-wire
  • floresta
  • florestad
  • Other:

Description

Fix #378

This commit present some changes for gettxoutproof, adding the optional blockhash
input which will make the method interns differ, searching for the transactions
inside the specified block, otherwise, the previous default behavior of getting it
from the wallet cache remains. The method now receives an array of txids instead of
just one.

Also, now named gettxoutproof, was gettxproof.

A unused #[allow(unused)] was also removed from merkle.rs

Notes to the reviewers

While trying to fork and just complete #379 to accomplish one of 0.8.0 milestones i noticed some opportunities to optimize some decisions and add two new fixes to the #378 issue. (1. and 2.)

Still validating if the changes are effective and are working.

Author Checklist

  • I've followed the contribution guidelines
  • I've verified one of the following:
    • Ran just pcc (recommended but slower)
    • Ran just lint-features '-- -D warnings' && cargo test --release
    • Confirmed CI passed on my fork
  • I've linked any related issue(s) in the sections above

Finally, you are encouraged to sign all your commits (it proves authorship and guards against tampering—see How (and why) to sign Git commits and GitHub's guide to signing commits).

@Davidson-Souza Davidson-Souza added bug Something isn't working RPC Changes something with our JSON-RPC interface labels May 5, 2025
@jaoleal jaoleal marked this pull request as ready for review May 6, 2025 18:27
@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch 3 times, most recently from 9ff7536 to 9a8bed0 Compare May 7, 2025 16:39
@jaoleal
Copy link
Contributor Author
jaoleal commented May 7, 2025

Applied @Davidson-Souza requests and rewrote the commit message, now appears to better explain whats being done here.

Refer to the PR description to read the last commit message

@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch from 9a8bed0 to a336c21 Compare May 7, 2025 18:11
@jaoleal
Copy link
Contributor Author
jaoleal commented May 7, 2025

Applied @Davidson-Souza s suggestions. (#472 (comment))

&self,
tx_ids: &[Txid],
blockhash: Option<BlockHash>,
) -> Result<Vec<Vec<String>>, RpcError> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

From Core's documentaion I think this function should return one string. It is probably better if you use rust-bitcoin for this. For the block case you can use MerkleBlock::from_header_txids_with_predicate and then serialize_hex. For the cached ones it's harder, I don't think there's an easy solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, this change a lot of things to really make this core-like. Turning to draft again.

Copy link
Contributor Author
@jaoleal jaoleal May 14, 2025

Choose a reason for hiding this comment

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

MerkleBlock doesnt have any serialize_hex, im trying to use consensus_encode() since its what might be the right way to do it... The only thing that might be wrong here is if rust-bitcoin enconding doesnt match cores. But im not being able to reproduce the command perfectly, the setup needed is quite boring to workout and floresta is giving me some strange bugs that i may post issues about.

Copy link
Collaborator

Choose a reason for hiding this comment

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

MerkleBlock doesnt have any serialize_hex

serialize_hex is a standalone function from bitcoin::consensus

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, saw it... but it just does what im already doing... I`ll change the code for sanity but the result will be the same

@jaoleal jaoleal marked this pull request as draft May 8, 2025 19:04
@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch 6 times, most recently from bfd35e8 to 32699d5 Compare May 14, 2025 16:05
@jaoleal jaoleal marked this pull request as ready for review May 14, 2025 18:40
@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch 4 times, most recently from 127f778 to 248ceef Compare May 14, 2025 19:21
Comment on lines 150 to 156
#[command(name = "gettxoutproof")]
GetTxOutProof {
/// The transaction IDs to prove
#[arg( required = true, value_parser = parsers::jsonlike_array_of_txids)]
txids: std::vec::Vec<Txid>, // you need to specify the path of Vec https://github.com/clap-rs/clap/discussions/4695

/// The block in which to look for the transactions
#[arg(short = 'b', long = "blockhash", last = true, required = false)]
blockhash: Option<BlockHash>,
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Im struggling with clap config aiming to match cores api but it seems impossible since the only way that i can pass blockhash is by either specifying a flag or passing it after a --
The way it is, you can call it like:

floresta-cli gettxoutproof '["77bc13bb64c290fc6a1be9f2b9141d84417329a416411ada2f035ee2f754bb86"]' -- 00000000000000000002266ea7f71eb350a9a55e5672136a51ce6534d42247eb

in the end, youll need atleast to adaptate something to integrate floresta RPC where cores was

Copy link
8000 Collaborator
@Davidson-Souza Davidson-Souza May 15, 2025

Choose a reason for hiding this comment

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

This is because you made it into an option, rather than an argument. Remove all the annotation for the second field but #[arg(required = false)]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice, made it work!!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

floresta-cli gettxoutproof '["77bc13bb64c290fc6a1be9f2b9141d84417329a416411ada2f035ee2f754bb86"  , "77bc13bb64c290fc6a1be9f2b9141d84417329a416411ada2f035ee2f754bb86"]' 00000000000000000002266ea7f71eb350a9a55e5672136a51ce6534d42247eb

When i print with

println!("{:?}", txids);
println!("{:?}", blockhash);

[77bc13bb64c290fc6a1be9f2b9141d84417329a416411ada2f035ee2f754bb86, 77bc13bb64c290fc6a1be9f2b9141d84417329a416411ada2f035ee2f754bb86]
Some(00000000000000000002266ea7f71eb350a9a55e5672136a51ce6534d42247eb)

@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch from 248ceef to 19d5ff7 Compare May 14, 2025 19:42
@jaoleal
Copy link
Contributor Author
jaoleal commented May 15, 2025

332e69d, made the command succeed exactly with cores api, you can check this by yourself.

floresta-cli gettxoutproof '["5a4ebf66822b0b2d56bd9dc64ece0bc38ee7844a23ff1d7320a88c5fdb2ad3e2"]' 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6

"01000000ba8b9cda965dd8e536670f9ddec10e53aab14b20bacad27b9137190000000000190760b278fe7b8565fda3b968b918d5fd997f993b23674c0af3b6fde300b38f33a5914ce6ed5b1b01e32f570200000002252bf9d75c4f481ebb6278d708257d1f12beb6dd30301d26c623f789b2ba6fc0e2d32adb5f8ca820731dff234a84e78ec30bce4ec69dbd562d0b2b8266bf4e5a0105"

and this is from a bitcoin core node (Im using a gambiarra with jq and a public node)

[nix-shell:~]$ btc-rpc gettxoutproof '["5a4ebf66822b0b2d56bd9dc64ece0bc38ee7844a23ff1d7320a88c5fdb2ad3e2"]' 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6

{
  "jsonrpc": "2.0",
  "id": "curl",
  "result": "01000000ba8b9cda965dd8e536670f9ddec10e53aab14b20bacad27b9137190000000000190760b278fe7b8565fda3b968b918d5fd997f993b23674c0af3b6fde300b38f33a5914ce6ed5b1b01e32f570200000002252bf9d75c4f481ebb6278d708257d1f12beb6dd30301d26c623f789b2ba6fc0e2d32adb5f8ca820731dff234a84e78ec30bce4ec69dbd562d0b2b8266bf4e5a0105"
}

cc @Davidson-Souza

This commit present some changes for gettxoutproof, adding the optional blockhash
input which will make the method interns differ, searching for the transactions
inside the specified block, otherwise, the previous default behavior of getting it
from the wallet cache remains. The method now receives an array of txids instead of
just one.

A unused #[allow(unused)] was also removed from merkle.rs

Also, now named gettxoutproof, was gettxproof.
@jaoleal jaoleal force-pushed the rpcsaga_addblockhashtogettxoutproof branch from 19d5ff7 to 332e69d Compare May 15, 2025 18:10
Copy link
Collaborator
@Davidson-Souza Davidson-Souza left a comment

Choose a reason for hiding this comment

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

I've tested it and it seems to work fine. Cross checked with core and it seems right.

Some comments about the code

@@ -21,6 +21,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
jsonrpc = { version = "0.18.0", optional = true, features = ["minreq_http"] }
thiserror = "2.0.12"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think in #86 we've discussed we wouldn't use thiserror forward. Using the macros and manual derivation instead. So I think we shouldn't add it here.

///
/// A good example for these parsers is the ['parsers::jsonlike_array_of_txids']
/// that permit to `gettxoutproof` to receive the txids input as '["txid1","txid2"]'.
pub mod parsers {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you intended to add more of these? Might be better to leave them in their own file.

fn get_txout_proof(&self, txids: Vec<Txid>, blockhash: Option<BlockHash>) -> Result<String> {
let params: Vec<Value> = match blockhash {
Some(blockhash) => vec![
serde_json::to_value(txids).unwrap(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove the unwraps

let tx = self.get_transaction(txid)?;
/// Returns the Merkle Proof for a given txid
///
/// Fails if a given Txid is an unconfirmed transaction.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Returns None. Failing more like a function that returns Result

@@ -28,6 +28,10 @@ impl MerkleProof {
pos: 0,
}
}
F438 /// Return the hashes fot this proof as a [`Vec<String>`]
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: typo on for

/// This function has two paths, when blockhash is inserted and when isn't.
///
/// Specifying the blockhash will make this function go after the block and search
/// for the transcations inside it, building a merkle proof from the block with its
Copy link
Collaborator

Choose a reason for hiding this comment

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

typo: transcations

Comment on lines +225 to +230
// Before building the merkle block we try to remove all txids
// that arent present in the block we found, meaning that
// at least one of the txids doesnt belong to the block which
// in case needs to make the command fails.
//
// this makes the use MerkleBlock::from_block_with_predicate useless.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Before building the merkle block we try to remove all txids
// that arent present in the block we found, meaning that
// at least one of the txids doesnt belong to the block which
// in case needs to make the command fails.
//
// this makes the use MerkleBlock::from_block_with_predicate useless.
// Before building the merkle block we try to remove all txids
// that aren't present in the block we found, meaning that
// at least one of the txids doesn't belong to the block which
// in case needs to make the command fails.
//
// this makes the use MerkleBlock::from_block_with_predicate useless.

@@ -202,6 +203,7 @@ pub enum Error {
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::InvalidBlockHash => write!(f, "Inserted a invalid BlockHash"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Error::InvalidBlockHash => write!(f, "Inserted a invalid BlockHash"),
Error::InvalidBlockHash => write!(f, "Provided a invalid BlockHash"),

.0
.to_lower_hex_string(),
)
.expect("GetTxOutProof implements serde"))
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit empty line after the end of gettxoutproof

Comment on lines +276 to +283
let blockhash = if params.len() > 1 {
Some(
serde_json::from_value(params[1].clone())
.map_err(|_| Error::InvalidBlockHash)?,
)
} else {
None
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can make this more clear with combinators

Suggested change
let blockhash = if params.len() > 1 {
Some(
serde_json::from_value(params[1].clone())
.map_err(|_| Error::InvalidBlockHash)?,
)
} else {
None
};
let blockhash = params
.get(1)
.cloned()
.map(serde_json::from_value)
.transpose()
.map_err(|_| Error::InvalidBlockHash)?;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working RPC Changes something with our JSON-RPC interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Floresta-CLI gettxproof command don't work with blockhashs argument passed
2 participants
0