Skip to content

Commit

Permalink
Merge pull request #57 from ajtowns/202404-inq27-cat
Browse files Browse the repository at this point in the history
Implement BIN-24-1 validation (BIP 347, OP_CAT)
  • Loading branch information
ajtowns authored May 7, 2024
2 parents 011ad33 + 61ba80e commit fdce1db
Show file tree
Hide file tree
Showing 16 changed files with 883 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum DeploymentPos : uint16_t {
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_CHECKTEMPLATEVERIFY, // Deployment of CTV (BIP 119)
DEPLOYMENT_ANYPREVOUT,
DEPLOYMENT_OP_CAT,
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
Expand Down
6 changes: 6 additions & 0 deletions src/deploymentinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
/*.name =*/ "anyprevout",
/*.gbt_force =*/ true,
},
{
/*.name =*/ "opcat",
/*.gbt_force =*/ true,
},
};

std::string DeploymentName(Consensus::BuriedDeployment dep)
Expand Down Expand Up @@ -89,6 +93,8 @@ const std::map<std::string, uint32_t> g_verify_flag_names{
FLAG_NAME(DISCOURAGE_CHECK_TEMPLATE_VERIFY_HASH),
FLAG_NAME(ANYPREVOUT),
FLAG_NAME(DISCOURAGE_ANYPREVOUT),
FLAG_NAME(OP_CAT),
FLAG_NAME(DISCOURAGE_OP_CAT),
};
#undef FLAG_NAME

Expand Down
13 changes: 12 additions & 1 deletion src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = SetupDeployment{.activate = 0x30000000, .abandon = 0, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY] = SetupDeployment{.activate = 0x60007700, .abandon = 0x40007700, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_ANYPREVOUT] = SetupDeployment{.activate = 0x60007600, .abandon = 0x40007600, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_OP_CAT] = SetupDeployment{.activate = 0x62000100, .abandon = 0x42000100, .never = true};

consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000063c4ebd298db40af57541800");
consensus.defaultAssumeValid = uint256S("0x000000000000000000026811d149d4d261995ec5b3f64f439a0a10e1a464af9a"); // 824000
Expand Down Expand Up @@ -245,6 +246,7 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = SetupDeployment{.activate = 0x30000000, .abandon = 0, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY] = SetupDeployment{.activate = 0x60007700, .abandon = 0x40007700, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_ANYPREVOUT] = SetupDeployment{.activate = 0x60007600, .abandon = 0x40007600, .never = true};
consensus.vDeployments[Consensus::DEPLOYMENT_OP_CAT] = SetupDeployment{.activate = 0x62000100, .abandon = 0x42000100, .never = true};

consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000c59b14e264ba6c15db9");
consensus.defaultAssumeValid = uint256S("0x000000000001323071f38f21ea5aae529ece491eadaccce506a59bcc2d968917"); // 2550000
Expand Down Expand Up @@ -386,6 +388,15 @@ class SigNetParams : public CChainParams {
.activate = 0x60007600,
.abandon = 0x40007600,
};
consensus.vDeployments[Consensus::DEPLOYMENT_OP_CAT] = SetupDeployment{
.year = 2024,
.number = 1,
.revision = 0,
.start = 1704085200, // 2024-01-01
.timeout = 2019704400, // 2034-01-01
.activate = 0x62000100,
.abandon = 0x42000100,
};

RenounceDeployments(options.renounce, consensus.vDeployments);

Expand Down Expand Up @@ -460,7 +471,7 @@ class CRegTestParams : public CChainParams
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = SetupDeployment{.start = 0, .timeout = Consensus::HereticalDeployment::NO_TIMEOUT, .activate = 0x30000000, .abandon = 0x50000000};
consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY] = SetupDeployment{.activate = 0x60007700, .abandon = 0x40007700, .always = true};
consensus.vDeployments[Consensus::DEPLOYMENT_ANYPREVOUT] = SetupDeployment{.activate = 0x60007600, .abandon = 0x40007600, .always = true};

consensus.vDeployments[Consensus::DEPLOYMENT_OP_CAT] = SetupDeployment{.activate = 0x62000100, .abandon = 0x42000100, .always = true};
consensus.nMinimumChainWork = uint256{};
consensus.defaultAssumeValid = uint256{};

Expand Down
4 changes: 3 additions & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECK_TEMPLATE_VERIFY_HASH |
SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH |
SCRIPT_VERIFY_ANYPREVOUT};
SCRIPT_VERIFY_ANYPREVOUT |
SCRIPT_VERIFY_OP_CAT
};

/** 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};
Expand Down
1 change: 1 addition & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager&
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_ANYPREVOUT);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_OP_CAT);
return softforks;
}
} // anon namespace
Expand Down
40 changes: 34 additions & 6 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,16 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) {
return set_error(serror, SCRIPT_ERR_OP_COUNT);
}

// When OP_SUCCESS disabled opcodes (CVE-2010-5137) are
// redefined in tapscript, remove them from the if below
// and put them here
if (opcode == OP_CAT) {
return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes (CVE-2010-5137).
}
}

if (opcode == OP_CAT ||
opcode == OP_SUBSTR ||
if (opcode == OP_SUBSTR ||
opcode == OP_LEFT ||
opcode == OP_RIGHT ||
opcode == OP_INVERT ||
Expand Down Expand Up @@ -534,6 +540,19 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
case OP_NOP:
break;

case OP_CAT:
{
if (stack.size() < 2)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
valtype& vch1 = stacktop(-2);
valtype& vch2 = stacktop(-1);
if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE)
return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
vch1.insert(vch1.end(), vch2.begin(), vch2.end());
stack.pop_back();
}
break;

case OP_CHECKLOCKTIMEVERIFY:
{
if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
Expand Down Expand Up @@ -1963,12 +1982,21 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
// Note how this condition would not be reached if an unknown OP_SUCCESSx was found
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
}
// New opcodes will be listed here. May use a different sigversion to modify existing opcodes.

if (IsOpSuccess(opcode)) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
if (opcode == OP_CAT) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_CAT) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_CAT);
} else if (!(flags & SCRIPT_VERIFY_OP_CAT)) {
return set_success(serror);
}
} else {
// OP_SUCCESS behaviour
if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
}
return set_success(serror);
}
return set_success(serror);
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/script/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ enum : uint32_t {
// Making ANYPREVOUT public key versions (in BIP 342 scripts) non-standard
SCRIPT_VERIFY_DISCOURAGE_ANYPREVOUT = (1U << 25),

// Support OP_CAT in tapscript
SCRIPT_VERIFY_OP_CAT = (1U << 26),
SCRIPT_VERIFY_DISCOURAGE_OP_CAT = (1U << 27),

// Constants to point to the highest flag in use. Add new flags above this line.
//
SCRIPT_VERIFY_END_MARKER
Expand Down
1 change: 1 addition & 0 deletions src/script/script_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef enum ScriptError_t
SCRIPT_ERR_DISCOURAGE_OP_SUCCESS,
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE,
SCRIPT_ERR_DISCOURAGE_ANYPREVOUT,
SCRIPT_ERR_DISCOURAGE_OP_CAT,

/* segregated witness */
SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH,
Expand Down
Loading

0 comments on commit fdce1db

Please sign in to comment.