From c8aeb925c950c6db554bd465f3e29b6d4efe23eb Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Mon, 28 Mar 2022 11:46:53 +0200 Subject: [PATCH 1/2] Always check scripts with P2SH + Segwit. P2SH and Segwit have been activated on Namecoin for a long time now. Upstream Bitcoin enforces those script flags (plus Taproot which is not yet active on Namecoin) now unconditionally on the full block history, except for certain specific blocks that would fail. In Namecoin, actually all old blocks validate with P2SH and Segwit. Thus this changes GetBlockScriptFlags to always turn on P2SH and Segwit, which tidies up / simplifies things and also brings the code more in line with upstream. --- src/validation.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 68057097a8..2cd5dcbb0c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1960,21 +1960,19 @@ static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams) { - uint32_t flags{SCRIPT_VERIFY_NONE}; + /* For simplicity, we enforce P2SH+Segwit for all previous blocks (before + the actual activation) as well. They all are valid with these extra + checks turned on. */ + uint32_t flags{SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS}; /* We allow overriding flags with exceptions, in case a few historical blocks violate a softfork that got activated later, and which we want - to otherwise enforce unconditionally. For now, there are no - flags enforced unconditionally, though. */ + to otherwise enforce unconditionally. */ const auto it{consensusparams.script_flag_exceptions.find(*Assert(block_index.phashBlock))}; if (it != consensusparams.script_flag_exceptions.end()) { flags = it->second; } - if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_P2SH)) { - flags |= SCRIPT_VERIFY_P2SH; - } - // Enforce the DERSIG (BIP66) rule if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_DERSIG)) { flags |= SCRIPT_VERIFY_DERSIG; @@ -1999,7 +1997,6 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Co // Enforce BIP147 NULLDUMMY (activated simultaneously with segwit) if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) { flags |= SCRIPT_VERIFY_NULLDUMMY; - flags |= SCRIPT_VERIFY_WITNESS; } return flags; From b0ded3dda74cd24632cca017bfe1bfdf90c36d72 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Mon, 28 Mar 2022 11:48:38 +0200 Subject: [PATCH 2/2] Update name_segwit.py for always-on segwit. Since script verification enforces segwit always now (without taking activation into account), we can no longer check for cases where transactions breaking segwit would be allowed pre-activation. This simplifies name_segwit.py, and makes it now just double-check that segwit is indeed enforced as it should be, as well as that generally names on segwit addresses work. --- test/functional/name_segwit.py | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/test/functional/name_segwit.py b/test/functional/name_segwit.py index 3439f129ab..d3944ded28 100755 --- a/test/functional/name_segwit.py +++ b/test/functional/name_segwit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2021 Daniel Kraft +# Copyright (c) 2014-2022 Daniel Kraft # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -28,8 +28,6 @@ from decimal import Decimal import io -SEGWIT_ACTIVATION_HEIGHT = 300 - class NameSegwitTest (NameTestFramework): @@ -37,7 +35,6 @@ def set_test_params (self): self.setup_name_test ([[ "-debug", "-par=1", - f"-testactivationheight=segwit@{SEGWIT_ACTIVATION_HEIGHT}" ]] * 1) def checkNameValueAddr (self, name, value, addr): @@ -133,34 +130,12 @@ def run_test (self): self.generate (self.node, 5) self.checkNameValueAddr (name, value, addr) - # Before segwit activation, the script should behave as anyone-can-spend. - # It will still fail due to non-mandatory flag checks when submitted - # into the mempool. - assert not softfork_active (self.node, "segwit") + # Verify that trying to update the name without a proper signature + # fails both directly in a block and through sendrawtransaction. assert_raises_rpc_error (-26, 'Script failed an OP_EQUALVERIFY operation', self.tryUpdateSegwitName, name, "wrong value", addr) self.generate (self.node, 1) - self.checkNameValueAddr (name, value, addr) - - # But directly in a block, the update should work with a dummy witness. - assert_equal (self.tryUpdateInBlock (name, "stolen", addr, - withWitness=False), - None) - self.checkNameValueAddr (name, "stolen", addr) - - # Activate segwit. Since this makes the original name expire, we have - # to re-register it. - self.generate (self.node, 100) - new = self.node.name_new (name) - self.generate (self.node, 10) - self.firstupdateName (0, name, new, value, {"destAddress": addr}) - self.generate (self.node, 5) - self.checkNameValueAddr (name, value, addr) - - # Verify that now trying to update the name without a proper signature - # fails differently. - assert softfork_active (self.node, "segwit") assert_equal (self.tryUpdateInBlock (name, "wrong value", addr, withWitness=True), 'non-mandatory-script-verify-flag'