From 766805948c5ca4a259c65417d0b251511bfeb555 Mon Sep 17 00:00:00 2001 From: Armin Sabouri Date: Sat, 28 Oct 2023 15:31:45 -0400 Subject: [PATCH] OP_CAT deployment --- src/consensus/params.h | 1 + src/deploymentinfo.cpp | 4 ++++ src/kernel/chainparams.cpp | 13 +++++++++++- src/rpc/blockchain.cpp | 1 + src/validation.cpp | 27 +++++++++++++++++++----- test/functional/rpc_blockchain.py | 17 +++++++++++++-- test/functional/test_framework/script.py | 3 +++ 7 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/consensus/params.h b/src/consensus/params.h index 501ab73205252e..628fb858c2f6d2 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -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 }; diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 53eb994cb40b4b..8b5736f17b18c4 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -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) diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index 109d37d7589739..71dcbe30db6d1a 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -144,6 +144,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 = uint256{"000000000000000000000000000000000000000088e186b70e0862c193ec44d6"}; consensus.defaultAssumeValid = uint256{"000000000000000000011c5890365bdbe5d25b97ce0057589acaef4f1a57263f"}; // 856760 @@ -262,6 +263,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 = uint256{"000000000000000000000000000000000000000000000f209695166be8b61fa9"}; consensus.defaultAssumeValid = uint256{"000000000000000465b1a66c9f386308e8c75acef9201f3f577811da09fc90ad"}; // 2873500 @@ -497,6 +499,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); @@ -572,7 +583,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{}; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ee58565e18c24e..ef05d4c3d2d2cd 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1395,6 +1395,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 diff --git a/src/validation.cpp b/src/validation.cpp index 5e2f05a1073858..a3c0c741d5e8f1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1224,6 +1224,17 @@ bool MemPoolAccept::PackageMempoolChecks(const std::vector& txn return true; } +static unsigned int DepDiscourageFlags(const CBlockIndex* tip, const ChainstateManager& chainman, const std::vector>& depflags) +{ + unsigned int result = SCRIPT_VERIFY_NONE; + for (auto [dep, flags] : depflags) { + if (!DeploymentActiveAfter(tip, chainman, dep)) { + result |= flags; + } + } + return result; +} + bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) { AssertLockHeld(cs_main); @@ -1231,11 +1242,12 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) const CTransaction& tx = *ws.m_ptx; TxValidationState& state = ws.m_state; - const bool ctv_active = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman, Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY); - const bool apo_active = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman, Consensus::DEPLOYMENT_ANYPREVOUT); - const unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS - | (ctv_active ? SCRIPT_VERIFY_NONE : SCRIPT_VERIFY_DISCOURAGE_CHECK_TEMPLATE_VERIFY_HASH) - | (apo_active ? SCRIPT_VERIFY_NONE : SCRIPT_VERIFY_DISCOURAGE_ANYPREVOUT); + const unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS | + DepDiscourageFlags(m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman, { + { Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY, SCRIPT_VERIFY_DISCOURAGE_CHECK_TEMPLATE_VERIFY_HASH }, + { Consensus::DEPLOYMENT_ANYPREVOUT, SCRIPT_VERIFY_DISCOURAGE_ANYPREVOUT }, + { Consensus::DEPLOYMENT_OP_CAT, SCRIPT_VERIFY_DISCOURAGE_OP_CAT }, + }); // Check input scripts and signatures. // This is done last to help prevent CPU exhaustion denial-of-service attacks. @@ -2381,6 +2393,11 @@ unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Chainstat flags |= SCRIPT_VERIFY_ANYPREVOUT; } + // Enforce OP_CAT + if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_OP_CAT)) { + flags |= SCRIPT_VERIFY_OP_CAT; + } + return flags; } diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 1b35db6ca93cb5..f54fd0851b1d5e 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -193,11 +193,10 @@ def _test_getblockchaininfo(self): def check_signalling_deploymentinfo_result(self, gdi_result, height, blockhash): assert height >= 144 and height <= 287 - assert_equal(gdi_result, { "hash": blockhash, "height": height, - "script_flags": ["ANYPREVOUT","CHECKLOCKTIMEVERIFY","CHECKSEQUENCEVERIFY","DEFAULT_CHECK_TEMPLATE_VERIFY_HASH","DERSIG","NULLDUMMY","P2SH","TAPROOT","WITNESS"], + "script_flags": ["ANYPREVOUT","CHECKLOCKTIMEVERIFY","CHECKSEQUENCEVERIFY","DEFAULT_CHECK_TEMPLATE_VERIFY_HASH","DERSIG","NULLDUMMY","OP_CAT","P2SH","TAPROOT","WITNESS"], "deployments": { 'bip34': {'type': 'buried', 'active': True, 'height': 2}, 'bip66': {'type': 'buried', 'active': True, 'height': 3}, @@ -248,6 +247,20 @@ def check_signalling_deploymentinfo_result(self, gdi_result, height, blockhash): 'active': True, 'height': 0, }, + 'opcat': { + 'type': 'heretical', + 'heretical': { + 'binana-id': "BIN-2024-0001-000", + 'start_time': -1, + 'timeout': 9223372036854775807, + 'period': 144, + 'status': 'active', + 'since': 0, + 'status_next': 'active' + }, + 'height': 0, + 'active': True, + }, } }) diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py index 6749bc55adc27a..b386c452f77aeb 100644 --- a/test/functional/test_framework/script.py +++ b/test/functional/test_framework/script.py @@ -966,4 +966,7 @@ def taproot_construct(pubkey, scripts=None, *, keyver=None, treat_internal_as_in return TaprootInfo(CScript([OP_1, tweaked]), pubkey, negated + 0, tweak, leaves, h, tweaked, keyver) def is_op_success(o): + # assume OP_CAT is activated in tests + if o == OP_CAT: + return False return o == 0x50 or o == 0x62 or o == 0x89 or o == 0x8a or o == 0x8d or o == 0x8e or (o >= 0x7e and o <= 0x81) or (o >= 0x83 and o <= 0x86) or (o >= 0x95 and o <= 0x99) or (o >= 0xbb and o <= 0xfe)