rpc: implement getdifficulty#973
Conversation
| // getchaintxstats | ||
| // getdeploymentinfo | ||
|
|
||
| // getdifficulty |
There was a problem hiding this comment.
Ok but would be nice if you did this formatting only in a single commit, its easier to review.
| 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 | ||
| ) | ||
| ) |
There was a problem hiding this comment.
Extend this with a difficulty increase cenario
There was a problem hiding this comment.
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

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

is this a necessary assertion to keep though??
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
sounds good @jaoleal ....i will open a follow-up PR to track the signet network scenerio so it doesn't get lost
There was a problem hiding this comment.
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
|
|
||
| ### Ok response | ||
|
|
||
| - `difficulty` - (numeric) The proof-of-work difficulty as a multiple of the minimum difficulty. |
There was a problem hiding this comment.
I think its good to add notes for this doc that we have an acceptable difficulty difference compared to core.
66c1fb3 to
4133e75
Compare
|
friendly ping @jaoleal |
|
Goddamit |
4133e75 to
cad67da
Compare
|
Needs rebase. |
cad67da to
ce29a41
Compare
|
rebased .... modified the testcase to make use of the new pytest convention @Davidson-Souza |
| 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) |
There was a problem hiding this comment.
This is wrong. You’re not testing anything related to Floresta here. Basically, you’re just calling bitcoind.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
will take it out now
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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}
the different nBits approach is rejected at the consensus level on regtest...
There was a problem hiding this comment.
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
ce29a41 to
2c0cc4e
Compare
jaoleal
left a comment
There was a problem hiding this comment.
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 ?






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()andchain.get_block_header()to get the difficulty_float() from headers.It returns an f64 difficulty which matches Bitcoin Core's output shape
Test plan
getdifficulty.py- spins up florestad + bitcoind on regtest, asserts both report a positive difficulty and match withinrel_tol=1e-9(a small drift between rust-bitcoin and Bitcoin Core's C++ arithmetic)bitcoin-cli getdifficultyfor parity