Skip to content

rpc: implement getdifficulty#973

Open
Micah-Shallom wants to merge 5 commits into
getfloresta:masterfrom
Micah-Shallom:feat/rpc-getdifficulty
Open

rpc: implement getdifficulty#973
Micah-Shallom wants to merge 5 commits into
getfloresta:masterfrom
Micah-Shallom:feat/rpc-getdifficulty

Conversation

@Micah-Shallom
Copy link
Copy Markdown
Contributor

Description and Notes

This PR implements getdifficulty, which returns the proof-of-work difficulty at the chain tip as a multiple of the minimum difficulty.

  • Uses the underlying implementations of using chain.get_best_block() and chain.get_block_header() to get the difficulty_float() from headers.

  • It returns an f64 difficulty which matches Bitcoin Core's output shape

Test plan

  • Functional test getdifficulty.py - spins up florestad + bitcoind on regtest, asserts both report a positive difficulty and match within rel_tol=1e-9 (a small drift between rust-bitcoin and Bitcoin Core's C++ arithmetic)
  • Manually tested on local regtest node against bitcoin-cli getdifficulty for parity
  • Clippy clean, fmt clean, build passes
image

@Davidson-Souza Davidson-Souza added new rpc This issue/PR implements a new json-rpc endpoint RPC Changes something with our JSON-RPC interface labels Apr 21, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in Floresta Apr 21, 2026
@Davidson-Souza Davidson-Souza moved this from Backlog to Needs review in Floresta Apr 21, 2026
Copy link
Copy Markdown
Member

@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.

ACK 66c1fb3

// getchaintxstats
// getdeploymentinfo

// getdifficulty
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can remove the comment now

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

okay though looking at the other rpc methods, there are oneline comments for each methods // <rpcname>
image

so i followed the same pattern for getdifficulty and shifted the remaining TODO method markers to the TODO block further down
image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok but would be nice if you did this formatting only in a single commit, its easier to review.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done @jaoleal ...moved to its own commit c41cbd7

Comment thread tests/floresta-cli/getdifficulty.py Outdated
Comment on lines +32 to +48
def run_test(self):
# Start florestad and bitcoind; both should start on the regtest
# genesis block and report a positive difficulty value.
self.run_node(self.florestad)
self.run_node(self.bitcoind)

floresta_difficulty = self.florestad.rpc.get_difficulty()
bitcoind_difficulty = self.bitcoind.rpc.get_difficulty()
self.log(f"florestad={floresta_difficulty}, bitcoind={bitcoind_difficulty}")

self.assertIsSome(floresta_difficulty)
self.assertTrue(floresta_difficulty > 0)
self.assertTrue(
math.isclose(
floresta_difficulty, bitcoind_difficulty, rel_tol=self.tolerance
)
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Extend this with a difficulty increase cenario

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @jaoleal.....i did a little search and saw that regtest sets fPowNoRetargeting = true, so nBits never changes no matter how many blocks we mine ....a true difficulty increase isn't reachable on that network as discussed here
image
https://bitcointalk.org/index.php?topic=5293244.0

this means REGTEST difficulty remains constant...
to confirm i extended the test to mine past the 2016 boundary and checked the difficulty at each step
image

and got
image

is this a necessary assertion to keep though??

note: 2016 was used cus of
image

Copy link
Copy Markdown
Member

@jaoleal jaoleal Apr 22, 2026

Choose a reason for hiding this comment

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

Okay, i went to search on how to do this with signet and it would need some more tooling on python side so perhaps it could be in a follow up ? I think its important to have that case being exercised.

Copy link
Copy Markdown
Contributor Author

@Micah-Shallom Micah-Shallom Apr 22, 2026

Choose a reason for hiding this comment

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

sounds good @jaoleal ....i will open a follow-up PR to track the signet network scenerio so it doesn't get lost

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ughmm should i strip the regtest mining assertions i added since they dont really excercise a real increase or maybe just keep it as a check to show that RPC always tracks the tip

Comment thread doc/rpc/getdifficulty.md

### Ok response

- `difficulty` - (numeric) The proof-of-work difficulty as a multiple of the minimum difficulty.
Copy link
Copy Markdown
Member

@jaoleal jaoleal Apr 22, 2026

Choose a reason for hiding this comment

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

I think its good to add notes for this doc that we have an acceptable difficulty difference compared to core.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

@Micah-Shallom Micah-Shallom force-pushed the feat/rpc-getdifficulty branch from 66c1fb3 to 4133e75 Compare April 22, 2026 13:35
@Micah-Shallom Micah-Shallom requested a review from jaoleal April 22, 2026 13:37
@Micah-Shallom
Copy link
Copy Markdown
Contributor Author

CI build for this got stuck after 6hrs
image

@Micah-Shallom
Copy link
Copy Markdown
Contributor Author

friendly ping @jaoleal

@jaoleal
Copy link
Copy Markdown
Member

jaoleal commented Apr 27, 2026

Goddamit

@Davidson-Souza
Copy link
Copy Markdown
Member

Needs rebase.

@Micah-Shallom Micah-Shallom force-pushed the feat/rpc-getdifficulty branch from cad67da to ce29a41 Compare April 30, 2026 21:30
@Micah-Shallom
Copy link
Copy Markdown
Contributor Author

rebased .... modified the testcase to make use of the new pytest convention @Davidson-Souza

Comment thread tests/floresta-cli/getdifficulty.py Outdated
Comment on lines +37 to +44
baseline = bitcoind_difficulty
for target_height in RETARGET_HEIGHTS:
current = bitcoind.rpc.get_block_count()
to_mine = target_height - current
if to_mine > 0:
bitcoind.rpc.generate_block(to_mine)
difficulty = bitcoind.rpc.get_difficulty()
assert math.isclose(difficulty, baseline, rel_tol=TOLERANCE)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is wrong. You’re not testing anything related to Floresta here. Basically, you’re just calling bitcoind.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yea i was actually going to strip that off as seen here #973 (comment) ...
@jaoleal asked for a difficulty increase..that block of code was to show that even on bitcoind difficulty doesnt not increase......i was just using bitcoind as a reference

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will take it out now

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm, he mentioned trying to vary the difficulty, and I agree with him; if that’s possible, it would be very welcome.

From what I looked at in the code, you extract the difficulty from the best block header. I think we could do the following: mine a block with a higher difficulty, take that hexadecimal value, hardcode it, and then just submit that block to bitcoind via submitblock.

I think that should work because the regtest genesis is static, so we can probably use a hardcoded block as long as it points to genesis as the previous block.

Copy link
Copy Markdown
Contributor Author

@Micah-Shallom Micah-Shallom May 2, 2026

Choose a reason for hiding this comment

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

thanks for ur review @moisesPompilio........ i tried this locally...generated a python script that mined 1 block with generatetoaddress, then fetched the raw block hex...mutated the bits a bit so that nBits differs from the regtest's default so we can see if bitcoind will accept it, remined the new nonce, cleared the chain tip and submitted the modified block but
Bitcoind responded:

Original nBits: 0x207fffff
Modified nBits: 0x207ffffe
submitblock response: {"jsonrpc":"2.0","result":"bad-diffbits","id":1}

image

the different nBits approach is rejected at the consensus level on regtest...

actual bitcoind regtest logs:
image

Copy link
Copy Markdown
Contributor Author

@Micah-Shallom Micah-Shallom May 2, 2026

Choose a reason for hiding this comment

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

it looks like the only way this will be successful is on a network that retargets its difficulty value just as......signet/testnet

WYT?? ion think we even have that test environment to begin with

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ping on this @moisesPompilio thanks

@Micah-Shallom Micah-Shallom force-pushed the feat/rpc-getdifficulty branch from ce29a41 to 2c0cc4e Compare May 1, 2026 14:34
@csgui csgui added reliability Related to runtime reliability, stability and production readiness and removed new rpc This issue/PR implements a new json-rpc endpoint labels May 8, 2026
@csgui csgui added this to the Q2/2026 milestone May 8, 2026
Copy link
Copy Markdown
Member

@jaoleal jaoleal left a comment

Choose a reason for hiding this comment

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

ACK 2c0cc4e

Regarding the tests, i think what we have here is enough for now... We still dont have a doable way to vary difficulty without odds workaround that possibly would loose the point of the test or to be out-of-scope to implement the pumbling for it... Perhaps we write a issue for that ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

reliability Related to runtime reliability, stability and production readiness RPC Changes something with our JSON-RPC interface

Projects

Status: Needs review

Development

Successfully merging this pull request may close these issues.

5 participants