示例#1
0
    def getblocks(self, message):
        blkmeta = self.chaindb.locate(message.locator)
        height = blkmeta.height
        top_height = self.getheight()
        end_height = height + 500
        if end_height > top_height:
            end_height = top_height

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

            inv = net.CInv()
            inv.type = messages.MSG_BLOCK
            inv.hash = hash
            msg.inv.append(inv)

            height += 1

        if len(msg.inv) > 0:
            self.send_message(msg)
            if height <= top_height:
                self.hash_continue = msg.inv[-1].hash
    def test_inv_message_msg_unknown(self):
        inv = net.CInv()
        inv.type = "Unknown"
        msg = messages.msg_inv
        msg.inv = [inv]
        self.networking.inv_message(self.private_connection, msg)

        self.assertFalse(self.private_connection.send.called)
        self.assertFalse(self.public_connection1.send.called)
        self.assertFalse(self.public_connection2.send.called)
    def test_inv_message_msg_error(self):
        inv = net.CInv()
        inv.type = networking.inv_typemap['Error']
        msg = messages.msg_inv
        msg.inv = [inv]
        self.networking.inv_message(self.private_connection, msg)

        self.assertFalse(self.private_connection.send.called)
        self.assertFalse(self.public_connection1.send.called)
        self.assertFalse(self.public_connection2.send.called)
    def test_inv_message_msg_tx_known(self):
        inv = net.CInv()
        inv.type = networking.inv_typemap['TX']
        inv.hash = 'hash1'
        msg = messages.msg_inv()
        msg.inv = [inv]
        self.networking.txs = {inv.hash: 'saved_transaction'}

        self.networking.inv_message(self.private_connection, msg)

        self.assertFalse(self.private_connection.send.called)
        self.assertFalse(self.public_connection1.send.called)
        self.assertFalse(self.public_connection2.send.called)
示例#5
0
 def send_getblocks(self):
     our_height = self.chaindb.getheight()
     if our_height < 0:
         gd = messages.msg_getdata(protover=self.ver_send)
         inv = net.CInv()
         inv.type = 2
         inv.hash = self.params.GENESIS_BLOCK.GetHash()
         gd.inv.append(inv)
         self.send_message(gd)
     elif our_height < self.remote_height:
         gb = messages.msg_getblocks(protover=self.ver_send)
         if our_height >= 0:
             gb.locator.vHave.append(self.chaindb.gettophash())
         self.send_message(gb)
    def test_inv_message_msg_block_private(self, mock):
        mock.return_value = ['hash20', 'hash19']
        self.networking.request_blocks = MagicMock()

        inv = net.CInv()
        inv.hash = 'hash1'
        inv.type = networking.inv_typemap['Block']
        msg = messages.msg_inv
        msg.inv = [inv]
        self.networking.inv_message(self.private_connection, msg)

        self.assertEqual(self.private_connection.send.call_count, 1)
        self.assertTrue(mock.called)
        self.assertEqual(self.private_connection.send.call_args_list[0][0][0],
                         'getheaders')
    def test_inv_message_msg_request_block(self, mock):
        mock.return_value = ['hash20', 'hash19']
        self.networking.request_blocks = MagicMock()

        inv = net.CInv()
        inv.hash = 'hash1'
        inv.type = networking.inv_typemap['Block']
        msg = messages.msg_inv
        msg.inv = [inv]

        self.networking.inv_message(self.private_connection, msg)

        self.assertTrue(self.networking.request_blocks.called)
        self.assertEqual(self.networking.request_blocks.call_args[0][0],
                         self.private_connection)
        self.assertEqual(self.networking.request_blocks.call_args[0][1],
                         ['hash1'])
示例#8
0
    def getdata_block(self, blkhash):
        block = self.chaindb.getblock(blkhash)
        if block is None:
            return

        msg = messages.msg_block()
        msg.block = block

        self.send_message(msg)

        if blkhash == self.hash_continue:
            self.hash_continue = None

            inv = net.CInv()
            inv.type = messages.MSG_BLOCK
            inv.hash = self.chaindb.gettophash()

            msg = messages.msg_inv()
            msg.inv.append(inv)

            self.send_message(msg)
示例#9
0
    def got_message(self, message):
        gevent.sleep()

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

        self.log.debug("recv %s" % repr(message))

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

            if (self.ver_send >= self.params.NOBLKS_VERSION_START
                    and self.ver_send <= self.params.NOBLKS_VERSION_END):
                self.getblocks_ok = False

            self.remote_height = message.nStartingHeight
            self.send_message(messages.msg_verack(self.ver_send))
            if self.ver_send >= self.params.CADDR_TIME_VERSION:
                self.send_message(messages.msg_getaddr(self.ver_send))
            self.request_latest()
            self.client_version = message.strSubVer

        elif message.command == "verack":
            self.ver_recv = self.ver_send

            if self.ver_send >= self.params.MEMPOOL_GD_VERSION:
                self.send_message(messages.msg_mempool())

        elif message.command == "ping":
            if self.ver_send > self.params.BIP0031_VERSION:
                self.send_message(messages.msg_pong(self.ver_send))

        elif message.command == "addr":
            self.peermgr.new_addrs(message.addrs)

        elif message.command == "inv":

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

            want = messages.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)
            if len(want.inv):
                self.send_message(want)

        elif message.command == "tx":
            if self.chaindb.tx_is_orphan(message.tx):
                self.log.info("MemPool: Ignoring orphan TX {}".format(
                    message.tx.GetHash().encode('hex')))
            elif not self.chaindb.tx_signed(message.tx, None, True):
                self.log.info("MemPool: Ignoring failed-sig TX {}".format(
                    message.tx.GetHash().encode('hex')))
            else:
                self.mempool.add(message.tx)

        elif message.command == "block":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "headers":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "getdata":
            self.getdata(message)

        elif message.command == "getblocks":
            self.getblocks(message)

        elif message.command == "getheaders":
            self.getheaders(message)

        elif message.command == "getaddr":
            msg = messages.msg_addr()
            msg.addrs = self.peermgr.random_addrs()

            self.send_message(msg)

        elif message.command == "mempool":
            msg = messages.msg_inv()
            for k in self.mempool.pool.iterkeys():
                inv = net.CInv()
                inv.type = messages.MSG_TX
                inv.hash = k
                msg.inv.append(inv)

                if len(msg.inv) == 50000:
                    break

            self.send_message(msg)

        # if we haven't seen a 'block' message in a little while,
        # and we're still not caught up, send another getblocks
        last_blkmsg = time.time() - self.last_block_rx
        if last_blkmsg > 5:
            self.request_latest()
示例#10
0
def hash_to_inv(inv_type, inv_hash):
    inv = net.CInv()
    inv.type = inv_typemap[inv_type]
    inv.hash = inv_hash
    return inv