diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 0d918f082..62944baff 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -63,6 +63,7 @@ BITCOIN_TESTS =\ test/claimtrie_tests.cpp \ test/claimtriecache_tests.cpp \ test/claimtriebranching_tests.cpp \ + test/nameclaim_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/policyestimator_tests.cpp \ diff --git a/src/nameclaim.cpp b/src/nameclaim.cpp index f3d2978d0..417341540 100644 --- a/src/nameclaim.cpp +++ b/src/nameclaim.cpp @@ -1,7 +1,9 @@ +#include #include "nameclaim.h" #include "hash.h" #include "util.h" + std::vector uint32_t_to_vch(uint32_t n) { std::vector vchN; @@ -173,3 +175,27 @@ size_t ClaimNameSize(const CScript& scriptIn) return vvchParams[0].size(); } } + +CAmount CalcMinClaimTrieFee(const CTransaction& tx, const CAmount &minFeePerNameClaimChar) +{ + if (minFeePerNameClaimChar == 0) + { + return 0; + } + + CAmount min_fee = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + int op; + std::vector > vvchParams; + if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams)) + { + if (op == OP_CLAIM_NAME) + { + int claim_name_size = vvchParams[0].size(); + min_fee += claim_name_size*minFeePerNameClaimChar; + } + } + } + return min_fee; +} diff --git a/src/nameclaim.h b/src/nameclaim.h index 6821af470..0d9ff2775 100644 --- a/src/nameclaim.h +++ b/src/nameclaim.h @@ -1,22 +1,33 @@ #ifndef BITCOIN_NAMECLAIM_H #define BITCOIN_NAMECLAIM_H +#include "amount.h" #include "script/script.h" +#include "primitives/transaction.h" #include "uint256.h" #include +// This is the minimum claim fee per character in the name of an OP_CLAIM_NAME command that must +// be attached to transactions for it to be accepted into the memory pool. +// Rationale: current implementation of the claim trie uses more memory for longer name claims +// due to the fact that each chracater is assigned a trie node regardless of whether it contains +// any claims or not. In the future, we can switch to a radix tree implementation where +// empty nodes do not take up any memory and the minimum fee can be priced on a per claim +// basis. +#define MIN_FEE_PER_NAMECLAIM_CHAR 200000 + // 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. +// 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 CScript ClaimNameScript(std::string name, std::string value); CScript SupportClaimScript(std::string name, uint160 claimId); -CScript UpdateClaimScript(std::string name, uint160 claimId, std::string value); +CScript UpdateClaimScript(std::string name, uint160 claimId, std::string value); 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); @@ -24,10 +35,11 @@ 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 +// 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); - +// get size of the name in a claim script, returns 0 if scriptin is not a claimetrie transaction +size_t ClaimNameSize(const CScript& scriptIn); +// calculate the minimum fee (mempool rule) required for transaction +CAmount CalcMinClaimTrieFee(const CTransaction& tx, const CAmount &minFeePerNameClaimChar); #endif // BITCOIN_NAMECLAIM_H diff --git a/src/test/nameclaim_tests.cpp b/src/test/nameclaim_tests.cpp new file mode 100644 index 000000000..92735ae14 --- /dev/null +++ b/src/test/nameclaim_tests.cpp @@ -0,0 +1,38 @@ +#include "nameclaim.h" +#include "primitives/transaction.h" +#include +#include "test/test_bitcoin.h" + +//BOOST_FIXTURE_TEST_SUITE(nameclaim_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(calc_min_claimtrie_fee) +{ + + CMutableTransaction tx; + tx.vout.resize(1); + tx.vout[0].scriptPubKey = ClaimNameScript("A","test"); + BOOST_CHECK_EQUAL(CalcMinClaimTrieFee(tx, MIN_FEE_PER_NAMECLAIM_CHAR), MIN_FEE_PER_NAMECLAIM_CHAR); + + // check that fee is adjusted based on name length + CMutableTransaction tx2; + tx2.vout.resize(1); + tx2.vout[0].scriptPubKey = ClaimNameScript("ABCDE","test"); + BOOST_CHECK_EQUAL(CalcMinClaimTrieFee(tx2,MIN_FEE_PER_NAMECLAIM_CHAR), MIN_FEE_PER_NAMECLAIM_CHAR*5); + + // check that multiple OP_CLAIM_NAME outputs are counted + CMutableTransaction tx3; + tx3.vout.resize(2); + tx3.vout[0].scriptPubKey = ClaimNameScript("A","test"); + tx3.vout[1].scriptPubKey = ClaimNameScript("AB","test"); + BOOST_CHECK_EQUAL(CalcMinClaimTrieFee(tx3,MIN_FEE_PER_NAMECLAIM_CHAR), MIN_FEE_PER_NAMECLAIM_CHAR*3); + + // if tx has no claim minimum fee is 0 + CMutableTransaction tx4; + tx4.vout.resize(1); + BOOST_CHECK_EQUAL(CalcMinClaimTrieFee(tx4,MIN_FEE_PER_NAMECLAIM_CHAR), 0); + +} + + + +//BOOST_AUTO_TEST_SUITE_END()