// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movq %rsi, %rdi
callq 0x2210
movq %rax, %r15
leaq 0x78(%r14), %rsi
movl $0x1, %edx
movq %rbx, %rdi
callq 0x2180
movl 0x78(%r14), %eax
decl %eax
cmpl $0x2, %eax
jae 0x3323
movq %rbx, %rdi
callq 0x43ac
testl %eax, %eax
js 0x336d
movq %rbx, %rdi
movl $0x1, %esi
callq 0x3f60
testl %eax, %eax
js 0x336d
movq %rbx, %rdi
movl $0xff, %esi
callq 0x3f60
testl %eax, %eax
js 0x336d
movq %rbx, %rdi
callq 0x43ac
testl %eax, %eax
js 0x336d
leaq -0x40(%rbp), %rsi
movq %rbx, %rdi
callq 0x41d2
testl %eax, %eax
js 0x33c7
cmpq $0x0, -0x40(%rbp)
je 0x3288
xorl %r12d, %r12d
movq %rbx, %rdi
callq 0x43ac
testl %eax, %eax
js 0x336d
movq %rbx, %rdi
movl $0x2, %esi
callq 0x3f60
testl %eax, %eax
js 0x336d
movq %rbx, %rdi
movl $0x20, %esi
callq 0x4487
cmpl $0x20, %eax
jne 0x336d
incq %r12
cmpq %r12, -0x40(%rbp)
ja 0x3244
leaq -0x38(%rbp), %rsi
movq %rbx, %rdi
callq 0x41d2
testl %eax, %eax
js 0x33dc
movl -0x38(%rbp), %esi
movq %rbx, %rdi
callq 0x4487
cmpl -0x38(%rbp), %eax
jne 0x33f1
movq %rbx, %rdi
callq 0x2210
movq %rax, %r13
xorl %r12d, %r12d
movq %rbx, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x2190
subq %r15, %r13
leaq 0x60(%r14), %rdi
leaq -0x29(%rbp), %rdx
movb $0x0, (%rdx)
movq %r13, %rsi
callq 0x37be
movq 0x60(%r14), %rsi
movq %rbx, %rdi
movq %r13, %rdx
callq 0x2180
cmpl $0x2, 0x78(%r14)
jne 0x33b5
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3f60
testl %eax, %eax
je 0x33b5
movq 0x4cd9(%rip), %rdi      # 0x7ff0
leaq 0x2020(%rip), %rsi      # 0x533e
jmp 0x33ff
movq 0x4cc6(%rip), %rbx      # 0x7ff0
leaq 0x1fdc(%rip), %rsi      # 0x530d
movl $0x30, %edx
movq %rbx, %rdi
callq 0x2160
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20d0
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
jmp 0x33b5
movq 0x4c7c(%rip), %rbx      # 0x7ff0
leaq 0x1fc3(%rip), %rsi      # 0x533e
movl $0x2a, %edx
movq %rbx, %rdi
callq 0x2160
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20d0
movl $0xfffffffe, %r12d      # imm = 0xFFFFFFFE
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x4c22(%rip), %rbx      # 0x7ff0
leaq 0x1f94(%rip), %rsi      # 0x5369
movl $0x40, %edx
jmp 0x3380
movq 0x4c0d(%rip), %rdi      # 0x7ff0
leaq 0x1fc0(%rip), %rsi      # 0x53aa
movl $0x34, %edx
jmp 0x3404
movq 0x4bf8(%rip), %rdi      # 0x7ff0
leaq 0x1fe0(%rip), %rsi      # 0x53df
movl $0x2a, %edx
callq 0x2160
movq 0x4be0(%rip), %rdi      # 0x7ff0
callq 0x2090
jmp 0x33af
nop