// File: jeffchan[P]blockchain-parser/BlockChain.cpp
// Function: BlockChainImpl::readBlockHeader()
bool readBlockHeader(void)
	{
		bool ok = false;
		FILE *fph = mBlockChain[mBlockIndex];
		if ( fph )
		{
			uint32_t magicID = 0;
			uint32_t lastBlockRead = (uint32_t)ftell(fph);
			size_t r = fread(&magicID,sizeof(magicID),1,fph);	// Attempt to read the magic id for the next block
			if ( r == 0 )
			{
				mBlockIndex++;	// advance to the next data file if we couldn't read any further in the current data file
				if ( openBlock() )
				{
					fph = mBlockChain[mBlockIndex];
					r = fread(&magicID,sizeof(magicID),1,fph); // if we opened up a new file; read the magic id from it's first block.
					lastBlockRead = ftell(fph);
				}
			}
			// If after reading the previous block, we did not encounter a block header, we need to scan for the next block header..
			if ( r == 1 && magicID != MAGIC_ID )
			{
				fseek(fph,lastBlockRead,SEEK_SET);
				printf("Warning: Missing block-header; scanning for next one.\r\n");
				uint8_t *temp = (uint8_t *)::malloc(MAX_BLOCK_SIZE);
				memset(temp,0,MAX_BLOCK_SIZE);
				uint32_t c = (uint32_t)fread(temp,1,MAX_BLOCK_SIZE,fph);
				bool found = false;
				if ( c > 0 )
				{
					for (uint32_t i=0; i<c; i++)
					{
						const uint32_t *check = (const uint32_t *)&temp[i];
						if ( *check == MAGIC_ID )
						{
							printf("Found the next block header after skipping: %s bytes forward in the file.\r\n", formatNumber(i) );
							lastBlockRead+=i; // advance to this location.
							found = true;
							break;
						}
					}
				}
				::free(temp);
				if ( found )
				{
					fseek(fph,lastBlockRead,SEEK_SET);
					r = fread(&magicID,sizeof(magicID),1,fph); // if we opened up a new file; read the magic id from it's first block.
					assert( magicID == MAGIC_ID );
				}

				if ( found ) // if we found it before the EOF, we are cool, otherwise, we need to advance to the next file.
				{
				}
				else
				{
					mBlockIndex++;	// advance to the next data file if we couldn't read any further in the current data file
					if ( openBlock() )
					{
						fph = mBlockChain[mBlockIndex];
						r = fread(&magicID,sizeof(magicID),1,fph); // if we opened up a new file; read the magic id from it's first block.
						if ( r == 1 )
						{
							if ( magicID != MAGIC_ID )
							{
								printf("Advanced to the next data file; but it does not start with a valid block.  Aborting reading the block-chain.\r\n");
								r = 0;
							}
						}
					}
					else
					{
						r = 0; // done
					}
				}
			}
			if ( r == 1 )	// Ok, this is a valid block, let's continue
			{
				BlockHeader header;
				BlockPrefix prefix;
				header.mFileIndex = mBlockIndex;
				r = fread(&header.mBlockLength,sizeof(header.mBlockLength),1,fph); // read the length of the block
				header.mFileOffset = (uint32_t)ftell(fph);
				if ( r == 1 )
				{
					assert( header.mBlockLength < MAX_BLOCK_SIZE ); // make sure the block length does not exceed our maximum expected ever possible block size
					if ( header.mBlockLength < MAX_BLOCK_SIZE )
					{
						r = fread(&prefix,sizeof(prefix),1,fph); // read the rest of the block (less the 8 byte header we have already consumed)
						if ( r == 1 )
						{
							Hash256 *blockHash = static_cast< Hash256 *>(&header);
							memcpy(header.mPreviousBlockHash,prefix.mPreviousBlock,32);
							BLOCKCHAIN_SHA256::computeSHA256((uint8_t *)&prefix,sizeof(prefix),(uint8_t *)blockHash);
							BLOCKCHAIN_SHA256::computeSHA256((uint8_t *)blockHash,32,(uint8_t *)blockHash);
							uint32_t currentFileOffset = ftell(fph); // get the current file offset.
							uint32_t advance = header.mBlockLength - sizeof(BlockPrefix);
							currentFileOffset+=advance;
							fseek(fph,currentFileOffset,SEEK_SET); // skip past the block to get to the next header.
							mLastBlockHeader = mBlockHeaderMap.insert(header);
							ok = true;
						}
					}
				}
			}
		}
		return ok;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x100(%rbp)
movb $0x0, -0x9(%rbp)
movl 0x1208(%rax), %ecx
movq 0x208(%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x22669
movl $0x0, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2030
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rcx
leaq -0x1c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x222f3
movq -0x100(%rbp), %rdi
movl 0x1208(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x1208(%rdi)
callq 0x1a5e0
testb $0x1, %al
jne 0x222b1
jmp 0x222f1
movq -0x100(%rbp), %rax
movl 0x1208(%rax), %ecx
movq 0x208(%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rcx
leaq -0x1c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2030
movl %eax, -0x20(%rbp)
jmp 0x222f3
cmpq $0x1, -0x28(%rbp)
jne 0x224c7
cmpl $0xd9b4bef9, -0x1c(%rbp) # imm = 0xD9B4BEF9
je 0x224c7
movq -0x18(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2170
leaq 0x102b4(%rip), %rdi     # 0x325d6
movb $0x0, %al
callq 0x2050
movl $0xa00000, %edi         # imm = 0xA00000
callq 0x21e0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0xa00000, %edx         # imm = 0xA00000
callq 0x20b0
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rcx
movl $0x1, %esi
movl $0xa00000, %edx         # imm = 0xA00000
callq 0x2220
movl %eax, -0x34(%rbp)
movb $0x0, -0x35(%rbp)
cmpl $0x0, -0x34(%rbp)
jbe 0x223cb
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jae 0x223c9
movq -0x30(%rbp), %rax
movl -0x3c(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpl $0xd9b4bef9, (%rax)     # imm = 0xD9B4BEF9
jne 0x223bc
movl -0x3c(%rbp), %edi
callq 0x19c20
movq %rax, %rsi
leaq 0x10268(%rip), %rdi     # 0x3260e
movb $0x0, %al
callq 0x2050
movl -0x3c(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movb $0x1, -0x35(%rbp)
jmp 0x223c9
jmp 0x223be
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x22372
jmp 0x223cb
movq -0x30(%rbp), %rdi
callq 0x21a0
testb $0x1, -0x35(%rbp)
je 0x22431
movq -0x18(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2170
movq -0x18(%rbp), %rcx
leaq -0x1c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
cmpl $0xd9b4bef9, -0x1c(%rbp) # imm = 0xD9B4BEF9
jne 0x22410
jmp 0x2242f
leaq 0x10243(%rip), %rdi     # 0x3265a
leaq 0xe832(%rip), %rsi      # 0x30c50
movl $0x139f, %edx           # imm = 0x139F
leaq 0x10244(%rip), %rcx     # 0x3266e
callq 0x20c0
jmp 0x22431
testb $0x1, -0x35(%rbp)
je 0x2243c
jmp 0x224c5
movq -0x100(%rbp), %rdi
movl 0x1208(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x1208(%rdi)
callq 0x1a5e0
testb $0x1, %al
jne 0x2245d
jmp 0x224bb
movq -0x100(%rbp), %rax
movl 0x1208(%rax), %ecx
movq 0x208(%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rcx
leaq -0x1c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
cmpq $0x1, -0x28(%rbp)
jne 0x224b9
cmpl $0xd9b4bef9, -0x1c(%rbp) # imm = 0xD9B4BEF9
je 0x224b7
leaq 0x101ed(%rip), %rdi     # 0x32695
movb $0x0, %al
callq 0x2050
movq $0x0, -0x28(%rbp)
jmp 0x224b9
jmp 0x224c3
movq $0x0, -0x28(%rbp)
jmp 0x224c5
jmp 0x224c7
cmpq $0x1, -0x28(%rbp)
jne 0x22667
leaq -0x98(%rbp), %rdi
callq 0x22680
movq -0x100(%rbp), %rax
movl 0x1208(%rax), %eax
movl %eax, -0x78(%rbp)
leaq -0x98(%rbp), %rdi
addq $0x28, %rdi
movq -0x18(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2030
movl %eax, -0x74(%rbp)
cmpq $0x1, -0x28(%rbp)
jne 0x22665
cmpl $0xa00000, -0x70(%rbp)  # imm = 0xA00000
jae 0x22532
jmp 0x22551
leaq 0x101cb(%rip), %rdi     # 0x32704
leaq 0xe710(%rip), %rsi      # 0x30c50
movl $0x13c4, %edx           # imm = 0x13C4
leaq 0x10122(%rip), %rcx     # 0x3266e
callq 0x20c0
cmpl $0xa00000, -0x70(%rbp)  # imm = 0xA00000
jae 0x22663
movq -0x18(%rbp), %rcx
leaq -0xe8(%rbp), %rdi
movl $0x50, %esi
movl $0x1, %edx
callq 0x2220
movq %rax, -0x28(%rbp)
cmpq $0x1, -0x28(%rbp)
jne 0x22661
leaq -0x98(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xe4(%rbp), %rax
movq %rax, -0x6c(%rbp)
movq -0xdc(%rbp), %rax
movq %rax, -0x64(%rbp)
movq -0xd4(%rbp), %rax
movq %rax, -0x5c(%rbp)
movq -0xcc(%rbp), %rax
movq %rax, -0x54(%rbp)
movq -0xf0(%rbp), %rdx
leaq -0xe8(%rbp), %rdi
movl $0x50, %esi
callq 0x186b0
movq -0xf0(%rbp), %rdi
movq -0xf0(%rbp), %rdx
movl $0x20, %esi
callq 0x186b0
movq -0x18(%rbp), %rdi
callq 0x2030
movl %eax, -0xf4(%rbp)
movl -0x70(%rbp), %eax
subq $0x50, %rax
movl %eax, -0xf8(%rbp)
movl -0xf8(%rbp), %eax
addl -0xf4(%rbp), %eax
movl %eax, -0xf4(%rbp)
movq -0x18(%rbp), %rdi
movl -0xf4(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2170
movq -0x100(%rbp), %rdi
addq $0x36f1328, %rdi        # imm = 0x36F1328
leaq -0x98(%rbp), %rsi
callq 0x226c0
movq %rax, %rcx
movq -0x100(%rbp), %rax
movq %rcx, 0x36f1318(%rax)
movb $0x1, -0x9(%rbp)
jmp 0x22663
jmp 0x22665
jmp 0x22667
jmp 0x22669
movb -0x9(%rbp), %al
andb $0x1, %al
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw (%rax,%rax)