// File: /workspace/github_cpp_makefile_star2_O2/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 0x2230
movq %rax, %r15
leaq 0x78(%r14), %rsi
pushq $0x1
popq %rdx
movq %rbx, %rdi
callq 0x2190
movl 0x78(%r14), %eax
decl %eax
cmpl $0x2, %eax
jae 0x2e0b
movq %rbx, %rdi
callq 0x3c02
testl %eax, %eax
js 0x2dec
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x3910
testl %eax, %eax
js 0x2dec
movq %rbx, %rdi
movl $0xff, %esi
callq 0x3910
testl %eax, %eax
js 0x2dec
movq %rbx, %rdi
callq 0x3c02
testl %eax, %eax
js 0x2dec
leaq -0x40(%rbp), %rsi
movq %rbx, %rdi
callq 0x3ad4
testl %eax, %eax
js 0x2e3c
pushq $-0x1
popq %r13
pushq $0x2
popq %r12
incq %r13
cmpq %r13, -0x40(%rbp)
jbe 0x2e4c
movq %rbx, %rdi
callq 0x3c02
testl %eax, %eax
js 0x2dec
movq %rbx, %rdi
movl %r12d, %esi
callq 0x3910
testl %eax, %eax
js 0x2dec
movq %rbx, %rdi
pushq $0x20
popq %rsi
callq 0x3c9f
cmpl $0x20, %eax
je 0x2db4
movq 0x51fd(%rip), %rdi      # 0x7ff0
leaq 0x24f9(%rip), %rsi      # 0x52f3
callq 0x2120
movq %rax, %rdi
callq 0x20a0
pushq $-0x2
jmp 0x2e28
movq 0x51de(%rip), %rdi      # 0x7ff0
leaq 0x24a9(%rip), %rsi      # 0x52c2
callq 0x2120
movq %rax, %rdi
callq 0x20a0
pushq $-0x1
popq %r12
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x51ad(%rip), %rdi      # 0x7ff0
leaq 0x24d4(%rip), %rsi      # 0x531e
jmp 0x2dfa
leaq -0x38(%rbp), %rsi
movq %rbx, %rdi
callq 0x3ad4
testl %eax, %eax
js 0x2ed5
movl -0x38(%rbp), %esi
movq %rbx, %rdi
callq 0x3c9f
cmpl -0x38(%rbp), %eax
jne 0x2ede
movq %rbx, %rdi
callq 0x2230
movq %rax, %r13
xorl %r12d, %r12d
movq %rbx, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x21a0
subq %r15, %r13
leaq 0x60(%r14), %rdi
leaq -0x29(%rbp), %rdx
movb $0x0, (%rdx)
movq %r13, %rsi
callq 0x31dc
movq 0x60(%r14), %rsi
movq %rbx, %rdi
movq %r13, %rdx
callq 0x2190
cmpl $0x2, 0x78(%r14)
jne 0x2e2a
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3910
testl %eax, %eax
je 0x2e2a
leaq 0x2420(%rip), %rsi      # 0x52f3
jmp 0x2ee5
leaq 0x2483(%rip), %rsi      # 0x535f
jmp 0x2ee5
leaq 0x24af(%rip), %rsi      # 0x5394
movq 0x5104(%rip), %rdi      # 0x7ff0
jmp 0x2dfa
nop