Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions applications/coinexplorer/coinexplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a useful addition in general. You should propose it to upstream libcoin as pull request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

/M

On Sep 23, 2014, at 9:55 AM, Daniel Kraft notifications@github.com wrote:

In 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)));
    
  •    }*/
    

This seems like a useful addition in general. You should propose it to upstream libcoin as pull request.


Reply to this email directly or view it on GitHub.


// Node methods relevant for coin explorer
server.registerMethod(method_ptr(new GetBlock(node)));
Expand Down
6 changes: 5 additions & 1 deletion applications/libcoind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use libcoind also for the Namecoin testnet, like it is the same binary for Namecoin, Bitcoin, Dogecoin, Testnet3 and so on? Selecting Namecoin testnet should be done by some --namecoin-testnet option, similar to --namecoin.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best solution would be to let it compile to "libcoind" and symlink that to "namecoind", because the code detects what process is running and selects the chain after that.

I havent tested/coded this yet, but wish that "namecoind --testnet" would select namecointest. Right now "libcoind --namecointest" is doing that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested both "libcoind --namecoin --testnet" and "namecoind --testnet", the default is --namecointest or namecointestd.

35 changes: 20 additions & 15 deletions applications/libcoind/libcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here again, this looks like a fix for a really annoying problem. Please propose this upstream as a separate patch, I'm sure @gronager will accept it.


asio::ip::tcp::endpoint proxy_server;
if(conf.proxy().size()) {
Expand All @@ -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<short>(host_port[1]));
}
Node node(conf.chain(), conf.data_dir(), conf.listen(), lexical_cast<string>(conf.node_port()), proxy_server, conf.timeout()); // it is also here we specify the use of a proxy!
node.setClientVersion("libcoin/bitcoind", vector<string>());
node.setClientVersion("libcoin/namecoind", vector<string>(), 37654);
node.verification(conf.verification());
node.validation(conf.validation());
node.persistence(conf.persistance());
Expand Down Expand Up @@ -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);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem nice for testing, but shouldn't be part of the final patch. Instead, as stated above, this should be done with a --namecoin-testnet option.

Expand Down
1 change: 1 addition & 0 deletions contrib/coinexplorer.conf
28 changes: 28 additions & 0 deletions contrib/libcoind.conf
Original file line number Diff line number Diff line change
@@ -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

1 change: 1 addition & 0 deletions contrib/namecoind.conf
1 change: 1 addition & 0 deletions contrib/namecointestd.conf
2 changes: 1 addition & 1 deletion include/coin/AuxPow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not checked the details, but is the need for the new isTestnet argument due to testnet starting merge-mining immediately, while Namecoin started it only later? If so, could this decision be made by adapting adhere_aux_pow in the Chain subclass instead? This seems like the proper place to do it, if possible.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost all code to enable testnet is a carbon copy from Khal, his code is syncing up to height 6000 if I remember correctly. I would like to leave a breadcrumb to indicate this, maybe pull one commit from his repo.


uint256 GetParentBlockHash() const {
return parentBlock.getHash();
Expand Down
91 changes: 90 additions & 1 deletion include/coinChain/Chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit pick: I prefer to not have an "else" clause if you return in the "if" anyway. Just remove the else.

Is it really possible that count may be both a timestamp and a block height? (Usually, it is a block height in libcoin.) Seems very odd - but I haven't checked where enforce_name_rules is really called.

}


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<int, uint256> Checkpoints;
Checkpoints _checkpoints;
};

extern const NamecoinTestChain namecointest;

class COINCHAIN_EXPORT LitecoinChain : public Chain {
public:
LitecoinChain();
Expand Down
2 changes: 1 addition & 1 deletion include/coinChain/ChatClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class EndpointPool;
class COINCHAIN_EXPORT ChatClient
{
public:
ChatClient(boost::asio::io_service& io_service, boost::function<void (void)> 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<void (void)> 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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! If you submit a pull request to upstream for the other changes not related to testnet, include this. :)


~ChatClient() {
boost::system::error_code ec;
Expand Down
7 changes: 7 additions & 0 deletions include/coinChain/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions src/coin/AuxPow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 14 additions & 6 deletions src/coinChain/BlockChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int64_t>("SELECT CASE WHEN COUNT(*)=0 THEN 0 ELSE MIN(count) END FROM Confirmations");
Expand Down Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be done via a method in Chain (similar to adhere_names & friends), to follow libcoin's design spirit. Something like allow_incorrect_pow (not sure yet what the thing we have to allow here really is, some name that describes it).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using a --letmesync command line option. This is the hack I wish would not be necessary, why is namecoin/d/qt accepting blocks with so little time between them.

string timetravel = string("Incorrect proof of work: " + lexical_cast<string>(block.getBits()) + " versus " + lexical_cast<string>(_chain.nextWorkRequired(prev)));
string powlimit = string("Incorrect proof of work (limit): " + lexical_cast<string>(block.getBits()) + " versus " + lexical_cast<string>(_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<string>(block.getBits()) + " versus " + lexical_cast<string>(_chain.nextWorkRequired(prev)));
else if ( block.getBits() != _chain.proofOfWorkLimit().GetCompact())
throw Error("Incorrect proof of work (limit): " + lexical_cast<string>(block.getBits()) + " versus " + lexical_cast<string>(_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");

Expand Down
Loading