Mining Blob
The mining blob is the block header + merkle root + number of TX-es. It's similar to block identifier as defined in CNS003:
Calculation of Block Identifier
The identifier of a block is the result of hashing the following data with Keccak:
size of [block_header, Merkle root hash, and the number of transactions] in bytes (varint)
block_header,
Merkle root hash,
number of transactions (varint).
The goal of the Merkle root hash is to "attach" the transactions referred to in the list to the block header: once the Merkle root hash is fixed, the transactions cannot be modified.
Note that the block identifier is the result of hashing the blob with Keccak and it is not the same as PoW hash. The PoW hash is obtained by hashing the blob with CryptoNight, and it doesn't contain the "size of [block header, ..." which is used exclusively for the block identifier.
See get_block_hashing_blob
implementation in Monero source code for details.
blobdata get_block_hashing_blob(const block& b)
{
blobdata blob = t_serializable_object_to_blob(static_cast<block_header>(b));
crypto::hash tree_root_hash = get_tx_tree_hash(b);
blob.append(reinterpret_cast<const char*>(&tree_root_hash), sizeof(tree_root_hash));
blob.append(tools::get_varint_data(b.tx_hashes.size()+1));
return blob;
}
As you can see, it retrieves the block header blob, and appends Merkle tree root and number of transactions to the blob.
Block Header
Block header is also defined in CNS003:
4.1 Block Header
Each block starts with a block header. The major version defines the block header parsing rules (i.e. block header format) and is incremented with each block header format update. The table below describes version 1 of the block header format. The minor version defines the interpretation details that are not related to block header parsing.
It is always safe to parse the block header of a particular major version with a parsing procedure suitable for said version, even if the minor version is unknown. Parsing the block header with an unknown major version is not safe as the content of the block header may be misinterpreted.
+---------------+------------------+--------------------------------+
| Field | Type | Content |
+---------------+------------------+--------------------------------+
| major_version | varint | Major block header version |
| | | (always 1) |
+---------------+------------------+--------------------------------+
| minor_version | varint | Minor block header version |
| | | |
+---------------+------------------+--------------------------------+
| timestamp | varint | Block creation time |
| | | (UNIX timestamp) |
+---------------+------------------+--------------------------------+
| prev_id | hash | Identifier of the previous |
| | | block |
+---------------+------------------+--------------------------------+
| nonce | 4 bytes | Any value which is used in the |
| | | network consensus algorithm |
+---------------+------------------+--------------------------------+
Table 4.1: Block header structure description
The definition of block header is found in Monero source code as well.
struct block_header
{
uint8_t major_version;
uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
uint64_t timestamp;
crypto::hash prev_id;
uint32_t nonce;
Note that major version is used for hard-fork upgrade counting, as seen in Monero source code (1, 2). Looks like it's not exactly following the CN specification, where it was supposed to be changed only if the header parsing scheme changes.
Block PoW Hashing
For actual hashing, see get_block_longhash
implementation in Monero source code and explanation of the "block 202612 bug workaround": What happened at block 202612?