Revert "Litecoin: Remove native coin generation."

This reverts commit 94bf538131.

Conflicts:
	src/init.cpp
This commit is contained in:
Warren Togami 2013-11-01 21:05:42 -10:00
parent ea24796726
commit d4c56161ae
7 changed files with 239 additions and 4 deletions

View File

@ -208,6 +208,9 @@ static const CRPCCommand vRPCCommands[] =
{ "getaddednodeinfo", &getaddednodeinfo, true, true }, { "getaddednodeinfo", &getaddednodeinfo, true, true },
{ "getdifficulty", &getdifficulty, true, false }, { "getdifficulty", &getdifficulty, true, false },
{ "getnetworkhashps", &getnetworkhashps, true, false }, { "getnetworkhashps", &getnetworkhashps, true, false },
{ "getgenerate", &getgenerate, true, false },
{ "setgenerate", &setgenerate, true, false },
{ "gethashespersec", &gethashespersec, true, false },
{ "getinfo", &getinfo, true, false }, { "getinfo", &getinfo, true, false },
{ "getmininginfo", &getmininginfo, true, false }, { "getmininginfo", &getmininginfo, true, false },
{ "getnewaddress", &getnewaddress, true, false }, { "getnewaddress", &getnewaddress, true, false },
@ -1143,6 +1146,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
// //
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]); if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]); if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]); if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);

View File

@ -140,7 +140,10 @@ extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, boo
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp);

View File

@ -306,6 +306,7 @@ std::string HelpMessage()
" -? " + _("This help message") + "\n" + " -? " + _("This help message") + "\n" +
" -conf=<file> " + _("Specify configuration file (default: litecoin.conf)") + "\n" + " -conf=<file> " + _("Specify configuration file (default: litecoin.conf)") + "\n" +
" -pid=<file> " + _("Specify pid file (default: litecoind.pid)") + "\n" + " -pid=<file> " + _("Specify pid file (default: litecoind.pid)") + "\n" +
" -gen " + _("Generate coins (default: 0)") + "\n" +
" -datadir=<dir> " + _("Specify data directory") + "\n" + " -datadir=<dir> " + _("Specify data directory") + "\n" +
" -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
" -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" +
@ -1137,6 +1138,9 @@ bool AppInit2(boost::thread_group& threadGroup)
if (fServer) if (fServer)
StartRPCThreads(); StartRPCThreads();
// Generate coins in the background
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
// ********************************************************* Step 12: finished // ********************************************************* Step 12: finished
uiInterface.InitMessage(_("Done loading")); uiInterface.InitMessage(_("Done loading"));

View File

@ -4081,9 +4081,22 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
return true; return true;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// LitecoinMiner // BitcoinMiner
// //
int static FormatHashBlocks(void* pbuffer, unsigned int len) int static FormatHashBlocks(void* pbuffer, unsigned int len)
@ -4490,7 +4503,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
return false; return false;
//// debug print //// debug print
printf("Litecoin RPCMiner:\n"); printf("BitcoinMiner:\n");
printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
pblock->print(); pblock->print();
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
@ -4499,7 +4512,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{ {
LOCK(cs_main); LOCK(cs_main);
if (pblock->hashPrevBlock != hashBestChain) if (pblock->hashPrevBlock != hashBestChain)
return error("LitecoinMiner : generated block is stale"); return error("BitcoinMiner : generated block is stale");
// Remove key from key pool // Remove key from key pool
reservekey.KeepKey(); reservekey.KeepKey();
@ -4513,12 +4526,165 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
// Process this block the same as if we had received it from another node // Process this block the same as if we had received it from another node
CValidationState state; CValidationState state;
if (!ProcessBlock(state, NULL, pblock)) if (!ProcessBlock(state, NULL, pblock))
return error("LitecoinMiner : ProcessBlock, block not accepted"); return error("BitcoinMiner : ProcessBlock, block not accepted");
} }
return true; return true;
} }
void static BitcoinMiner(CWallet *pwallet)
{
printf("BitcoinMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
RenameThread("bitcoin-miner");
// Each thread has its own key and counter
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
try { loop {
while (vNodes.empty())
MilliSleep(1000);
//
// Create new block
//
unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
CBlockIndex* pindexPrev = pindexBest;
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(reservekey));
if (!pblocktemplate.get())
return;
CBlock *pblock = &pblocktemplate->block;
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
//
// Pre-build hash buffers
//
char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
FormatHashBuffers(pblock, pmidstate, pdata, phash1);
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
//
// Search
//
int64 nStart = GetTime();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
loop
{
unsigned int nHashesDone = 0;
uint256 thash;
char scratchpad[SCRYPT_SCRATCHPAD_SIZE];
loop
{
scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad);
if (thash <= hashTarget)
{
// Found a solution
SetThreadPriority(THREAD_PRIORITY_NORMAL);
CheckWork(pblock, *pwalletMain, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
break;
}
pblock->nNonce += 1;
nHashesDone += 1;
if ((pblock->nNonce & 0xFF) == 0)
break;
}
// Meter hashes/sec
static int64 nHashCounter;
if (nHPSTimerStart == 0)
{
nHPSTimerStart = GetTimeMillis();
nHashCounter = 0;
}
else
nHashCounter += nHashesDone;
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
static CCriticalSection cs;
{
LOCK(cs);
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
nHPSTimerStart = GetTimeMillis();
nHashCounter = 0;
static int64 nLogTime;
if (GetTime() - nLogTime > 30 * 60)
{
nLogTime = GetTime();
printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
}
}
}
}
// Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point();
if (vNodes.empty())
break;
if (pblock->nNonce >= 0xffff0000)
break;
if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
break;
if (pindexPrev != pindexBest)
break;
// Update nTime every few seconds
pblock->UpdateTime(pindexPrev);
nBlockTime = ByteReverse(pblock->nTime);
if (fTestNet)
{
// Changing pblock->nTime can change work required on testnet:
nBlockBits = ByteReverse(pblock->nBits);
hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
}
}
} }
catch (boost::thread_interrupted)
{
printf("BitcoinMiner terminated\n");
throw;
}
}
void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
{
static boost::thread_group* minerThreads = NULL;
int nThreads = GetArg("-genproclimit", -1);
if (nThreads < 0)
nThreads = boost::thread::hardware_concurrency();
if (minerThreads != NULL)
{
minerThreads->interrupt_all();
delete minerThreads;
minerThreads = NULL;
}
if (nThreads == 0 || !fGenerate)
return;
minerThreads = new boost::thread_group();
for (int i = 0; i < nThreads; i++)
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
}
// Amount compression: // Amount compression:
// * If the amount is 0, output 0 // * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) // * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)

View File

@ -154,6 +154,8 @@ bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle); bool SendMessages(CNode* pto, bool fSendTrickle);
/** Run an instance of the script checking thread */ /** Run an instance of the script checking thread */
void ThreadScriptCheck(); void ThreadScriptCheck();
/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
/** Generate a new block, without valid proof-of-work */ /** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(CReserveKey& reservekey); CBlockTemplate* CreateNewBlock(CReserveKey& reservekey);
/** Modify the extranonce in a block */ /** Modify the extranonce in a block */

View File

@ -1873,6 +1873,7 @@ void StartNode(boost::thread_group& threadGroup)
bool StopNode() bool StopNode()
{ {
printf("StopNode()\n"); printf("StopNode()\n");
GenerateBitcoins(false, NULL);
MapPort(false); MapPort(false);
nTransactionsUpdated++; nTransactionsUpdated++;
if (semOutbound) if (semOutbound)

View File

@ -63,6 +63,57 @@ Value getnetworkhashps(const Array& params, bool fHelp)
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
} }
Value getgenerate(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"getgenerate\n"
"Returns true or false.");
return GetBoolArg("-gen");
}
Value setgenerate(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"setgenerate <generate> [genproclimit]\n"
"<generate> is true or false to turn generation on or off.\n"
"Generation is limited to [genproclimit] processors, -1 is unlimited.");
bool fGenerate = true;
if (params.size() > 0)
fGenerate = params[0].get_bool();
if (params.size() > 1)
{
int nGenProcLimit = params[1].get_int();
mapArgs["-genproclimit"] = itostr(nGenProcLimit);
if (nGenProcLimit == 0)
fGenerate = false;
}
mapArgs["-gen"] = (fGenerate ? "1" : "0");
GenerateBitcoins(fGenerate, pwalletMain);
return Value::null;
}
Value gethashespersec(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"gethashespersec\n"
"Returns a recent hashes per second performance measurement while generating.");
if (GetTimeMillis() - nHPSTimerStart > 8000)
return (boost::int64_t)0;
return (boost::int64_t)dHashesPerSec;
}
Value getmininginfo(const Array& params, bool fHelp) Value getmininginfo(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
@ -76,6 +127,9 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx));
obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar"))); obj.push_back(Pair("errors", GetWarnings("statusbar")));
obj.push_back(Pair("generate", GetBoolArg("-gen")));
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("testnet", fTestNet));