1

This comment is in the 0.9.3 miner.cpp bitcoin source, right above the ScanHash_CryptoPP definition.

//
// ScanHash scans nonces looking for a hash with at least some zero bits.
// It operates on big endian data.  Caller does the byte reversing.
// All input buffers are 16-byte aligned.  nNonce is usually preserved
// between calls, but periodically or if nNonce is 0xffff0000 or above,
// the block is rebuilt and nNonce starts over at zero.
//
unsigned int static ScanHash_CryptoPP...
  1. What does it mean that the input buffers are 16-byte aligned? Is that important for calculating the hash?

I notice that some of the parameters to this method are defined as follows:

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);

All of the arrays already have a length that is divisible by 16, what's the need for the extra 16 chars?

  1. And why only try 0xffff nonces? Is this just an artificial limit put so that the hashing doesn't take forever?
3
  1. What does it mean that the input buffers are 16-byte aligned? Is that important for calculating the hash?

    It means that the lower four bits of the starting address are always zero. I assume that this was done for speed reasons. There are instructions that won't work on non-16 byte aligned addresses. Also, some CPU caches might prefer it. I don't know.

    It doesn't affect how mining is done, though.

  2. All of the arrays already have a length that is divisible by 16, what's the need for the extra 16 chars?

    Not quite. Notice how it gets those addresses. It declares an array, then manipulates the pointer to that array. There's no platform-independent way to ask the OS for an aligned section of memory. Instead, you have to ask for something slightly larger than what you want, and increment the pointer until it lands on the boundary that you want.

    Side note: This is an off-by-one error. Really, the array only needs to be 15 bytes larger than normal. Probably not worth fixing.

  3. And why only try 0xffff nonces? Is this just an artificial limit put so that the hashing doesn't take forever?

    It tries all nonce values. However, it returns from the function every 65536 iterations, so the parent function can check

    • that it's still mining on the top of the chain,
    • that it's still actually connected to the network,
    • that the transactions are not out of date, and
    • that the nonce is not going to wrap around.

    Basically, all of the complicated logic is implemented in its caller, BitcoinMiner.

    PS: That comment is wrong. It appears to describe ScanHash, but it's actually talking about this section of code within BitcoinMiner:

        // Check for stop or if block needs to be rebuilt
        boost::this_thread::interruption_point();
        if (vNodes.empty() && Params().NetworkID() != CChainParams::REGTEST)
            break;
        if (nBlockNonce >= 0xffff0000)
            break;
        if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
            break;
        if (pindexPrev != chainActive.Tip())
            break;
    

    Somebody should probably move the comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.