// File: adamjanovsky[P]PA193_test_parser_monero/src/block.cpp
// Function: Block::load_miner_tx(std::basic_ifstream<char, std::char_traits<char>>&)
int Block::load_miner_tx(ifstream & in) {
    long long start_pos = in.tellg();

    in.read((char *) & this->miner_tx_version, 1);
    if(this->miner_tx_version != 0x01 and this->miner_tx_version != 0x02) {
        std::cerr << "Transaction parser: Wrong version of transaction" << std::endl;
        return ERR_TRANS_CORRUPTED_FORMAT;
    }

    // read and store miner_tx version

    // Check initial stamps and the input transaction:
    // (1) Skip unlock varint
    // (2) Check that there is only one input transaction
    // (3) Check format of input transaction (0xff = tf_gen)
    // (4) Skip input transaction (one varint indicating height of the block)
    if(tools::skip_varint(in) < 0           or
       tools::expect_byte(in, 0x01) < 0     or
       tools::expect_byte(in, 0xff) < 0     or
       tools::skip_varint(in) < 0) {
        std::cerr << "Transaction parser: Invalid header format." << std::endl;
        return ERR_TRANS_PARSER_ERROR;
    }

    // Read number of output trans
    unsigned long tx_out_count;
    if (tools::read_varint(in, tx_out_count) < 0) {
        std::cerr << "Transaction parser: Could not read count of output transactions." << std::endl;
        return ERR_TRANS_PARSER_ERROR;
    }

    // Read all output trans
    for(int i = 0; i < tx_out_count; i++)
    {
        // Skip the output transaction:
        // (1) Amount varint
        // (2) Check the key tag (0x02)
        // (3) Skip the key
        if(tools::skip_varint(in) < 0           or
           tools::expect_byte(in, 0x02) < 0     or
           tools::skip_bytes(in, hash::HASH_SIZE) != hash::HASH_SIZE) {
            std::cerr << "Transaction parser: Invalid header format." << std::endl;
            return ERR_TRANS_PARSER_ERROR;
        }
    }

    // Get number of extras
    unsigned long int extras_count;
    if(tools::read_varint(in, extras_count) < 0)
    {
        std::cerr << "Transaction parser: failed to read number of extras." << std::endl;
        return ERR_TRANS_PARSER_ERROR;
    }

    // Skip the extras
    if(tools::skip_bytes(in, static_cast<unsigned int>(extras_count)) != static_cast<int>(extras_count))
    {
        std::cerr << "Transaction parser: Failed to skip extras." << std::endl;
        return ERR_TRANS_PARSER_ERROR;
    }

    // Get the position and calculate the complete length
    long long end_pos = in.tellg();
    in.seekg(start_pos);
    long long miner_tx_length = end_pos - start_pos;

    // Read the entire miner_tx to memory
    miner_tx_data.resize(miner_tx_length, 0x00);
    in.read(reinterpret_cast<char *>(&miner_tx_data[0]), miner_tx_length);

    // v2: skip one zero byte
    if(this->miner_tx_version == 2) {
        if(tools::expect_byte(in, 0x00)) {
            std::cerr << "Transaction parser: Invalid header format." << std::endl;
            return ERR_TRANS_PARSER_ERROR;
        }
    }

    return OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rdi
callq 0x22c0
movq %rax, -0x30(%rbp)
movq %rdx, -0x28(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x45c0
movq -0x88(%rbp), %rsi
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
addq $0x78, %rsi
movl $0x1, %edx
callq 0x21d0
movq -0x88(%rbp), %rax
cmpl $0x1, 0x78(%rax)
je 0x3a8d
movq -0x88(%rbp), %rax
cmpl $0x2, 0x78(%rax)
je 0x3a8d
movq 0x958a(%rip), %rdi      # 0xcff0
leaq 0x5857(%rip), %rsi      # 0x92c4
callq 0x2160
movq %rax, %rdi
movq 0x9544(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x3d37
movq -0x18(%rbp), %rdi
callq 0x7b90
cmpl $0x0, %eax
jl 0x3acf
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7790
cmpl $0x0, %eax
jl 0x3acf
movq -0x18(%rbp), %rdi
movl $0xff, %esi
callq 0x7790
cmpl $0x0, %eax
jl 0x3acf
movq -0x18(%rbp), %rdi
callq 0x7b90
cmpl $0x0, %eax
jge 0x3afd
movq 0x951a(%rip), %rdi      # 0xcff0
leaq 0x5818(%rip), %rsi      # 0x92f5
callq 0x2160
movq %rax, %rdi
movq 0x94d4(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
movq -0x18(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x79c0
cmpl $0x0, %eax
jge 0x3b3d
movq 0x94da(%rip), %rdi      # 0xcff0
leaq 0x5803(%rip), %rsi      # 0x9320
callq 0x2160
movq %rax, %rdi
movq 0x9494(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
movl $0x0, -0x3c(%rbp)
movslq -0x3c(%rbp), %rax
cmpq -0x38(%rbp), %rax
jae 0x3bbd
movq -0x18(%rbp), %rdi
callq 0x7b90
cmpl $0x0, %eax
jl 0x3b82
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x7790
cmpl $0x0, %eax
jl 0x3b82
movq -0x18(%rbp), %rdi
movl $0x20, %esi
callq 0x7c80
cmpl $0x20, %eax
je 0x3bb0
movq 0x9467(%rip), %rdi      # 0xcff0
leaq 0x5765(%rip), %rsi      # 0x92f5
callq 0x2160
movq %rax, %rdi
movq 0x9421(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
jmp 0x3bb2
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x3b44
movq -0x18(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x79c0
cmpl $0x0, %eax
jge 0x3bfd
movq 0x941a(%rip), %rdi      # 0xcff0
leaq 0x5784(%rip), %rsi      # 0x9361
callq 0x2160
movq %rax, %rdi
movq 0x93d4(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rax
movl %eax, %esi
callq 0x7c80
movq -0x48(%rbp), %rcx
cmpl %ecx, %eax
je 0x3c42
movq 0x93d5(%rip), %rdi      # 0xcff0
leaq 0x5774(%rip), %rsi      # 0x9396
callq 0x2160
movq %rax, %rdi
movq 0x938f(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
movq -0x18(%rbp), %rdi
callq 0x22c0
movq %rax, -0x60(%rbp)
movq %rdx, -0x58(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x45c0
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x4580
movq -0x98(%rbp), %rdi
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
callq 0x21e0
movq -0x88(%rbp), %rdi
movq -0x50(%rbp), %rax
subq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
addq $0x60, %rdi
movq -0x78(%rbp), %rsi
movb $0x0, -0x79(%rbp)
leaq -0x79(%rbp), %rdx
callq 0x45e0
movq -0x88(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0x90(%rbp)
addq $0x60, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4690
movq -0x90(%rbp), %rdi
movq %rax, %rsi
movq -0x78(%rbp), %rdx
callq 0x21d0
movq -0x88(%rbp), %rax
cmpl $0x2, 0x78(%rax)
jne 0x3d30
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x7790
cmpl $0x0, %eax
je 0x3d2e
movq 0x92e6(%rip), %rdi      # 0xcff0
leaq 0x55e4(%rip), %rsi      # 0x92f5
callq 0x2160
movq %rax, %rdi
movq 0x92a0(%rip), %rsi      # 0xcfc0
callq 0x2190
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x3d37
jmp 0x3d30
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)