Merge #15846: [POLICY] Make sending to future native witness outputs standard

c634b1e20 [POLICY] Make sending to future native witness outputs standard (Pieter Wuille)

Pull request description:

  As discussed in the April 18 2019 IRC meeting.

  This makes sending to future Segwit versions via native outputs (bech32) standard for relay, mempool acceptance, and mining. The reasons are:
  * This may interfere with smooth adoption of future segwit versions, if they're defined (by the sender wallet/node).
  * It violates BIP173 ("Version 0 witness addresses are always 42 or 62 characters, but implementations MUST allow the use of any version."), though admittedly this code was written before BIP173.
  * It doesn't protect much, as P2SH-embedded segwit cannot be filtered in this way.
  * As a general policy, the sender shouldn't care what the receiver likes his outputs to be.

  Note that _spending_ such outputs (including P2SH-embedded ones) remains nonstandard, as that is actually required for softfork safety.

ACKs for commit c634b1:
  MarcoFalke:
    utACK c634b1e207
  harding:
    Tested ACK c634b1e207
  meshcollider:
    utACK c634b1e207

Tree-SHA512: e37168a1be9f445a04d4280593f0a92bdae33eee00ecd803d5eb16acb5c9cfc0f1f0a1dfbd5a0cc73da2c9928ec11cbdac7911513a78f85b789ae0d00e1b5962
This commit is contained in:
MeshCollider 2019-04-27 21:50:25 +12:00
commit b025aa3b9e
No known key found for this signature in database
GPG key ID: D300116E1C875A3D
2 changed files with 6 additions and 6 deletions

View file

@ -59,7 +59,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
whichType = Solver(scriptPubKey, vSolutions); whichType = Solver(scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD || whichType == TX_WITNESS_UNKNOWN) { if (whichType == TX_NONSTANDARD) {
return false; return false;
} else if (whichType == TX_MULTISIG) { } else if (whichType == TX_MULTISIG) {
unsigned char m = vSolutions.front()[0]; unsigned char m = vSolutions.front()[0];

View file

@ -1360,7 +1360,8 @@ class SegWitTest(BitcoinTestFramework):
def test_segwit_versions(self): def test_segwit_versions(self):
"""Test validity of future segwit version transactions. """Test validity of future segwit version transactions.
Future segwit version transactions are non-standard, but valid in blocks. Future segwit versions are non-standard to spend, but valid in blocks.
Sending to future segwit versions is always allowed.
Can run this before and after segwit activation.""" Can run this before and after segwit activation."""
NUM_SEGWIT_VERSIONS = 17 # will test OP_0, OP1, ..., OP_16 NUM_SEGWIT_VERSIONS = 17 # will test OP_0, OP1, ..., OP_16
@ -1400,7 +1401,7 @@ class SegWitTest(BitcoinTestFramework):
assert len(self.nodes[0].getrawmempool()) == 0 assert len(self.nodes[0].getrawmempool()) == 0
# Finally, verify that version 0 -> version 1 transactions # Finally, verify that version 0 -> version 1 transactions
# are non-standard # are standard
script_pubkey = CScript([CScriptOp(OP_1), witness_hash]) script_pubkey = CScript([CScriptOp(OP_1), witness_hash])
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")]
@ -1408,10 +1409,9 @@ class SegWitTest(BitcoinTestFramework):
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program]
tx2.rehash() tx2.rehash()
# Gets accepted to test_node, because standardness of outputs isn't # Gets accepted to both policy-enforcing nodes and others.
# checked with fRequireStandard
test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True) test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True)
test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=False) test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=True)
temp_utxo.pop() # last entry in temp_utxo was the output we just spent temp_utxo.pop() # last entry in temp_utxo was the output we just spent
temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))