From ad7304e321ce7b09dca654615f2270c5adc39c27 Mon Sep 17 00:00:00 2001 From: kkurokawa Date: Thu, 21 Jul 2016 14:07:27 -0400 Subject: [PATCH] Limits name length of claimtrie transactions to 255 bytes --- src/main.cpp | 6 ++++++ src/nameclaim.cpp | 14 ++++++++++++++ src/nameclaim.h | 9 +++++++++ src/test/transaction_tests.cpp | 27 +++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 22d0c3237..d5515bfa2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -961,8 +961,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + + // check claimtrie transactions + if (ClaimScriptSize(txout.scriptPubKey) > MAX_CLAIM_SCRIPT_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-txns-claimscriptsize-toolarge"); + if (ClaimNameSize(txout.scriptPubKey) > MAX_CLAIM_NAME_SIZE) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-claimscriptname-toolarge"); + } // Check for duplicate inputs diff --git a/src/nameclaim.cpp b/src/nameclaim.cpp index 8e1b10de9..292123992 100644 --- a/src/nameclaim.cpp +++ b/src/nameclaim.cpp @@ -136,3 +136,17 @@ size_t ClaimScriptSize(const CScript& scriptIn) return scriptIn.size() - strippedScript.size(); } +size_t ClaimNameSize(const CScript& scriptIn) +{ + std::vector > vvchParams; + CScript::const_iterator pc = scriptIn.begin(); + int op; + if (!DecodeClaimScript(scriptIn, op, vvchParams, pc)) + { + return 0; + } + else + { + return vvchParams[0].size(); + } +} diff --git a/src/nameclaim.h b/src/nameclaim.h index 8798d0ac0..8c0144b86 100644 --- a/src/nameclaim.h +++ b/src/nameclaim.h @@ -6,8 +6,14 @@ #include +// This is the max claim script size in bytes, not including the script pubkey part of the script. +// Scripts exceeding this size are rejected in CheckTransaction in main.cpp #define MAX_CLAIM_SCRIPT_SIZE 8192 +// This is the max claim name size in bytes, for all claim trie transactions. +// Scripts exceeding this size are rejected in CheckTransaction in main.cpp +#define MAX_CLAIM_NAME_SIZE 255 + bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector >& vvchParams); bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector >& vvchParams, CScript::const_iterator& pc); CScript StripClaimScriptPrefix(const CScript& scriptIn); @@ -15,6 +21,9 @@ CScript StripClaimScriptPrefix(const CScript& scriptIn, int& op); uint160 ClaimIdHash(const uint256& txhash, uint32_t nOut); std::vector uint32_t_to_vch(uint32_t n); uint32_t vch_to_uint32_t(std::vector& vchN); +// get size of the claim script, minus the script pubkey part size_t ClaimScriptSize(const CScript& scriptIn); +// get size of the name in a claim script, returns 0 if scriptin is not a claimetrie transaction +size_t ClaimNameSize(const CScript& scriptIn); #endif // BITCOIN_NAMECLAIM_H diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 17f9f9e5b..0e35af45e 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -12,6 +12,7 @@ #include "key.h" #include "keystore.h" #include "main.h" // For CheckTransaction +#include "nameclaim.h" #include "policy/policy.h" #include "script/script.h" #include "script/script_error.h" @@ -445,6 +446,7 @@ BOOST_AUTO_TEST_CASE(test_claimsValid) BOOST_CHECK(CheckTransaction(t, state)); BOOST_CHECK(state.IsValid()); + // exceeds max script size vchName = std::vector(2<<12, '0'); vchValue = std::vector(2<<12, '0'); @@ -454,5 +456,30 @@ BOOST_AUTO_TEST_CASE(test_claimsValid) BOOST_CHECK(!CheckTransaction(t, state)); BOOST_CHECK(!state.IsValid()); + + // does not exceed max name size + vchName = std::vector(MAX_CLAIM_NAME_SIZE, '0'); + vchValue = std::vector(1, '0'); + + t.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP << OP_TRUE; + + state = CValidationState(); + + BOOST_CHECK(CheckTransaction(t, state)); + BOOST_CHECK(state.IsValid()); + + // exceeds max name size + vchName = std::vector(MAX_CLAIM_NAME_SIZE+1, '0'); + vchValue = std::vector(1, '0'); + + t.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP << OP_TRUE; + + state = CValidationState(); + + BOOST_CHECK(!CheckTransaction(t, state)); + BOOST_CHECK(!state.IsValid()); + + + } BOOST_AUTO_TEST_SUITE_END()