Make Taproot spends standard + policy limits

This adds a `TxoutType::WITNESS_V1_TAPROOT` for P2TR outputs, and permits spending
them in standardness rules. No corresponding `CTxDestination` is added for it,
as that isn't needed until we want wallet integration. The taproot validation flags
are also enabled for mempool transactions, and standardness rules are added
(stack item size limit, no annexes).
This commit is contained in:
Pieter Wuille
2020-09-11 14:34:10 -07:00
parent 865d2c37e2
commit e9a021d7e6
8 changed files with 61 additions and 7 deletions

View File

@@ -9,7 +9,7 @@
#include <consensus/validation.h>
#include <coins.h>
#include <span.h>
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
@@ -206,6 +206,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
// get the scriptPubKey corresponding to this input:
CScript prevScript = prev.scriptPubKey;
bool p2sh = false;
if (prevScript.IsPayToScriptHash()) {
std::vector <std::vector<unsigned char> > stack;
// If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
@@ -216,6 +217,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
if (stack.empty())
return false;
prevScript = CScript(stack.back().begin(), stack.back().end());
p2sh = true;
}
int witnessversion = 0;
@@ -237,6 +239,36 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
return false;
}
}
// Check policy limits for Taproot spends:
// - MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE limit for stack item size
// - No annexes
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
// Taproot spend (non-P2SH-wrapped, version 1, witness program size 32; see BIP 341)
auto stack = MakeSpan(tx.vin[i].scriptWitness.stack);
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
// Annexes are nonstandard as long as no semantics are defined for them.
return false;
}
if (stack.size() >= 2) {
// Script path spend (2 or more stack elements after removing optional annex)
const auto& control_block = SpanPopBack(stack);
SpanPopBack(stack); // Ignore script
if (control_block.empty()) return false; // Empty control block is invalid
if ((control_block[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT) {
// Leaf version 0xc0 (aka Tapscript, see BIP 342)
for (const auto& item : stack) {
if (item.size() > MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE) return false;
}
}
} else if (stack.size() == 1) {
// Key path spend (1 stack element after removing optional annex)
// (no policy rules apply)
} else {
// 0 stack elements; this is already invalid by consensus rules
return false;
}
}
}
return true;
}

View File

@@ -40,6 +40,8 @@ static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
/** The maximum size of each witness stack item in a standard P2WSH script */
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
/** The maximum size of each witness stack item in a standard BIP 342 script (Taproot, leaf version 0xc0) */
static const unsigned int MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE = 80;
/** The maximum size of a standard witnessScript */
static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
/** Min feerate for defining dust. Historically this has been based on the
@@ -68,7 +70,11 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE
SCRIPT_VERIFY_WITNESS |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM |
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE |
SCRIPT_VERIFY_CONST_SCRIPTCODE;
SCRIPT_VERIFY_CONST_SCRIPTCODE |
SCRIPT_VERIFY_TAPROOT |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE;
/** For convenience, standard but not mandatory verify flags. */
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;