Only relay Taproot spends if next block has it active#20165
Only relay Taproot spends if next block has it active#20165maflcko merged 2 commits intobitcoin:masterfrom
Conversation
|
A suggestion that is not included here is rejecting the creation of witness v1 spends during a period preceding activation to protect users sending to such outputs too early. It's easy to add if desired, but perhaps less necessary. @sdaftuar Doing this for the entire defined/started/lockedin period adds additional non-homogeneity to network relay policy. @ajtowns suggested doing it only during during the lockedin period, to provide a short but still coordinated window of additional protection. |
kallewoof
left a comment
There was a problem hiding this comment.
utACK 6d568731862b1d888fa8db9effb3663dfe8e0e46
|
utACK 6d56873 |
|
utACK 6d568731862b1d888fa8db9effb3663dfe8e0e46 Could you elaborate on what this means:
|
|
Concept ACK the change suggested in this PR.
I'm not sure I entirely see a reason for concern over the non-homogeneity of network relay policy with respect to anyone-can-spend outputs; in my view, taproot-enabled software (by which I mean software that is aware of all the taproot consensus changes, necessarily including activation criteria for enforcing those rules) should differ from other software with how it treats v1 addresses, because it is the only software that actually knows what they mean. One way to think about this is that if the community is using bitcoind to determine whether it's reasonable to relay a transaction creating a v1 output, that having the taproot-enabled-version of bitcoind correctly say "no" prior to activation is a useful thing to do. In the absence of us implementing that behavior, how would a user implement such footgun protection on their own? Arguably, we could ship a taproot-enabled version of bitcoind that relayed such transactions anyway, if the user requested (eg by command-line option or something); but none of the reasons that come to mind right now of why someone might want to use such an option seem very good to me. |
|
@naumenkogs Some background, this was discussed on the last IRC dev meeting, where I brought up two things we can do:
The PR here only does the first, as I think there are a few trade-offs to consider regarding the second. |
|
Concept ACK -- I think it makes sense to not do any "create witness v1 outputs" protection until an activation method is defined. Making spends non-standard is valuable for signet (where standardness and consensus aren't all that different, so making something standard but not consensus-enforced means it can be relied on in practice). |
|
Concept ACK will review when I am done reading through the other taproot changes |
jnewbery
left a comment
There was a problem hiding this comment.
Concept ACK. Presumably this code can be reverted once taproot has been activated for some time?
I don't understand one change in the functional test.
|
I checked out the test and ran it against master, without failure. Similarly running master against this test didn't result in a failure either. Concept ACK on not changing policy for creation of v1 outputs ACK 6d568731862b1d888fa8db9effb3663dfe8e0e46 👉 Show signature and timestampSignature: Timestamp of file with hash |
6d56873 to
5482545
Compare
5482545 to
3d0556d
Compare
|
utACK 3d0556d |
|
review ACK 3d0556d 🏓 Show signature and timestampSignature: Timestamp of file with hash |
|
utACK 3d0556d |
jonatack
left a comment
There was a problem hiding this comment.
Concept ACK, posthumous ACK 3d0556d
Verified the updated test fails on pre-merge master with
File "test/functional/feature_taproot.py", line 1457, in run_test
self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[1])
File "test/functional/feature_taproot.py", line 1426, in test_spenders
assert_raises_rpc_error(-26, None, node.sendrawtransaction, tx.serialize().hex(), 0)
File "/home/jon/projects/bitcoin/bitcoin/test/functional/test_framework/util.py", line 123, in assert_raises_rpc_error
assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
AssertionError: No exception raised
| * Check for standard transaction types | ||
| * @param[in] mapInputs Map of previous transactions that have outputs we're spending | ||
| * @param[in] mapInputs Map of previous transactions that have outputs we're spending | ||
| * @param[in] taproot_active Whether or taproot consensus rules are active (used to decide whether spends of them are permitted) |
| // Check for non-standard pay-to-script-hash in inputs | ||
| if (fRequireStandard && !AreInputsStandard(tx, m_view)) { | ||
| const auto& params = args.m_chainparams.GetConsensus(); | ||
| auto taproot_state = VersionBitsState(::ChainActive().Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache); |
There was a problem hiding this comment.
525cbd4 perhaps s/auto/ThresholdState/ like validation.cpp::L1834 and mining.cpp::L820
There should be no change to mempool transaction behavior for witness v1 transactions as long as no activation is defined. Until that point, we should treat the consensus rules as under debate, and for soft-fork safety, that means spends should be treated as non-standard.
It's possible to go further: don't relay them unless the consensus rules are actually active for the next block. This extends non-relay to the period where a deployment is defined, started, locked in, or failed. I see no downsides to this, and the code change is very simple.