// File: nvanbenschoten[P]byzantine-agreement/src/general.cc
// Function: generals::Lieutenant::ValidMessage(msg::Message const&, net::Address const&) const
bool Lieutenant::ValidMessage(const msg::Message& msg,
                              const net::Address& from) const {
  // Invalid if the message is from a later round.
  if (msg.round > round_) {
    return false;
  }
  // Invalid if the message has an incorrect number of ids.
  if (msg.round + 1 != msg.ids.size()) {
    return false;
  }
  // Invalid if the first message is not from the General (pid 0);
  if (msg.ids.at(0) != 0) {
    return false;
  }
  // Invalid if not all ids are unique.
  std::set<unsigned int> idset;
  for (auto const& id : msg.ids) {
    // Invalid if any id is out of bounds.
    if (id >= processes_.size()) {
      return false;
    }
    // Invalid if any id is our id.
    if (id == id_) {
      return false;
    }
    idset.insert(id);
  }
  if (idset.size() < msg.ids.size()) {
    return false;
  }
  // Invalid if the last id does not match the sender. This check will not
  // be complete for processes on the same host, because we can not know the
  // sending port of the process, only its receiving port.
  if (processes_.at(msg.ids.back()).hostname() != from.hostname()) {
    return false;
  }
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0xa0(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
cmpl 0x64(%rcx), %eax
jbe 0x27056
movb $0x0, -0x1(%rbp)
jmp 0x27292
movq -0x18(%rbp), %rax
movl (%rax), %eax
addl $0x1, %eax
movl %eax, %eax
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x25170
movq %rax, %rcx
movq -0xa8(%rbp), %rax
cmpq %rcx, %rax
je 0x2708d
movb $0x0, -0x1(%rbp)
jmp 0x27292
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29fe0
cmpl $0x0, (%rax)
je 0x270ac
movb $0x0, -0x1(%rbp)
jmp 0x27292
leaq -0x50(%rbp), %rdi
callq 0x2a020
movq -0x18(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x25280
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
callq 0x252b0
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x2a040
testb $0x1, %al
jne 0x270f1
jmp 0x271bd
leaq -0x60(%rbp), %rdi
callq 0x2a080
movq -0xa0(%rbp), %rdi
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl (%rax), %eax
movq %rax, -0xb0(%rbp)
addq $0x8, %rdi
callq 0xcaf0
movq %rax, %rcx
movq -0xb0(%rbp), %rax
cmpq %rcx, %rax
jb 0x2713a
movb $0x0, -0x1(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x27289
movq -0xa0(%rbp), %rcx
movq -0x70(%rbp), %rax
movl (%rax), %eax
cmpl 0x58(%rcx), %eax
jne 0x2715c
movb $0x0, -0x1(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x27289
movq -0x70(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x2a0a0
movb %dl, -0xb9(%rbp)
movq %rax, -0xb8(%rbp)
jmp 0x27178
movb -0xb9(%rbp), %al
movq -0xb8(%rbp), %rcx
movq %rcx, -0x98(%rbp)
movb %al, -0x90(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x2a0f0
jmp 0x270db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x2a170
jmp 0x272a0
leaq -0x50(%rbp), %rdi
callq 0x2a110
movq %rax, -0xc8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x25170
movq %rax, %rcx
movq -0xc8(%rbp), %rax
cmpq %rcx, %rax
jae 0x271f9
movb $0x0, -0x1(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x27289
movq -0xa0(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x2a130
movq -0xd8(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xcbb0
movq %rax, -0xd0(%rbp)
jmp 0x27231
movq -0xd0(%rbp), %rdi
callq 0xcbf0
movq %rax, -0xe0(%rbp)
jmp 0x27246
movq -0x20(%rbp), %rdi
callq 0xcbf0
movq %rax, -0xe8(%rbp)
jmp 0x27258
movq -0xe8(%rbp), %rsi
movq -0xe0(%rbp), %rdi
callq 0xcb80
testb $0x1, %al
jne 0x27271
jmp 0x2727e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x27289
movb $0x1, -0x1(%rbp)
movl $0x1, -0x74(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x2a170
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xf0, %rsp
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x6750
nopl (%rax)