Skip to content

Instantly share code, notes, and snippets.

@1ma
Created June 2, 2023 10:39
Show Gist options
  • Save 1ma/2c6cbecd4eb3ce410918f8f2ac67da84 to your computer and use it in GitHub Desktop.
Save 1ma/2c6cbecd4eb3ce410918f8f2ac67da84 to your computer and use it in GitHub Desktop.
diff --git a/src/init.cpp b/src/init.cpp
index af39e8078..c0b5e09dc 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -553,6 +553,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
+ argsman.AddArg("-relayopfalseopif", strprintf("Relay and mine transactions containing the OP_FALSE OP_IF data envelope (default: %u)", DEFAULT_ACCEPT_OP_FALSE_OP_IF_DATA_ENVELOPE), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
@@ -1009,6 +1010,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
fIsBareMultisigStd = args.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
fAcceptDatacarrier = args.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER);
+ fAcceptOpFalseOpIfDataEnvelope = args.GetBoolArg("-relayopfalseopif", DEFAULT_ACCEPT_OP_FALSE_OP_IF_DATA_ENVELOPE);
nMaxDatacarrierBytes = args.GetIntArg("-datacarriersize", nMaxDatacarrierBytes);
// Option to startup with mocktime set (used for regression testing):
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 11b1a1c88..48acfea83 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -10,6 +10,7 @@
#include <crypto/sha256.h>
#include <pubkey.h>
#include <script/script.h>
+#include <script/standard.h>
#include <uint256.h>
typedef std::vector<unsigned char> valtype;
@@ -504,6 +505,14 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
return set_error(serror, SCRIPT_ERR_MINIMALDATA);
}
stack.push_back(vchPushValue);
+ if (!fAcceptOpFalseOpIfDataEnvelope && ((flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) && opcode == OP_FALSE)) {
+ auto pc_tmp = pc;
+ opcodetype next_opcode;
+ valtype dummy_data;
+ if (script.GetOp(pc_tmp, next_opcode, dummy_data) && next_opcode == OP_IF) {
+ return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
+ }
+ }
} else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
switch (opcode)
{
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 5fb98cc30..cee03ec6a 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -17,6 +17,8 @@
typedef std::vector<unsigned char> valtype;
bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
+bool fAcceptOpFalseOpIfDataEnvelope = DEFAULT_ACCEPT_OP_FALSE_OP_IF_DATA_ENVELOPE;
+
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in)) {}
diff --git a/src/script/standard.h b/src/script/standard.h
index eb5042176..a406edc9c 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -16,6 +16,7 @@
#include <variant>
static const bool DEFAULT_ACCEPT_DATACARRIER = true;
+static const bool DEFAULT_ACCEPT_OP_FALSE_OP_IF_DATA_ENVELOPE = true;
class CKeyID;
class CScript;
@@ -43,6 +44,12 @@ static const unsigned int MAX_OP_RETURN_RELAY = 83;
*/
extern bool fAcceptDatacarrier;
+/**
+ * OP_FALSE OP_IF <data> OP_ENDIF is one known opcode sequence that allows embedding
+ * arbitrary byte streams in them of up to ~4MiB, known as a "data envelope".
+ */
+extern bool fAcceptOpFalseOpIfDataEnvelope;
+
/** Maximum size of TxoutType::NULL_DATA scripts that this node considers standard. */
extern unsigned nMaxDatacarrierBytes;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment