diff --git a/applications/coinexplorer/coinexplorer.cpp b/applications/coinexplorer/coinexplorer.cpp index 0653113e..9e2e7ce4 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/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/applications/libcoind/libcoind.cpp b/applications/libcoind/libcoind.cpp index 9000bf55..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,7 +110,22 @@ int main(int argc, char* argv[]) } } - // Else we start the bitcoin node and server! + // 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; if(conf.proxy().size()) { @@ -131,7 +136,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 +189,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/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..5dcedf3d --- /dev/null +++ b/contrib/libcoind.conf @@ -0,0 +1,28 @@ +# 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 = 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/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 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 2cdf2704..ac21888f 100644 --- a/include/coinChain/Chain.h +++ b/include/coinChain/Chain.h @@ -362,7 +362,96 @@ class COINCHAIN_EXPORT NamecoinChain : public Chain { extern const NamecoinChain namecoin; - +class COINCHAIN_EXPORT NamecoinTestChain : public Chain { +public: + 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) >> 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; } + 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 > 150001; // 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 = 10 * CENT; + 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(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() == 0x6F) + 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 18334; } + + virtual unsigned int ircChannels() const { return 0; } // 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 NamecoinTestChain namecointest; + class COINCHAIN_EXPORT LitecoinChain : public Chain { public: LitecoinChain(); 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/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/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/BlockChain.cpp b/src/coinChain/BlockChain.cpp index 9caae8bc..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"); @@ -1107,13 +1107,21 @@ 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))); - 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 (block.getTime() - (int)prev->time < _chain.maxInterBlockTime()) { + if (!isNamecoinTestnet) { throw Error(timetravel); } else { log_warn(timetravel); } + } else if ( block.getBits() != _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"); diff --git a/src/coinChain/Chain.cpp b/src/coinChain/Chain.cpp index ae73db5a..a7ac53da 100644 --- a/src/coinChain/Chain.cpp +++ b/src/coinChain/Chain.cpp @@ -595,11 +595,200 @@ 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); +NamecoinTestChain::NamecoinTestChain() : Chain("namecointest", "NMCTST", 8), _genesis("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008") { + _alert_key = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); + _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() << 0x1d00ffff << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.addInput(Input(Coin(), signature)); + Script script = Script() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; + txNew.addOutput(Output(50 * COIN, script)); + _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("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 NamecoinTestChain::totalBlocksEstimate() const { + return _checkpoints.rbegin()->first; +} + + +const Block& NamecoinTestChain::genesisBlock() const { + return _genesisBlock; +} + +const int64_t NamecoinTestChain::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 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 + // 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 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: + // - 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, 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 + 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 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; + + // Genesis block + int h = blk.height(); + if (h == 0) // trick to test that it is asking for the genesis block + return 0x1d00fff8; + + // 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 >= 0 && (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 NamecoinTestChain::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 namecoin testnet chain +const NamecoinTestChain namecointest; + +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. @@ -747,6 +936,7 @@ const uint256 LitecoinChain::getPoWHash(const Block& block) const { return hash; } +// global const definition of the litecoin chain const LitecoinChain litecoin; @@ -937,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") { @@ -1211,6 +1401,7 @@ const uint256 DogecoinChain::getPoWHash(const BlockHeader& block) const { return hash; } +// global const definition of the dogecoin chain const DogecoinChain dogecoin; @@ -1422,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..74d8e407 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") @@ -161,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); 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"))); 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());