<ol>
<li><blockquote>
  <p>What does it mean that the input buffers are 16-byte aligned? Is that important for calculating the hash?</p>
</blockquote>

<p>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.</p>

<p>It doesn't affect how mining is done, though.</p></li>
<li><blockquote>
  <p>All of the arrays already have a length that is divisible by 16, what's the need for the extra 16 chars?</p>
</blockquote>

<p>Not quite. Notice how it gets those addresses. It declares an array, <em>then</em> 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.</p>

<p>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.</p></li>
<li><blockquote>
  <p>And why only try 0xffff nonces? Is this just an artificial limit put so that the hashing doesn't take forever?</p>
</blockquote>

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

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

<p>Basically, all of the complicated logic is implemented in its caller, <code>BitcoinMiner</code>.</p>

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

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

<p>Somebody should probably move the comment.</p></li>
</ol>

CC BY-SA 3.0
2014-12-02T03:11:19.093Z
2014-12-02T03:11:19.093Z
Nick ODell
<p>This comment is in the 0.9.3 miner.cpp bitcoin source, right above the <code>ScanHash_CryptoPP</code> definition. </p>

<pre>
//
// 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...
</pre>

<ol>
<li>What does it mean that the input buffers are 16-byte aligned? Is that important for calculating the hash? </li>
</ol>

<p>I notice that some of the parameters to this method are defined as follows:</p>

<pre><code>char pmidstatebuf[32+16]; char* pmidstate = alignup&lt;16&gt;(pmidstatebuf);
char pdatabuf[128+16];    char* pdata     = alignup&lt;16&gt;(pdatabuf);
char phash1buf[64+16];    char* phash1    = alignup&lt;16&gt;(phash1buf);
</code></pre>

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

<ol start="2">
<li>And why only try 0xffff nonces? Is this just an artificial limit put so that the hashing doesn't take forever?</li>
</ol>

<mining-technical-details><bitcoin-core-development><nonce>
Explain this comment on nNonce from the bitcoin miner.cpp source?
morsecoder
# Explain this comment on nNonce from the bitcoin miner.cpp source?

(Asked by: username_0 on 2014-12-02)

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?

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

**Tags:** mining-technical-details, bitcoin-core-development, nonce


---

## 1 answers

### Answer by username_1 on 2014-12-02. Score: 3 | Accepted answer

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.


---

