mining fixes: add salt to instance and use correct username for signing

This commit is contained in:
Miguel Freitas 2013-07-25 12:06:18 -03:00
parent f2699c4753
commit 9946d6ed72
3 changed files with 42 additions and 35 deletions

View File

@ -3416,19 +3416,19 @@ public:
};
static bool CreateSpamMsgTx(CTransaction &txNew)
static bool CreateSpamMsgTx(CTransaction &txNew, std::vector<unsigned char> &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<unsigned char> 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<unsigned char> &salt)
{
// Create new block
auto_ptr<CBlockTemplate> 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<unsigned char> 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<CBlockTemplate> pblocktemplate(CreateNewBlock(reservekey));
auto_ptr<CBlockTemplate> 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

View File

@ -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<unsigned char> &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 */

View File

@ -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<unsigned char> 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");