Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always check scripts with P2SH + Segwit #499

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
31 changes: 3 additions & 28 deletions test/functional/name_segwit.py
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -28,16 +28,13 @@
from decimal import Decimal
import io

SEGWIT_ACTIVATION_HEIGHT = 300


class NameSegwitTest (NameTestFramework):

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):
Expand Down Expand Up @@ -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'
Expand Down