import binascii import logging import time from broadcast import Broadcast from direct import Direct from commands import BROADCAST from commands import DIRECT class OrderBuffer(object): def __init__(self, state): self.buffer = {} self.state = state def add(self, message): ts = time.time() if message['command'] == BROADCAST: m = Broadcast(message, self.state) assert(m.message_hash == message['message_hash']) elif message['command'] == DIRECT: m = Direct(message, self.state) else: return if self.buffer.get(ts) is None: self.buffer[ts] = [m] else: self.buffer[ts].append(m) def expects(self, message_hash): for value in self.buffer.values(): for message in value: if message_hash == message.self_chain: return True elif message_hash == message.net_chain: return True return False def dequeue_and_order_mature_messages(self): current_time = time.time() sorted_messages = sorted(self.buffer.keys()) mature_messages = [] for timestamp in sorted_messages: if timestamp < current_time - int(self.state.get_knob('order_buffer_expiration_seconds')): for message in self.buffer[timestamp]: mature_messages.append(message) del self.buffer[timestamp] return sorted(mature_messages, key=lambda m: m.timestamp)