add CReserveScript to allow modular script keeping/returning
- use one CReserveScript per mining thread
This commit is contained in:
parent
087e65def9
commit
5496253966
6 changed files with 42 additions and 23 deletions
|
@ -421,7 +421,7 @@ static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void static BitcoinMiner(const CChainParams& chainparams, const CScript& coinbaseScript)
|
void static BitcoinMiner(const CChainParams& chainparams)
|
||||||
{
|
{
|
||||||
LogPrintf("BitcoinMiner started\n");
|
LogPrintf("BitcoinMiner started\n");
|
||||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||||
|
@ -429,7 +429,14 @@ void static BitcoinMiner(const CChainParams& chainparams, const CScript& coinbas
|
||||||
|
|
||||||
unsigned int nExtraNonce = 0;
|
unsigned int nExtraNonce = 0;
|
||||||
|
|
||||||
|
boost::shared_ptr<CReserveScript> coinbaseScript;
|
||||||
|
GetMainSignals().ScriptForMining(coinbaseScript);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
//throw an error if no script was provided
|
||||||
|
if (!coinbaseScript->reserveScript.size())
|
||||||
|
throw std::runtime_error("No coinbase script available (mining requires a wallet)");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (chainparams.MiningRequiresPeers()) {
|
if (chainparams.MiningRequiresPeers()) {
|
||||||
// Busy-wait for the network to come online so we don't waste time mining
|
// Busy-wait for the network to come online so we don't waste time mining
|
||||||
|
@ -452,7 +459,7 @@ void static BitcoinMiner(const CChainParams& chainparams, const CScript& coinbas
|
||||||
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
||||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||||
|
|
||||||
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript));
|
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
|
||||||
if (!pblocktemplate.get())
|
if (!pblocktemplate.get())
|
||||||
{
|
{
|
||||||
LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
|
LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
|
||||||
|
@ -486,6 +493,7 @@ void static BitcoinMiner(const CChainParams& chainparams, const CScript& coinbas
|
||||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
|
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
|
||||||
ProcessBlockFound(pblock, chainparams);
|
ProcessBlockFound(pblock, chainparams);
|
||||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||||
|
coinbaseScript->KeepScript();
|
||||||
|
|
||||||
// In regression test mode, stop mining after a block is found.
|
// In regression test mode, stop mining after a block is found.
|
||||||
if (chainparams.MineBlocksOnDemand())
|
if (chainparams.MineBlocksOnDemand())
|
||||||
|
@ -551,14 +559,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainpar
|
||||||
if (nThreads == 0 || !fGenerate)
|
if (nThreads == 0 || !fGenerate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CScript coinbaseScript;
|
|
||||||
GetMainSignals().ScriptForMining(coinbaseScript);
|
|
||||||
|
|
||||||
//throw an error if no script was provided
|
|
||||||
if (!coinbaseScript.size())
|
|
||||||
throw std::runtime_error("No coinbase script available (mining requires a wallet)");
|
|
||||||
|
|
||||||
minerThreads = new boost::thread_group();
|
minerThreads = new boost::thread_group();
|
||||||
for (int i = 0; i < nThreads; i++)
|
for (int i = 0; i < nThreads; i++)
|
||||||
minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams), coinbaseScript));
|
minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include "univalue/univalue.h"
|
#include "univalue/univalue.h"
|
||||||
|
|
||||||
|
@ -131,11 +132,11 @@ UniValue generate(const UniValue& params, bool fHelp)
|
||||||
int nHeight = 0;
|
int nHeight = 0;
|
||||||
int nGenerate = params[0].get_int();
|
int nGenerate = params[0].get_int();
|
||||||
|
|
||||||
CScript coinbaseScript;
|
boost::shared_ptr<CReserveScript> coinbaseScript;
|
||||||
GetMainSignals().ScriptForMining(coinbaseScript);
|
GetMainSignals().ScriptForMining(coinbaseScript);
|
||||||
|
|
||||||
//throw an error if no script was provided
|
//throw an error if no script was provided
|
||||||
if (!coinbaseScript.size())
|
if (!coinbaseScript->reserveScript.size())
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
|
||||||
|
|
||||||
{ // Don't keep cs_main locked
|
{ // Don't keep cs_main locked
|
||||||
|
@ -148,7 +149,7 @@ UniValue generate(const UniValue& params, bool fHelp)
|
||||||
UniValue blockHashes(UniValue::VARR);
|
UniValue blockHashes(UniValue::VARR);
|
||||||
while (nHeight < nHeightEnd)
|
while (nHeight < nHeightEnd)
|
||||||
{
|
{
|
||||||
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript));
|
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
|
||||||
if (!pblocktemplate.get())
|
if (!pblocktemplate.get())
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
|
||||||
CBlock *pblock = &pblocktemplate->block;
|
CBlock *pblock = &pblocktemplate->block;
|
||||||
|
@ -166,6 +167,9 @@ UniValue generate(const UniValue& params, bool fHelp)
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
||||||
++nHeight;
|
++nHeight;
|
||||||
blockHashes.push_back(pblock->GetHash().GetHex());
|
blockHashes.push_back(pblock->GetHash().GetHex());
|
||||||
|
|
||||||
|
//mark script as important because it was used at least for one coinbase output
|
||||||
|
coinbaseScript->KeepScript();
|
||||||
}
|
}
|
||||||
return blockHashes;
|
return blockHashes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,4 +609,13 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CReserveScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CScript reserveScript;
|
||||||
|
virtual void KeepScript() {}
|
||||||
|
CReserveScript() {}
|
||||||
|
virtual ~CReserveScript() {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_SCRIPT_SCRIPT_H
|
#endif // BITCOIN_SCRIPT_SCRIPT_H
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
#define BITCOIN_VALIDATIONINTERFACE_H
|
#define BITCOIN_VALIDATIONINTERFACE_H
|
||||||
|
|
||||||
#include <boost/signals2/signal.hpp>
|
#include <boost/signals2/signal.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
class CBlock;
|
class CBlock;
|
||||||
struct CBlockLocator;
|
struct CBlockLocator;
|
||||||
class CScript;
|
class CReserveScript;
|
||||||
class CTransaction;
|
class CTransaction;
|
||||||
class CValidationInterface;
|
class CValidationInterface;
|
||||||
class CValidationState;
|
class CValidationState;
|
||||||
|
@ -35,7 +36,7 @@ protected:
|
||||||
virtual void Inventory(const uint256 &hash) {}
|
virtual void Inventory(const uint256 &hash) {}
|
||||||
virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
|
virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
|
||||||
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
|
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
|
||||||
virtual void GetScriptForMining(CScript &script) {};
|
virtual void GetScriptForMining(boost::shared_ptr<CReserveScript>&) {};
|
||||||
virtual void UpdateRequestCount(const CBlock&) {};
|
virtual void UpdateRequestCount(const CBlock&) {};
|
||||||
friend void ::RegisterValidationInterface(CValidationInterface*);
|
friend void ::RegisterValidationInterface(CValidationInterface*);
|
||||||
friend void ::UnregisterValidationInterface(CValidationInterface*);
|
friend void ::UnregisterValidationInterface(CValidationInterface*);
|
||||||
|
@ -56,7 +57,7 @@ struct CMainSignals {
|
||||||
/** Notifies listeners of a block validation result */
|
/** Notifies listeners of a block validation result */
|
||||||
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
|
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
|
||||||
/** Notifies listeners that a key for mining is required (coinbase) */
|
/** Notifies listeners that a key for mining is required (coinbase) */
|
||||||
boost::signals2::signal<void (CScript &script)> ScriptForMining;
|
boost::signals2::signal<void (boost::shared_ptr<CReserveScript>&)> ScriptForMining;
|
||||||
/** Notifies listeners that a block has been successfully mined */
|
/** Notifies listeners that a block has been successfully mined */
|
||||||
boost::signals2::signal<void (const CBlock&)> BlockFound;
|
boost::signals2::signal<void (const CBlock&)> BlockFound;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2583,14 +2583,15 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::GetScriptForMining(CScript &script)
|
void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
|
||||||
{
|
{
|
||||||
CReserveKey reservekey(this);
|
boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
|
||||||
CPubKey pubkey;
|
CPubKey pubkey;
|
||||||
if (!reservekey.GetReservedKey(pubkey))
|
if (!rKey->GetReservedKey(pubkey))
|
||||||
return;
|
return;
|
||||||
script = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
|
|
||||||
reservekey.KeepKey();
|
script = rKey;
|
||||||
|
script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::LockCoin(COutPoint& output)
|
void CWallet::LockCoin(COutPoint& output)
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings
|
* Settings
|
||||||
*/
|
*/
|
||||||
|
@ -680,7 +682,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetScriptForMining(CScript &script);
|
void GetScriptForMining(boost::shared_ptr<CReserveScript> &script);
|
||||||
void UpdateRequestCount(const CBlock& block)
|
void UpdateRequestCount(const CBlock& block)
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
@ -742,7 +744,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A key allocated from the key pool. */
|
/** A key allocated from the key pool. */
|
||||||
class CReserveKey
|
class CReserveKey : public CReserveScript
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CWallet* pwallet;
|
CWallet* pwallet;
|
||||||
|
@ -763,6 +765,7 @@ public:
|
||||||
void ReturnKey();
|
void ReturnKey();
|
||||||
bool GetReservedKey(CPubKey &pubkey);
|
bool GetReservedKey(CPubKey &pubkey);
|
||||||
void KeepKey();
|
void KeepKey();
|
||||||
|
void KeepScript() { KeepKey(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue