feat: implement the dash analogue to BIP143#5860
Conversation
|
This pull request has conflicts, please rebase. |
|
Would be nice to have 7be17ee in a separate PR. Could maybe also introduce and use another helper like while at it. |
abdedb4 to
160dc04
Compare
|
pls check https://github.com/UdjinM6/dash/commits/pr5860/ branch for wip suggestions, specifically 84905a2 NOTE: I had to revert 0ef6ded and 160dc04 to make it work and also cf150bd to avoid merge conflicts in the future but the latter is optional I guess |
My thoughts: and DIP0143 would have been a nice moment for imposing no |
My idea was that with the current implementation that we have |
|
ok, so then smth like that 1eb9b4e on top I guess? |
So that the overall effect is moving this check from to yes, I like it so we can even get rid of |
not sure we can do that but let's see - we need tests :) |
e8e4762 to
774991a
Compare
Only if this flag is enabled it's possible to use the new sighash algorithm
Since Sigversion is now a local property of each input.
- Test that txs with SigVersion DIP0143 pass script verification only when the corresponding flag is set - Test that multi sig transactions can have their inputs signed with different SigVersion (one BASE, the other DIP0143) - Test that SigHashType DIP0143 cannot be used alone
So it is possible to generate DIP0143 SigHash from python tests
At the end I tried both methods and the one with |
8b6c96d refactor: a new constant with Tx Version (Alessandro Rezzi) 9d429f4 refactor: drop functions from struct which supposed to be simple as possible (Alessandro Rezzi) b2bb097 refactor: simplify vExtra using in wallet and add const (Alessandro Rezzi) d9f0e93 refactor: use CTransaction for immutable tx in evo_assetlocks_tests (Alessandro Rezzi) ca0fe8c refactor: introduce HasExtraPayloadField() (Alessandro Rezzi) 72d2008 refactor: introduce IsSpecialTxVersion() (Alessandro Rezzi) Pull request description: ## Issue being fixed or feature implemented Refactor extracted from #5860. Even if that PR should not need anymore this commit (since it has been found a better way to activate dip143), I think It's still a worthy refactor ## What was done? Introduce `tx.IsSpecialTxVersion()` in place of `tx.nVersion == 3`, `tx.nVersion >= 3` and `tx.HasExtraPayloadField()` in place of `tx.nVersion == 3 && tx.nType != TRANSACTION_NORMAL` ## How Has This Been Tested? ## Breaking Changes ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [X] I have performed a self-review of my own code - [X] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: knst: utACK 8b6c96d Tree-SHA512: aa16f9ee570e0fa86561cc440ffba40f6d554caa3e08b630b481732b899cc613eef596c672b5a20dbf3582ad109ffb687f4ad815f712dc16f636f8857d98480a
238978e fix: adjust `signrawtransactionwithkey` help text (UdjinM6) Pull request description: ## Issue being fixed or feature implemented `amount` was introduced in #3101. Double checked the code and yes, we do pass it around (for compatibility reasons) but it doesn’t affect the sig right now, you can set it to 0 or just skip it completely so it should be `optional`, not `required`. We even have a test that uses `signrawtransactionwithkey ` and ignores `amount` https://github.com/dashpay/dash/blob/master/test/functional/rpc_signrawtransaction.py#L19-L46. NOTE: It might become required for `sighashtype` with `SIGHASH_DIP0143` flag after #5860 activation. kudos to @pshenmic for noticing ## What was done? Adjust help text ## How Has This Been Tested? Run tests ## Breaking Changes n/a ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ Top commit has no ACKs. Tree-SHA512: e028c46b8b9c1663d9940642b08d56444ab4e5ab33015af1cb99265338b75f9e1c156cbbdd8e00f313bce87117019c769241cc4d83ccd6693ec0ffbaa8940e89
|
This pull request has conflicts, please rebase. |
❌ Backport Verification - Issues DetectedOriginal Bitcoin commit: N/A (Dash-native DIP0143 implementation) Issues found:
Note: This is not a Bitcoin backport but a Dash-native feature implementation. The standard backport verification process does not fully apply, but the PR requires significant manual work to address reviewer feedback and conflicts before it can be considered ready for merge. Please address the reviewer feedback from @UdjinM6 and @panleone, resolve merge conflicts, and ensure CI passes before re-requesting verification. |
Review GateCommit:
|
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
One real consensus issue: DIP0143 verification still applies legacy FindAndDelete to scriptCode, diverging from the verbatim hashing in SignatureHash and breaking BIP143-style semantics for spends whose script contains signature bytes. A functional-test helper also serializes vExtraPayload without its CompactSize prefix, diverging from C++ and any unit-test reference. The regtest-only deployment is explicit in the commit history (feat: add DIP0143 regtest params), so that is a staged-rollout observation rather than a blocker.
Reviewed commit: 0a2b5c8
🔴 1 blocking | 🟡 1 suggestion(s) | 💬 1 nitpick(s)
blocking: DIP0143 verification still applies FindAndDelete to scriptCode
src/script/interpreter.cpp (lines 356-359)
SignatureHash(..., SigVersion::DIP0143) at lines 1561-1609 hashes the supplied scriptCode verbatim (the central point of the BIP143-style preimage). However, EvalChecksig() at line 357 unconditionally calls FindAndDelete(scriptCode, CScript() << vchSig) before invoking checker.CheckSig, and the OP_CHECKMULTISIG path repeats the same unconditional deletion at lines 1178-1181. After DIP0143 activation, any spend whose executed script tail contains a signature byte sequence will be verified against a different preimage than the signer produced, causing valid DIP0143 signatures to fail (or, worse, divergent consensus across implementations that get this right vs. wrong). BIP143 specifically forbids FindAndDelete on the scriptCode for this reason; DIP0143 must do the same. The current unit tests only sign simple scripts where the signature bytes never appear in scriptCode, so they cannot catch this. Gate the FindAndDelete call behind sigversion == SigVersion::BASE (or skip when nHashType & SIGHASH_DIP0143 is set and the flag is enabled), matching BIP143's behavior in segwit code paths.
suggestion: DIP0143SignatureHash serializes vExtraPayload without CompactSize length prefix
test/functional/test_framework/script.py (lines 710-711)
The C++ preimage hashes extra payload with ss << txTo.vExtraPayload (interpreter.cpp:1601-1602), which—because vExtraPayload is a std::vector<unsigned char>—includes a CompactSize length prefix. Dash's Python serializer matches this: CTransaction.serialize_with_witness calls ser_string(self.vExtraPayload) (messages.py:495). The new DIP0143SignatureHash helper instead appends the raw bytes (ss += txTo.vExtraPayload), so any future functional test signing a version-3 special transaction with DIP0143 will compute the wrong hash. Use ser_string to match the on-the-wire encoding.
if (txTo.nVersion == 3 and txTo.nType != 0):
ss += ser_string(txTo.vExtraPayload)
nitpick: DIP0143 deployment parameters are only set on regtest
src/chainparams.cpp (lines 836-843)
DEPLOYMENT_DIP0143 parameters are added solely inside CRegTestParams (chainparams.cpp:836-843). Mainnet, testnet, and devnet constructors leave the deployment zero-initialized, so SCRIPT_ENABLE_DIP0143 will never be set in GetBlockScriptFlags() on persistent networks. The commit history (1c313a9c3a feat: add DIP0143 regtest params) suggests this is an intentional staged rollout where mainnet/testnet/devnet activation lands in a follow-up. Worth confirming with the PR author that this is deliberate, and tracking the follow-up to add the production deployments before DIP0143 is announced as usable.
_Inline posting via scripts/review_poster.py failed, so I posted the verified findings in the review body instead: Traceback (most recent call last):
File "/Users/claw/.openclaw/workspace/scripts/review_poster.py", line 138, in
result = post_review(repo, pr_number, head_sha, verified, dry_run=dry_run)
File "/Users/claw/.openclaw/workspace/scripts/review_poster.py", line 107, in post_review
result = _gh(
File "/Users/claw/.openclaw/workspace/scripts/review_poster.py", line 23, in gh
raise RuntimeError(f"gh {' '.join(args)} failed: {result.stderr.strip()}")
RuntimeError: gh api /repos/dashpay/dash/pulls/5860/reviews --method POST --input - failed: gh: Unprocessable Entity (HTTP 422)
Issue being fixed or feature implemented
Implement the bip143 analogue for dash, see here for documenation (dashpay/dips#149).
What was done?
A new sigHashType
SIGHASH_DIP0143has been added and txs inputs with this new sigHashType are signed with the new signature hash algorithm specified in the document.Feature is activated with an EHF hard fork and controlled with the script flag
SCRIPT_ENABLE_DIP0143How Has This Been Tested?
Many tests have been added:
SCRIPT_ENABLE_DIP0143is set, and the signed input contains the sigHashTypeSIGHASH_DIP0143SCRIPT_ENABLE_DIP0143is set.Checklist:
Go over all the following points, and put an
xin all the boxes that apply.