diff --git a/src/main.cpp b/src/main.cpp index d98c2b3c..d6ff37ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3416,19 +3416,19 @@ public: }; -static bool CreateSpamMsgTx(CTransaction &txNew) +static bool CreateSpamMsgTx(CTransaction &txNew, std::vector &salt) { txNew.message = CScript() << strSpamMessage; + std::string strUsername = strSpamUser; - // get keyid from wallet (hopefully this is pubkey of strSpamUser) - CKeyID defaultKeyId( pwalletMain->vchDefaultKey.GetID() ); - printf("CreateSpamMsgTx: keyId = %s\n", defaultKeyId.ToString().c_str() ); - CKey key; - // get privkey from pubkey - if( !pwalletMain->GetKey(defaultKeyId, key) ) { - printf("CreateNewBlock: Failed to get privKey to sign SpamMessage\n"); - return false; + CKeyID keyID; + if( !pwalletMain->GetKeyIdFromUsername(strSpamUser, keyID) ) { + if( pwalletMain->vchDefaultKey.IsValid() ) { + keyID = pwalletMain->vchDefaultKey.GetID(); + strUsername = pwalletMain->mapKeyMetadata[keyID].username; + } } + printf("CreateSpamMsgTx: keyId = %s\n", keyID.ToString().c_str() ); // compute message hash and sign it CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); @@ -3437,25 +3437,36 @@ static bool CreateSpamMsgTx(CTransaction &txNew) // vchSig is sig(hash(message)) vector vchSig; - if (!key.Sign(hashMsg, vchSig)) { - printf("CreateNewBlock: Failed to sign SpamMessage\n"); - return false; + + if( keyID != CKeyID() ) { + CKey key; + // get privkey from pubkey + if( !pwalletMain->GetKey(keyID, key) ) { + printf("CreateNewBlock: Failed to get privKey to sign SpamMessage\n"); + return false; + } + + if (!key.Sign(hashMsg, vchSig)) { + printf("CreateNewBlock: Failed to sign SpamMessage\n"); + return false; + } } - printf("CreateSpamMsgTx: msg = %s user = %s hash = %s signedhash = %s\n", txNew.message.ToString().c_str(), strSpamUser.c_str(), + printf("CreateSpamMsgTx: msg = %s user = %s hash = %s signedhash = %s\n", + txNew.message.ToString().c_str(), strUsername.c_str(), hashMsg.ToString().c_str(), EncodeBase64(&vchSig[0], vchSig.size()).c_str() ); // add username and signature - txNew.userName = CScript() << strSpamUser; + txNew.userName = CScript() << strUsername; txNew.userName += CScript() << vchSig; + txNew.userName += CScript() << salt; txNew.pubKey.clear(); // pubKey will be updated to include extranonce txNew.nNonce = 0; // no update needed for spamMessage's nonce. return true; } -// [MF] FIXME: reservekey gives uniqueness to this worker thread, but it's not being used in twister. -CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) +CBlockTemplate* CreateNewBlock(std::vector &salt) { // Create new block auto_ptr pblocktemplate(new CBlockTemplate()); @@ -3465,7 +3476,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) // Create coinbase tx CTransaction txNew; - if( !CreateSpamMsgTx(txNew) ) + if( !CreateSpamMsgTx(txNew, salt) ) return NULL; // Add our coinbase tx as first transaction @@ -3613,7 +3624,7 @@ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash } -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +bool CheckWork(CBlock* pblock, CWallet& wallet) { uint256 hash = pblock->GetHash(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); @@ -3633,9 +3644,6 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) if (pblock->hashPrevBlock != hashBestChain) return error("BitcoinMiner : generated block is stale"); - // Remove key from key pool - reservekey.KeepKey(); - // Track how many getdata requests this block gets { LOCK(wallet.cs_wallet); @@ -3749,8 +3757,9 @@ void static BitcoinMiner(CWallet *pwallet) SetThreadPriority(THREAD_PRIORITY_LOWEST); RenameThread("bitcoin-miner"); - // Each thread has its own key and counter - CReserveKey reservekey(pwallet); + // Each thread has its own salt and counter + std::vector salt(4); + RAND_bytes(salt.data(), sizeof(salt)); unsigned int nExtraNonce = 0; try { loop { @@ -3767,7 +3776,7 @@ void static BitcoinMiner(CWallet *pwallet) unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; CBlockIndex* pindexPrev = pindexBest; - auto_ptr pblocktemplate(CreateNewBlock(reservekey)); + auto_ptr pblocktemplate(CreateNewBlock(salt)); if (!pblocktemplate.get()) return; CBlock *pblock = &pblocktemplate->block; @@ -3819,7 +3828,7 @@ void static BitcoinMiner(CWallet *pwallet) assert(hash == pblock->GetHash()); SetThreadPriority(THREAD_PRIORITY_NORMAL); - CheckWork(pblock, *pwalletMain, reservekey); + CheckWork(pblock, *pwalletMain); SetThreadPriority(THREAD_PRIORITY_LOWEST); // In regression test mode, stop mining after a block is found. This diff --git a/src/main.h b/src/main.h index e7dbfcd5..5ac70493 100644 --- a/src/main.h +++ b/src/main.h @@ -17,7 +17,6 @@ class CWallet; class CBlock; class CBlockIndex; class CKeyItem; -class CReserveKey; class CAddress; class CInv; @@ -109,7 +108,6 @@ extern string strSpamUser; static const uint64 nMinDiskSpace = 52428800; -class CReserveKey; class CCoinsDB; class CBlockTreeDB; struct CDiskBlockPos; @@ -166,13 +164,13 @@ bool SendMessages(CNode* pto, bool fSendTrickle); /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, CWallet* pwallet); /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(CReserveKey& reservekey); +CBlockTemplate* CreateNewBlock(std::vector &salt); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); /** Do mining precalculation */ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); /** Check mined block */ -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +bool CheckWork(CBlock* pblock, CWallet& wallet); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); /** Calculate the minimum amount of work a received block needs, without knowing its direct parent */ diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index e10f57ed..1caacd09 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -13,17 +13,17 @@ using namespace std; // Key used by getwork/getblocktemplate miners. // Allocated in InitRPCMining, free'd in ShutdownRPCMining -static CReserveKey* pMiningKey = NULL; +static std::vector salt; void InitRPCMining() { // getwork/getblocktemplate mining rewards paid here: - pMiningKey = new CReserveKey(pwalletMain); + salt.resize(4); + RAND_bytes(salt.data(), sizeof(salt)); } void ShutdownRPCMining() { - delete pMiningKey; pMiningKey = NULL; } Value getgenerate(const Array& params, bool fHelp) @@ -148,7 +148,7 @@ Value getwork(const Array& params, bool fHelp) nStart = GetTime(); // Create new block - pblocktemplate = CreateNewBlock(*pMiningKey); + pblocktemplate = CreateNewBlock(salt); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); vNewBlockTemplate.push_back(pblocktemplate); @@ -210,7 +210,7 @@ Value getwork(const Array& params, bool fHelp) */ pblock->hashMerkleRoot = pblock->BuildMerkleTree(); - return CheckWork(pblock, *pwalletMain, *pMiningKey); + return CheckWork(pblock, *pwalletMain); } } @@ -283,7 +283,7 @@ Value getblocktemplate(const Array& params, bool fHelp) delete pblocktemplate; pblocktemplate = NULL; } - pblocktemplate = CreateNewBlock(*pMiningKey); + pblocktemplate = CreateNewBlock(salt); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");