Commit cbf44109 authored by dexx's avatar dexx Committed by Amaur Séchet
Browse files

Add a flag that update default datacarriersize to 220 byte

Summary: To disincentivize the use of other methods to embed data into the chain, in particular via P2SH, the default datacarriersize is raised from 80 byte to 220 byte, so it becomes the "cheapest" way of embedding data into the chain. The default value is changed when a flag is passed to `IsStandardTx`

Test Plan:
1. Check, if a script with max custom provided payload size is considered standard, with and without the flag
2. Check, if a script with max custom provided payload size + 1 is considered non-standard, with and without the flag
3. Check, if a script with max old default payload size (83 byte total) is considered standard, when the HF is not active
4. Check, if a script with max old default payload size + 1 (84 byte total) is considered non-standard, when the HF is not active
5. Check, if a script with max new default payload size (223 byte total) is considered standard, when the HF is active
6. Check, if a script with max new default payload size + 1 (224 byte total) is considered non-standard, when the HF is active

Via: make check

Reviewers: O1 Bitcoin ABC, #bitcoin_abc, dexX7, schancel, matiu

Reviewed By: O1 Bitcoin ABC, #bitcoin_abc, dexX7, schancel, matiu

Subscribers: jasonbcox, matiu, schancel, deadalnix, teamcity

Maniphest Tasks: T302

Differential Revision: https://reviews.bitcoinabc.org/D1158
parent cbaa7fe4
......@@ -823,9 +823,10 @@ std::string HelpMessage(HelpMessageMode mode) {
DEFAULT_ACCEPT_DATACARRIER));
strUsage += HelpMessageOpt(
"-datacarriersize",
strprintf(_("Maximum size of data in data carrier transactions we "
"relay and mine (default: %u)"),
MAX_OP_RETURN_RELAY));
strprintf(
_("Maximum size of data in data carrier transactions we relay and "
"mine (pre-fork default: %u, post-fork default: %u)"),
MAX_OP_RETURN_RELAY, MAX_OP_RETURN_RELAY_LARGE));
strUsage += HelpMessageGroup(_("Block creation options:"));
strUsage += HelpMessageOpt(
......
......@@ -27,7 +27,8 @@
* expensive-to-check-upon-redemption script like:
* DUP CHECKSIG DROP ... repeated 100 times... OP_1
*/
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType) {
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType,
bool allowLargeOpReturn) {
std::vector<std::vector<uint8_t>> vSolutions;
if (!Solver(scriptPubKey, whichType, vSolutions)) {
return false;
......@@ -45,7 +46,9 @@ bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType) {
}
unsigned nMaxDatacarrierBytes =
gArgs.GetArg("-datacarriersize", MAX_OP_RETURN_RELAY);
gArgs.GetArg("-datacarriersize",
allowLargeOpReturn ? MAX_OP_RETURN_RELAY_LARGE
: MAX_OP_RETURN_RELAY);
if (scriptPubKey.size() > nMaxDatacarrierBytes) {
return false;
}
......@@ -54,7 +57,8 @@ bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType) {
return whichType != TX_NONSTANDARD;
}
bool IsStandardTx(const CTransaction &tx, std::string &reason) {
bool IsStandardTx(const CTransaction &tx, std::string &reason,
bool allowLargeOpReturn) {
if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
......@@ -90,7 +94,7 @@ bool IsStandardTx(const CTransaction &tx, std::string &reason) {
unsigned int nDataOut = 0;
txnouttype whichType;
for (const CTxOut &txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, whichType)) {
if (!::IsStandard(txout.scriptPubKey, whichType, allowLargeOpReturn)) {
reason = "scriptpubkey";
return false;
}
......
......@@ -74,13 +74,17 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS =
static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS =
LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST;
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType);
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType,
bool allowLargeOpReturn = false);
/**
* Check for standard transaction types
* @return True if all outputs (scriptPubKeys) use only standard transaction
* forms
*/
bool IsStandardTx(const CTransaction &tx, std::string &reason);
bool IsStandardTx(const CTransaction &tx, std::string &reason,
bool allowLargeOpReturn = false);
/**
* Check for standard transaction types
* @param[in] mapInputs Map of previous transactions that have outputs we're
......
......@@ -28,6 +28,7 @@ public:
//!< bytes (+1 for OP_RETURN, +2 for the pushdata opcodes)
static const unsigned int MAX_OP_RETURN_RELAY = 83;
static const unsigned int MAX_OP_RETURN_RELAY_LARGE = 223;
extern bool fAcceptDatacarrier;
/**
......
......@@ -587,6 +587,74 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) {
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
/**
* Check acceptance of larger op_return when asked to.
*/
// New default size of 223 byte is standard
t.vout[0].scriptPubKey =
CScript() << OP_RETURN
<< ParseHex("646578784062697477617463682e636f2092c558ed52c56d"
"8dd14ca76226bc936a84820d898443873eb03d8854b21fa3"
"952b99a2981873e74509281730d78a21786d34a38bd1ebab"
"822fad42278f7f4420db6ab1fd2b6826148d4f73bb41ec2d"
"40a6d5793d66e17074a0c56a8a7df21062308f483dd6e38d"
"53609d350038df0a1b2a9ac8332016e0b904f66880dd0108"
"81c4e8074cce8e4ad6c77cb3460e01bf0e7e811b5f945f83"
"732ba6677520a893d75d9a966cb8f85dc301656b1635c631"
"f5d00d4adf73f2dd112ca75cf19754651909becfbe65aed1"
"3afb2ab8");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY_LARGE, t.vout[0].scriptPubKey.size());
BOOST_CHECK(IsStandardTx(CTransaction(t), reason, true));
// Larger than default size of 223 byte is non-standard
t.vout[0].scriptPubKey =
CScript() << OP_RETURN
<< ParseHex("646578784062697477617463682e636f2092c558ed52c56d"
"8dd14ca76226bc936a84820d898443873eb03d8854b21fa3"
"952b99a2981873e74509281730d78a21786d34a38bd1ebab"
"822fad42278f7f4420db6ab1fd2b6826148d4f73bb41ec2d"
"40a6d5793d66e17074a0c56a8a7df21062308f483dd6e38d"
"53609d350038df0a1b2a9ac8332016e0b904f66880dd0108"
"81c4e8074cce8e4ad6c77cb3460e01bf0e7e811b5f945f83"
"732ba6677520a893d75d9a966cb8f85dc301656b1635c631"
"f5d00d4adf73f2dd112ca75cf19754651909becfbe65aed1"
"3afb2ab800");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY_LARGE + 1,
t.vout[0].scriptPubKey.size());
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason, true));
/**
* Check when a custom value is used for -datacarriersize .
*/
unsigned newMaxSize = MAX_OP_RETURN_RELAY + 7;
gArgs.ForceSetArg("-datacarriersize", std::to_string(newMaxSize));
// Max user provided payload size is standard
t.vout[0].scriptPubKey =
CScript() << OP_RETURN
<< ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
"a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
"271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
"b649f6bc3f4cef3877696e64657878");
BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize);
BOOST_CHECK(IsStandardTx(CTransaction(t), reason, false));
BOOST_CHECK(IsStandardTx(CTransaction(t), reason, true));
// Max user provided payload size + 1 is non-standard
t.vout[0].scriptPubKey =
CScript() << OP_RETURN
<< ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
"a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
"271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
"b649f6bc3f4cef3877696e6465787800");
BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize + 1);
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason, false));
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason, true));
// Clear custom confirguration.
gArgs.ClearArg("-datacarriersize");
// Data payload can be encoded in any way...
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment