Ejemplo n.º 1
0
 def __init__(self, socket=None, logstats=True):
     """ Socket may be provided when in the context of a threaded TCP Server.
     """
     self.protocmd = commands_pb2.Command()
     self.protomsg = commands_pb2.Command()
     self.logstats = logstats
     self.socket = socket
     if socket:
         self.connected = True
         self.peer_ip = socket.getpeername()[0]
         if logstats:
             self.stats[STATS_COSINCE] = time.time()
Ejemplo n.º 2
0
	def __init__(self, version=-1, socket = None, logstats= True):
		""" Default version is -1, will auto detect if needed on first receive
		Socket may be provided when in the context of a threaded TCP Server.
		"""
		self.version = version
		self.protocmd = commands_pb2.Command()
		self.protomsg = commands_pb2.Command()
		self.logstats = logstats
		self.socket = socket
		if socket:
			self.connected = True
			self.peer_ip = socket.getpeername()[0]
			if logstats:
				self.stats[STATS_COSINCE] = time.time()
Ejemplo n.º 3
0
async def async_receive(stream, ip, timeout=-1):
    """
    Get a command block from the stream, async version

    :param stream:
    :param ip: the related ip, for stats purposes
    :param timeout: timeout for getting answer
    :return: a protobuf object
    """
    global MY_NODE
    protomsg = commands_pb2.Command()
    # TODO: add some timeout here
    if timeout == -1:
        header = await stream.read_bytes(4)
    else:
        header = await tornado.gen.with_timeout(datetime.timedelta(seconds=timeout), stream.read_bytes(4))
    if len(header) < 4:
        raise RuntimeError("Socket EOF")
    data_len = struct.unpack('>i', header[:4])[0]
    # TODO: and here (depending on size?)
    if timeout == -1:
        data = await stream.read_bytes(data_len)
    else:
        data = await tornado.gen.with_timeout(datetime.timedelta(seconds=timeout), stream.read_bytes(data_len))
    try:
        MY_NODE.clients[ip]['stats'][STATS_LASTACT] = time.time()
        MY_NODE.clients[ip]['stats'][STATS_MSGRECV] += 1
        MY_NODE.clients[ip]['stats'][STATS_BYTRECV] += 4 + data_len
    except:
        pass
    protomsg.ParseFromString(data)
    return protomsg
Ejemplo n.º 4
0
    async def async_getblock(self, a_height):
        """
        Command id 14
        returns the block of the given height.

        :param a_height: int
        :return: protocmd with the block if exists or None
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.getblock

            block = await self.async_fetchone(SQL_HEIGHT_BLOCK, (a_height,), as_dict=True)
            if not block:
                return protocmd
            block = PosBlock().from_dict(dict(block))
            # Add the block txs
            txs = await self.async_fetchall(SQL_TXS_FOR_HEIGHT, (block.height,))
            for tx in txs:
                tx = PosMessage().from_dict(dict(tx))
                block.txs.append(tx)
            block.add_to_proto(protocmd)
            return protocmd

        except Exception as e:
            self.app_log.error("SRV: async_getblock: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 5
0
    async def async_gettx(self, params):
        """
        Command id 16
        returns the tx or empty protocmd.

        :param params: str: a transaction signature
        :return: protocmd with the tx or None
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.gettx
            txid = poscrypto.hex_to_raw(str(params))
            tx = await self.async_fetchone(SQL_TX_FOR_TXID, (sqlite3.Binary(txid),), as_dict=True)
            if tx:
                tx = PosMessage().from_dict(dict(tx))
                tx.add_to_proto(protocmd)
            return protocmd

        except Exception as e:
            self.app_log.error("SRV: async_gettx: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 6
0
    async def async_getheaders(self, param):
        """
        Async. Return 20 latest block headers.

        :param param: (string) empty: last 20 blocks headers. start_height,count or ,count (last N headers)
        :return:
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.getheaders
            if param is None or param == 'None':
                param = ''
            if param == '':
                blocks = await self.async_fetchall(SQL_BLOCKS_LAST, (config.BLOCK_SYNC_COUNT,))
            else:
                start, count = param.split(',')
                if '' == start:
                    blocks = await self.async_fetchall(SQL_BLOCKS_LAST, (count,))
                else:
                    blocks = await self.async_fetchall(SQL_BLOCKS_SYNC, (start, count))
            for block in blocks:
                block = PosBlock().from_dict(dict(block))
                block.add_to_proto(protocmd)
            return protocmd
        except Exception as e:
            self.app_log.error("SRV: async_getheaders: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 7
0
 def __init__(self, socket=None, logstats=True):
     """ Socket may be provided when in the context of a threaded TCP Server.
     """
     # cmd : from us to peer
     self.protocmd = commands_pb2.Command()
     # msg : from peer to us
     self.protomsg = commands_pb2.Command()
     self.logstats = logstats
     self.socket = socket
     self.peer_ip = ''
     self.connected = False
     # first 4 bytes allow to ID the protocol version, it's the message len on 4 bytes.
     self.first_bytes = []
     # connection stats
     self.stats = [0, 0, 0, 0, 0]
     # last socket activity
     self.last_activity = 0
     if socket:
         self.connected = True
         self.peer_ip = socket.getpeername()[0]
         if logstats:
             self.stats[STATS_COSINCE] = time.time()
Ejemplo n.º 8
0
async def async_send_void(cmd, stream, ip):
    """
    Sends a command to the stream, async.

    :param cmd: the protobuff command
    :param stream:
    :param ip: the related ip, for stats purposes
    :return: none
    """
    protocmd = commands_pb2.Command()
    protocmd.Clear()
    protocmd.command = cmd
    await async_send(protocmd, stream, ip)
Ejemplo n.º 9
0
    async def async_getaddtxs(self, params):
        """
        Command id 15
        returns a list of txs.

        :param params: str: an address or address,extra
        :return: protocmd with the txs list or None
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.getaddtxs
            if ',' not in params:
                # address only
                txs = await self.async_fetchall(SQL_TXS_FOR_ADDRESS,
                                                (params, params))
            else:
                address, option = params.split(',')
                if len(option) < 10:
                    # Say this is a block height
                    option = int(option)
                    txs = await self.async_fetchall(
                        SQL_TXS_FOR_ADDRESS_FROM_HEIGHT,
                        (address, address, option))
                else:
                    # consider as a tx signature
                    # FR: not sure this param useful after all
                    option = poscrypto.hex_to_raw(str(option))
                    # Get the height of the given signature
                    tx = await self.async_fetchone(SQL_TX_FOR_TXID,
                                                   (sqlite3.Binary(option), ),
                                                   as_dict=True)
                    # Then the following txs
                    txs = await self.async_fetchall(
                        SQL_TXS_FOR_ADDRESS_FROM_HEIGHT,
                        (address, address, tx.get('block_height')))
            # Fill the protobuf in
            for tx in txs:
                tx = PosMessage().from_dict(dict(tx))
                tx.add_to_proto(protocmd)

            return protocmd

        except Exception as e:
            self.app_log.error("SRV: async_getaddtxs: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(
                exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 10
0
async def async_send_int32(cmd, value, stream, ip):
    """
    Sends a command with int32 param to the stream, async.

    :param cmd: the protobuff command
    :param value:
    :param stream:
    :param ip: the related ip, for stats purposes
    :return: none
    """
    protocmd = commands_pb2.Command()
    protocmd.Clear()
    protocmd.command = cmd
    protocmd.int32_value = value
    await async_send(protocmd, stream, ip)
Ejemplo n.º 11
0
async def async_send_height(cmd, height, stream, ip):
    """
    Sends a height status to the stream, async.

    :param cmd: the protobuff command
    :param height: a PosHeight object
    :param stream:
    :param ip: the related ip, for stats purposes
    :return: none
    """
    protocmd = commands_pb2.Command()
    protocmd.Clear()
    protocmd.command = cmd
    height.to_proto(protocmd.height_value)
    await async_send(protocmd, stream, ip)
Ejemplo n.º 12
0
async def async_send_txs(cmd, txs, stream, ip):
    """
    Sends a list of tx to the stream, async.

    :param cmd: the protobuff command
    :param txs: a list of tx
    :param stream:
    :param ip: the related ip, for stats purposes
    :return: none
    """
    protocmd = commands_pb2.Command()
    protocmd.Clear()
    protocmd.command = cmd
    for tx in txs:
        tx.add_to_proto(protocmd)
    await async_send(protocmd, stream, ip)
Ejemplo n.º 13
0
    async def async_roundblocks(self, a_round):
        """
        Command id 13
        returns all blocks of the given round.

        FR: Harmonize. this one needs a proto as output (proto command with list of blocks)

        :param a_round:
        :return: protocmd with all blocks
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.roundblocks

            blocks = await self.async_fetchall(SQL_ROUND_BLOCKS, (a_round, ))
            for block in blocks:
                block = PosBlock().from_dict(dict(block))
                # Add the block txs
                txs = await self.async_fetchall(SQL_TXS_FOR_HEIGHT,
                                                (block.height, ))
                for tx in txs:
                    tx = PosMessage().from_dict(dict(tx))
                    block.txs.append(tx)
                block.add_to_proto(protocmd)
                # check block integrity
                if len(txs) != block.msg_count:
                    self.app_log.error(
                        "Only {} tx for block {} instead of {} announced".
                        format(len(txs), block.height, block.msg_count))
                    com_helpers.MY_NODE.stop()

            return protocmd

        except Exception as e:
            self.app_log.error("SRV: async_roundblocks: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(
                exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 14
0
    def to_proto(self):
        """
        Create a protobuf object from current native format.

        :return: a protobuf object.
        """
        protocmd = commands_pb2.Command()
        protocmd.Clear()
        protocmd.command = commands_pb2.Command.block
        block = protocmd.block_value.add(
        )  # protocmd.block_value  # commands_pb2.Block()
        block.height, block.round, block.sir = self.height, self.round, self.sir
        block.ts, block.previous_hash = self.timestamp, self.previous_hash
        for tx in self.txs:
            tx.add_to_proto_block(block)
        # todo: unify sources / names
        block.msg_count, block.sources = self.msg_count, self.uniques_sources
        block.signature, block.block_hash = self.signature, self.block_hash
        block.forger = self.forger
        # protocmd.block_value = block
        return protocmd
Ejemplo n.º 15
0
    async def async_blocksync(self, height):
        """
        returns N blocks starting with the given height.

        FR: Harmonize. this one needs a proto as output (proto command with list of blocks)

        :param height:
        :return:
        """
        try:
            protocmd = commands_pb2.Command()
            protocmd.Clear()
            protocmd.command = commands_pb2.Command.blocksync

            blocks = await self.async_fetchall(
                SQL_BLOCKS_SYNC, (height, config.BLOCK_SYNC_COUNT))
            for block in blocks:
                block = PosBlock().from_dict(dict(block))
                # Add the block txs
                txs = await self.async_fetchall(SQL_TXS_FOR_HEIGHT,
                                                (block.height, ))
                for tx in txs:
                    tx = PosMessage().from_dict(dict(tx))
                    block.txs.append(tx)
                # check block integrity
                if len(txs) != block.msg_count:
                    self.app_log.error(
                        "Only {} tx for block {} instead of {} announced".
                        format(len(txs), height, block.msg_count))
                    com_helpers.MY_NODE.stop()
                block.add_to_proto(protocmd)
            #print(protocmd)
            return protocmd
        except Exception as e:
            self.app_log.error("SRV: async_blocksync: Error {}".format(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            self.app_log.error('detail {} {} {}'.format(
                exc_type, fname, exc_tb.tb_lineno))
            raise
Ejemplo n.º 16
0
    def command(name, **kwargs):
        """
        Creates a protobuf command to be inserted into a transaction
        :param name: CamelCased name of command
        :param kwargs: command arguments as they defined in schema
        :return: a proto command

        Usage example:
        cmd = Iroha.command('CreateDomain', domain_id='test', default_role='user')
        """
        command_wrapper = commands_pb2.Command()
        field_name = Iroha._camel_case_to_snake_case(name)
        internal_command = getattr(command_wrapper, field_name)
        for key, value in kwargs.items():
            if 'permissions' == key:
                permissions_attr = getattr(internal_command, key)
                permissions_attr.extend(value)
                continue
            if 'peer' == key:
                peer_attr = getattr(internal_command, key)
                peer_attr.CopyFrom(value)
                continue
            setattr(internal_command, key, value)
        return command_wrapper
Ejemplo n.º 17
0
def main():
    print "Creating new testing server"
    host = '127.0.0.1'
    port = 15000
    server = socket.socket()
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((host, port))
    server.listen(1)
    conn, addr = server.accept()

    print "New connection from {}".format(addr)
    while (True):
        data = conn.recv(4)  # read in 4 byte length
        if (not data):
            break
        data_len, = struct.unpack('!i', data)
        print "Attempting to read {} bytes".format(data_len)
        data = conn.recv(data_len)
        if (not data):
            break
        command = commands_pb2.Command()
        command.ParseFromString(data)
        print "Data: {}".format(command)
    server.close()
Ejemplo n.º 18
0
 def valid_add_peer_command(self):
   command = cmd.Command()
   command.add_peer.peer.address = "127.0.0.1:50500"
   command.add_peer.peer.peer_key = b'A' * 32
   return command
Ejemplo n.º 19
0
def run_joystick(server, name):
    logging.info("Running joystick mode")
    pygame.init()
    joystick = None
    stretch_mode = False
    sock = None
    port = 15000

    modes = ["Trot", "Crawl", "Creep"]

    command = commands_pb2.Command()
    command.cmd = Cmds.STOP
    command.gait = Mode.TROT

    joystick_count = pygame.joystick.get_count()
    if (joystick_count == 0):
        logging.error("No joystick detected")
        logging.error("Check that one is plugged in or run with --keyboard")
        return
    elif (joystick_count == 1):
        joystick = pygame.joystick.Joystick(0)
        joystick.init()
    else:
        logging.error("To many joysticks detected")
        return

    if (joystick == None):
        loggign.critical("Failed to locate a valid joystick")
        return
    done = False

    pygame.time.set_timer(USEREVENT + 1, 100)

    if (server != None):
        logging.info("Connecting to server {}".format(server))
        sock = socket.socket()
        sock.connect((server, port))
        if (not sock):
            logging.error("Failed to connect to {}:{}".format(server, port))
            return

    while (done != True):
        for event in pygame.event.get():
            if (event.type == pygame.QUIT):
                done = True
            '''
                We have a button pressed, we must handle each button on it's own
                There is currently only two buttons we care about. The trigger,
                which will enter stretch mode when pressed, and the auxilary 11,
                which will quit the program.
            '''
            if (event.type == pygame.JOYBUTTONDOWN):
                if (event.button == Buttons.TRIGGER
                        and command.cmd == Cmds.STOP):
                    stretch_mode = True
                    command.cmd = Cmds.STRETCH
                elif (event.button == Buttons.AUX11):
                    command.cmd = Cmds.QUIT
                    done = True
                elif (event.button == Buttons.AUX02):
                    ''' Cycle Gait down'''
                    if (command.gait == Mode.TROT):
                        command.gait = Mode.CREEP
                    else:
                        command.gait -= 1
                    logging.info("Setting gait to: {0}".format(
                        modes[command.gait]))
                elif (event.button == Buttons.AUX03):
                    ''' Cycle gait up '''
                    if (command.gait == Mode.CREEP):
                        command.gait = Mode.TROT
                    else:
                        command.gait += 1
                    logging.info("Setting gait to: {0}".format(
                        modes[command.gait]))
                elif (event.button == Buttons.AUX06):
                    command.cmd = Cmds.STAND
                elif (event.button == Buttons.AUX07):
                    command.cmd = Cmds.PARK
                else:
                    logging.warning(
                        "Unhandled button down event: {0}".format(event))
            '''
                We have a button released, and like the button press, handle each
                button on it's own.  Trigger release will indicate exiting stretch
                mode. Should leaving stretch mode recenter the body?
            '''
            if (event.type == pygame.JOYBUTTONUP):
                if (event.button == Buttons.TRIGGER
                        or event.button == Buttons.AUX06
                        or event.button == Buttons.AUX07):
                    stretch_mode = False
                    command.cmd = Cmds.STOP
                    command.roll = 0.0
                    command.pitch = 0.0
                    command.yaw = 0.0
                    command.delta_x = 0
                    command.delta_y = 0
                elif (event.button == Buttons.AUX02
                      or event.button == Buttons.AUX03):
                    pass
                else:
                    logging.warning(
                        "Unhandled button up event: {0}".format(event))
            '''
                We have an axis motion event. This indicates one of the joystick
                axes have changed position. Can become quite jittery, and need
                to look into having some kind of jitter filter.

                If we are in stretch mode, the PITCH, ROLL, and YAW axes will
                correspond to rotating the body up to a max/min of 30 degrees.
                The aux axis currently has no usage.

                If we are in normal mode, th PITCH and ROLL will be used to
                calculate a vector on which the robot should walk. And the YAW
                axis will be used to send TURN commands.
            '''
            if (event.type == pygame.JOYAXISMOTION):
                if (stretch_mode):
                    if (event.axis == Axis.ROLL):
                        command.roll = interp(event.value, [-1.0, 1.0],
                                              [-30.0, 30.0])
                    if (event.axis == Axis.PITCH):
                        command.pitch = interp(event.value, [-1.0, 1.0],
                                               [-30.0, 30.0])
                    if (event.axis == Axis.YAW):
                        command.yaw = interp(event.value, [-1.0, 1.0],
                                             [-30.0, 30.0])
                else:
                    ''' This is where we would create the walk vector, or the turn event '''
                    if (event.axis == Axis.PITCH and command.cmd != Cmds.TURN):
                        if (event.value > 0.5):
                            command.cmd = Cmds.WALK
                            command.dir = Dir.BACKWARD
                        elif (event.value < -0.5):
                            command.cmd = Cmds.WALK
                            command.dir = Dir.FORWARD
                        else:
                            command.cmd = Cmds.STOP
                    if (event.axis == Axis.YAW and command.cmd != Cmds.WALK):
                        if (event.value > 0.5):
                            command.cmd = Cmds.TURN
                            command.dir = Dir.RIGHT
                        elif (event.value < -0.5):
                            command.cmd = Cmds.TURN
                            command.dir = Dir.LEFT
                        else:
                            command.cmd = Cmds.STOP
            '''
                The hat on top of joystick has moved.  If in stretch mode, this
                will perform a translation. Normal mode will have no affect at
                this time.

            '''
            if (event.type == pygame.JOYHATMOTION):
                if (stretch_mode):
                    command.delta_x = event.value[0]
                    command.delta_y = event.value[1]
            '''
                This is a timer event set to trigger 10 times every second. The
                idea being that we won't spam the server with commands everytime
                the joystick moves. Still considering if this is a valid solution
                or if we should just accept the XTREME traffic.
            '''
            if (event.type == USEREVENT + 1):
                send_command(sock, command)

    # Send the one final command
    send_command(sock, command)

    if (sock != None):
        logging.info("Closing connection to server")
        sock.close()
    pygame.quit()
Ejemplo n.º 20
0
import time, json
import ipaddress
import commands_pb2

bcommand = commands_pb2.Command()
bcommand.command = commands_pb2.Command.sendsync

# Simple command
serial = bcommand.SerializeToString()
print("sendsync", len(serial), serial)

# List of ips (peers)
test_ip = "127.0.0.1"
bcommand.command = commands_pb2.Command.peers
ip = bcommand.ips.add()
ip.ipv4 = int(ipaddress.ip_address(test_ip))
serial = bcommand.SerializeToString()
print("ipv4", len(serial), serial)

ip.port = 6060
serial = bcommand.SerializeToString()
print("ipv4+port", len(serial), serial)

bcommand = commands_pb2.Command()
bcommand.command = commands_pb2.Command.peers
for i in range(100):
    ip = bcommand.ips.add()
    ip.ipv4 = int(ipaddress.ip_address('127.0.0.' + str(i)))
serial = bcommand.SerializeToString()
print("100 ipv4", len(serial), serial)