Repository navigation
Commit 625b6f7
committed
Merge #7489: fix: conflict ProRegTx collateral reuse with in-mempool masternode updates
95341f5 refactor: extract removeProTxReferences and cover replacement eviction (pasta)
9b3ca40 fix: conflict ProReg collateral reuse with mempool MN updates (pasta)
4d4f579 test: prove ProReg replacement conflicts with same-MN updates (pasta)
Pull request description:
## Issue being fixed or feature implemented
A ProRegTx that reuses an external collateral *replaces* the masternode that collateral
currently backs — the old masternode ceases to exist and its `proTxHash` becomes unknown.
The mempool does not model that. It tracks collateral *spends*
(`removeProTxSpentCollateralConflicts`), but reuse is not a spend, so:
- A replacement ProRegTx and an update (ProUpServTx / ProUpRegTx / ProUpRevTx) targeting the
masternode being replaced can sit in the mempool at the same time.
- If both are selected into one block, `BuildNewListFromBlock()` deletes the masternode when
it applies the ProRegTx, then fails `bad-protx-hash` on the update.
- That aborts block assembly in the miner.
The same hazard exists when the replacement ProRegTx arrives in a block rather than through
the mempool: the stale update is left behind and can never be mined.
## What was done?
Three commits.
**1. Mempool admission (`existsProviderTxConflict`)** — the two directions are now
symmetric:
- A ProRegTx reusing an external collateral conflicts if any mempool transaction still
references the incumbent masternode's `proTxHash`.
- A ProUpServTx / ProUpRegTx / ProUpRevTx conflicts if a pending ProRegTx already claims its
masternode's collateral outpoint.
This is first-in-wins with no RBF-style tiebreak. That is a deliberate policy choice: both
transactions are individually valid, and the only requirement is that they not coexist.
Preferring the incumbent would mean evicting an already-accepted transaction on arrival of a
new one, which is a bigger policy change than this problem warrants.
**2. Eviction on block connect (`removeProTxConflicts`)** — when a collateral-reusing
ProRegTx is mined, any mempool transaction still targeting the replaced masternode is
removed. This covers the case where the ProRegTx never passed through this node's mempool,
so the admission check above never ran.
**3. Refactor** — the removal loop inside `removeProTxSpentCollateralConflicts` is extracted
as `CTxMemPool::removeProTxReferences()` and reused by both call sites. No behaviour change;
it just avoids a second copy of the iterator-invalidation-safe loop.
### One thing reviewers should look at
The eviction in (2) calls `dmnman->GetListAtChainTip()` and needs it to resolve to the list
at the *previous* tip, so `GetMNByCollateral()` returns the masternode being replaced rather
than its replacement. That holds because `CDeterministicMNManager::tipIndex` is assigned in
`UpdatedBlockTip()`, which fires from `ActivateBestChain()` (`validation.cpp:3339-3340`) —
after `ConnectTip()` calls `removeForBlock()` (`validation.cpp:3025`).
`removeProTxSpentCollateralConflicts()` already depends on this ordering, so the new code is
consistent with the file. The difference is that there it is an optimisation, whereas here it
is load-bearing: if the ordering changed, `GetMNByCollateral()` would return the replacement
masternode and the eviction would silently become a no-op. I have noted the dependency in a
comment, but flagging it explicitly since it is the least obvious part of the change.
## How Has This Been Tested?
`test_mempool_proreg_replacement_update_conflict` in
`src/test/evo_deterministicmns_tests.cpp`, added in the commit *preceding* the fix. It
covers both paths:
- admission, via `existsProviderTxConflict()` in both directions;
- eviction, via `removeForBlock()` with a block containing the replacement ProRegTx.
Without the fix the admission assertions fail (2 failures) — the conflicting pair is
accepted. With the fix, `evo_dip3_activation_tests` passes (19 cases).
Built and run on macOS/arm64 against current `develop`.
## Breaking Changes
Mempool policy only; no consensus rules change. Some transaction pairs that were previously
accepted together are now mutually exclusive in the mempool. Neither could have been mined
together, so nothing that was previously minable is rejected.
## Known follow-up
Coverage is C++ unit level only. A functional test exercising the miner path end to end
would strengthen this; happy to add one in this PR if reviewers would prefer it before merge.
## Checklist:
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] 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
Top commit has no ACKs.
Tree-SHA512: 07fc7348712ce7e48e40f8234c9a988eb9cac50baed9a85e5229300a1a18ab7caefe46110f348978a44a3943aa7ce068253b4823af51619fc82e02cda78202243 files changed
Lines changed: 168 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1418 | 1418 | | |
1419 | 1419 | | |
1420 | 1420 | | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
1421 | 1527 | | |
1422 | 1528 | | |
1423 | 1529 | | |
| |||
3144 | 3250 | | |
3145 | 3251 | | |
3146 | 3252 | | |
| 3253 | + | |
| 3254 | + | |
| 3255 | + | |
| 3256 | + | |
| 3257 | + | |
| 3258 | + | |
3147 | 3259 | | |
3148 | 3260 | | |
3149 | 3261 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
937 | 937 | | |
938 | 938 | | |
939 | 939 | | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
940 | 961 | | |
941 | 962 | | |
942 | 963 | | |
943 | | - | |
944 | | - | |
945 | | - | |
946 | | - | |
947 | | - | |
948 | | - | |
949 | | - | |
950 | | - | |
951 | | - | |
952 | | - | |
953 | | - | |
954 | | - | |
955 | | - | |
956 | | - | |
957 | | - | |
958 | | - | |
959 | | - | |
960 | | - | |
961 | | - | |
962 | 964 | | |
963 | 965 | | |
964 | 966 | | |
965 | 967 | | |
966 | 968 | | |
967 | | - | |
| 969 | + | |
968 | 970 | | |
969 | 971 | | |
970 | 972 | | |
971 | 973 | | |
972 | | - | |
| 974 | + | |
973 | 975 | | |
974 | 976 | | |
975 | 977 | | |
| |||
1027 | 1029 | | |
1028 | 1030 | | |
1029 | 1031 | | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
1030 | 1039 | | |
1031 | 1040 | | |
1032 | 1041 | | |
| |||
1450 | 1459 | | |
1451 | 1460 | | |
1452 | 1461 | | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
1453 | 1470 | | |
1454 | 1471 | | |
1455 | 1472 | | |
| |||
1470 | 1487 | | |
1471 | 1488 | | |
1472 | 1489 | | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
1473 | 1496 | | |
1474 | 1497 | | |
1475 | 1498 | | |
| |||
1484 | 1507 | | |
1485 | 1508 | | |
1486 | 1509 | | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
1487 | 1514 | | |
1488 | 1515 | | |
1489 | 1516 | | |
| |||
1506 | 1533 | | |
1507 | 1534 | | |
1508 | 1535 | | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
1509 | 1540 | | |
1510 | 1541 | | |
1511 | 1542 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
650 | 650 | | |
651 | 651 | | |
652 | 652 | | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
653 | 657 | | |
654 | 658 | | |
655 | 659 | | |
| |||
0 commit comments