Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
0b056c2
fix(rpc-json)!: resolve Core 23 nested platform addresses (breaking f…
lklimek Jun 17, 2026
64d9267
fix(key-wallet): honor account index in DashPay derivation path (#813)
shumkov Jun 18, 2026
ceee4a9
revert(rpc-json)!: resolve Core 23 nested platform addresses (#814)
shumkov Jun 19, 2026
95a3c8f
fix(dash-spv): prevent filter sync crash on new block after full sync…
xdustinface Jun 22, 2026
3f207d8
feat(key-wallet): add Signer::extended_public_key (#817)
shumkov Jun 24, 2026
d9fe0a3
chore(dash-spv): refresh masternode seed files (#805)
github-actions[bot] Jun 24, 2026
7262125
feat(key-wallet): address pools gap limit can be externally modified …
ZocoLini Jun 25, 2026
8c7b501
feat(key-wallet): track internal address pools for CoinJoin accounts …
ZocoLini Jun 26, 2026
e6b8b87
fix: resolve just-retired quorum by walking earlier masternode lists …
xdustinface Jun 26, 2026
1b53458
fix(dash-spv): reprocess blocks on rescan against newly derived scrip…
xdustinface Jun 26, 2026
e9f3816
fix: compute SML entry hash with `SER_GETHASH` semantics in `dash` (#…
xdustinface Jun 26, 2026
ddb59d9
fix: release builds warning removed (#825)
ZocoLini Jun 26, 2026
03096dd
feat(key-wallet): support for more account types + strategy to consum…
ZocoLini Jun 29, 2026
6adc753
docs: add `0.43.0` and `0.44.0` changelog entries (#830)
xdustinface Jun 30, 2026
78d1002
chore: bump version to `0.45.0` (#829)
xdustinface Jun 30, 2026
d7caf4e
feat(key-wallet): impl Zeroize for ExtendedPrivKey (#833)
lklimek Jul 2, 2026
9cb8037
refactor(key-wallet): ManagedAccountType::from_account_type refactor …
ZocoLini Jul 2, 2026
a8a0968
perf: reduced amount of block hashes computed (#834)
ZocoLini Jul 2, 2026
788c19d
fix(key-wallet): reserve selected UTXOs to prevent double-spend (#812)
xdustinface Jul 2, 2026
afcff15
refactor(key-wallet): move extended_public_key out of Signer into Ext…
QuantumExplorer Jul 2, 2026
b0a909c
ci: fix `ready-for-review` label automation for fork pull requests (#…
xdustinface Jul 2, 2026
95d0813
fix(dash-spv): degrade gracefully when advisory file locking is unsup…
QuantumExplorer Jul 5, 2026
a1b9848
fix(dash-spv): replaced TARGET_PEERS with already existing max_peers …
ZocoLini Jul 5, 2026
c88264e
fix(dash-spv): avoid filter sync getting stuck on the first new block…
xdustinface Jul 5, 2026
417d61d
fix(key-wallet): don't build asset locks on unconfirmed funds (#836)
xdustinface Jul 6, 2026
647fa98
ci: stop `evaluate` failing when a PR's CI is pending or red (#844)
xdustinface Jul 6, 2026
3170ad3
fix(key-wallet): preserve UTXO flags across reprocessing (#837)
xdustinface Jul 6, 2026
49c243a
feat(key-wallet): seed sync checkpoint from `birth_height` (#693)
xdustinface Jul 7, 2026
832bab2
perf(hashes): SIMD-batched SipHash-2-4 for BIP158 filter matching (#845)
ZocoLini Jul 8, 2026
91bb72e
peer reputation module cleanup (#328)
ZocoLini Jul 9, 2026
e4f11a1
feat(dash-spv): anchor sync at wallet birth height checkpoint (#848)
xdustinface Jul 9, 2026
116421f
fix(key-wallet): actionable error when add_account(_, None) hits a ke…
lklimek Jul 9, 2026
1860089
chore(dash-spv): add recent mainnet/testnet checkpoints (#857)
xdustinface Jul 9, 2026
0786810
fix(dash-spv): derive storage lockfile path from full directory name …
QuantumExplorer Jul 10, 2026
66f0873
fix(key-wallet): zeroize ExtendedBLSPrivKey and ExtendedEd25519PrivKe…
QuantumExplorer Jul 10, 2026
845ee9e
fix(spv): match masternode owner/voting key hashes in compact filters…
xdustinface Jul 10, 2026
1ee1c94
fix(spv): match masternode collateral outpoints in compact filters (#…
xdustinface Jul 11, 2026
d4692bb
feat(key-wallet-ffi): one-shot transaction decode to (address, amount…
QuantumExplorer Jul 12, 2026
234e3c4
fix(key-wallet): return the fee the tx actually pays from build/build…
QuantumExplorer Jul 12, 2026
93b7477
fix(key-wallet): cover CoinJoin/DashPay accounts for AssetLock routin…
bfoss765 Jul 13, 2026
b536179
feat(key-wallet): widen DEFAULT_COINJOIN_GAP_LIMIT 30 -> 100 for dash…
bfoss765 Jul 13, 2026
337f6cc
feat(key-wallet-ffi): typed special-transaction payload on FFITransac…
QuantumExplorer Jul 13, 2026
35684e1
chore(dash-spv): refresh masternode seed files (#874)
github-actions[bot] Jul 13, 2026
0ae8df4
feat(dash-spv): floor mainnet sync at HD/BIP39 activation height (#877)
xdustinface Jul 13, 2026
56a4078
fix(key-wallet): derive BLS operator & Ed25519 platform-node keys per…
QuantumExplorer Jul 13, 2026
bc6cbf9
feat(key-wallet): gate-free provider-key derivation API (operator/pla…
QuantumExplorer Jul 14, 2026
be18425
fix(key-wallet): extend gap limit for operator keys like owner/voting…
QuantumExplorer Jul 14, 2026
a959459
fix(key-wallet): platform node id is the Tenderdash node ID (SHA256[0…
QuantumExplorer Jul 14, 2026
2045cd2
feat(dash): dedicated PlatformNodeId newtype for platform_node_id fie…
QuantumExplorer Jul 14, 2026
ac8828c
feat(key-wallet): add missing DIP-15 derivation constants to dip9 (#886)
shumkov Jul 14, 2026
7221d86
fix(dash): normalize PlatformNodeId to canonical byte order at consen…
QuantumExplorer Jul 14, 2026
38c689d
feat(key-wallet): stamp retained transaction records with their in-bl…
QuantumExplorer Jul 14, 2026
19690d3
fix(dash-spv): don't preload filters below the actually stored range …
QuantumExplorer Jul 15, 2026
70d4bf8
feat(dash-spv): track network acceptance of broadcast transactions (#…
QuantumExplorer Jul 22, 2026
4c1b468
fix(key-wallet): fix issue 911 (#914)
ZocoLini Jul 27, 2026
ce4f26c
feat(dash-spv-bench): multi-scenario sync benchmark harness (#908)
ZocoLini Jul 27, 2026
05702cd
fix(dash-spv): reduced debug log verbosity (#917)
ZocoLini Jul 27, 2026
6e5d2f0
feat(key-wallet): reserve receive addresses on hand-out (#818)
xdustinface Jul 27, 2026
9c87ccb
feat(key-wallet): CoinJoin funding account + drain mode for asset-loc…
QuantumExplorer Jul 27, 2026
9cbe4e7
fix(key-wallet): rewrite branch-and-bound coin selection (#918) (#919)
ZocoLini Jul 30, 2026
8f78baa
feat(key-wallet): owner-tagged reservations to close the broadcast-re…
bfoss765 Aug 5, 2026
712bab1
fix(dash-spv): recover InstantSend locks received before quorum sync …
bfoss765 Aug 6, 2026
a041f44
fix(key-wallet): out-of-order UTXO spend recorded nowhere — phantom u…
bfoss765 Aug 6, 2026
c6deac5
fix(dash-spv): fix dashd process port assignation (#923)
ZocoLini Aug 6, 2026
08bf729
feat(key-wallet-manager): add a lossless persistence event channel to…
QuantumExplorer Aug 6, 2026
dca5b05
feat(key-wallet): OP_RETURN outputs, output-order control and change-…
romchornyi Aug 6, 2026
2b1f744
fix(key-wallet): stop counting a contact's watch-only coins as the wa…
romchornyi Aug 7, 2026
09904a6
feat(key-wallet): fund transactions from several account types (#925)
ZocoLini Aug 7, 2026
944e53a
feat(key-wallet): dashpay contact account funding (#929)
ZocoLini Aug 7, 2026
6be2407
fix(key-wallet): never offer an outpoint the builder already holds (#…
QuantumExplorer Aug 7, 2026
b056d07
fix(dash-spv): stop the filter rescan loop when the chain anchors abo…
xdustinface Aug 8, 2026
d91ad05
fix(dash-spv): using WalletAccountCreationOptions::default() in the b…
ZocoLini Aug 10, 2026
5a80bd7
feat(key-wallet): fund an asset lock from a caller-chosen list of acc…
QuantumExplorer Aug 10, 2026
9c0e874
feat(key-wallet): canonical is_contact_owned predicate on account typ…
QuantumExplorer Aug 11, 2026
47166b5
fix(dash-spv): requeue in-flight downloads when a single peer disconn…
xdustinface Aug 11, 2026
94eba8e
fix(dash-spv): reliable peer selection and stall handling during sync…
xdustinface Aug 11, 2026
34886d9
fix(dash-spv): reissue requeued masternode requests from `tick` (#953)
xdustinface Aug 11, 2026
37b1a36
feat(dash-spv): prune spent single-use CoinJoin addresses from the fi…
QuantumExplorer Aug 11, 2026
36b49cb
feat(dash-spv): accelerate compressed header sync (#950)
PastaPastaPasta Aug 12, 2026
173ffac
fix(dash): key rotation ChainLock signatures per quorum work block (#…
xdustinface Aug 12, 2026
0fdad66
fix(dash-spv): resume on the invariant start_download asserts (#955)
romchornyi Aug 13, 2026
0f94859
feat(key-wallet): let a drain carry zero-value OP_RETURN data outputs…
HashEngineering Aug 13, 2026
ae2a5d6
fix(dash-spv): release clean storage segments below the committed hei…
bfoss765 Aug 14, 2026
730ed8f
chore(dash-spv): refresh masternode seed files (#906)
github-actions[bot] Aug 14, 2026
55afccf
fix(key-wallet-manager): enable key-wallet/getrandom for mnemonic gen…
QuantumExplorer Aug 14, 2026
639e70e
fix(key-wallet): stop a never-broadcast transaction from crediting mo…
romchornyi Aug 14, 2026
54b7f7e
fix(dash-spv): promote finished header segments from the tick, not on…
romchornyi Aug 17, 2026
f4b907c
feat(key-wallet-manager)!: name the outpoints a sweep releases (#962)
romchornyi Aug 17, 2026
73c4a1d
fix(dash-spv): rescan committed filter ranges for newly derived scrip…
HashEngineering Aug 18, 2026
3f009ba
feat(dash-spv-bench): bench client env (#965)
ZocoLini Aug 18, 2026
75f318b
fix(key-wallet): collect a sweep's surviving inputs once instead of p…
romchornyi Aug 19, 2026
e9ef99c
fix(dash-spv): extend the CFHeaders queue from the tick, not only on …
romchornyi Aug 19, 2026
29b39f0
chore(dash-spv): refresh masternode seed files (#963)
github-actions[bot] Aug 19, 2026
1b90f3a
chore(seeds): refresh mainnet seed list (probe 2026-08-19) (#970)
llbartekll Aug 19, 2026
60a331c
feat(dash-spv-bench): improved bench rate limit + display progress ba…
ZocoLini Aug 19, 2026
5877d15
fix(key-wallet): walk a sweep's descendant closure once instead of pe…
romchornyi Aug 19, 2026
1a6fb3b
fix(dash-spv): recover masternode sync from a rejected QRInfo (#947)
bfoss765 Aug 22, 2026
b66db39
fix(key-wallet): accept non-English BIP-39 mnemonics on all parse pat…
llbartekll Aug 22, 2026
090faea
feat(key-wallet-manager): carry the sweep winner's mined height on Tr…
romchornyi Aug 23, 2026
c246993
fix(dash-spv): count acceptance signals that arrived before the broad…
romchornyi Aug 23, 2026
01900ee
refactor(key-wallet)!: unify mnemonic parsing on one auto-detecting p…
PastaPastaPasta Aug 23, 2026
20dfe1e
chore(dash-spv): refresh masternode seed files (#983)
github-actions[bot] Aug 24, 2026
237f79a
fix(dash-spv): coalesce committed-range filter rescans across batch c…
romchornyi Aug 25, 2026
5f2de2e
feat(key-wallet): payload-finalization seam for input-committing spec…
QuantumExplorer Aug 28, 2026
810ec54
fix*dash-spv-bench): build on linux host + survive having no terminal…
ZocoLini Aug 31, 2026
eefe35e
fix(dash-spv-bench): report the transactions each account knows (#984)
ZocoLini Aug 31, 2026
21aaafe
fix(key-wallet): stop pruning spent CoinJoin addresses from the filte…
ZocoLini Aug 31, 2026
ff725ac
feat(key-wallet): let a build fund from only the inputs it was given …
romchornyi Sep 1, 2026
b4e73a3
fix(dash-spv): coinbase maturity clock (#996)
ZocoLini Sep 1, 2026
e871c02
docs: clarify Dash consensus validation scope (#997)
PastaPastaPasta Sep 1, 2026
93260bf
fix(key-wallet): promote confirmed spend-only transactions (#998)
shumkov Sep 2, 2026
7e315af
fix(key-wallet): ask every account whether a transaction is new, not …
ZocoLini Sep 7, 2026
057e79c
build!: adopt GroveDB bincode across the workspace (#1005)
QuantumExplorer Sep 8, 2026
0e56657
fix(key-wallet): keep a spend-first coin recognisable so its spend st…
ZocoLini Sep 9, 2026
354a1cb
fix(key-wallet): discover DashPay asset unlock receipts (#1004)
PastaPastaPasta Sep 10, 2026
e4208c9
fix(dash-spv): stop losing derived scripts, and close the loop on wal…
ZocoLini Sep 10, 2026
7608a01
fix(rpc-json)!: re-land nested platform addresses for Core v24
shumkov Sep 30, 2026
ca43f07
fix(rpc-json): read Core v24 non-IP service and -1 platform ports
shumkov Sep 30, 2026
56feb85
fix(rpc-json)!: model Core v24 shared and multi-payout masternodes
shumkov Sep 30, 2026
538522b
fix(rpc-json): apply Core's partial addresses diffs per purpose
shumkov Sep 30, 2026
40268cc
fix(rpc-json): bracket an IPv6 host in the legacy platform address fa…
shumkov Oct 1, 2026
3cbed46
test(dash): add the test-case dev-dependency
shumkov Oct 12, 2026
891f1fb
feat(dash)!: decode and encode CbTx v4 `merkleRootAssetUnlocks` (#1137)
ZocoLini Oct 8, 2026
386f0df
feat(dash)!: decode unknown special transaction types as raw payloads…
ZocoLini Oct 10, 2026
e18bd80
feat(dash)!: decode and encode ProUpServTx and ProUpRegTx version 3 (…
ZocoLini Oct 11, 2026
9e65cea
feat(dash)!: decode and encode ProRegTx version 3 (#1152)
ZocoLini Oct 11, 2026
00f4d6a
fix(dash): keep the pre-v4 serde shape of `CoinbasePayload` (partial …
ZocoLini Oct 12, 2026
6c5775c
fix(dash): only decode a special payload from transaction version 3 (…
ZocoLini Oct 12, 2026
7302d0a
feat(dash)!: keep special payloads raw when their layout is unknown (…
ZocoLini Oct 12, 2026
379f057
fix(rpc): decode Core v24 getblockchaininfo and add getdeploymentinfo
shumkov Oct 14, 2026
a5ae637
feat(dash): decode asset locks ignoring their payload length prefix
shumkov Oct 14, 2026
edc4d43
refactor(dash): move the legacy asset lock decoder into its own module
shumkov Oct 14, 2026
f22f7d6
fix(rpc-client): send the ChainLock block hash in display order to `s…
ZocoLini Oct 10, 2026
a40daba
feat(dash)!: temporarily expose the unverified coinbase of the newest…
shumkov Oct 20, 2026
593133e
chore: merge `integration/v5.0-core-v24` into the `v0.45.0` release b…
xdustinface Oct 20, 2026
9502535
chore: add `0.45.0` changelog entry
xdustinface Oct 20, 2026
17dca33
fix(key-wallet): import `MasternodeNetInfo` in `keep_finalized_transa…
xdustinface Oct 20, 2026
9fa8d71
fix(key-wallet): prune observed spends during the initial sync (#1014)
ZocoLini Sep 23, 2026
b1ecc2f
chore: add #1014 to the `0.45.0` changelog
xdustinface Oct 20, 2026
d937399
fix(key-wallet): consult every fund-bearing account for provider tran…
ZocoLini Sep 12, 2026
77ce3a4
fix(key-wallet): extend DIP-15 contact pools as their payments arrive…
ZocoLini Sep 20, 2026
88dc3fa
fix(key-wallet): keep a mined transaction promotable when its IS lock…
ZocoLini Sep 23, 2026
7a105b7
fix(key-wallet): re-apply a spend whose coin was funded after it (#1015)
ZocoLini Sep 23, 2026
765abba
fix(dash): reject a ChainLock the list below its signing height refus…
ZocoLini Sep 25, 2026
a9cbd92
fix(dash): reject headers messages above Core's batch limit (#1140)
ZocoLini Oct 8, 2026
6d57046
fix(rpc-client): keep request arguments and results out of the logs (…
ZocoLini Oct 10, 2026
b7def0a
fix(key-wallet): sweep a conflict loser's keys-only records too (#1143)
lklimek Oct 12, 2026
09b5ddb
fix(dash): set LLMQ params to Dash Core's values (#1187)
ZocoLini Oct 16, 2026
ef452d3
chore: add the backported fixes to the `0.45.0` changelog
xdustinface Oct 21, 2026
e75a8c9
chore: merge `integration/v5.0-core-v24` with #1204 into the `v0.45.0…
xdustinface Oct 21, 2026
c4dd8e3
chore: add #1204 to the `0.45.0` changelog and date it `2026-10-21`
xdustinface Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ci-groups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ excluded:
- integration_test # Requires live Dash node
- dash-fuzz # Honggfuzz binary targets, tested by fuzz.yml
- masternode-seeds-fetcher # Tooling binary; needs live dashd RPC, exercised by update-masternode-seeds.yml
- dash-spv-bench # Benchmarking binary
- git-state # Compile-time proc-macro with no tests, exercised via dash-spv
23 changes: 21 additions & 2 deletions .github/scripts/check_ci_status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,27 @@ set -euo pipefail
PR_NUMBER="$1"
REPO="$2"

gh pr checks "$PR_NUMBER" --repo "$REPO" --json name,bucket --jq '
[.[] | select(.name | test("^(validate-triggers|evaluate)$") | not)] |
# gh pr checks signals check state through its exit code: 0 when every check
# passed (and, with --json, also when some failed), 8 when checks are still
# pending. Any other code is gh itself failing (auth, rate limit, network,
# unknown PR); surface that instead of misreading it as an empty check set,
# which would silently strip the label and hide the error. Keep stderr visible.
set +e
CHECKS=$(gh pr checks "$PR_NUMBER" --repo "$REPO" --json name,bucket)
EXIT=$?
set -e

if [ "$EXIT" -ne 0 ] && [ "$EXIT" -ne 8 ]; then
exit "$EXIT"
fi

if [ -z "$CHECKS" ]; then
echo "no_checks"
exit 0
fi

echo "$CHECKS" | jq -r '
[.[] | select(.name | test("^(validate-triggers|evaluate|ready-for-review-trigger)$") | not)] |
if length == 0 then "no_checks"
elif all(.bucket == "pass" or .bucket == "skipping") then "all_passed"
elif any(.bucket == "fail") then "has_failures"
Expand Down
7 changes: 7 additions & 0 deletions .github/scripts/ci_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ def run_group_tests(args):
cmd = ["cargo", "test", "-p", crate, "--all-features"]
result = subprocess.run(cmd)

if (
result.returncode == 0
and not coverage
and crate == "key-wallet-manager"
):
result = subprocess.run(["cargo", "test", "-p", crate])

if result.returncode != 0:
failed.append(crate)
github_error(f"Test failed for {crate} on {args.os}")
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/ready-for-review-trigger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Ready for Review Trigger

# Fork pull requests run pull_request and pull_request_review events with a
# read-only token and no secrets, so they cannot add or remove labels. This
# workflow does nothing but complete, which fires a workflow_run event that the
# privileged "Ready for Review Label" workflow reacts to with a write token.
on:
pull_request:
types: [ready_for_review, labeled, converted_to_draft]
pull_request_review:
types: [submitted, dismissed]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions: {}

jobs:
relay:
name: ready-for-review-trigger
runs-on: ubuntu-latest
steps:
- name: Relay to applier
run: echo "Relaying pull request event to the ready-for-review applier via workflow_run."
96 changes: 40 additions & 56 deletions .github/workflows/ready-for-review.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
name: Ready for Review Label

# Runs only on workflow_run so it holds a write-capable token even for pull
# requests opened from forks. Events tied to the fork head (pull_request,
# pull_request_review) get a read-only token and no secrets, so they cannot
# mutate labels themselves. The companion "Ready for Review Trigger" workflow
# relays those events here by completing and firing this workflow_run.
on:
pull_request:
types: [ready_for_review, labeled]
pull_request_review:
types: [submitted, dismissed]
workflow_run:
workflows: ["Continuous integration", "Pre-commit Checks", "Sanitizer"]
workflows:
- "Continuous integration"
- "Pre-commit Checks"
- "Sanitizer"
- "Ready for Review Trigger"
types: [completed]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.workflow_run.head_branch }}
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_sha }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
checks: read
issues: write

jobs:
# Ensure all pull_request-triggered workflows are monitored by workflow_run
validate-triggers:
runs-on: ubuntu-latest
if: github.event_name == 'workflow_run'
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -34,10 +40,7 @@ jobs:
SELF=".github/workflows/ready-for-review.yml"

# Extract workflow names from the workflow_run trigger list in this file
MONITORED=$(grep -A1 'workflows:' "$SELF" \
| grep '\[' \
| tr ',' '\n' \
| sed 's/.*"\([^"]*\)".*/\1/')
MONITORED=$(grep -E '^\s+- "' "$SELF" | sed 's/.*"\([^"]*\)".*/\1/')

MISSING=""
for f in .github/workflows/*.yml; do
Expand Down Expand Up @@ -73,14 +76,6 @@ jobs:

evaluate:
runs-on: ubuntu-latest
permissions:
pull-requests: write
checks: read
issues: write
# Skip non-CodeRabbit reviews
if: >-
github.event_name != 'pull_request_review' ||
github.event.review.user.login == 'coderabbitai[bot]'
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -90,54 +85,42 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
EVENT_NAME: ${{ github.event_name }}
EVENT_ACTION: ${{ github.event.action }}
REVIEW_STATE: ${{ github.event.review.state }}
PR_NUMBER_DIRECT: ${{ github.event.pull_request.number }}
LABEL_NAME: ${{ github.event.label.name }}
PULL_REQUESTS_JSON: ${{ toJson(github.event.workflow_run.pull_requests) }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
# On review dismissal or changes requested, remove label and exit
if [ "$EVENT_NAME" = "pull_request_review" ]; then
if [ "$EVENT_ACTION" = "dismissed" ] || [ "$REVIEW_STATE" = "changes_requested" ]; then
echo "CodeRabbit review dismissed or changes requested, removing label."
gh pr edit "$PR_NUMBER_DIRECT" --repo "$REPO" --remove-label "ready-for-review" || true
exit 0
fi
fi

# On merge-conflict label, remove ready-for-review and exit
if [ "$EVENT_NAME" = "pull_request" ] && [ "$EVENT_ACTION" = "labeled" ]; then
if [ "$LABEL_NAME" = "merge-conflict" ]; then
echo "Merge conflict detected, removing ready-for-review label."
gh pr edit "$PR_NUMBER_DIRECT" --repo "$REPO" --remove-label "ready-for-review" || true
fi
exit 0
fi

# Collect PR numbers depending on the event type
if [ "$EVENT_NAME" = "workflow_run" ]; then
PR_NUMBERS=$(echo "$PULL_REQUESTS_JSON" | jq -r '.[].number')
else
PR_NUMBERS="$PR_NUMBER_DIRECT"
fi
# Resolve the PR(s) for the head commit. github.event.workflow_run's
# pull_requests array is empty for fork PRs, and the commit-to-PR
# endpoint does not index fork heads, so match the head sha against
# the list of open PRs, which works regardless of where the branch
# lives. Matching the exact sha also ignores stale runs whose commit
# the PR has already moved past.
PR_NUMBERS=$(gh api --paginate "repos/$REPO/pulls?state=open&per_page=100" \
--jq ".[] | select(.head.sha == \"$HEAD_SHA\") | .number")

if [ -z "$PR_NUMBERS" ]; then
echo "No associated pull requests found, skipping."
echo "No open pull request found for $HEAD_SHA, skipping."
exit 0
fi

for PR_NUMBER in $PR_NUMBERS; do
echo "=== Checking PR #$PR_NUMBER ==="

# Skip draft PRs
IS_DRAFT=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json isDraft --jq '.isDraft')
if [ "$IS_DRAFT" = "true" ]; then
echo "PR is a draft. Skipping."
PR_JSON=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json isDraft,labels)

if [ "$(echo "$PR_JSON" | jq -r '.isDraft')" = "true" ]; then
echo "PR is a draft. Removing ready-for-review label if present."
gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "ready-for-review" || true
continue
fi

# Check if CodeRabbit has approved
# A merge conflict disqualifies the PR regardless of the other gates.
if [ "$(echo "$PR_JSON" | jq -r '[.labels[].name] | index("merge-conflict") != null')" = "true" ]; then
echo "Merge conflict present. Removing ready-for-review label if present."
gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "ready-for-review" || true
continue
fi

# Check if CodeRabbit has approved. A dismissed or changes-requested
# review leaves the latest state != APPROVED and removes the label.
CODERABBIT_STATE=$(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/reviews" | jq -rs '
add
| map(select(.user.login == "coderabbitai[bot]"))
Expand All @@ -148,7 +131,8 @@ jobs:
echo "CodeRabbit review state: $CODERABBIT_STATE"

if [ "$CODERABBIT_STATE" != "APPROVED" ]; then
echo "CodeRabbit has not approved. Skipping."
echo "CodeRabbit has not approved. Removing label if present."
gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "ready-for-review" || true
continue
fi

Expand Down
19 changes: 14 additions & 5 deletions .github/workflows/sanitizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ on:
permissions:
contents: read

# Pinned nightly: nightly-2026-07-14 (rustc daf2e5e18) ICEs while expanding the
# libtest harness for dash-spv-ffi ("attribute is missing tokens:
# rustc_test_entrypoint_marker" in rustc_ast/src/attr/mod.rs). Bump or restore
# the floating `nightly` once a fixed nightly ships.
env:
SANITIZER_TOOLCHAIN: nightly-2026-07-13

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Expand All @@ -28,8 +35,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.SANITIZER_TOOLCHAIN }}
components: rust-src

- name: Run tests with ASAN
Expand All @@ -41,20 +49,21 @@ jobs:
SKIP_DASHD_TESTS: 1
run: |
# FFI crates (C interop)
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
cargo "+$SANITIZER_TOOLCHAIN" test -Zbuild-std --target x86_64-unknown-linux-gnu \
-p key-wallet-ffi -p dash-spv-ffi --lib --tests

# Core crypto crates (unsafe optimizations)
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
cargo "+$SANITIZER_TOOLCHAIN" test -Zbuild-std --target x86_64-unknown-linux-gnu \
-p dashcore -p dashcore_hashes --lib --tests

tsan:
name: Thread Sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.SANITIZER_TOOLCHAIN }}
components: rust-src

- name: Run tests with TSAN
Expand All @@ -65,5 +74,5 @@ jobs:
SKIP_DASHD_TESTS: 1
run: |
# Async crate with concurrent code
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
cargo "+$SANITIZER_TOOLCHAIN" test -Zbuild-std --target x86_64-unknown-linux-gnu \
-p dash-spv --lib --tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ __pycache__/

# Build scripts artifacts
*.log
target-linux/
Loading
Loading