Repository navigation
Conversation
Avoid executing scriptSig when only the final pushed redeem script is needed.
|
NACK at this default. Tested 6836789 on a Release build with The floor refuses most real multisig spends. Over blocks 976024 to 976740, 5,980 of the 6,568 transactions it applies to (a CHECKMULTISIG input, not a bpub reveal, nested P2SH-P2WSH included) paid less than 500 sat per key: 4,016 of the 4,390 plain 2-of-3 spends and 1,534 of the 1,714 plain 2-of-2 spends. They pay a median 132 sat per key today. A pre-signed 2-of-2 at 300 sat (2 sat/vB) relays on 29.4.2 (the plumb6 build) alone or with a CPFP child; here nothing under 1,000 sat passes, child or not:
Against the encoder it targets: the 725 bpub reveals in the same window paid 0.405 BTC and would have needed 14.45 BTC here, 35.7x. knots#422 already counts data in all 725 at its allowance of 10 and in none of the 6,611 others with a multisig input, because it counts only the keys no signature proves. A floor on those keys would land on the 14 unsigned keys of a 1-of-15 and on one key of a 2-of-3.
Scripts, logs and the per-transaction data: https://gist.github.com/jasonsopko/d07b6b8044f2b02a3ebea87711dab9e7 |
|
Can multisig just be disabled until expiration of RDTS? |
Restore consistent excess-key integration, retain dropped key pushes, and share input counting with the wallet. Fund the floor from change or coin reselection and inspect the selected Taproot satisfaction. Require a witness for ambiguous unsigned Taproot funding. Add regression cases. Validation: static review and git diff --check only; not compiled and tests not run.
Hi friend. Removing important and useful features every time we get a new spam attack is not really wise. And it could also lock many people out of their cold stored coin. This filter will likely not affect 99.8% of the transactions. 0.18% of the transactions will have to pay ~0.6¢ in miner fees to stay in line with policy. And ~0.02% of transactions will have to pay ~1¢ to 50¢ in miner fees. But the spammers will feel the brunt of this filter, having to pay $10 to $60 in miner fees. I should also say that a weakness of this proposal is that violent price swings could make the filter too aggressive, or too weak. So we have to rely on individual nodes to adjust the setting appropriately, or for the devs to adjust defaults with frequent releases. With suggested settings and current price, the spammer would have to pay over $1500 of miner fees per day to keep up his current volume, instead of the less than $60/day he is currently spending. |
… [skip ci] Collect optional observations from normal script validation instead of using key-sized pushes as the admission counter. Preserve one free unproven operand per executed script. Carry observations through the validity cache and wallet signing, and aggregate actual fees/floors for supported package admission. Add regression cases and document the narrower executed-path scope. Validation: Python syntax and diff checks only. Native build configuration blocked before C++ compilation; unit and functional runtime tests not run.
|
@jasonsopko Thank you for the concrete reproducer, measurements and historical sample. They exposed real problems with the earlier all-keys floor, including its impact on ordinary and presigned multisig transactions, the missing CPFP path, the OP_RETURN test failure and the missing CHECKSIGADD coverage. The draft has been reworked substantially in response:
The design follows #422's unproven-key idea. The preference here is to explore a graduated fee floor rather than classifying those operands as datacarrier usage. That is a design preference, not evidence that this proposal is universally better than #422. The executed-path scope is also deliberately narrower: the free operand, dead-branch payload and other data encodings remain limitations. Your relay-CPU measurements are not refuted by these changes. This floor is checked after script verification; no early CPU protection is claimed. The historical sample has not been replayed under this revision, so I am not claiming new rejection percentages or that all presigned-transaction compatibility concerns are resolved. Validation status: Python syntax checks and For attribution, this proposal implements an idea from Pepe Lapiu and does not necessarily represent Volkrad's personal view. |
Behavior
This draft implements an experimental relay-policy fee floor for unproven key operands in executed multisig input scripts, not a consensus rule or a general data filter. The default is 1,000 sats per charged operand, with one unproven operand free per executed script. For a successful canonical m-of-n spend, the charged count is
max(0, n - m - 1): 2-of-2 and 2-of-3 have no additional floor; 1-of-15 has a 13,000-sat floor. Counts accumulate across inputs. The floor and ordinary fee requirements both apply; their amounts are not added.This PR implements an idea proposed by Pepe Lapiu. It does not necessarily represent Volkrad's personal view.
Executed-operand accounting
The normal policy script-validation pass now collects optional observations rather than using the old static push-size estimate for admission:
-minrelaymultisigexcesskeyfee=<n>sets integer satoshis per charged operand; zero disables it.-corepolicydisables it unless explicitly overridden.CPFP and Lightning
A floor failure is reconsiderable. In the existing child-with-unconfirmed-parents admission path, newly evaluated package members must pay the sum of their floors in actual fees, including any charged child. Already-admitted/mempool transactions and prioritisation deltas do not provide reusable fee credit. Ordinary minimum relay fee, topology, replacement, signature and mempool-limit rules remain in force.
testmempoolacceptretains individual-fee semantics; eligiblesubmitpackagesubmissions use package accounting.This is not arbitrary package relay or a permanent parent/child binding, and does not guarantee joint mining or survival after eviction/replacement. P2P interoperability remains untested.
The authoritative counter no longer uses a Lightning template exemption: ordinary funding 2-of-2 and HTLC 2-of-2 paths prove both operands; to_local and standard HTLC revocation/preimage paths do not execute multisig. These paths have no additional floor. This does not establish compatibility with every future Lightning script or presigned protocol.
Wallet funding
Signed creation obtains counts from its existing signing verification, adjusts change or retries coin selection with bounded retries/max-fee checks, then checks the final signed path against the actual fee. A more expensive final path fails creation rather than silently producing an underfunded transaction.
Unsigned funding still uses a static estimate, including the earlier stack-identity normalization and exact BOLT #3 template allowance; neither controls admission. Complex scripts can be over- or underestimated. Unsigned Taproot funding reserves the largest estimate among known leaves unless
options.multisig_feesupplies a nonnegative integer total floor in satoshis. Zero can express a planned key-path spend. This is not a relay override; a different eventual path may need re-funding or an eligible package.Relationship to #422 and limitations
This takes inspiration from #422's unproven-key concept, but chooses a fee floor instead of datacarrier classification. Executed-operand accounting is a different, narrower scope than static script-data accounting, not proof that this PR is universally better.
The free operand is intentional. Payload in dead branches, non-key data and other encodings remains outside this rule; independent datacarrier policies still apply. This is not an unbypassable spam classifier. The floor is evaluated after script verification, so no early relay-CPU protection is claimed. The NACK's historical sample has not been replayed under this revision, and no new impact percentages or speedup claims are made. Presigned charged transactions and unsupported packages remain compatibility concerns.
Validation status — still draft
Python syntax checks for the mempool and wallet functional-test files and
git diff --checkpassed. This revision has not been compiled; C++ tests and node-based functional tests have not run. Local Windows configuration was attempted but blocked before C++ compilation by dependency-tool process/handle and SDK registry access errors.Added/updated cases cover real ECDSA/Schnorr spends, dynamic key counts, mixed-script non-key data, witness-supplied operands, false multisig results, cache misses/eviction and witness/flag isolation, Lightning paths, wallet funding, and package fee boundaries/deduplication. Test existence is not evidence they pass. Interpreter instrumentation, wallet integration and package handling need runtime validation and independent review before merge readiness can be assessed.