Browse Source

use scrypt hash function like litecoin

miguelfreitas
Miguel Freitas 11 years ago
parent
commit
30992b87c3
  1. 8
      src/chainparams.cpp
  2. 3
      src/core.cpp
  3. 8
      src/core.h
  4. 32
      src/init.cpp
  5. 82
      src/main.cpp
  6. 2
      src/main.h
  7. 4
      src/scrypt-sse2.cpp
  8. 4
      src/scrypt.cpp

8
src/chainparams.cpp

@ -54,13 +54,13 @@ public:
genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1; genesis.nVersion = 1;
genesis.nHeight = 0; genesis.nHeight = 0;
genesis.nTime = 1383612321; genesis.nTime = 1384394255;
//genesis.nBits = 0x1d00ffff; //genesis.nBits = 0x1d00ffff;
genesis.nBits = 0x1d7fffff; genesis.nBits = 0x1f03ffff;
genesis.nNonce = 1353330432; genesis.nNonce = 2934;
hashGenesisBlock = genesis.GetHash(); hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0000001d5eb70d639089eb9b31a4175aa906d6824aae78a9b450ab71de5e6e12")); assert(hashGenesisBlock == uint256("9915158279673d101912be80f25c20627f1dd8bf5231e7c46bfec5ed19737f44"));
vSeeds.push_back(CDNSSeedData("twister.net.co", "seed.twister.net.co")); vSeeds.push_back(CDNSSeedData("twister.net.co", "seed.twister.net.co"));
vSeeds.push_back(CDNSSeedData("twister.net.co", "seed2.twister.net.co")); vSeeds.push_back(CDNSSeedData("twister.net.co", "seed2.twister.net.co"));

3
src/core.cpp

@ -258,8 +258,9 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
void CBlock::print() const void CBlock::print() const
{ {
printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n", printf("CBlock(hash=%s, PoW=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n",
GetHash().ToString().c_str(), GetHash().ToString().c_str(),
GetPoWHash().ToString().c_str(),
nVersion, nVersion,
hashPrevBlock.ToString().c_str(), hashPrevBlock.ToString().c_str(),
hashMerkleRoot.ToString().c_str(), hashMerkleRoot.ToString().c_str(),

8
src/core.h

@ -8,6 +8,7 @@
#include "uint256.h" #include "uint256.h"
#include "serialize.h" #include "serialize.h"
#include "script.h" #include "script.h"
#include "scrypt.h"
#include <stdio.h> #include <stdio.h>
@ -530,6 +531,13 @@ public:
vMerkleTree.clear(); vMerkleTree.clear();
} }
uint256 GetPoWHash() const
{
uint256 thash;
scrypt_1024_1_1_256(BEGIN(nVersion), BEGIN(thash));
return thash;
}
CBlockHeader GetBlockHeader() const CBlockHeader GetBlockHeader() const
{ {
CBlockHeader block; CBlockHeader block;

32
src/init.cpp

@ -27,6 +27,18 @@
#include <signal.h> #include <signal.h>
#endif #endif
#if defined(USE_SSE2)
#if !defined(MAC_OSX) && (defined(_M_IX86) || defined(__i386__) || defined(__i386))
#ifdef _MSC_VER
// MSVC 64bit is unable to use inline asm
#include <intrin.h>
#else
// GCC Linux or i686-w64-mingw32
#include <cpuid.h>
#endif
#endif
#endif
using namespace std; using namespace std;
using namespace boost; using namespace boost;
@ -370,6 +382,23 @@ bool AppInit2(boost::thread_group& threadGroup)
sigaction(SIGHUP, &sa_hup, NULL); sigaction(SIGHUP, &sa_hup, NULL);
#endif #endif
#if defined(USE_SSE2)
unsigned int cpuid_edx=0;
#if !defined(MAC_OSX) && (defined(_M_IX86) || defined(__i386__) || defined(__i386))
// 32bit x86 Linux or Windows, detect cpuid features
#if defined(_MSC_VER)
// MSVC
int x86cpuid[4];
__cpuid(x86cpuid, 1);
cpuid_edx = (unsigned int)buffer[3];
#else
// Linux or i686-w64-mingw32 (gcc-4.6.3)
unsigned int eax, ebx, ecx;
__get_cpuid(1, &eax, &ebx, &ecx, &cpuid_edx);
#endif
#endif
#endif
// ********************************************************* Step 2: parameter interactions // ********************************************************* Step 2: parameter interactions
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
@ -641,6 +670,9 @@ bool AppInit2(boost::thread_group& threadGroup)
AddOneShot(strDest); AddOneShot(strDest);
// ********************************************************* Step 7: load block chain // ********************************************************* Step 7: load block chain
#if defined(USE_SSE2)
scrypt_detect_sse2(cpuid_edx);
#endif
fReindex = GetBoolArg("-reindex", false); fReindex = GetBoolArg("-reindex", false);

82
src/main.cpp

@ -811,7 +811,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
} }
// Check the header // Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits)) if (!CheckProofOfWork(block.GetPoWHash(), block.nBits))
return error("ReadBlockFromDisk(CBlock&, CDiskBlockPos&) : errors in block header"); return error("ReadBlockFromDisk(CBlock&, CDiskBlockPos&) : errors in block header");
return true; return true;
@ -1566,7 +1566,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return state.DoS(100, error("CheckBlock() : size limits failed")); return state.DoS(100, error("CheckBlock() : size limits failed"));
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(), block.nBits))
return state.DoS(50, error("CheckBlock() : proof of work failed")); return state.DoS(50, error("CheckBlock() : proof of work failed"));
// Check timestamp // Check timestamp
@ -3783,7 +3783,7 @@ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash
bool CheckWork(CBlock* pblock, CWallet& wallet) bool CheckWork(CBlock* pblock, CWallet& wallet)
{ {
uint256 hash = pblock->GetHash(); uint256 hash = pblock->GetPoWHash();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
if (hash > hashTarget) if (hash > hashTarget)
@ -3829,48 +3829,32 @@ void GenesisMiner()
printf("Running GenesisMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), printf("Running GenesisMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); ::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& nBlockNonce = *(unsigned int*)(pdata + 64 + 12 + 4);
// //
// Search // Search
// //
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
uint256 hashbuf[2]; uint256 hash;
uint256& hash = *alignup<16>(hashbuf);
loop loop
{ {
unsigned int nHashesDone = 0; unsigned int nHashesDone = 0;
unsigned int nNonceFound;
// Crypto++ SHA256
nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
(char*)&hash, nHashesDone);
// Check if something found do {
if (nNonceFound != (unsigned int) -1) pblock->nNonce++;
{ hash = pblock->GetPoWHash();
for (unsigned int i = 0; i < sizeof(hash)/4; i++) } while( hash > hashTarget &&
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]); (pblock->nNonce & 0xffff) != 0 );
nHashesDone = 0xffff+1;
// Check if something found
if (hash <= hashTarget) if (hash <= hashTarget)
{ {
// Found a solution // Found a solution
pblock->nNonce = ByteReverse(nNonceFound);
assert(hash == pblock->GetHash());
printf("genesishash: %s\n", pblock->GetHash().ToString().c_str()); printf("genesishash: %s\n", pblock->GetHash().ToString().c_str());
printf("genesisPOWhash: %s\n", pblock->GetPoWHash().ToString().c_str());
printf("merkle: %s\n", pblock->hashMerkleRoot.ToString().c_str()); printf("merkle: %s\n", pblock->hashMerkleRoot.ToString().c_str());
printf("nonce: %d\n", pblock->nNonce); printf("nonce: %d\n", pblock->nNonce);
exit(0); exit(0);
} }
}
// Meter hashes/sec // Meter hashes/sec
static int64 nHashCounter; static int64 nHashCounter;
@ -3903,7 +3887,7 @@ void GenesisMiner()
// Check for stop or if block needs to be rebuilt // Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
if (nBlockNonce >= 0xffff0000) if (pblock->nNonce >= 0xffff0000)
break; break;
} }
} }
@ -3942,48 +3926,27 @@ void static BitcoinMiner(CWallet *pwallet)
printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); ::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 + 4);
unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8 + 4);
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12 + 4);
// //
// Search // Search
// //
int64 nStart = GetTime(); int64 nStart = GetTime();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
uint256 hashbuf[2]; uint256 hash;
uint256& hash = *alignup<16>(hashbuf);
loop loop
{ {
unsigned int nHashesDone = 0; unsigned int nHashesDone = 0;
unsigned int nNonceFound;
// Crypto++ SHA256 do {
nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1, pblock->nNonce++;
(char*)&hash, nHashesDone); hash = pblock->GetPoWHash();
} while( hash > hashTarget &&
(pblock->nNonce & 0xffff) != 0 );
nHashesDone = 0xffff+1;
// Check if something found // Check if something found
if (nNonceFound != (unsigned int) -1)
{
for (unsigned int i = 0; i < sizeof(hash)/4; i++)
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
if (hash <= hashTarget) if (hash <= hashTarget)
{ {
// Found a solution // Found a solution
pblock->nNonce = ByteReverse(nNonceFound);
assert(hash == pblock->GetHash());
SetThreadPriority(THREAD_PRIORITY_NORMAL); SetThreadPriority(THREAD_PRIORITY_NORMAL);
CheckWork(pblock, *pwalletMain); CheckWork(pblock, *pwalletMain);
SetThreadPriority(THREAD_PRIORITY_LOWEST); SetThreadPriority(THREAD_PRIORITY_LOWEST);
@ -3995,7 +3958,6 @@ void static BitcoinMiner(CWallet *pwallet)
break; break;
} }
}
// Meter hashes/sec // Meter hashes/sec
static int64 nHashCounter; static int64 nHashCounter;
@ -4030,7 +3992,7 @@ void static BitcoinMiner(CWallet *pwallet)
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
if (vNodes.empty() && Params().NetworkID() != CChainParams::REGTEST) if (vNodes.empty() && Params().NetworkID() != CChainParams::REGTEST)
break; break;
if (nBlockNonce >= 0xffff0000) if (pblock->nNonce >= 0xffff0000)
break; break;
if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
break; break;
@ -4039,11 +4001,9 @@ void static BitcoinMiner(CWallet *pwallet)
// Update nTime every few seconds // Update nTime every few seconds
UpdateTime(*pblock, pindexPrev); UpdateTime(*pblock, pindexPrev);
nBlockTime = ByteReverse(pblock->nTime);
if (TestNet()) if (TestNet())
{ {
// Changing pblock->nTime can change work required on testnet: // Changing pblock->nTime can change work required on testnet:
nBlockBits = ByteReverse(pblock->nBits);
hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
} }
} }

2
src/main.h

@ -756,7 +756,7 @@ public:
bool CheckIndex() const bool CheckIndex() const
{ {
return CheckProofOfWork(GetBlockHash(), nBits); return CheckProofOfWork(CBlock(GetBlockHeader()).GetPoWHash(), nBits);
} }
enum { nMedianTimeSpan=11 }; enum { nMedianTimeSpan=11 };

4
src/scrypt-sse2.cpp

@ -104,7 +104,7 @@ void scrypt_1024_1_1_256_sp_sse2(const char *input, char *output, char *scratchp
V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); PBKDF2_SHA256((const uint8_t *)input, 84, (const uint8_t *)input, 84, 1, B, 128);
for (k = 0; k < 2; k++) { for (k = 0; k < 2; k++) {
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
@ -132,5 +132,5 @@ void scrypt_1024_1_1_256_sp_sse2(const char *input, char *output, char *scratchp
} }
} }
PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32); PBKDF2_SHA256((const uint8_t *)input, 84, B, 128, 1, (uint8_t *)output, 32);
} }

4
src/scrypt.cpp

@ -252,7 +252,7 @@ void scrypt_1024_1_1_256_sp_generic(const char *input, char *output, char *scrat
V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); PBKDF2_SHA256((const uint8_t *)input, 84, (const uint8_t *)input, 84, 1, B, 128);
for (k = 0; k < 32; k++) for (k = 0; k < 32; k++)
X[k] = le32dec(&B[4 * k]); X[k] = le32dec(&B[4 * k]);
@ -273,7 +273,7 @@ void scrypt_1024_1_1_256_sp_generic(const char *input, char *output, char *scrat
for (k = 0; k < 32; k++) for (k = 0; k < 32; k++)
le32enc(&B[4 * k], X[k]); le32enc(&B[4 * k], X[k]);
PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32); PBKDF2_SHA256((const uint8_t *)input, 84, B, 128, 1, (uint8_t *)output, 32);
} }
#if defined(USE_SSE2) #if defined(USE_SSE2)

Loading…
Cancel
Save