-
-
Notifications
You must be signed in to change notification settings - Fork 19
refactor: change PoW difficulty to numeric target hash threshold #133
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,7 +14,7 @@ def calculate_hash(block_dict): | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def mine_block( | ||||||||||||||||||||||||||||||||||||
| block, | ||||||||||||||||||||||||||||||||||||
| difficulty=None, | ||||||||||||||||||||||||||||||||||||
| target=None, | ||||||||||||||||||||||||||||||||||||
| max_nonce=None, | ||||||||||||||||||||||||||||||||||||
| timeout_seconds=None, | ||||||||||||||||||||||||||||||||||||
| logger=None, | ||||||||||||||||||||||||||||||||||||
|
|
@@ -23,20 +23,20 @@ def mine_block( | |||||||||||||||||||||||||||||||||||
| """Mines a block using Proof-of-Work without mutating input block until success.""" | ||||||||||||||||||||||||||||||||||||
| max_nonce = max_nonce if max_nonce is not None else MINING_MAX_NONCE | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| difficulty = difficulty if difficulty is not None else block.difficulty | ||||||||||||||||||||||||||||||||||||
| if not isinstance(difficulty, int) or difficulty <= 0: | ||||||||||||||||||||||||||||||||||||
| raise ValueError("Difficulty must be a positive integer.") | ||||||||||||||||||||||||||||||||||||
| target = target if target is not None else block.target | ||||||||||||||||||||||||||||||||||||
| if not isinstance(target, int) or target <= 0: | ||||||||||||||||||||||||||||||||||||
| raise ValueError("Target must be a positive integer.") | ||||||||||||||||||||||||||||||||||||
| block.target = target | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| target = "0" * difficulty | ||||||||||||||||||||||||||||||||||||
| local_nonce = 0 | ||||||||||||||||||||||||||||||||||||
| header_dict = block.to_header_dict() # Construct header dict once outside loop | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Keep target overrides atomic and consensus-valid. Line 29 mutates the input before timeout/cancellation/max-nonce failure, contradicting the documented contract; a later retry can mine with the stale override. Also reject targets above Proposed fix def mine_block(...):
+ from .network_config import MAX_TARGET
+
target = target if target is not None else block.target
- if not isinstance(target, int) or target <= 0:
- raise ValueError("Target must be a positive integer.")
- block.target = target
+ if isinstance(target, bool) or not isinstance(target, int) or not 0 < target <= MAX_TARGET:
+ raise ValueError("Target must be an integer within consensus bounds.")
local_nonce = 0
- header_dict = block.to_header_dict()
+ header_dict = block.to_header_dict()
+ header_dict["target"] = hex(target)
...
if int(block_hash, 16) < target:
+ block.target = target
block.nonce = local_nonce📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.16.0)[warning] 28-28: Avoid specifying long messages outside the exception class (TRY003) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| start_time = time.monotonic() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if logger: | ||||||||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||||||||
| "Mining block %s (Difficulty: %s)", | ||||||||||||||||||||||||||||||||||||
| "Mining block %s (Target: %s)", | ||||||||||||||||||||||||||||||||||||
| block.index, | ||||||||||||||||||||||||||||||||||||
| difficulty, | ||||||||||||||||||||||||||||||||||||
| target, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| while True: | ||||||||||||||||||||||||||||||||||||
|
|
@@ -56,8 +56,8 @@ def mine_block( | |||||||||||||||||||||||||||||||||||
| header_dict["nonce"] = local_nonce | ||||||||||||||||||||||||||||||||||||
| block_hash = calculate_hash(header_dict) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| # Check difficulty target | ||||||||||||||||||||||||||||||||||||
| if block_hash.startswith(target): | ||||||||||||||||||||||||||||||||||||
| # Check target | ||||||||||||||||||||||||||||||||||||
| if int(block_hash, 16) < target: | ||||||||||||||||||||||||||||||||||||
| block.nonce = local_nonce # Assign only on success | ||||||||||||||||||||||||||||||||||||
| block.hash = block_hash | ||||||||||||||||||||||||||||||||||||
| if logger: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Parse protocol targets strictly before validating bounds.
int(raw_target)silently converts values such astrueand1.9, whileisinstance(block.target, int)also acceptsTrue. Restrict targets to non-boolean integers or valid hex strings, and handle conversion failures consistently.minichain/chain.py#L96-L102: reject booleans/floats instead of coercing them, and catch malformed hex or numeric values before exiting.minichain/chain.py#L30-L34: explicitly reject booleans when validating a received block target.📍 Affects 1 file
minichain/chain.py#L96-L102(this comment)minichain/chain.py#L30-L34🤖 Prompt for AI Agents