예제 #1
0
    def testVersionSerialization(self):
        """
        Version message:
         9C 7C 00 00                                                                   - 31900 (version 0.3.19)
         01 00 00 00 00 00 00 00                                                       - 1 (NODE_NETWORK services)
         E6 15 10 4D 00 00 00 00                                                       - Mon Dec 20 21:50:14 EST 2010
         01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 20 8D - Recipient address info - see Network Address
         01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 02 20 8D - Sender address info - see Network Address
         DD 9D 20 2C 3A B4 57 13                                                       - Node random unique ID
         00                                                                            - "" sub-version string (string is 0 bytes long)
         55 81 01 00                                                                   - Last block sending node has is block #98645
        """
        b = ("9C7C00000100000000000000E615104D00000000010000000000000000000000" + \
            "000000000000FFFF0A000001208D010000000000000000000000000000000000" + \
            "FFFF0A000002208DDD9D202C3AB457130055810100").decode("hex")
        from bitcoin.BitcoinProtocol import VersionPacket
        p = VersionPacket()
        p.parse(BytesIO(b))
        self.assertEquals(p.version, 31900, "Version")
        self.assertEquals(p.services, 1, "Services")
        self.assertEquals(p.timestamp, 1292899814)
        self.assertEqual("dd9d202c3ab45713", p.nonce.encode("hex"))
        self.assertEqual(98645, p.best_height)

        buf = BytesIO()
        p.toWire(buf)
        self.assertEquals(b.encode("hex"),
                          buf.getvalue().encode("hex"), "Serialization")
예제 #2
0
    def testSegwitTx(self):
        txhash = "85b2c5e202950eb7dc87ff570d68e366d02a801759283c8c8ca66986e7f25242"
        wtxhash = "da9f24ac73ba45e28f87510b9515e7ab6591d3a86aec6b59d5447cdf2e22ca38"
        b = BytesIO(
            open(os.path.join(BASENAME, 'resources', "segwit-tx.dmp")).read())
        t = messages.TxPacket()
        self.assertTrue(t.parse(b, {'segwit': True}))
        self.assertEquals(b.tell(), len(b.getvalue()))

        self.assertEquals(txhash, t.hash().encode('hex'))

        self.assertEquals(11, len(t.inputs))
        self.assertEquals(11, len(t.outputs))
        self.assertEquals(t.lock_time, 0)
        self.assertEquals(11, len(t.witnesses))
        self.assertTrue(t.is_segwit)
        self.assertFalse(t.is_coinbase())

        buf = BytesIO()
        opts = {'segwit': True, 'version': 70001}
        t.toWire(buf, opts)
        self.assertEquals(b.getvalue().encode("hex"),
                          buf.getvalue().encode("hex"))

        self.assertEquals(wtxhash, t.whash().encode('hex'))
예제 #3
0
    def testInvPacket(self):
        b = ('030100000013789a2379fc190f292c9bc8087205a2dd4ee49f18cc5e9247ccc'
             '32525009550010000009c2c5169e550e49c118f9e57a06fd709e23b4f75cc2f'
             'c9af618c3ceda4e35eb20100000017e644fbcb3e92589ece8c42d88b2930c4d'
             '787d89e45415883ec61303bf88e42').decode("hex")
        i = messages.InvPacket()
        i.parse(BytesIO(b), None)

        buf = BytesIO()
        i.toWire(buf, None)
        self.assertEquals(b.encode("hex"), buf.getvalue().encode("hex"))
예제 #4
0
 def testAddressSerialization(self):
     b = ('010000000000000000000000000000000000FFFF0A000001208D'
          ).decode("hex")
     a = messages.Address()
     a.parse(BytesIO(b), {'version': 0})
     self.assertTrue(a.isIPv4, "Is IPv4")
     self.assertEqual("10.0.0.1", a.ip, "IP")
     self.assertEqual(8333, a.port, "Port")
     self.assertEqual(1, a.services, "Services")
     buf = BytesIO()
     a.toWire(buf, {'version': 0})
     self.assertEqual(b.encode("hex"), buf.getvalue().encode("hex"))
예제 #5
0
    def testInvPacket(self):
        from bitcoin.BitcoinProtocol import InvPacket
        b = ("030100000013789a2379fc190f292c9bc8087205a2dd4ee49f18cc5e9247ccc" + \
             "32525009550010000009c2c5169e550e49c118f9e57a06fd709e23b4f75cc2f" + \
             "c9af618c3ceda4e35eb20100000017e644fbcb3e92589ece8c42d88b2930c4d" + \
             "787d89e45415883ec61303bf88e42").decode("hex")
        i = InvPacket()
        i.parse(BytesIO(b))

        buf = BytesIO()
        i.toWire(buf)
        self.assertEquals(b.encode("hex"), buf.getvalue().encode("hex"))
예제 #6
0
    def testTxPacket(self):
        from bitcoin.BitcoinProtocol import TxPacket
        b = BytesIO(open("test/resources/tx-9c0f7b2.dmp").read())
        t = TxPacket()
        t.parse(b)
        self.assertEquals(b.tell(), len(b.getvalue()))

        self.assertEquals(1, len(t.inputs))
        self.assertEquals(2, len(t.outputs))
        self.assertEquals(t.lock_time, 0)

        buf = BytesIO()
        t.toWire(buf)
        self.assertEquals(b.getvalue().encode("hex"),
                          buf.getvalue().encode("hex"))
예제 #7
0
    def testTxPacket(self):
        b = BytesIO(
            open(os.path.join(BASENAME, 'resources', "tx-9c0f7b2.dmp")).read())
        t = messages.TxPacket()
        t.parse(b, None)
        self.assertEquals(b.tell(), len(b.getvalue()))

        self.assertEquals(1, len(t.inputs))
        self.assertEquals(2, len(t.outputs))
        self.assertEquals(t.lock_time, 0)

        buf = BytesIO()
        t.toWire(buf, {'version': 70001})
        self.assertEquals(b.getvalue().encode("hex"),
                          buf.getvalue().encode("hex"))
예제 #8
0
 def test_length(self):
     p = ('01E215104D010000000000000000000000000000000000FFFF0A000001208D'
          ).decode("hex")
     b = BytesIO(p)
     a = messages.AddrPacket()
     a.parse(b, None)
     self.assertEquals(len(p), len(a))
예제 #9
0
    def testVersionSerialization(self):
        b = ('9C7C00000100000000000000E615104D00000000010000000000000000000000'
             '000000000000FFFF0A000001208D010000000000000000000000000000000000'
             'FFFF0A000002208DDD9D202C3AB457130055810100').decode("hex")
        p = messages.VersionPacket()
        p.parse(BytesIO(b), None)
        self.assertEquals(p.version, 31900, "Version")
        self.assertEquals(p.services, 1, "Services")
        self.assertEquals(p.timestamp, 1292899814)
        self.assertEqual("dd9d202c3ab45713", p.nonce.encode("hex"))
        self.assertEqual(98645, p.best_height)

        self.assertEquals(p.addr_from.ip, '10.0.0.2')
        self.assertEquals(p.addr_recv.ip, '10.0.0.1')

        buf = BytesIO()
        p.toWire(buf, {'version': p.version})
        self.assertEquals(b.encode("hex"), buf.getvalue().encode("hex"))
예제 #10
0
    def testBlockPacket(self):
        from bitcoin.BitcoinProtocol import BlockPacket
        by = BytesIO(open("test/resources/block-188817.dmp").read())
        b = BlockPacket()
        b.parse(by)

        self.assertEquals(1342158910, b.timestamp)
        self.assertEquals(1, b.version)
        self.assertEquals(
            "000000000000051d9fa2edb8bb1a7e2466a91e2244222218e94057e0aba50545",
            b.prev_block.encode("hex"))
        self.assertEquals(436835377, b.bits)
        self.assertEquals(2064516359, b.nonce)
        self.assertEquals(88, len(b.transactions))

        buf = BytesIO()
        b.toWire(buf)
        self.assertEquals(len(by.getvalue()), len(buf.getvalue()))
예제 #11
0
    def testBlockPacket(self):
        by = BytesIO(
            open(os.path.join(BASENAME, 'resources',
                              "block-188817.dmp")).read())
        b = messages.BlockPacket()
        b.parse(by, None)

        self.assertEquals(1342158910, b.timestamp)
        self.assertEquals(1, b.version)
        self.assertEquals(
            '000000000000051d9fa2edb8bb1a7e2466a91e2244222218e94057e0aba50545',
            b.prev_block.encode("hex"))
        self.assertEquals(436835377, b.bits)
        self.assertEquals(2064516359, b.nonce)
        self.assertEquals(88, len(b.transactions))

        buf = BytesIO()
        b.toWire(buf, None)
        self.assertEquals(len(by.getvalue()), len(buf.getvalue()))
예제 #12
0
    def testTxHashing(self):
        real_hash = ("9c0f7b2e9aac5c283f451915a04ec71a1da0e2215dbf9388990a7e99"
                     "b7f3d3fd")
        b = BytesIO(
            open(os.path.join(BASENAME, 'resources', "tx-9c0f7b2.dmp")).read())
        t = messages.TxPacket()
        t.parse(b, None)

        t._hash = None
        self.assertEquals(t.hash().encode("hex"), real_hash)
예제 #13
0
 def testAddressSerialization(self):
     """
     Network address:
      01 00 00 00 00 00 00 00                         - 1 (NODE_NETWORK: see services listed under version command)
      00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 - IPv6: ::ffff:10.0.0.1 or IPv4: 10.0.0.1
      20 8D
     """
     from bitcoin.BitcoinProtocol import Address
     b = "010000000000000000000000000000000000FFFF0A000001208D".decode(
         "hex")
     a = Address()
     a.parse(BytesIO(b), False)
     self.assertTrue(a.isIPv4, "Is IPv4")
     self.assertEqual("10.0.0.1", a.ip, "IP")
     self.assertEqual(8333, a.port, "Port")
     self.assertEqual(1, a.services, "Services")
     buf = BytesIO()
     a.toWire(buf, False)
     self.assertEqual(b.encode("hex"),
                      buf.getvalue().encode("hex"), "Serialization matches")
예제 #14
0
    def testAddrPacket(self):
        b = BytesIO(
            ('01E215104D010000000000000000000000000000000000FFFF0A000001208D'
             ).decode("hex"))
        a = messages.AddrPacket()
        a.parse(b, None)

        self.assertEqual(1, len(a.addresses))
        address = a.addresses[0]
        self.assertEquals("addr", a.type)
        self.assertTrue(address.isIPv4)
        self.assertEquals(1292899810, address.timestamp)
        self.assertEqual(1, address.services)
        self.assertEquals("10.0.0.1", address.ip)
        self.assertEquals(8333, address.port)

        buf = BytesIO()
        a.toWire(buf, {})
        self.assertEquals(b.getvalue().encode("hex"),
                          buf.getvalue().encode("hex"))
예제 #15
0
    def testAddrPacket(self):
        from bitcoin.BitcoinProtocol import AddrPacket
        b = BytesIO(
            "01E215104D010000000000000000000000000000000000FFFF0A000001208D".
            decode("hex"))
        a = AddrPacket()
        a.parse(b)

        self.assertEqual(1, len(a.addresses))
        address = a.addresses[0]
        self.assertEquals("addr", a.type)
        self.assertTrue(address.isIPv4)
        self.assertEquals(1292899810, address.timestamp)
        self.assertEqual(1, address.services)
        self.assertEquals("10.0.0.1", address.ip)
        self.assertEquals(8333, address.port)

        buf = BytesIO()
        a.toWire(buf)
        self.assertEquals(b.getvalue().encode("hex"),
                          buf.getvalue().encode("hex"))
예제 #16
0
    def request(self, channel, path="", data={}, throw=True):

        # add in the common values
        data["channel"] = channel
        data["connectionType"] = "long-polling"
        data["id"] = self.msgId
        self.msgId += 1

        if self.clientId is not None:
            data["clientId"] = self.clientId

        url = "%s%s" % (self.url, path)

        if self.apiKey is not None:
            url = "%s?&%s" % (url,
                              urllib.urlencode({
                                  "_user": self.userId,
                                  "_apikey": self.apiKey
                              }))

        request = urllib2.Request(url)
        request.add_data(json.dumps([data]))
        request.add_header("Content-Type", "application/json;charset=UTF-8")
        request.add_header('Accept-encoding', 'gzip')
        response = self.opener.open(request)
        if response.code != 200:
            raise Exception("Connect failed, status %s" % response.code)

        if response.info().get('Content-Encoding') == 'gzip':
            # need to buffer in memory - facepalm: http://bugs.python.org/issue914340
            response.json = json.load(
                gzip.GzipFile(fileobj=BytesIO(response.read())))
        else:
            response.json = json.load(response)

        for msg in response.json:
            if "successful" in msg and msg["successful"] is not True:
                msg = "Unsuccessful request: %s", msg
                if throw:
                    raise Exception(msg)
                else:
                    logger.warn(msg)
            try:
                if msg["channel"] != self.messagingChannel: continue
            except:
                print "Encountered error in importio: %s\n" % (
                    sys.exc_info()[0])
                break
            self.queue.put(msg["data"])

        return response
예제 #17
0
    def testBlockHashing(self):
        by = BytesIO(
            open(os.path.join(BASENAME, 'resources',
                              "block-188817.dmp")).read())
        b = messages.BlockPacket()
        b.parse(by, None)

        # Try the cached hash from parsing first
        self.assertEquals(
            b.hash().encode("hex"),
            "0000000000000295df119db2d63b6f2d6ea33196fae5f825cb4323e06d0c46f8")

        # Unset cached hash and try again
        b._hash = None
        self.assertEquals(
            b.hash().encode("hex"),
            "0000000000000295df119db2d63b6f2d6ea33196fae5f825cb4323e06d0c46f8")
예제 #18
0
    def render_POST(self, request):
        remoteVortexUuid = request.args[b'vortexUuid'][0].decode()
        remoteVortexName = request.args[b'vortexName'][0].decode()

        if self.__vortex.isShutdown():
            return None

        httpSession = request.getSession()
        conn = VortexResourceConnection(self.__vortex, remoteVortexUuid,
                                        remoteVortexName, request)

        # Send a heart beat down the new connection, tell it who we are.
        connectPayloadFilt = {}
        connectPayloadFilt[
            PayloadEnvelope.vortexUuidKey] = self.__vortex.uuid()
        connectPayloadFilt[
            PayloadEnvelope.vortexNameKey] = self.__vortex.name()
        conn.write(PayloadEnvelope(filt=connectPayloadFilt).toVortexMsg())

        data = request.content.read()
        if len(data):
            for vortexStr in data.strip(b'.').split(b'.'):
                self._processVortexMsg(httpSession, conn,
                                       vortexStr.decode("UTF-8"))

        # Request will be around for a while, do some cleanups
        request.content = BytesIO()
        request.args = {}

        self.__vortex.connectionOpened(httpSession, conn)

        def connClosed(err):
            logger.debug("VortexServer connection ended by client")
            self.__vortex.connectionClosed(conn)

        request.notifyFinish().addErrback(connClosed)

        return NOT_DONE_YET
예제 #19
0
    def setUp(self):
        data = b"abcdefghijklmnopqrstuvwxyz"
        bytes_io = BytesIO(data)

        self.bytes_io = bytes_io
        self.isw = IStreamWrapper(bytes_io, len(data))
예제 #20
0
    def request(self, channel, path="", data={}, throw=True):
        '''
        Helper method that makes a generic request on the messaging channel
        '''

        # These are CometD configuration values that are common to all requests we need to send
        data["channel"] = channel
        data["connectionType"] = "long-polling"

        # We need to increment the message ID with each request that we send
        data["id"] = self.msgId
        self.msgId += 1

        # If we have a client ID, then we need to send that (will be provided on handshake)
        if self.client_id is not None:
            data["clientId"] = self.client_id

        # Build the URL that we are going to request
        url = "%s%s" % (self.url, path)

        # If the user has chosen API key authentication, we need to send the API key with each request
        if self.api_key is not None:
            url = "%s?&%s" % (url,
                              urllib.parse.urlencode({
                                  "_user": self.user_id,
                                  "_apikey": self.api_key
                              }))

        # Build the request object we are going to use to initialise the request
        request = urllib.request.Request(url,
                                         data=json.dumps([data
                                                          ]).encode('utf-8'))
        request.add_header("Content-Type", "application/json;charset=UTF-8")
        request.add_header('Accept-encoding', 'gzip')
        request.add_header('import-io-client', self.clientName)
        request.add_header('import-io-client-version', self.clientVersion)

        # Send the request itself
        try:
            response = self.opener.open(request)
        except urllib.error.HTTPError:
            error_message = "Exception raised connecting to import.io for url %s" % url
            if throw:
                raise Exception(error_message)
            else:
                logger.warn(error_message)
                return

        # Don't process the response if we've disconnected in the meantime
        if not self.connected and not self.connecting:
            return

        # If the server responds non-200 we have a serious issue (configuration wrong or server down)
        if response.code != 200:
            error_message = "Unable to connect to import.io, status %s for url %s" % (
                response.code, url)
            if throw:
                raise Exception(error_message)
            else:
                logger.warn(error_message)
                return

        # If the data comes back as gzip, we need to manually decode it
        if response.info().get('Content-Encoding') == 'gzip':
            # Unfortunately we need to buffer it in memory to decode the gzip: http://bugs.python.org/issue914340
            raw_response = gzip.GzipFile(fileobj=BytesIO(response.read()))
            response.json = json.loads(raw_response.read().decode('utf-8'))
        else:
            response.json = json.loads(response.read().decode('utf-8'))

        # Iterate through each of the messages in the response content
        for msg in response.json:
            # If the message is not successful, i.e. an import.io server error has occurred, decide what action to take
            if "successful" in msg and msg["successful"] is not True:
                errorMessage = "Unsuccessful request: %s" % msg
                if not self.disconnecting and self.connected and not self.connecting:

                    # If we get a 402 unknown client we need to reconnect
                    if msg["error"] == "402::Unknown client":
                        logger.warn("402 received, reconnecting")
                        self.io.reconnect()

                if throw:
                    raise Exception(errorMessage)
                else:
                    logger.warn(errorMessage)
                    continue

            # Ignore messages that come back on a CometD channel that we have not subscribed to
            if msg["channel"] != self.messagingChannel: continue

            # Now we have a valid message on the right channel, queue it up to be processed
            self.queue.put(msg["data"])

        # We have finished processing the response messages, return the response in case the client wants anything else from it
        return response