Exemplo n.º 1
0
    def getheaders_message(self, connection, message):
        self.sync.lock.acquire()
        try:
            logging.debug('received getheaders message with {} headers from {}'
                          .format(len(message.locator.vHave), self.repr_connection(connection)))

            if connection.host[0] == self.private_ip:
                blocks = chainutil.respond_get_headers(self.chain.tips, BlockOrigin.private, message.locator.vHave, message.hashstop)
            else:
                blocks = chainutil.respond_get_headers(self.chain.tips, BlockOrigin.public, message.locator.vHave, message.hashstop)

            message = messages.msg_headers()
            message.headers = [core.CBlock(block.cblock.nVersion,
                                           block.cblock.hashPrevBlock,
                                           block.cblock.hashMerkleRoot,
                                           block.cblock.nTime,
                                           block.cblock.nBits,
                                           block.cblock.nNonce) for block in blocks]
            connection.send('headers', message)
            logging.debug('sent headers message with {} headers to {}'
                          .format(len(message.headers), self.repr_connection(connection)))
            if len(message.headers) > 0:
                logging.debug('sent headers with starting hash={}'.format(core.b2lx(message.headers[0].GetHash())))

        finally:
            self.sync.lock.release()
            logging.debug('processed getheaders message from {}'.format(self.repr_connection(connection)))
Exemplo n.º 2
0
    def test_headers_message_one_block_not_in_flight(self):
        header1 = CBlockHeader(nNonce=1)
        header2 = CBlockHeader(nNonce=2)
        message = messages.msg_headers()
        message.headers = [header1, header2]
        self.networking.blocks_in_flight = {header1.GetHash(): 'in_flight'}

        self.networking.headers_message(self.private_connection, message)

        self.assertEqual(self.private_connection.send.call_args[0][0],
                         'getdata')
        self.assertEqual(len(self.private_connection.send.call_args[0][1].inv),
                         1)
Exemplo n.º 3
0
    def test_headers_message_known_blocks(self):
        cblock1 = CBlock(nNonce=1)
        block1 = Block(cblock1, None)

        cblock2 = CBlock(nNonce=2)
        block2 = Block(cblock2, None)

        self.chain.blocks = {block1.hash(): block1, block2.hash(): block2}
        self.networking.request_blocks = MagicMock()

        message = messages.msg_headers()
        message.headers = [cblock1.get_header(), cblock2.get_header()]
        self.networking.headers_message(self.public_connection1, message)

        self.assertFalse(self.public_connection1.send.called)
        self.assertFalse(self.chain.process_header.called)
        self.assertFalse(self.private_connection.send.called)
        self.assertTrue(self.networking.request_blocks.called)
        self.assertEqual(len(self.networking.request_blocks.call_args[0][1]),
                         0)
Exemplo n.º 4
0
    def test_headers_message_two_unknown_blocks(self):
        header1 = CBlockHeader(nNonce=1)
        header2 = CBlockHeader(nNonce=2)

        message = messages.msg_headers()
        message.headers = [header1, header2]
        self.networking.blocks_in_flight = {}
        self.networking.request_blocks = MagicMock()

        self.networking.headers_message(self.private_connection, message)

        self.assertEqual(self.chain.process_header.call_count, 2)
        self.assertEqual(self.chain.process_header.call_args[0][1],
                         BlockOrigin.private)

        self.assertTrue(self.networking.request_blocks.called)
        self.assertEqual(len(self.networking.request_blocks.call_args[0][1]),
                         2)
        self.assertIn(header1.GetHash(),
                      self.networking.request_blocks.call_args[0][1])
        self.assertIn(header2.GetHash(),
                      self.networking.request_blocks.call_args[0][1])
Exemplo n.º 5
0
    def getheaders(self, message):
        blkmeta = self.chaindb.locate(message.locator)
        height = blkmeta.height
        top_height = self.getheight()
        end_height = height + 2000
        if end_height > top_height:
            end_height = top_height

        msg = messages.msg_headers()
        while height <= end_height:
            blkhash = long(self.chaindb.height[str(height)])
            if blkhash == message.hashstop:
                break

            db_block = self.chaindb.getblock(blkhash)
            block = copy.copy(db_block)
            block.vtx = []

            msg.headers.append(block)

            height += 1

        self.send_message(msg)
Exemplo n.º 6
0
    def getheaders(self, message):
        blkmeta = self.chaindb.locate(message.locator)
        height = blkmeta.height
        top_height = self.getheight()
        end_height = height + 2000
        if end_height > top_height:
            end_height = top_height

        msg = messages.msg_headers()
        while height <= end_height:
            blkhash = long(self.chaindb.height[str(height)])
            if blkhash == message.hashstop:
                break

            db_block = self.chaindb.getblock(blkhash)
            block = copy.copy(db_block)
            block.vtx = []

            msg.headers.append(block)

            height += 1

        self.send_message(msg)
Exemplo n.º 7
0
    def got_message(self, message):
        gevent.sleep()

        if self.last_sent + 30 * 60 < time.time():
            self.send_message(msg_ping(self.ver_send))

        if verbose_recvmsg(message):
            self.log.info("recv %s" % repr(message))

        if message.command == b"version":
            self.ver_send = min(PROTO_VERSION, message.nVersion)
            if self.ver_send < MIN_PROTO_VERSION:
                self.log.info("Obsolete version %d, closing" %
                              (self.ver_send, ))
                self.handle_close()
                return

            self.remote_height = message.nStartingHeight
            self.send_message(msg_verack(self.ver_send))

            if self.ver_send >= CADDR_TIME_VERSION:
                self.send_message(msg_getaddr(self.ver_send))

            # self.send_getblocks()

        elif message.command == b'ping':
            if self.ver_send > BIP0031_VERSION:
                self.send_message(msg_pong(self.ver_send))

        elif message.command == b"verack":
            self.ver_recv = self.ver_send
            self.send_message(msg_addr())
            self.send_getaddr()

        elif message.command == b"inv":

            # special message sent to kick getblocks
            # if (len(message.inv) == 1 and
            #     message.inv[0].type == MSG_BLOCK and
            #     self.chaindb.haveblock(message.inv[0].hash, True)):
            #     self.send_getblocks(False)
            #     return

            want = msg_getdata(self.ver_send)
            for i in message.inv:
                if i.type == 1:
                    want.inv.append(i)
                elif i.type == 2:
                    want.inv.append(i)
                self.last_want = i.hash
            if len(want.inv):
                self.send_message(want)

        # elif message.command == b"block":
        #     bhash = b2lx(message.block.GetHash())
        #     self.chaindb.putblock(message.block)
        #     self.last_block_rx = time.time()
        #     if self.last_want == 0:
        #         gevent.spawn(self.send_getblocks)
        #     elif bhash == b2lx(self.last_want):
        #         gevent.spawn(self.send_getblocks)
        elif message.command == b"addr":
            self.peermgr.new_addrs(message.addrs)
            for addr in message.addrs:
                self.peermgr.add(addr.ip, addr.port)
        elif message.command == b'getheaders':
            self.send_message(msg_headers())