From 714dd309e57b555f7c583e403d2a1fe23f455318 Mon Sep 17 00:00:00 2001 From: jonasbits Date: Fri, 12 Sep 2014 21:54:02 +0200 Subject: [PATCH 1/6] carbon copy of namecoin mainnet the next commit will have the changes to become testnet --- include/coinChain/Chain.h | 90 +++++++++++++++++- src/coinChain/Chain.cpp | 191 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 1 deletion(-) diff --git a/include/coinChain/Chain.h b/include/coinChain/Chain.h index 2cdf2704..18a3b9a2 100644 --- a/include/coinChain/Chain.h +++ b/include/coinChain/Chain.h @@ -362,7 +362,95 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { extern const NamecoinChain namecoin; - +class COINCHAIN_EXPORT NamecoinChain : public Chain { +public: + NamecoinChain(); + virtual const int protocol_version() const { return 37200; } // 0.3.72.0 + virtual const Block& genesisBlock() const ; + virtual const uint256& genesisHash() const { return _genesis; } + virtual const int64_t subsidy(unsigned int height, uint256 prev = uint256(0)) const ; + virtual bool isStandard(const Transaction& tx) const ; + virtual const CBigNum proofOfWorkLimit() const { return CBigNum(~uint256(0) >> 32); } + virtual int nextWorkRequired(BlockIterator blk) const; + virtual const bool checkProofOfWork(const Block& block) const; + virtual bool adhere_aux_pow() const { return true; } + virtual bool adhere_names() const { return true; } + virtual bool enforce_name_rules(int count) const { // see: https://bitcointalk.org/index.php?topic=310954 + if (count > 500000000) + return count > 1386499470; // the timestamp of block 150000 - so will always return true... + else + return count > 150000; // enforce from block 150000 + } + + + virtual bool checkPoints(const unsigned int height, const uint256& hash) const ; + virtual unsigned int totalBlocksEstimate() const; + + virtual int64_t min_fee() const { + return 500000; + } + + virtual int64_t network_fee(int count) const { + int height = count - 1; + // Speed up network fee decrease 4x starting at 24000 + if (height >= 24000) + height += (height - 24000) * 3; + if ((height >> 13) >= 60) + return 0; + int64_t start = 50 * COIN; + int64_t res = start >> (height >> 13); + res -= (res >> 14) * (height % 8192); + return res; + } + + virtual int expirationDepth(int count) const { + int height = count - 1; + if (height < 24000) + return 12000; + if (height < 48000) + return height - 12000; + return 36000; + } + + // To enable upgrade from one block version to another we define a quorum and a majority for acceptance + // of minimum this version as well as a quorum and majority for when the checks of that block version should be enforced. + virtual size_t accept_quorum() const { return 1000;} + virtual size_t accept_majority() const { return 1001; } // 95% of the last 1000 + + virtual size_t enforce_quorum() const { return 1000; } + virtual size_t enforce_majority() const { return 1001; } // 75% of the last 1000 + + const PubKey& alert_key() const { return _alert_key; } + + // virtual char networkId() const { return 0x00; } // 0x00, 0x6f, 0x34 (bitcoin, testnet, namecoin) + virtual ChainAddress getAddress(PubKeyHash hash) const { return ChainAddress(0x34, hash); } + virtual ChainAddress getAddress(ScriptHash hash) const { throw std::runtime_error("ScriptHash not supported by Namecoin!"); } + virtual ChainAddress getAddress(std::string str) const { + ChainAddress addr(str); + if(addr.version() == 0x34) + addr.setType(ChainAddress::PUBKEYHASH); + else + throw std::runtime_error("ScriptHash not supported by Namecoin!"); + return addr; + } + + virtual std::string signedMessageMagic() const { return "Namecoin Signed Message:\n"; } + + virtual const Magic& magic() const { return _magic; }; + virtual unsigned short defaultPort() const { return 8334; } + + virtual unsigned int ircChannels() const { return 1; } // number of groups to try (100 for bitcoin, 2 for litecoin) + +private: + Block _genesisBlock; + uint256 _genesis; + Magic _magic; + typedef std::map Checkpoints; + Checkpoints _checkpoints; +}; + +extern const NamecoinChain namecoin; + class COINCHAIN_EXPORT LitecoinChain : public Chain { public: LitecoinChain(); diff --git a/src/coinChain/Chain.cpp b/src/coinChain/Chain.cpp index ae73db5a..bbd9ea14 100644 --- a/src/coinChain/Chain.cpp +++ b/src/coinChain/Chain.cpp @@ -600,6 +600,197 @@ const NamecoinChain namecoin; RegisterChain g_namecoin(namecoin); +NamecoinChain::NamecoinChain() : Chain("namecoin", "NMC", 8), _genesis("000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770") { + _alert_key = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); + _magic[0] = 0xf9; _magic[1] = 0xbe; _magic[2] = 0xb4; _magic[3] = 0xfe; + const char* pszTimestamp = "... choose what comes next. Lives of your own, or a return to chains. -- V"; + Transaction txNew; + Script signature = Script() << 0x1c007fff << CBigNum(522) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.addInput(Input(Coin(), signature)); + Script script = Script() << ParseHex("04b620369050cd899ffbbc4e8ee51e8c4534a855bb463439d63d235d4779685d8b6f4870a238cf365ac94fa13ef9a2a22cd99d0d5ee86dcabcafce36c7acf43ce5") << OP_CHECKSIG; + txNew.addOutput(Output(50 * COIN, script)); + _genesisBlock = Block(1, uint256(0), uint256(0), 1303000001, 0x1c007fff, 0xa21ea192U); + _genesisBlock.addTransaction(txNew); + _genesisBlock.updateMerkleTree(); // genesisBlock + assert(_genesisBlock.getHash() == _genesis); + + _checkpoints = boost::assign::map_list_of + ( 2016, uint256("0x0000000000660bad0d9fbde55ba7ee14ddf766ed5f527e3fbca523ac11460b92")) + ( 4032, uint256("0x0000000000493b5696ad482deb79da835fe2385304b841beef1938655ddbc411")) + ( 6048, uint256("0x000000000027939a2e1d8bb63f36c47da858e56d570f143e67e85068943470c9")) + ( 8064, uint256("0x000000000003a01f708da7396e54d081701ea406ed163e519589717d8b7c95a5")) + ( 10080, uint256("0x00000000000fed3899f818b2228b4f01b9a0a7eeee907abd172852df71c64b06")) + ( 12096, uint256("0x0000000000006c06988ff361f124314f9f4bb45b6997d90a7ee4cedf434c670f")) + ( 14112, uint256("0x00000000000045d95e0588c47c17d593c7b5cb4fb1e56213d1b3843c1773df2b")) + ( 16128, uint256("0x000000000001d9964f9483f9096cf9d6c6c2886ed1e5dec95ad2aeec3ce72fa9")) + ( 18940, uint256("0x00000000000087f7fc0c8085217503ba86f796fa4984f7e5a08b6c4c12906c05")) + ( 30240, uint256("0xe1c8c862ff342358384d4c22fa6ea5f669f3e1cdcf34111f8017371c3c0be1da")) + ( 57000, uint256("0xaa3ec60168a0200799e362e2b572ee01f3c3852030d07d036e0aa884ec61f203")) + (112896, uint256("0x73f880e78a04dd6a31efc8abf7ca5db4e262c4ae130d559730d6ccb8808095bf")) + (182000, uint256("0xd47b4a8fd282f635d66ce34ebbeb26ffd64c35b41f286646598abfd813cba6d9")) + ; + +} + +unsigned int NamecoinChain::totalBlocksEstimate() const { + return _checkpoints.rbegin()->first; +} + + +const Block& NamecoinChain::genesisBlock() const { + return _genesisBlock; +} + +const int64_t NamecoinChain::subsidy(unsigned int height, uint256 prev) const { + int64_t s = 50 * COIN; + + // Subsidy is cut in half every 4 years + s >>= (height / 210000); + + return s; +} + +bool NamecoinChain::isStandard(const Transaction& tx) const { + + // Extremely large transactions with lots of inputs can cost the network + // almost as much to process as they cost the sender in fees, because + // computing signature hashes is O(ninputs*txsize). Limiting transactions + // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. + unsigned int sz = serialize_size(tx);//tx.GetSerializeSize(SER_NETWORK); + if (sz >= MAX_STANDARD_TX_SIZE) + return false; + + BOOST_FOREACH(const Input& txin, tx.getInputs()) { + // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG + // pay-to-script-hash, which is 3 ~80-byte signatures, 3 + // ~65-byte public keys, plus a few script ops. + if (txin.signature().size() > 500) { + log_debug("nonstandard txin, size too big: %s", txin.signature().toString()); + return false; + } + if (!txin.signature().isPushOnly()) { + log_debug("nonstandard txin, signature is not push only: %s", txin.signature().toString()); + return false; + } + } + BOOST_FOREACH(const Output& txout, tx.getOutputs()) { + std::vector > solution; + txnouttype txnout; + if (!Solver(txout.script(), txnout, solution)) { + log_debug("nonstandard txout - solver returned false: %s", txout.script().toString()); + return false; + } + if (txout.isDust(MIN_RELAY_TX_FEE)) { + log_debug("nonstandard txout - is dust, value = %d", txout.value()); + return false; + } + } + + return true; +} + +/// This function has changed as it served two purposes: sanity check for headers and real proof of work check. We only need the proofOfWorkLimit for the latter +/// For namecoin we allow merged mining for the PoW! +const bool NamecoinChain::checkProofOfWork(const Block& block) const { + log_trace("Enter %s (block.version = %d)", __FUNCTION__, block.getVersion()); + // we accept aux pow all the time - the lockins will ensure we get the right chain + // Prevent same work from being submitted twice: + // - this block must have our chain ID + // - parent block must not have the same chain ID (see CAuxPow::Check) + // - index of this chain in chain merkle tree must be pre-determined (see CAuxPow::Check) + // if (nHeight != INT_MAX && GetChainID() != GetOurChainID()) + // return error("CheckProofOfWork() : block does not have our chain ID"); + + CBigNum target; + target.SetCompact(block.getBits()); + if (proofOfWorkLimit() != 0 && (target <= 0 || target > proofOfWorkLimit())) { + cout << target.GetHex() << endl; + cout << proofOfWorkLimit().GetHex() << endl; + log_error("CheckProofOfWork() : nBits below minimum work"); + return false; + } + + if (block.getVersion()&BLOCK_VERSION_AUXPOW) { + if (!block.getAuxPoW().Check(block.getHash(), block.getVersion()/BLOCK_VERSION_CHAIN_START)) { + log_error("CheckProofOfWork() : AUX POW is not valid"); + return false; + } + // Check proof of work matches claimed amount + if (block.getAuxPoW().GetParentBlockHash() > target.getuint256()) { + log_error("CheckProofOfWork() : AUX proof of work failed"); + return false; + } + } + else { + // Check proof of work matches claimed amount + if (block.getHash() > target.getuint256()) { + log_error("CheckProofOfWork() : proof of work failed"); + return false; + } + } + log_trace("Return(true): %s", __FUNCTION__); + return true; +} + +int NamecoinChain::nextWorkRequired(BlockIterator blk) const { + const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + const int64_t nTargetSpacing = 10 * 60; + const int64_t nInterval = nTargetTimespan / nTargetSpacing; + + // Genesis block + int h = blk.height(); + if (h == 0) // trick to test that it is asking for the genesis block + return 0x1c007fff; + + // Only change once per interval + if ((h + 1) % nInterval != 0) + return blk->bits; + + // Go back by what we want to be 14 days worth of blocks + BlockIterator former = blk - (nInterval-1); + + if (h >= 19200 && (h+1 > nInterval)) + former = blk - nInterval; + + // Limit adjustment step + int nActualTimespan = blk->time - former->time; + log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); + if (nActualTimespan < nTargetTimespan/4) + nActualTimespan = nTargetTimespan/4; + if (nActualTimespan > nTargetTimespan*4) + nActualTimespan = nTargetTimespan*4; + + // Retarget + CBigNum bnNew; + bnNew.SetCompact(blk->bits); + bnNew *= nActualTimespan; + bnNew /= nTargetTimespan; + + if (bnNew > proofOfWorkLimit()) + bnNew = proofOfWorkLimit(); + + /// debug print + log_info("GetNextWorkRequired RETARGET"); + log_info("\tnTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); + log_info("\tBefore: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); + log_info("\tAfter: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); + + return bnNew.GetCompact(); +} + +bool NamecoinChain::checkPoints(const unsigned int height, const uint256& hash) const { + Checkpoints::const_iterator i = _checkpoints.find(height); + if (i == _checkpoints.end()) + return true; + + return hash == i->second; +} + +// global const definition of the bitcoin chain +const NamecoinChain namecoin; + +RegisterChain g_namecoin(namecoin); + LitecoinChain::LitecoinChain() : Chain("litecoin", "LTC", 8), _genesis("0x12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2") { _alert_key = ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9"); _magic[0] = 0xfb; _magic[1] = 0xc0; _magic[2] = 0xb6; _magic[3] = 0xdb; // Litecoin: increase each by adding 2 to bitcoin's value. From 13907205cc4256d3bb0c488786c5c874101b1ca4 Mon Sep 17 00:00:00 2001 From: jonasbits Date: Tue, 16 Sep 2014 21:53:17 +0200 Subject: [PATCH 2/6] various changes to enable namecoin testnet testnet uses irc channel #namecoinTEST without any numbers at the end, getinfo now returns testnet:true, auxpow at height 4042 --- include/coin/AuxPow.h | 2 +- include/coinChain/Chain.h | 21 ++++----- include/coinChain/ChatClient.h | 2 +- src/coin/AuxPow.cpp | 5 ++- src/coinChain/Chain.cpp | 77 +++++++++++++++++---------------- src/coinChain/ChatClient.cpp | 9 +++- src/coinChain/Configuration.cpp | 1 + src/coinChain/NodeRPC.cpp | 2 +- 8 files changed, 64 insertions(+), 55 deletions(-) diff --git a/include/coin/AuxPow.h b/include/coin/AuxPow.h index d57687cf..fad89483 100644 --- a/include/coin/AuxPow.h +++ b/include/coin/AuxPow.h @@ -41,7 +41,7 @@ class AuxPow : public MerkleTx { friend std::istream& operator>>(std::istream& is, AuxPow& ap); - bool Check(uint256 hashAuxBlock, int nChainID) const; + bool Check(uint256 hashAuxBlock, int nChainID, bool isTestnet = false) const; uint256 GetParentBlockHash() const { return parentBlock.getHash(); diff --git a/include/coinChain/Chain.h b/include/coinChain/Chain.h index 18a3b9a2..ac21888f 100644 --- a/include/coinChain/Chain.h +++ b/include/coinChain/Chain.h @@ -362,16 +362,17 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { extern const NamecoinChain namecoin; -class COINCHAIN_EXPORT NamecoinChain : public Chain { +class COINCHAIN_EXPORT NamecoinTestChain : public Chain { public: - NamecoinChain(); + NamecoinTestChain(); virtual const int protocol_version() const { return 37200; } // 0.3.72.0 virtual const Block& genesisBlock() const ; virtual const uint256& genesisHash() const { return _genesis; } virtual const int64_t subsidy(unsigned int height, uint256 prev = uint256(0)) const ; virtual bool isStandard(const Transaction& tx) const ; - virtual const CBigNum proofOfWorkLimit() const { return CBigNum(~uint256(0) >> 32); } + virtual const CBigNum proofOfWorkLimit() const { return CBigNum(~uint256(0) >> 28); } virtual int nextWorkRequired(BlockIterator blk) const; + virtual const int maxInterBlockTime() const { return 2*10*60; } //if 20 minutes of no new (2*10*60) blocks, lower target virtual const bool checkProofOfWork(const Block& block) const; virtual bool adhere_aux_pow() const { return true; } virtual bool adhere_names() const { return true; } @@ -379,7 +380,7 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { if (count > 500000000) return count > 1386499470; // the timestamp of block 150000 - so will always return true... else - return count > 150000; // enforce from block 150000 + return count > 150001; // enforce from block 150000 } @@ -397,7 +398,7 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { height += (height - 24000) * 3; if ((height >> 13) >= 60) return 0; - int64_t start = 50 * COIN; + int64_t start = 10 * CENT; int64_t res = start >> (height >> 13); res -= (res >> 14) * (height % 8192); return res; @@ -423,11 +424,11 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { const PubKey& alert_key() const { return _alert_key; } // virtual char networkId() const { return 0x00; } // 0x00, 0x6f, 0x34 (bitcoin, testnet, namecoin) - virtual ChainAddress getAddress(PubKeyHash hash) const { return ChainAddress(0x34, hash); } + virtual ChainAddress getAddress(PubKeyHash hash) const { return ChainAddress(0x6F, hash); } virtual ChainAddress getAddress(ScriptHash hash) const { throw std::runtime_error("ScriptHash not supported by Namecoin!"); } virtual ChainAddress getAddress(std::string str) const { ChainAddress addr(str); - if(addr.version() == 0x34) + if(addr.version() == 0x6F) addr.setType(ChainAddress::PUBKEYHASH); else throw std::runtime_error("ScriptHash not supported by Namecoin!"); @@ -437,9 +438,9 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { virtual std::string signedMessageMagic() const { return "Namecoin Signed Message:\n"; } virtual const Magic& magic() const { return _magic; }; - virtual unsigned short defaultPort() const { return 8334; } + virtual unsigned short defaultPort() const { return 18334; } - virtual unsigned int ircChannels() const { return 1; } // number of groups to try (100 for bitcoin, 2 for litecoin) + virtual unsigned int ircChannels() const { return 0; } // number of groups to try (100 for bitcoin, 2 for litecoin) private: Block _genesisBlock; @@ -449,7 +450,7 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { Checkpoints _checkpoints; }; -extern const NamecoinChain namecoin; +extern const NamecoinTestChain namecointest; class COINCHAIN_EXPORT LitecoinChain : public Chain { public: diff --git a/include/coinChain/ChatClient.h b/include/coinChain/ChatClient.h index 856ee7a6..acdabdb6 100644 --- a/include/coinChain/ChatClient.h +++ b/include/coinChain/ChatClient.h @@ -38,7 +38,7 @@ class EndpointPool; class COINCHAIN_EXPORT ChatClient { public: - ChatClient(boost::asio::io_service& io_service, boost::function new_endpoint_notifier, const std::string& server, EndpointPool& endpointPool, std::string channel, unsigned int channles, boost::asio::ip::tcp::endpoint proxy = boost::asio::ip::tcp::endpoint()); + ChatClient(boost::asio::io_service& io_service, boost::function new_endpoint_notifier, const std::string& server, EndpointPool& endpointPool, std::string channel, unsigned int channels, boost::asio::ip::tcp::endpoint proxy = boost::asio::ip::tcp::endpoint()); ~ChatClient() { boost::system::error_code ec; diff --git a/src/coin/AuxPow.cpp b/src/coin/AuxPow.cpp index 4ce7909d..0f65aefd 100644 --- a/src/coin/AuxPow.cpp +++ b/src/coin/AuxPow.cpp @@ -27,13 +27,14 @@ istream& operator>>(istream& is, AuxPow& ap) { } -bool AuxPow::Check(uint256 hashAuxBlock, int nChainID) const +bool AuxPow::Check(uint256 hashAuxBlock, int nChainID, bool isTestnet) const { + //default to isTestnet false if nothing else is specified try { if (_index != 0) throw runtime_error("AuxPow is not a generate"); - if (parentBlock.getVersion() / BLOCK_VERSION_CHAIN_START == nChainID) + if (!isTestnet && parentBlock.getVersion() / BLOCK_VERSION_CHAIN_START == nChainID) throw runtime_error("Aux POW parent has our chain ID"); if (vChainMerkleBranch.size() > 30) diff --git a/src/coinChain/Chain.cpp b/src/coinChain/Chain.cpp index bbd9ea14..a7ac53da 100644 --- a/src/coinChain/Chain.cpp +++ b/src/coinChain/Chain.cpp @@ -595,53 +595,51 @@ bool NamecoinChain::checkPoints(const unsigned int height, const uint256& hash) return hash == i->second; } -// global const definition of the bitcoin chain +// global const definition of the namecoin chain const NamecoinChain namecoin; RegisterChain g_namecoin(namecoin); -NamecoinChain::NamecoinChain() : Chain("namecoin", "NMC", 8), _genesis("000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770") { +NamecoinTestChain::NamecoinTestChain() : Chain("namecointest", "NMCTST", 8), _genesis("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008") { _alert_key = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); - _magic[0] = 0xf9; _magic[1] = 0xbe; _magic[2] = 0xb4; _magic[3] = 0xfe; - const char* pszTimestamp = "... choose what comes next. Lives of your own, or a return to chains. -- V"; + _magic[0] = 0xfa; _magic[1] = 0xbf; _magic[2] = 0xb5; _magic[3] = 0xfe; + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; Transaction txNew; - Script signature = Script() << 0x1c007fff << CBigNum(522) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + Script signature = Script() << 0x1d00ffff << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.addInput(Input(Coin(), signature)); - Script script = Script() << ParseHex("04b620369050cd899ffbbc4e8ee51e8c4534a855bb463439d63d235d4779685d8b6f4870a238cf365ac94fa13ef9a2a22cd99d0d5ee86dcabcafce36c7acf43ce5") << OP_CHECKSIG; + Script script = Script() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; txNew.addOutput(Output(50 * COIN, script)); - _genesisBlock = Block(1, uint256(0), uint256(0), 1303000001, 0x1c007fff, 0xa21ea192U); + _genesisBlock = Block(1, uint256(0), uint256(0), 1296688602, 0x1d07fff8, 0x16ec0bffU); _genesisBlock.addTransaction(txNew); _genesisBlock.updateMerkleTree(); // genesisBlock assert(_genesisBlock.getHash() == _genesis); _checkpoints = boost::assign::map_list_of - ( 2016, uint256("0x0000000000660bad0d9fbde55ba7ee14ddf766ed5f527e3fbca523ac11460b92")) - ( 4032, uint256("0x0000000000493b5696ad482deb79da835fe2385304b841beef1938655ddbc411")) - ( 6048, uint256("0x000000000027939a2e1d8bb63f36c47da858e56d570f143e67e85068943470c9")) - ( 8064, uint256("0x000000000003a01f708da7396e54d081701ea406ed163e519589717d8b7c95a5")) - ( 10080, uint256("0x00000000000fed3899f818b2228b4f01b9a0a7eeee907abd172852df71c64b06")) - ( 12096, uint256("0x0000000000006c06988ff361f124314f9f4bb45b6997d90a7ee4cedf434c670f")) - ( 14112, uint256("0x00000000000045d95e0588c47c17d593c7b5cb4fb1e56213d1b3843c1773df2b")) - ( 16128, uint256("0x000000000001d9964f9483f9096cf9d6c6c2886ed1e5dec95ad2aeec3ce72fa9")) - ( 18940, uint256("0x00000000000087f7fc0c8085217503ba86f796fa4984f7e5a08b6c4c12906c05")) - ( 30240, uint256("0xe1c8c862ff342358384d4c22fa6ea5f669f3e1cdcf34111f8017371c3c0be1da")) - ( 57000, uint256("0xaa3ec60168a0200799e362e2b572ee01f3c3852030d07d036e0aa884ec61f203")) - (112896, uint256("0x73f880e78a04dd6a31efc8abf7ca5db4e262c4ae130d559730d6ccb8808095bf")) - (182000, uint256("0xd47b4a8fd282f635d66ce34ebbeb26ffd64c35b41f286646598abfd813cba6d9")) + ( 2016, uint256("0x00000000b9e4132e1a803114bc88df3e49184a3c794c01a6eac334f12f4ccadb")) + ( 4032, uint256("0x00000003fbc13a48b8de5c8742044c84b800edeabff8b39f7f23ac572c6d80ce")) + ( 8064, uint256("0xf594a75db40244bc7baa808a695f796ba81cae5bb48fa920e367cdd31dbfb0e3")) + ( 10080, uint256("0x398d44a1a6e58dce3f7463217f677c2532e42a83696dcc5d4d97329c00a10891")) + ( 12096, uint256("0x22c9278493cda563565fc2a4250eff48bd68ed40cb5fb30029ca08ea6120ddab")) + ( 14112, uint256("0x83bade3e3d88845eb52de90311a8017b1cdf725b15d19bc89c47a568f7b4e08c")) + ( 16128, uint256("0xf456354835623f733bb928ed77d97ae06b96ad6c40aba63f51f94f06e905effc")) + ( 18144, uint256("0xc0ec570117822ca3c76abd1d10449b283d8ad39c64290d6abafe2bed23917886")) + ( 34715, uint256("0x0000000580cf4342f869e278d94d7e67d2ac8cae4a411082e0fd518a8091ebf2")) + ( 48384, uint256("0x00000001d528af69dce584f882e3bdb36127104988607b726591cc5e62287922")) + ( 60480, uint256("0xd3af823c32e890ca589dd4277aa4d27b8cd290396b7e0eeeee5121481fd43ca5")) ; } -unsigned int NamecoinChain::totalBlocksEstimate() const { +unsigned int NamecoinTestChain::totalBlocksEstimate() const { return _checkpoints.rbegin()->first; } -const Block& NamecoinChain::genesisBlock() const { +const Block& NamecoinTestChain::genesisBlock() const { return _genesisBlock; } -const int64_t NamecoinChain::subsidy(unsigned int height, uint256 prev) const { +const int64_t NamecoinTestChain::subsidy(unsigned int height, uint256 prev) const { int64_t s = 50 * COIN; // Subsidy is cut in half every 4 years @@ -650,8 +648,8 @@ const int64_t NamecoinChain::subsidy(unsigned int height, uint256 prev) const { return s; } -bool NamecoinChain::isStandard(const Transaction& tx) const { - +bool NamecoinTestChain::isStandard(const Transaction& tx) const { + /* TESTNET allows everything // Extremely large transactions with lots of inputs can cost the network // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions @@ -685,13 +683,13 @@ bool NamecoinChain::isStandard(const Transaction& tx) const { return false; } } - + */ return true; } /// This function has changed as it served two purposes: sanity check for headers and real proof of work check. We only need the proofOfWorkLimit for the latter /// For namecoin we allow merged mining for the PoW! -const bool NamecoinChain::checkProofOfWork(const Block& block) const { +const bool NamecoinTestChain::checkProofOfWork(const Block& block) const { log_trace("Enter %s (block.version = %d)", __FUNCTION__, block.getVersion()); // we accept aux pow all the time - the lockins will ensure we get the right chain // Prevent same work from being submitted twice: @@ -711,8 +709,8 @@ const bool NamecoinChain::checkProofOfWork(const Block& block) const { } if (block.getVersion()&BLOCK_VERSION_AUXPOW) { - if (!block.getAuxPoW().Check(block.getHash(), block.getVersion()/BLOCK_VERSION_CHAIN_START)) { - log_error("CheckProofOfWork() : AUX POW is not valid"); + if (!block.getAuxPoW().Check( block.getHash(), block.getVersion()/BLOCK_VERSION_CHAIN_START, true) ) { + log_error("CheckProofOfWork() : AUX POW is not valid"); //pass along true because we are ^testnet return false; } // Check proof of work matches claimed amount @@ -732,7 +730,7 @@ const bool NamecoinChain::checkProofOfWork(const Block& block) const { return true; } -int NamecoinChain::nextWorkRequired(BlockIterator blk) const { +int NamecoinTestChain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks const int64_t nTargetSpacing = 10 * 60; const int64_t nInterval = nTargetTimespan / nTargetSpacing; @@ -740,7 +738,7 @@ int NamecoinChain::nextWorkRequired(BlockIterator blk) const { // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block - return 0x1c007fff; + return 0x1d00fff8; // Only change once per interval if ((h + 1) % nInterval != 0) @@ -749,7 +747,7 @@ int NamecoinChain::nextWorkRequired(BlockIterator blk) const { // Go back by what we want to be 14 days worth of blocks BlockIterator former = blk - (nInterval-1); - if (h >= 19200 && (h+1 > nInterval)) + if (h >= 0 && (h+1 > nInterval)) former = blk - nInterval; // Limit adjustment step @@ -778,7 +776,7 @@ int NamecoinChain::nextWorkRequired(BlockIterator blk) const { return bnNew.GetCompact(); } -bool NamecoinChain::checkPoints(const unsigned int height, const uint256& hash) const { +bool NamecoinTestChain::checkPoints(const unsigned int height, const uint256& hash) const { Checkpoints::const_iterator i = _checkpoints.find(height); if (i == _checkpoints.end()) return true; @@ -786,10 +784,10 @@ bool NamecoinChain::checkPoints(const unsigned int height, const uint256& hash) return hash == i->second; } -// global const definition of the bitcoin chain -const NamecoinChain namecoin; +// global const definition of the namecoin testnet chain +const NamecoinTestChain namecointest; -RegisterChain g_namecoin(namecoin); +RegisterChain g_namecointest(namecointest); LitecoinChain::LitecoinChain() : Chain("litecoin", "LTC", 8), _genesis("0x12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2") { _alert_key = ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9"); _magic[0] = 0xfb; _magic[1] = 0xc0; _magic[2] = 0xb6; _magic[3] = 0xdb; // Litecoin: increase each by adding 2 to bitcoin's value. @@ -938,6 +936,7 @@ const uint256 LitecoinChain::getPoWHash(const Block& block) const { return hash; } +// global const definition of the litecoin chain const LitecoinChain litecoin; @@ -1128,7 +1127,7 @@ bool TerracoinChain::checkPoints(const unsigned int height, const uint256& hash) return hash == i->second; } -// global const definition of the bitcoin chain +// global const definition of the terracoin chain const TerracoinChain terracoin; DogecoinChain::DogecoinChain() : Chain("dogecoin", "DGE", 8), _genesis("0x1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691") { @@ -1402,6 +1401,7 @@ const uint256 DogecoinChain::getPoWHash(const BlockHeader& block) const { return hash; } +// global const definition of the dogecoin chain const DogecoinChain dogecoin; @@ -1613,9 +1613,10 @@ const uint256 DogetestChain::getPoWHash(const Block& block) const { return hash; } +// global const definition of the dogecoin testnet chain const DogetestChain dogetest; RegisterChain g_dogetest(dogetest); -const Currency ripplecredits("ripple", "XRP", 6); \ No newline at end of file +const Currency ripplecredits("ripple", "XRP", 6); diff --git a/src/coinChain/ChatClient.cpp b/src/coinChain/ChatClient.cpp index 455bcf79..b3e27baf 100644 --- a/src/coinChain/ChatClient.cpp +++ b/src/coinChain/ChatClient.cpp @@ -181,6 +181,11 @@ void ChatClient::handle_read_line(const boost::system::error_code& err, size_t b txstream << "JOIN #" << _channel << ss.str() << "\r"; txstream << "WHO #" << _channel << ss.str() << "\r"; } + else if ( _channels == 0 ) { + txstream << "JOIN #" << _channel << "\r"; + txstream << "WHO #" << _channel << "\r"; + //dirty fix to let namecoin-testnet join the "correct" irc channel + } else { txstream << "JOIN #" << _channel << "00\r"; txstream << "WHO #" << _channel << "00\r"; @@ -216,7 +221,7 @@ void ChatClient::handle_read_line(const boost::system::error_code& err, size_t b // index 7 is limited to 16 characters // could get full length name at index 10, but would be different from join messages name = words[7]; - log_debug("IRC got who\n"); + log_debug("IRC got who\n" + name ); } if (words[1] == "JOIN" && words[0].size() > 1) { @@ -227,7 +232,7 @@ void ChatClient::handle_read_line(const boost::system::error_code& err, size_t b name = words[0].substr(1, exclamation_pos-1); // the 1, -1 is due to the colon // if (strchr(pszName, '!')) // *strchr(pszName, '!') = '\0'; - log_debug("IRC got join\n"); + log_debug("IRC got join\n" + name); } if (name[0] == 'u') { diff --git a/src/coinChain/Configuration.cpp b/src/coinChain/Configuration.cpp index 27fe5719..770cf824 100644 --- a/src/coinChain/Configuration.cpp +++ b/src/coinChain/Configuration.cpp @@ -43,6 +43,7 @@ Configuration::Configuration(int argc, char* argv[], const options_description& ("testnet3", "Use the test network") ("litecoin", "Run as a litecoin client") ("namecoin", "Run as a namecoin client") + ("namecointest", "Run as a namecoin testnet client") ("dogecoin", "Run as a dogecoin client") ("dogetest", "Run as a dogecoin test client") ("ripple", "Run as a ripple client") diff --git a/src/coinChain/NodeRPC.cpp b/src/coinChain/NodeRPC.cpp index b422c380..fd79a7f4 100644 --- a/src/coinChain/NodeRPC.cpp +++ b/src/coinChain/NodeRPC.cpp @@ -226,7 +226,7 @@ Value GetInfo::operator()(const Array& params, bool fHelp) { // obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); obj.push_back(Pair("difficulty", (double)_node.blockChain().getDifficulty())); // obj.push_back(Pair("hashespersec", gethashespersec(params, false))); - obj.push_back(Pair("testnet", (&_node.blockChain().chain() == &testnet3))); + obj.push_back(Pair("testnet", (&_node.blockChain().chain() == &namecointest || &_node.blockChain().chain() == &testnet3))); // obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); // obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); // obj.push_back(Pair("errors", GetWarnings("statusbar"))); From 65839534a081bcd5510563a9f1517a601515550c Mon Sep 17 00:00:00 2001 From: jonasbits Date: Wed, 17 Sep 2014 07:06:37 +0200 Subject: [PATCH 3/6] rpcuser/password and coinexplorer name rpc calls known bug: rpc user:pass needs to be in lowercase base64 v:a -> djph new feature: coinexplorer have got new rpc calls to handle names in the namecoin chains --- applications/coinexplorer/coinexplorer.cpp | 8 ++++++++ applications/libcoind/libcoind.cpp | 6 +++--- src/coinHTTP/RequestHandler.cpp | 7 +++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/applications/coinexplorer/coinexplorer.cpp b/applications/coinexplorer/coinexplorer.cpp index 0653113e..bfb2f14f 100644 --- a/applications/coinexplorer/coinexplorer.cpp +++ b/applications/coinexplorer/coinexplorer.cpp @@ -394,6 +394,14 @@ int main(int argc, char* argv[]) server.registerMethod(method_ptr(new GetConnectionCount(node))); server.registerMethod(method_ptr(new GetDifficulty(node))); server.registerMethod(method_ptr(new GetInfo(node))); + + // Register Node methods specific to Namecoin + if (conf.chain().adhere_names()) { + server.registerMethod(method_ptr(new NameShow(node))); + server.registerMethod(method_ptr(new NameHistory(node))); + server.registerMethod(method_ptr(new NameScan(node))); + server.registerMethod(method_ptr(new NameFilter(node))); + } // Node methods relevant for coin explorer server.registerMethod(method_ptr(new GetBlock(node))); diff --git a/applications/libcoind/libcoind.cpp b/applications/libcoind/libcoind.cpp index 9000bf55..c186f3d6 100644 --- a/applications/libcoind/libcoind.cpp +++ b/applications/libcoind/libcoind.cpp @@ -120,7 +120,7 @@ int main(int argc, char* argv[]) } } - // Else we start the bitcoin node and server! + // Else we start the namecoin node and server! asio::ip::tcp::endpoint proxy_server; if(conf.proxy().size()) { @@ -131,7 +131,7 @@ int main(int argc, char* argv[]) proxy_server = asio::ip::tcp::endpoint(asio::ip::address_v4::from_string(host_port[0]), lexical_cast(host_port[1])); } Node node(conf.chain(), conf.data_dir(), conf.listen(), lexical_cast(conf.node_port()), proxy_server, conf.timeout()); // it is also here we specify the use of a proxy! - node.setClientVersion("libcoin/bitcoind", vector()); + node.setClientVersion("libcoin/namecoind", vector(), 37654); node.verification(conf.verification()); node.validation(conf.validation()); node.persistence(conf.persistance()); @@ -184,7 +184,7 @@ int main(int argc, char* argv[]) /// The Pool enables you to run a backend for a miner, i.e. your private pool, it also enables you to participate in the "Name of Pool" // We need a list of blocks for the shared mining // - ChainAddress address("17uY6a7zUidQrJVvpnFchD1MX1untuAufd"); + ChainAddress address("muh4C4iuWBqkyfBJ3Wr3pJkM7irrXkXsa1"); //nmctest.net faucet address StaticPayee payee(address.getPubKeyHash()); Pool pool(node, payee); diff --git a/src/coinHTTP/RequestHandler.cpp b/src/coinHTTP/RequestHandler.cpp index 900e3ea0..525eba38 100755 --- a/src/coinHTTP/RequestHandler.cpp +++ b/src/coinHTTP/RequestHandler.cpp @@ -253,8 +253,11 @@ void RequestHandler::async_exec(const Request& req, Reply& rep, const Completion Methods::iterator m = _methods.find(rpc.method()); if (m != _methods.end()) { // check authorization - if (_auths.count(rpc.method()) && !_auths[rpc.method()].valid(req.basic_auth())) - throw Reply::unauthorized; + if (_auths.count(rpc.method()) && !_auths[rpc.method()].valid(req.basic_auth())) { + throw Reply::unauthorized; + //throw rpc.response(RPC::internal_error, req.basic_auth()); + //output the actual lowercase version of your auth base64 string + } // prepare for deferred execution rep.setMethod(m->second.get()); From 119933ba1e3558babe110f60c80203da5285a762 Mon Sep 17 00:00:00 2001 From: jonasbits Date: Wed, 17 Sep 2014 14:42:59 +0200 Subject: [PATCH 4/6] -coinexplorer name rpc calls, +chain specific ignoring of rules to enable sync now this code should not interfere with any other chain then namecoin testnet --- applications/coinexplorer/coinexplorer.cpp | 4 ++-- src/coinChain/BlockChain.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/applications/coinexplorer/coinexplorer.cpp b/applications/coinexplorer/coinexplorer.cpp index bfb2f14f..9e2e7ce4 100644 --- a/applications/coinexplorer/coinexplorer.cpp +++ b/applications/coinexplorer/coinexplorer.cpp @@ -396,12 +396,12 @@ int main(int argc, char* argv[]) server.registerMethod(method_ptr(new GetInfo(node))); // Register Node methods specific to Namecoin - if (conf.chain().adhere_names()) { + /*if (conf.chain().adhere_names()) { server.registerMethod(method_ptr(new NameShow(node))); server.registerMethod(method_ptr(new NameHistory(node))); server.registerMethod(method_ptr(new NameScan(node))); server.registerMethod(method_ptr(new NameFilter(node))); - } + }*/ // Node methods relevant for coin explorer server.registerMethod(method_ptr(new GetBlock(node))); diff --git a/src/coinChain/BlockChain.cpp b/src/coinChain/BlockChain.cpp index 9caae8bc..424fa99a 100644 --- a/src/coinChain/BlockChain.cpp +++ b/src/coinChain/BlockChain.cpp @@ -1107,13 +1107,20 @@ void BlockChain::append(const Block &block) { throw Error("Cannot accept orphan block: " + hash.toString()); if (block.getBits() != _chain.nextWorkRequired(prev)) { + //detect namecoin testnet + bool isNamecoinTestnet = false; + uint256 nmctestgenesishash = uint256("0x07199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"); + BlockIterator blk2 = _tree.find(nmctestgenesishash); + if (blk2 != _tree.end()) isNamecoinTestnet = true; + string timetravel = string("Incorrect proof of work: " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.nextWorkRequired(prev))); + string powlimit = string("Incorrect proof of work (limit): " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.proofOfWorkLimit().GetCompact())); // check if we can allow a block to slip through due to max time: if (block.getTime() - (int)prev->time < _chain.maxInterBlockTime()) - throw Error("Incorrect proof of work: " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.nextWorkRequired(prev))); + if (!isNamecoinTestnet) { throw Error(timetravel); } else { log_warn(timetravel); } else if ( block.getBits() != _chain.proofOfWorkLimit().GetCompact()) - throw Error("Incorrect proof of work (limit): " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.proofOfWorkLimit().GetCompact())); + if (!isNamecoinTestnet) { throw Error(powlimit); } else { log_warn(powlimit); } } - + if (block.getBlockTime() <= getMedianTimePast(prev)) throw Error("Block's timestamp is too early"); From a1e9e11dad662b4c45b042b8351cbe4b9b1abde7 Mon Sep 17 00:00:00 2001 From: jonasbits Date: Wed, 17 Sep 2014 15:31:25 +0200 Subject: [PATCH 5/6] symlink to +namecointestd.conf and makefile to create namecointestd --- applications/libcoind/CMakeLists.txt | 6 +++++- contrib/coinexplorer.conf | 1 + contrib/libcoind.conf | 22 ++++++++++++++++++++++ contrib/namecoind.conf | 1 + contrib/namecointestd.conf | 1 + 5 files changed, 30 insertions(+), 1 deletion(-) create mode 120000 contrib/coinexplorer.conf create mode 100644 contrib/libcoind.conf create mode 120000 contrib/namecoind.conf create mode 120000 contrib/namecointestd.conf diff --git a/applications/libcoind/CMakeLists.txt b/applications/libcoind/CMakeLists.txt index 6885049f..51500693 100644 --- a/applications/libcoind/CMakeLists.txt +++ b/applications/libcoind/CMakeLists.txt @@ -25,4 +25,8 @@ ELSE( CMAKE_SYSTEM MATCHES "Linux" ) ) ENDIF( CMAKE_SYSTEM MATCHES "Linux" ) -SETUP_APPLICATION(libcoind) +SETUP_APPLICATION(namecointestd) +IF( FALSE ) + SETUP_APPLICATION(namecoind) + SETUP_APPLICATION(libcoind) +ENDIF( FALSE ) diff --git a/contrib/coinexplorer.conf b/contrib/coinexplorer.conf new file mode 120000 index 00000000..aab4284f --- /dev/null +++ b/contrib/coinexplorer.conf @@ -0,0 +1 @@ +libcoind.conf \ No newline at end of file diff --git a/contrib/libcoind.conf b/contrib/libcoind.conf new file mode 100644 index 00000000..f9f278ae --- /dev/null +++ b/contrib/libcoind.conf @@ -0,0 +1,22 @@ +# namecointestd.conf - namecoin testnet (libcoin) configuration file + +# p2p port + port = 18334 # optional +# port = # 19334 # if you want to run namecoin/d/qt at the same time + +# rpc settings, known bug is that user and password must be as specified + rpcport = 18336 # must be specified. + rpcuser = v # warning, character ' and " are included in the username + rpcpassword = a # and password + # v:a is sent over the wire as base64 djph + # make sure that username:password is lowercase in its base64 representation +# needed for coinexplorer + searchable = 1 # this is hardcoded in coinexplorer + persistence = FULL # getblock can fetch blocks all the way back to genesis + +# check blocks + verification = CHECKPOINT + validation = NONE + +# port forwarding + portmap = 0 diff --git a/contrib/namecoind.conf b/contrib/namecoind.conf new file mode 120000 index 00000000..aab4284f --- /dev/null +++ b/contrib/namecoind.conf @@ -0,0 +1 @@ +libcoind.conf \ No newline at end of file diff --git a/contrib/namecointestd.conf b/contrib/namecointestd.conf new file mode 120000 index 00000000..aab4284f --- /dev/null +++ b/contrib/namecointestd.conf @@ -0,0 +1 @@ +libcoind.conf \ No newline at end of file From 32d3af574c771dab3c3d0f63b6500d3b5871ec78 Mon Sep 17 00:00:00 2001 From: jonasbits Date: Mon, 22 Sep 2014 00:53:19 +0200 Subject: [PATCH 6/6] purge depth, --version --help and rpc help persistence was warning when purge depth is 1 using FULL setting (zero), --version and --help now works, and RPC method "help" is no longer intercepted wrongly --- applications/libcoind/libcoind.cpp | 29 +++++++++++++++++------------ contrib/libcoind.conf | 12 +++++++++--- include/coinChain/Configuration.h | 7 +++++++ src/coinChain/BlockChain.cpp | 11 ++++++----- src/coinChain/Configuration.cpp | 4 +++- 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/applications/libcoind/libcoind.cpp b/applications/libcoind/libcoind.cpp index c186f3d6..11de0219 100644 --- a/applications/libcoind/libcoind.cpp +++ b/applications/libcoind/libcoind.cpp @@ -79,21 +79,11 @@ int main(int argc, char* argv[]) try { Auth auth(conf.user(), conf.pass()); // if rpc_user and rpc_pass are not set, all authenticated methods becomes disallowed. - + // If we have params on the cmdline we run as a command line client contacting a server + if (conf.method() != "") { - if (conf.method() == "help") { - cout << "Usage: " << argv[0] << " [options] [rpc-command param1 param2 ...]\n"; - cout << conf << "\n"; - cout << "If no rpc-command is specified, " << argv[0] << " start up as a daemon, otherwise it offers commandline access to a running instance\n"; - return 1; - } - if (conf.method() == "version") { - cout << argv[0] << " version is: " << FormatVersion(LIBRARY_VERSION) << "\n"; - return 1; - } - // create URL string url = conf.url(); Client client; @@ -120,6 +110,21 @@ int main(int argc, char* argv[]) } } + // If we have help or version on the cmdline we display and then exit + + if (conf.help()) { + cout << "Usage: " << argv[0] << " [options] [rpc-command param1 param2 ...]\n"; + cout << conf << "\n"; + cout << "If no rpc-command is specified, " << argv[0] << " start up as a daemon, otherwise it offers commandline access to a running instance\n"; + return 1; + } + + if (conf.version()) { + cout << argv[0] << " version is: " << FormatVersion(LIBRARY_VERSION) << "\n"; + return 1; + } + + // Else we start the namecoin node and server! asio::ip::tcp::endpoint proxy_server; diff --git a/contrib/libcoind.conf b/contrib/libcoind.conf index f9f278ae..5dcedf3d 100644 --- a/contrib/libcoind.conf +++ b/contrib/libcoind.conf @@ -1,8 +1,8 @@ # namecointestd.conf - namecoin testnet (libcoin) configuration file # p2p port - port = 18334 # optional -# port = # 19334 # if you want to run namecoin/d/qt at the same time +# port = 18334 # optional + port = 19334 # if you want to run namecoin/d/qt at the same time # rpc settings, known bug is that user and password must be as specified rpcport = 18336 # must be specified. @@ -10,6 +10,7 @@ rpcpassword = a # and password # v:a is sent over the wire as base64 djph # make sure that username:password is lowercase in its base64 representation + # needed for coinexplorer searchable = 1 # this is hardcoded in coinexplorer persistence = FULL # getblock can fetch blocks all the way back to genesis @@ -19,4 +20,9 @@ validation = NONE # port forwarding - portmap = 0 + portmap = false + +# connect/addnode to namecoin/d/qt on 127.0.0.1 +# addnode = 127.0.0.1:18334 +# connect = 127.0.0.1:18334 + diff --git a/include/coinChain/Configuration.h b/include/coinChain/Configuration.h index 0a6d21ed..b919a692 100644 --- a/include/coinChain/Configuration.h +++ b/include/coinChain/Configuration.h @@ -107,6 +107,12 @@ class Configuration { bool searchable() const { return _searchable; } + bool help() const { + return _help; + } + bool version() const { + return _version; + } friend std::ostream& operator<<(std::ostream& os, const Configuration&); private: boost::program_options::options_description _visible; @@ -120,6 +126,7 @@ class Configuration { strings _params; std::string _proxy; std::string _listen; + bool _help, _version; bool _portmap, _gen, _ssl; Node::Strictness _verification, _validation, _persistance; bool _searchable; diff --git a/src/coinChain/BlockChain.cpp b/src/coinChain/BlockChain.cpp index 424fa99a..fc498641 100644 --- a/src/coinChain/BlockChain.cpp +++ b/src/coinChain/BlockChain.cpp @@ -267,7 +267,7 @@ int BlockChain::purge_depth() const { } void BlockChain::purge_depth(int purge_depth) { - if (purge_depth < _purge_depth) + if (purge_depth + 1 < _purge_depth) log_warn("Requested a purge_depth (Persistance setting) deeper than currently, please re-download the blockchain to enforce this!"); _purge_depth = purge_depth; int current_depth = query("SELECT CASE WHEN COUNT(*)=0 THEN 0 ELSE MIN(count) END FROM Confirmations"); @@ -1112,13 +1112,14 @@ void BlockChain::append(const Block &block) { uint256 nmctestgenesishash = uint256("0x07199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"); BlockIterator blk2 = _tree.find(nmctestgenesishash); if (blk2 != _tree.end()) isNamecoinTestnet = true; - string timetravel = string("Incorrect proof of work: " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.nextWorkRequired(prev))); - string powlimit = string("Incorrect proof of work (limit): " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.proofOfWorkLimit().GetCompact())); + string timetravel = string("Incorrect proof of work: " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.nextWorkRequired(prev))); + string powlimit = string("Incorrect proof of work (limit): " + lexical_cast(block.getBits()) + " versus " + lexical_cast(_chain.proofOfWorkLimit().GetCompact())); // check if we can allow a block to slip through due to max time: - if (block.getTime() - (int)prev->time < _chain.maxInterBlockTime()) + if (block.getTime() - (int)prev->time < _chain.maxInterBlockTime()) { if (!isNamecoinTestnet) { throw Error(timetravel); } else { log_warn(timetravel); } - else if ( block.getBits() != _chain.proofOfWorkLimit().GetCompact()) + } else if ( block.getBits() != _chain.proofOfWorkLimit().GetCompact()) { if (!isNamecoinTestnet) { throw Error(powlimit); } else { log_warn(powlimit); } + } } if (block.getBlockTime() <= getMedianTimePast(prev)) diff --git a/src/coinChain/Configuration.cpp b/src/coinChain/Configuration.cpp index 770cf824..74d8e407 100644 --- a/src/coinChain/Configuration.cpp +++ b/src/coinChain/Configuration.cpp @@ -162,7 +162,9 @@ Configuration::Configuration(int argc, char* argv[], const options_description& _params.erase(_params.begin()); } - _listen = args.count("nolisten") ? "" : "0.0.0.0"; + _listen = args.count("nolisten") ? "" : "0.0.0.0"; + _version = args.count("version") ? true : false; + _help = args.count("help") ? true : false; _verification = strictness(verification); _validation = strictness(validation); _persistance = strictness(persistance);