<p>Bitcoin Core does this thing called non-atomic flushing. What that means is that the database, instead of being updated atomically (i.e. everything is written at the same time, or nothing is written), has data written to it over time. If the database crashes, with non-atomic flushing, there will be some data written, and some data that is not written. This is different from atomic flushing where either all of the data was written, or none of it was.</p>

<p>Non-atomic flushing allows Bitcoin Core to skip validation of things it has already validated and then just flush things to the database later after a crash or unclean shutdown. But in order to know where it has validated up to, it has to store that block hash (where it has validated up to and where it is flushing up to). It also has to store the block it started at (the block the database knew up to when flushing began). </p>

<p>This is where <code>GetHeadBlocks()</code> comes in. When Bitcoin Core begins flushing, it first writes those two blocks, the old one where the database head was at, and the new one, where the database head will be once flushing finishes. In the event of an unclean shutdown or database crash, these values are already written to the database so it can pull those out of the database, know where its last known good database state was at, and know where it has validated up to so it can skip full validation and just build the database data and flush it. If there was no unclean shutdown or crash, <code>GetHeadBlocks()</code> would return an empty vector.</p>

<hr>

<p>For example, suppose the database was at block 50, and it is flushing to block 60. When it begins flushing, the hashes of blocks 50 and 60 are written to the database. Suppose that the computer suddenly loses power when it has only flushed up to block 55. When the node comes back on, it will call <code>GetHeadBlocks()</code> and get the hashes of blocks 50 and 60. Now it knows that it was mid-flush when it uncleanly shutdown. So it then rebuilds what the database would be from blocks 50 to 60 but does not perform full validation. It then flushes the remaining data and removes the hashes of blocks 50 and 60 from where they were written.</p>

CC BY-SA 3.0
2018-01-30T16:37:15.727Z
When a crash happens during the flush from 50 to 60, it will have some changes from every block between 50 and 60, not neatly everything up to 55 and nothing above. This is a detail and doesn't impact the rest of the explanation, but it otherwise raises a question: if you've synced everything to 55, why not write that to the db, to avoid processing of blocks 50-54? If it's a mix of changes from all, you can't do that.
Pieter Wuille
CC BY-SA 3.0
2018-01-29T06:42:07.147Z
2018-01-30T16:34:32.197Z
2018-01-30T16:34:32.197Z
Ava Chow
<p>Your answer lies in the code.</p>

<p>Check where GetHeadBlocks is being used..
<a href="https://dev.visucore.com/bitcoin/doxygen/class_c_coins_view_d_b.html" rel="nofollow noreferrer">https://dev.visucore.com/bitcoin/doxygen/class_c_coins_view_d_b.html</a></p>

<p>The caller graph indicates that it's being used by CCoinsViewDB::BatchWrite. The assert statement in BatchWrite will abort the function execution if the latest head does not match the hashblock passed as an argument.</p>

<p>My 30 second research seems to indicate that it will return the block hashes of the old &amp; new block when it's in a syncing state. The BatchWrite is also responsible for updating the best block hash (check doxygen).</p>

CC BY-SA 3.0
2017-12-29T15:05:23.947Z
you answer too mindless..... why there exists old & new block, their function?
xiedeacc
CC BY-SA 3.0
2017-12-29T12:51:50.240Z
2017-12-29T12:51:50.240Z
Penquin
<p>I have google a lot, there exists little information, confused with the code comments </p>

<pre><code>Retrieve the range of blocks that may have been only partially written. If the database is in a consistent state, the result is the empty vector. Otherwise, a two-element vector is returned consisting of the new and the old block hash, in that order.
</code></pre>

<p>why there exists old &amp; new block, their function?</p>

<utxo><database>
what's CCoinsViewDB::GetHeadBlocks for?
xiedeacc
# what's CCoinsViewDB::GetHeadBlocks for?

(Asked by: username_0 on 2017-12-29)

I have google a lot, there exists little information, confused with the code comments

```
Retrieve the range of blocks that may have been only partially written. If the database is in a consistent state, the result is the empty vector. Otherwise, a two-element vector is returned consisting of the new and the old block hash, in that order.

```

why there exists old & new block, their function?

**Tags:** utxo, database


---

## 2 answers

### Answer by username_1 on 2018-01-29. Score: 1

Bitcoin Core does this thing called non-atomic flushing. What that means is that the database, instead of being updated atomically (i.e. everything is written at the same time, or nothing is written), has data written to it over time. If the database crashes, with non-atomic flushing, there will be some data written, and some data that is not written. This is different from atomic flushing where either all of the data was written, or none of it was.

Non-atomic flushing allows Bitcoin Core to skip validation of things it has already validated and then just flush things to the database later after a crash or unclean shutdown. But in order to know where it has validated up to, it has to store that block hash (where it has validated up to and where it is flushing up to). It also has to store the block it started at (the block the database knew up to when flushing began).

This is where `GetHeadBlocks()` comes in. When Bitcoin Core begins flushing, it first writes those two blocks, the old one where the database head was at, and the new one, where the database head will be once flushing finishes. In the event of an unclean shutdown or database crash, these values are already written to the database so it can pull those out of the database, know where its last known good database state was at, and know where it has validated up to so it can skip full validation and just build the database data and flush it. If there was no unclean shutdown or crash, `GetHeadBlocks()` would return an empty vector.

---

For example, suppose the database was at block 50, and it is flushing to block 60. When it begins flushing, the hashes of blocks 50 and 60 are written to the database. Suppose that the computer suddenly loses power when it has only flushed up to block 55. When the node comes back on, it will call `GetHeadBlocks()` and get the hashes of blocks 50 and 60. Now it knows that it was mid-flush when it uncleanly shutdown. So it then rebuilds what the database would be from blocks 50 to 60 but does not perform full validation. It then flushes the remaining data and removes the hashes of blocks 50 and 60 from where they were written.

> **Comments:**
> **username_2**: When a crash happens during the flush from 50 to 60, it will have some changes from every block between 50 and 60, not neatly everything up to 55 and nothing above. This is a detail and doesn't impact the rest of the explanation, but it otherwise raises a question: if you've synced everything to 55, why not write that to the db, to avoid processing of blocks 50-54? If it's a mix of changes from all, you can't do that.  

---

### Answer by username_3 on 2017-12-29. Score: 0

Your answer lies in the code.

Check where GetHeadBlocks is being used..
<https://dev.visucore.com/bitcoin/doxygen/class_c_coins_view_d_b.html>

The caller graph indicates that it's being used by CCoinsViewDB::BatchWrite. The assert statement in BatchWrite will abort the function execution if the latest head does not match the hashblock passed as an argument.

My 30 second research seems to indicate that it will return the block hashes of the old & new block when it's in a syncing state. The BatchWrite is also responsible for updating the best block hash (check doxygen).

> **Comments:**
> **username_0**: you answer too mindless..... why there exists old & new block, their function?  

---

