Example #1
0
    def test_override_same_height(self):
        private_tip = Block(CBlock(), None)
        private_tip.height = 2

        public_tip = Block(CBlock(), None)
        public_tip.height = 2

        with self.assertRaisesRegexp(ActionException, "private tip.*must > then public tip.*override.*"):
            self.executor.execute(Action.override, private_tip, public_tip)
Example #2
0
    def test_match_lead_public(self):
        private_tip = Block(CBlock(), None)
        private_tip.height = 1

        public_tip = Block(CBlock(), None)
        public_tip.height = 2

        with self.assertRaisesRegexp(ActionException, "private tip.*must >= then public tip.*match.*"):
            self.executor.execute(Action.match, private_tip, public_tip)
Example #3
0
    def test_adopt_same_height(self):
        private_tip = Block(CBlock(), None)
        private_tip.height = 2

        public_tip = Block(CBlock(), None)
        public_tip.height = 2

        with self.assertRaisesRegexp(ActionException, "public tip.*must > then private tip.*adopt.*"):
            self.executor.execute(Action.adopt, private_tip, public_tip)
    def test_send_inv_public_blocks(self):
        block1 = Block(CBlock(), BlockOrigin.public)
        block1.cached_hash = 'hash1'
        block2 = Block(CBlock(), BlockOrigin.public)
        block2.cached_hash = 'hash2'
        self.networking.send_inv([block1, block2])

        self.assertFalse(self.public_connection1.send.called)
        self.assertFalse(self.public_connection2.send.called)

        self.assertTrue(self.private_connection.send.called)
        inv = self.private_connection.send.call_args[0][1].inv
        self.assertEqual(len(inv), 2)
    def test_block_message_two_times(self):
        message = messages.msg_block()
        cblock1 = CBlock(nNonce=1)
        cblock2 = CBlock(nNonce=2)
        message.block = cblock1

        block = Block(None, BlockOrigin.private)
        block.cached_hash = message.block.GetHash()

        self.chain.blocks = {block.hash(): block}

        self.networking.block_message(self.private_connection, message)
        message.block = cblock2
        self.networking.block_message(self.private_connection, message)
    def test_getdata_message_with_two_blocks(self):
        cblock1 = CBlock()
        block1 = Block(cblock1, BlockOrigin.private)
        block1.cblock = cblock1
        cInv1 = CInv()
        cInv1.type = networking.inv_typemap['Block']
        cInv1.hash = cblock1.GetHash()
        cblock2 = CBlock()
        block2 = Block(cblock2, BlockOrigin.private)
        block2.cblock = cblock2
        cInv2 = CInv()
        cInv2.type = networking.inv_typemap['Block']
        cInv2.hash = cblock2.GetHash()
        message = messages.msg_getdata()
        message.inv = [cInv1, cInv2]

        self.chain.blocks = {
            cblock1.GetHash(): block1,
            cblock2.GetHash(): block2
        }

        self.networking.getdata_message(self.public_connection1, message)

        self.assertTrue(self.public_connection1.send.called)
        self.assertEqual(self.public_connection1.send.call_count, 2)
Example #7
0
    def test_insert_block_initializing_false(self):
        prevBlock = Block(CBlock(), BlockOrigin.private)
        prevBlock.cached_hash = 'hash2'
        prevBlock.height = 45
        block = Block(CBlock(), BlockOrigin.private)
        block.cached_hash = 'hash1'
        self.chain.tips = [prevBlock]
        self.chain.initializing = False

        self.chain.insert_block(prevBlock, block)

        retrieved_block = self.chain.tips[0]
        self.assertEqual(retrieved_block, block)
        self.assertEqual(retrieved_block.transfer_allowed, False)
    def test_check_blocks_in_flight_does_not_timeout(self):
        hash_ = CBlock().GetHash()
        self.networking.check_blocks_in_flight_interval = 2
        self.networking.blocks_in_flight = {hash_: BlockInFlight(hash_, 0)}

        self.networking.check_blocks_in_flight()
        self.assertEqual(len(self.networking.blocks_in_flight), 1)
Example #9
0
    def test_insert_block(self):
        prevBlock = Block(CBlock(), BlockOrigin.private)
        prevBlock.cached_hash = 'hash2'
        prevBlock.height = 45
        block = Block(CBlock(), BlockOrigin.private)
        block.cached_hash = 'hash1'
        self.chain.tips = [prevBlock]

        self.chain.insert_block(prevBlock, block)

        self.assertFalse(prevBlock in self.chain.tips)
        self.assertEqual(len(self.chain.tips), 1)

        retrieved_block = self.chain.tips[0]
        self.assertEqual(retrieved_block, block)
        self.assertEqual(retrieved_block.prevBlock, prevBlock)
        self.assertEqual(retrieved_block.height, 46)
Example #10
0
 def __init__(self):
     self.blockcount = 0
     self.rawmempool = {}
     self.on = True
     self._blockhashes, blocks_ser = load_obj(blockdata)
     self._blocks = {}
     for blockhash, block_ser in blocks_ser.items():
         self._blocks[blockhash] = CBlock.deserialize(block_ser)
Example #11
0
    def submitblock(self, params):
        err = { "code" : -1, "message" : "invalid params" }
        if (len(params) != 1 or
            (not isinstance(params[0], str) and
             not isinstance(params[0], unicode))):
            return (None, err)

        data = params[0].decode('hex')
        f = cStringIO.StringIO(data)
        block = CBlock()
        block.deserialize(f)

        res = self.chaindb.putblock(block)
        if not res:
            return ("rejected", None)

        return (None, None)
Example #12
0
 def __init__(self):
     self.blockcount = 0
     self.rawmempool = {}
     self.on = True
     self._blockhashes, blocks_ser = load_obj(blockdata)
     self._blocks = {}
     for blockhash, block_ser in blocks_ser.items():
         self._blocks[blockhash] = CBlock.deserialize(block_ser)
    def test_getdata_message_with_block(self):
        cblock = CBlock()
        block = Block(cblock, BlockOrigin.private)
        block.cblock = cblock
        message = messages.msg_getdata()
        cInv = CInv()
        cInv.type = networking.inv_typemap['Block']
        cInv.hash = cblock.GetHash()
        message.inv = [cInv]

        self.chain.blocks = {cblock.GetHash(): block}

        self.networking.getdata_message(self.public_connection1, message)

        self.assertTrue(self.public_connection1.send.called)
        self.assertEqual(self.public_connection1.send.call_args[0][0], 'block')
        self.assertEqual(self.public_connection1.send.call_args[0][1].block,
                         cblock)
    def test_getdata_message_cblock_not_available(self):
        cblock = CBlock()
        hash_ = cblock.GetHash()
        block = Block(cblock, BlockOrigin.private)
        message = messages.msg_getdata()
        cInv = CInv()
        cInv.type = networking.inv_typemap['Block']
        cInv.hash = hash_
        message.inv = [cInv]

        self.chain.blocks = {hash_: block}
        self.networking.deferred_block_requests = {}
        self.networking.getdata_message(self.public_connection1, message)

        self.assertFalse(self.public_connection1.called)
        self.assertIn(hash_, self.networking.deferred_block_requests)
        self.assertIn(self.public_connection1.host[0],
                      self.networking.deferred_block_requests[hash_])
Example #15
0
class msg_block(MsgSerializable):
    command = b"block"

    def __init__(self, protover=PROTO_VERSION):
        super(msg_block, self).__init__(protover)
        self.block = CBlock()

    @classmethod
    def msg_deser(cls, f, protover=PROTO_VERSION):
        c = cls()
        c.block = CBlock.stream_deserialize(f)
        return c

    def msg_ser(self, f):
        self.block.stream_serialize(f)

    def __repr__(self):
        return "msg_block(block=%s)" % (repr(self.block))
Example #16
0
class msg_block(MsgSerializable):
    command = b"block"

    def __init__(self, protover=PROTO_VERSION):
        super(msg_block, self).__init__(protover)
        self.block = CBlock()

    @classmethod
    def msg_deser(cls, f, protover=PROTO_VERSION):
        c = cls()
        c.block = CBlock.stream_deserialize(f)
        return c

    def msg_ser(self, f):
        self.block.stream_serialize(f)

    def __repr__(self):
        return "msg_block(block=%s)" % (repr(self.block))
    def test_block_message_deferred_requests(self):
        message = messages.msg_block()
        cblock = CBlock()
        hash_ = cblock.GetHash()
        message.block = cblock

        block = Block(None, BlockOrigin.private)
        block.cached_hash = hash_

        self.networking.deferred_block_requests = \
            {hash_: [self.private_connection.host[0], self.public_connection2.host[0]]}
        self.networking.send_block = MagicMock()

        self.networking.block_message(self.public_connection1, message)

        self.assertEqual(len(self.networking.deferred_block_requests), 0)
        self.assertEqual(self.networking.send_block.call_count, 2)
        self.assertEqual(self.networking.send_block.call_args[0][1], cblock)
    def test_getheaders_message_no_block_found(self, mock):
        message = messages.msg_getheaders()
        block1 = Block('cblock_header1', BlockOrigin.private)
        block1.cblock = CBlock(nNonce=1)
        block2 = Block('cblock_header2', BlockOrigin.private)
        block2.cblock = CBlock(nNonce=2)
        mock.return_value = [block1, block2]

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

        self.assertTrue(self.private_connection.send.called)
        self.assertEqual(
            len(self.private_connection.send.call_args[0][1].headers), 2)
        self.assertEqual(
            self.private_connection.send.call_args[0][1].headers[0],
            block1.cblock)
        self.assertEqual(
            self.private_connection.send.call_args[0][1].headers[1],
            block2.cblock)
Example #19
0
class BitcoinMainNet(object):
    # Replace global defs from bitcoin.core
    COIN = 100000000
    MAX_MONEY = 21000000 * COIN
    MAX_BLOCK_SIZE = 1000000
    MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE / 50

    BIP0031_VERSION = 60000
    PROTO_VERSION = 60002
    MIN_PROTO_VERSION = 209

    CADDR_TIME_VERSION = 31402

    # Mimick bitcoinlib "params" global
    MESSAGE_START = b'\xf9\xbe\xb4\xd9'
    DEFAULT_PORT = 8333
    RPC_PORT = 8332
    DNS_SEEDS = (('bitcoin.sipa.be', 'seed.bitcoin.sipa.be'),
                 ('bluematt.me', 'dnsseed.bluematt.me'),
                 ('dashjr.org', 'dnsseed.bitcoin.dashjr.org'),
                 ('bitcoinstats.com',
                  'seed.bitcoinstats.com'), ('xf2.org', 'bitseed.xf2.org'))
    BASE58_PREFIXES = {'PUBKEY_ADDR': 0, 'SCRIPT_ADDR': 5, 'SECRET_KEY': 128}

    # Mimick bitcoinlib "core_params" global
    NAME = 'bitcoin_mainnet'
    GENESIS_BLOCK = CBlock.deserialize(
        x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'
          ))
    SUBSIDY_HALVING_INTERVAL = 210000
    PROOF_OF_WORK_LIMIT = 2**256 - 1 >> 32

    # Not part of bitcoinlib
    CHECKPOINTS = {
        0:
        0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26fL,
        11111:
        0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1dL,
        33333:
        0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6L,
        74000:
        0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20L,
        105000:
        0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97L,
        134444:
        0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0feL,
        168000:
        0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763L,
        193000:
        0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317L,
    }
    MEMPOOL_GD_VERSION = 60002
    BIP0031_VERSION = 60000
    NOBLKS_VERSION_START = 32000
    NOBLKS_VERSION_END = 32400
Example #20
0
def loadfile(filename):
    fd = os.open(filename, os.O_RDONLY)
    print("IMPORTING DATA FROM " + filename)
    buf = ''
    wanted = 4096
    while True:
        if wanted > 0:
            if wanted < 4096:
                wanted = 4096
            s = os.read(fd, wanted)
            if len(s) == 0:
                break

            buf += s
            wanted = 0

        buflen = len(buf)
        startpos = string.find(buf, netmagic)
        startpos = 0
        if startpos < 0:
            wanted = 8
            continue

        sizepos = startpos + 4
        blkpos = startpos + 8
        if blkpos > buflen:
            wanted = 8
            continue

        blksize = struct.unpack("<i", buf[sizepos:blkpos])[0]
        print "blkpos: ", blkpos, "blksize: ", blksize, "buflen: ", buflen
        if (blkpos + blksize) > buflen:
            wanted = 8 + blksize
            continue

        ser_blk = buf[blkpos:blkpos+blksize]
        buf = buf[blkpos+blksize:]

        f = cStringIO.StringIO(ser_blk)
        block = CBlock()
        block.deserialize(f)
        print block
    def test_path_from_txid_to_merkleroot(self):

        def T(blk):
            merkle_root = blk.calc_merkle_root()
            for tx in blk.vtx:
                txid = tx.GetHash()
                path = path_from_txid_to_merkleroot(txid, blk)
                self.assertEqual(path(txid), merkle_root)

        # Block with two transactions in it
        blk170 = CBlock.deserialize(x('0100000055bd840a78798ad0da853f68974f3d183e2bd1db6a842c1feecf222a00000000ff104ccb05421ab93e63f8c3ce5c2c2e9dbb37de2764b3a3175c8166562cac7d51b96a49ffff001d283e9e700201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0102ffffffff0100f2052a01000000434104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac000000000100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000'))
        T(blk170)

        # 99960 three transactions
        blk_3tx = CBlock.deserialize(x('01000000e78b20013e6e9a21b6366ead5d866b2f9dc00664508b90f24da8000000000000f94b61259c7e9af3455b277275800d0d6a58b929eedf9e0153a6ef2278a5d53408d11a4d4c86041b0fbf10b00301000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0119ffffffff0100f2052a0100000043410427e729f9cb5564abf2a1ccda596c636b77bd4d9d91f657d4738f3c70fce8ac4e12b1c782905554d9ff2c2e050fdfe3ff93c91c5817e617877d51f450b528c9e4ac000000000100000001e853c9e0c133547fd9e162b1d3860dd0f27d5b9b8a7430d28896c00fbb3f1bc7000000008c49304602210095bcd54ebd0caa7cee75f0f89de472a765e6ef4b98c5fd4b32c7f9d4905db9ae022100ebd3f668e3a1a36d56e30184c27531dbb9fc136c84b1282be562064d86997d1e014104727eb4fdcc90658cd26abe7dcb0ae7297810b15b9e27c32bcf8e3edd934901968806dc18b1276d7273cc4c223feee0070361ed947888a3cef422bebfede96e08ffffffff020065cd1d000000001976a91468c6c2b3c0bc4a8eeb10d16a300d627a31a3b58588ac0008af2f000000001976a9141d87f0a54a1d704ffc70eae83b025698bc0fdcfc88ac00000000010000000125f582f1d37b6713b14b85665a2daea4f464f5ed1c3ab3d4dcf152fb61414b9e000000008a473044022066ec12ced31659e1bf961b542b58bba76ba8f2a1e8f36d5f60be0601598eac21022047ce33685a63283a4c3ebc390261191f215999b2f7d8e1504b8af39aae4a2881014104c5e1d713d10fe59cc48f60701a3efcac418969c22e9c6cf57440f71e44dc82837af5351bf3e1d898f06aa5c792bf0251a39902311d1d27c16847b1b414494f35ffffffff02404b4c00000000001976a91466a3b2e43cfa5c6d9b2f0095f7be5a5cb608478c88ac80b8dc3c030000001976a9146df5ed8cee34df5c05c90406761a11ed143c202d88ac00000000'))
        T(blk_3tx)

        # 99993 four transactions
        blk_4tx = CBlock.deserialize(x('01000000acda3db591d5c2c63e8c09e7523a5b0581707ef3e3520d6ca180000000000000701179cb9a9e0fe709cc96261b6b943b31362b61dacba94b03f9b71a06cc2eff7d1c1b4d4c86041b75962f880401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0152ffffffff014034152a01000000434104216220ab283b5e2871c332de670d163fb1b7e509fd67db77997c5568e7c25afd988f19cd5cc5aec6430866ec64b5214826b28e0f7a86458073ff933994b47a5cac0000000001000000042a40ae58b06c3a61ae55dbee05cab546e80c508f71f24ef0cdc9749dac91ea5f000000004a49304602210089c685b37903c4aa62d984929afeaca554d1641f9a668398cd228fb54588f06b0221008a5cfbc5b0a38ba78c4f4341e53272b9cd0e377b2fb740106009b8d7fa693f0b01ffffffff7b999491e30af112b11105cb053bc3633a8a87f44740eb158849a76891ff228b00000000494830450221009a4aa8663ff4017063d2020519f2eade5b4e3e30be69bf9a62b4e6472d1747b2022021ee3b3090b8ce439dbf08a5df31e2dc23d68073ebda45dc573e8a4f74f5cdfc01ffffffffdea82ec2f9e88e0241faa676c13d093030b17c479770c6cc83239436a4327d49000000004a493046022100c29d9de71a34707c52578e355fa0fdc2bb69ce0a957e6b591658a02b1e039d69022100f82c8af79c166a822d305f0832fb800786d831aea419069b3aed97a6edf8f02101fffffffff3e7987da9981c2ae099f97a551783e1b21669ba0bf3aca8fe12896add91a11a0000000049483045022100e332c81781b281a3b35cf75a5a204a2be451746dad8147831255291ebac2604d02205f889a2935270d1bf1ef47db773d68c4d5c6a51bb51f082d3e1c491de63c345601ffffffff0100c817a8040000001976a91420420e56079150b50fb0617dce4c374bd61eccea88ac00000000010000000265a7293b2d69ba51d554cd32ac7586f7fbeaeea06835f26e03a2feab6aec375f000000004a493046022100922361eaafe316003087d355dd3c0ef3d9f44edae661c212a28a91e020408008022100c9b9c84d53d82c0ba9208f695c79eb42a453faea4d19706a8440e1d05e6cff7501fffffffff6971f00725d17c1c531088144b45ed795a307a22d51ca377c6f7f93675bb03a000000008b483045022100d060f2b2f4122edac61a25ea06396fe9135affdabc66d350b5ae1813bc6bf3f302205d8363deef2101fc9f3d528a8b3907e9d29c40772e587dcea12838c574cb80f801410449fce4a25c972a43a6bc67456407a0d4ced782d4cf8c0a35a130d5f65f0561e9f35198349a7c0b4ec79a15fead66bd7642f17cc8c40c5df95f15ac7190c76442ffffffff0200f2052a010000001976a914c3f537bc307c7eda43d86b55695e46047b770ea388ac00cf7b05000000001976a91407bef290008c089a60321b21b1df2d7f2202f40388ac0000000001000000014ab7418ecda2b2531eef0145d4644a4c82a7da1edd285d1aab1ec0595ac06b69000000008c493046022100a796490f89e0ef0326e8460edebff9161da19c36e00c7408608135f72ef0e03e0221009e01ef7bc17cddce8dfda1f1a6d3805c51f9ab2f8f2145793d8e85e0dd6e55300141043e6d26812f24a5a9485c9d40b8712215f0c3a37b0334d76b2c24fcafa587ae5258853b6f49ceeb29cd13ebb76aa79099fad84f516bbba47bd170576b121052f1ffffffff0200a24a04000000001976a9143542e17b6229a25d5b76909f9d28dd6ed9295b2088ac003fab01000000001976a9149cea2b6e3e64ad982c99ebba56a882b9e8a816fe88ac00000000'))
        T(blk_4tx)
    def test_send_inv_blocks(self):
        block1 = Block(CBlock(), BlockOrigin.public)
        block1.cached_hash = 'hash1'
        block2 = Block(CBlock(), BlockOrigin.public)
        block2.cached_hash = 'hash2'
        block3 = Block(CBlock(), BlockOrigin.public)
        block3.cached_hash = 'hash3'
        block4 = Block(CBlock(), BlockOrigin.private)
        block4.cached_hash = 'hash4'
        block5 = Block(CBlock(), BlockOrigin.private)
        block5.cached_hash = 'hash5'

        self.networking.send_inv([block1, block2, block3, block4, block5])

        self.assertTrue(self.private_connection.send.called)
        inv = self.private_connection.send.call_args[0][1].inv
        self.assertEqual(len(inv), 3)

        self.assertTrue(self.public_connection1.send.called)
        self.assertTrue(self.public_connection2.send.called)
        self.assertEqual(len(self.public_connection2.send.call_args[0][1].inv),
                         2)
    def test_block_message(self):
        message = messages.msg_block()
        cblock = CBlock()
        message.block = cblock

        block = Block(None, BlockOrigin.private)
        block.cached_hash = message.block.GetHash()

        self.chain.blocks = {block.hash(): block}

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

        self.assertEqual(self.chain.blocks[block.hash()].cblock, cblock)
Example #24
0
    def setUp(self):
        self.networking = MagicMock()
        self.executor = Executor(self.networking)

        self.first_block_chain_b = Block(CBlock(), BlockOrigin.public)
        self.first_block_chain_b.height = 1
        self.first_block_chain_b.prevBlock = test_util.genesis_block
        self.first_block_chain_b.cached_hash = '1b'

        self.second_block_chain_b = Block(CBlock(), BlockOrigin.public)
        self.second_block_chain_b.height = 2
        self.second_block_chain_b.prevBlock = self.first_block_chain_b
        self.second_block_chain_b.cached_hash = '2b'

        self.first_block_chain_a = Block(CBlock(), BlockOrigin.private)
        self.first_block_chain_a.height = 1
        self.first_block_chain_a.prevBlock = test_util.genesis_block
        self.first_block_chain_a.cached_hash = '1a'

        self.second_block_chain_a = Block(CBlock(), BlockOrigin.private)
        self.second_block_chain_a.height = 2
        self.second_block_chain_a.prevBlock = self.first_block_chain_a
        self.second_block_chain_a.cached_hash = '2a'
    def test_block_message_remove_from_blocks_in_flight(self):
        message = messages.msg_block()
        cblock = CBlock()
        message.block = cblock

        block = Block(None, BlockOrigin.private)
        block.cached_hash = message.block.GetHash()

        self.chain.blocks = {block.hash(): block}
        self.networking.blocks_in_flight = {block.hash(): 'in_flight'}

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

        self.assertEqual(len(self.networking.blocks_in_flight), 0)
Example #26
0
    def getwork_submit(self, hexstr):
        data = hexstr.decode('hex')
        if len(data) != 128:
            err = { "code" : -5, "message" : "invalid data" }
            return (None, err)

        data = bufreverse(data)
        blkhdr = data[:80]
        # FIXME(obulpathi): can we just use the blkheader?
        #f = cStringIO.StringIO(blkhdr)
        f = cStringIO.StringIO(data)
        block_tmp = CBlock()
        block_tmp.deserialize(f)

        if block_tmp.hashMerkleRoot not in self.work_blocks:
            return (False, None)

        block = self.work_blocks[block_tmp.hashMerkleRoot]
        block.nTime = block_tmp.nTime
        block.nNonce = block_tmp.nNonce

        res = self.chaindb.putblock(block)

        return (res, None)
    def test_request_get_headers_very_long_chain(self, mock):
        first_block = Block(CBlock(), BlockOrigin.public)
        first_block.prevBlock = None
        first_block.cached_hash = '0'

        tmp = first_block
        for i in range(1, 17):
            block = Block(CBlock(), BlockOrigin.public)
            block.prevBlock = tmp
            block.cached_hash = str(i)

            tmp = block

        mock.return_value = tmp

        headers = chainutil.request_get_headers([MagicMock()],
                                                BlockOrigin.public)

        self.assertEqual(len(headers), 5)
        self.assertEqual(headers[0], '16')
        self.assertEqual(headers[1], '15')
        self.assertEqual(headers[2], '13')
        self.assertEqual(headers[3], '9')
        self.assertEqual(headers[4], '1')
Example #28
0
    def getwork_submit(self, hexstr):
        data = hexstr.decode('hex')
        if len(data) != 128:
            err = { "code" : -5, "message" : "invalid data" }
            return (None, err)

        data = bufreverse(data)
        blkhdr = data[:80]
        # why are we passing blkheader for constructing block, should not we pass the whole block"
        # f = cStringIO.StringIO(blkhdr)
        f = cStringIO.StringIO(data)
        block_tmp = CBlock()
        block_tmp.deserialize(f)

        if block_tmp.hashMerkleRoot not in self.work_blocks:
            return (False, None)

        block = self.work_blocks[block_tmp.hashMerkleRoot]
        block.nTime = block_tmp.nTime
        block.nNonce = block_tmp.nNonce

        res = self.chaindb.putblock(block)

        return (res, None)
Example #29
0
    def getblock(self, block_hash):
        """Get block <block_hash>

        Raises IndexError if block_hash is not valid.
        """
        try:
            block_hash = b2lx(block_hash)
        except TypeError:
            raise TypeError('%s.getblock(): block_hash must be bytes; got %r instance' %
                    (self.__class__.__name__, block_hash.__class__))
        try:
            r = self._call('getblock', block_hash, False)
        except JSONRPCException as ex:
            raise IndexError('%s.getblock(): %s (%d)' %
                    (self.__class__.__name__, ex.error['message'], ex.error['code']))
        return CBlock.deserialize(unhexlify(r))
Example #30
0
    def test_adopt_two_blocks_lead_public(self):
        third_block_chain_b = Block(CBlock(), BlockOrigin.public)
        third_block_chain_b.height = 3
        third_block_chain_b.prevBlock = self.second_block_chain_b
        third_block_chain_b.cached_hash = '3b'

        self.executor.execute(Action.adopt, self.first_block_chain_a, third_block_chain_b)

        self.assertTrue(self.networking.send_inv.called)

        blocks = [block.hash() for block in self.networking.send_inv.call_args[0][0]]

        self.assertEqual(len(blocks), 3)
        self.assertTrue('1b' in blocks)
        self.assertTrue('2b' in blocks)
        self.assertTrue('3b' in blocks)
Example #31
0
    def test_override_two_blocks_lead_private(self):
        third_block_chain_a = Block(CBlock(), BlockOrigin.private)
        third_block_chain_a.height = 3
        third_block_chain_a.prevBlock = self.second_block_chain_a
        third_block_chain_a.cached_hash = '3a'

        self.executor.execute(Action.override, third_block_chain_a, self.first_block_chain_b)

        self.assertTrue(self.networking.send_inv.called)

        blocks = [block.hash() for block in self.networking.send_inv.call_args[0][0]]

        self.assertEqual(len(blocks), 3)
        self.assertTrue('1a' in blocks)
        self.assertTrue('2a' in blocks)
        self.assertTrue('1b' in blocks)
	def provide_block(self, block_data):
		"""THIS METHOD WILL BLOCK UNTIL SENDING IS COMPLETE"""
		tx_count, read_pos = decode_varint(block_data, 80)
		self.send_lock.acquire()
		try:
			relay_data = pack('>3I', self.MAGIC_BYTES, self.BLOCK_TYPE, tx_count) + block_data[0:80]
			wire_bytes = 3 * 4 + 80
			for i in range(0, tx_count):
				tx_start = read_pos
				read_pos += 4

				tx_in_count, read_pos = decode_varint(block_data, read_pos)
				for j in range(0, tx_in_count):
					read_pos += 36
					script_len, read_pos = decode_varint(block_data, read_pos)
					read_pos += script_len + 4

				tx_out_count, read_pos = decode_varint(block_data, read_pos)
				for j in range(0, tx_out_count):
					read_pos += 8
					script_len, read_pos = decode_varint(block_data, read_pos)
					read_pos += script_len

				read_pos += 4

				transaction_data = block_data[tx_start:read_pos]
				tx_index = self.send_transaction_cache.get_index(transaction_data)
				if tx_index is None:
					relay_data += pack('>H', 0xffff) + pack('>HB', len(transaction_data) >> 8, len(transaction_data) & 0xff) + transaction_data
					wire_bytes += 2 + 3 + len(transaction_data)
				else:
					relay_data += pack('>H', tx_index)
					wire_bytes += 2
					self.send_transaction_cache.remove(transaction_data)

			relay_data += pack('>3I', self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0)
			self.relay_sock.sendall(relay_data)

			if deserialize_utils:
				block = CBlock.deserialize(block_data)
				print("Sent block " + str(b2lx(block.GetHash())) + " of size " + str(len(block_data)) + " with " + str(wire_bytes) + " bytes on the wire")
			else:
				print("Sent block of size " + str(len(block_data)) + " with " + str(wire_bytes) + " bytes on the wire")
		except (OSError, socket.error) as err:
			print("Failed to send to relay node: ", err)
		finally:
			self.send_lock.release()
Example #33
0
    def getblock(self, block_hash):
        """Get block <block_hash>

        Raises IndexError if block_hash is not valid.
        """
        try:
            block_hash = b2lx(block_hash)
        except TypeError:
            raise TypeError('%s.getblock(): block_hash must be bytes; got %r instance' %
                    (self.__class__.__name__, block_hash.__class__))
        try:
            # With this change ( https://github.com/bitcoin/bitcoin/commit/96c850c20913b191cff9f66fedbb68812b1a41ea#diff-a0c8f511d90e83aa9b5857e819ced344 ),
            # bitcoin core's rpc takes 0/1/2 instead of true/false as the 2nd argument which specifies verbosity, since v0.15.0.
            # The change above is backward-compatible so far; the old "false" is taken as the new "0".
            r = self._call('getblock', block_hash, False)
        except InvalidAddressOrKeyError as ex:
            raise IndexError('%s.getblock(): %s (%d)' %
                    (self.__class__.__name__, ex.error['message'], ex.error['code']))
        return CBlock.deserialize(unhexlify(r))
Example #34
0
class BitcoinRegTest(BitcoinMainNet):
    # Mimick bitcoinlib "core_params" global
    NAME = 'bitcoin_regtest'
    GENESIS_BLOCK = CBlock.deserialize(
        x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'
          ))
    SUBSIDY_HALVING_INTERVAL = 150
    PROOF_OF_WORK_LIMIT = 2**256 - 1 >> 1

    # Mimick bitcoinlib "params" global
    MESSAGE_START = b'\xfa\xbf\xb5\xda'
    DEFAULT_PORT = 18444
    RPC_PORT = 18332
    DNS_SEEDS = ()
    BASE58_PREFIXES = {
        'PUBKEY_ADDR': 111,
        'SCRIPT_ADDR': 196,
        'SECRET_KEY': 239
    }
    CHECKPOINTS = {}
Example #35
0
    def deserialize(self, raw):
        """Deserialize hex-encoded block/block header."""
        only_header = False
        if len(raw) == 160:
            only_header = True

        block = None
        block_header = None

        try:
            if only_header:
                block_header = CBlockHeader.deserialize(x(raw))
            else:
                # We don't use block.get_header() in case the header is
                # correct but the rest of the block isn't.
                block_header = CBlockHeader.deserialize(x(raw[0:160]))
                block = CBlock.deserialize(x(raw))
        except Exception:
            pass

        return (block, block_header)
Example #36
0
    def deserialize(self, raw):
        """Deserialize hex-encoded block/block header."""
        only_header = False
        if len(raw) == 160:
            only_header = True

        block = None
        block_header = None

        try:
            if only_header:
                block_header = CBlockHeader.deserialize(x(raw))
            else:
                # We don't use block.get_header() in case the header is
                # correct but the rest of the block isn't.
                block_header = CBlockHeader.deserialize(x(raw[0:160]))
                block = CBlock.deserialize(x(raw))
        except Exception:
            pass

        return (block, block_header)
Example #37
0
    def getblock(self, block_hash):
        """Get block <block_hash>

        Raises IndexError if block_hash is not valid.
        """
        try:
            block_hash = b2lx(block_hash)
        except TypeError:
            raise TypeError(
                '%s.getblock(): block_hash must be bytes; got %r instance' %
                (self.__class__.__name__, block_hash.__class__))
        try:
            # With this change ( https://github.com/bitcoin/bitcoin/commit/96c850c20913b191cff9f66fedbb68812b1a41ea#diff-a0c8f511d90e83aa9b5857e819ced344 ),
            # bitcoin core's rpc takes 0/1/2 instead of true/false as the 2nd argument which specifies verbosity, since v0.15.0.
            # The change above is backward-compatible so far; the old "false" is taken as the new "0".
            r = self._call('getblock', block_hash, False)
        except InvalidAddressOrKeyError as ex:
            raise IndexError('%s.getblock(): %s (%d)' %
                             (self.__class__.__name__, ex.error['message'],
                              ex.error['code']))
        return CBlock.deserialize(unhexlify(r))
Example #38
0
	def provide_block(self, block_data):
		# THIS METHOD WILL BLOCK UNTIL SENDING IS COMPLETE
		tx_count, read_pos = decode_varint(block_data, 80)
		self.send_lock.acquire()
		try:
			txn_bytes = []
			for i in range(0, tx_count):
				tx_start = read_pos

				tx_in_count, read_pos = decode_varint(block_data, read_pos + 4)
				for j in range(0, tx_in_count):
					script_len, read_pos = decode_varint(block_data, read_pos + 36)
					read_pos += script_len + 4

				tx_out_count, read_pos = decode_varint(block_data, read_pos)
				for j in range(0, tx_out_count):
					script_len, read_pos = decode_varint(block_data, read_pos + 8)
					read_pos += script_len

				read_pos += 4

				txn_bytes.append(block_data[tx_start:read_pos])

			send_data = pack('>3I', self.MAGIC_BYTES, self.BLOCK_TYPE, tx_count) + block_data[0:80] + b''.join((self.compress_tx(t) for t in txn_bytes))
			self.relay_sock.sendall(send_data)
			self.relay_sock.sendall(pack('>3I', self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0))

			if deserialize_utils:
				block = CBlock.deserialize(block_data)
				print("Sent block " + str(b2lx(block.GetHash())) + " of size " + str(len(block_data)) + " with " + str(len(send_data)) + " bytes on the wire")
			else:
				print("Sent block of size " + str(len(block_data)) + " with " + str(len(send_data)) + " bytes on the wire")
		except (OSError, socket.error) as err:
			print("Failed to send to relay node: ", err)
			self.relay_sock.shutdown(socket.SHUT_RDWR)
		finally:
			self.send_lock.release()
Example #39
0
class BitcoinTestNet(BitcoinMainNet):
    # Mimick bitcoinlib "core_params" global
    NAME = 'bitcoin_testnet'
    GENESIS_BLOCK = CBlock.deserialize(
        x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'
          ))

    # Mimick bitcoinlib "params" global
    MESSAGE_START = b'\x0b\x11\x09\x07'
    DEFAULT_PORT = 18333
    RPC_PORT = 18332
    DNS_SEEDS = (('bitcoin.petertodd.org',
                  'testnet-seed.bitcoin.petertodd.org'),
                 ('bluematt.me', 'testnet-seed.bluematt.me'))
    BASE58_PREFIXES = {
        'PUBKEY_ADDR': 111,
        'SCRIPT_ADDR': 196,
        'SECRET_KEY': 239
    }

    # Not part of bitcoinlib
    CHECKPOINTS = {
        0: 0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943L,
    }
    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)
Example #41
0
from bitcoin.core import CBlock
from bitcoin.core import CTxIn, CTxOut, CTransaction

txin = CTxIn()
txout = CTxOut()

txin.scriptSig = 0x04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73
txin.prevout = 0x0000000000000000000000000000000000000000000000000000000000000000FFFFFFFF
print txin, txin.is_valid()
tx.vout.nValue = 5000000000
tx.vout.scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704

tx = CTransaction()
tx.vin = [txin]
tx.vout = [txout]
"""
tx.vout.scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG
"""

block = CBlock()
block.nVersion = 1
block.hashPrevBlock = 0
block.hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
block.nTime    = 1231006505
block.nBits    = 0x1d00ffff
block.nNonce   = 2083236893
block.vtx = [tx]
block.sha256 = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
print block.is_valid()
Example #42
0
            log.write(tx.__repr__())
            return False
    return True

for height in xrange(1):
# for height in xrange(end_height):
    if height < start_height:
        continue
    heightidx = HeightIdx()
    heightidx.deserialize(str(height))

    blkhash = heightidx.blocks[0]
    ser_hash = ser_uint256(blkhash)

    f = cStringIO.StringIO(chaindb.getblock(ser_hash))
    block = CBlock()
    block.deserialize(f)

    start_time = time.time()

    for tx_tmp in block.vtx:
        if tx_tmp.is_coinbase():
            print "Tx is coinbase"
            continue

        scanned_tx += 1

        if not scan_tx(tx_tmp):
            failures += 1
            sys.exit(1)
Example #43
0
log = Log.Log(SETTINGS['log'])
mempool = MemPool.MemPool(log)
chaindb = ChainDb.ChainDb(SETTINGS['db'], log, mempool, NETWORKS[MY_NETWORK])

scanned = 0
failures = 0

for height in xrange(chaindb.getheight()):
	heightidx = ChainDb.HeightIdx()
	heightidx.deserialize(chaindb.height[str(height)])

	blkhash = heightidx.blocks[0]
	ser_hash = ser_uint256(blkhash)

	f = cStringIO.StringIO(chaindb.blocks[ser_hash])
	block = CBlock()
	block.deserialize(f)

	if not block.is_valid():
		log.write("block %064x failed" % (blkhash,))
		failures += 1

	scanned += 1
	if (scanned % 1000) == 0:
		log.write("Scanned height %d (%d failures)" % (
			height, failures))


log.write("Scanned %d blocks (%d failures)" % (scanned, failures))

Example #44
0
 def __init__(self, protover=PROTO_VERSION):
     super(msg_block, self).__init__(protover)
     self.block = CBlock()
Example #45
0
# construct txout
txout = CTxOut()
txout.nValue = 5000000000
txout.scriptPubKey = binascii.unhexlify(scriptPubKeyHex)

# create transaction
tx = CTransaction()
tx.vin.append(txin)
tx.vout.append(txout)
tx.calc_sha256()
print tx
print "Transaction: ", tx.is_valid()
print "hash: ", hex(tx.sha256)
print "Hash: ", "0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"

block = CBlock()
block.nVersion = 1
block.hashPrevBlock = 0
block.hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
block.nTime    = 1231006505
block.nBits    = 486604799 # 0x1d00ffff
block.nNonce   = 2083236893
block.vtx = [tx]

block.calc_sha256()
print "Calculated hash: ", hex(block.sha256)
print " >>>>>>>>>>>>>>: ", "0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
#
#print block.is_valid()

genesis = binascii.hexlify(block.serialize())
Example #46
0
def loadfile(filename,start,end,chaindb):
	fd = os.open(filename, os.O_RDONLY)
	#self.log.write("IMPORTING DATA FROM " + filename)
	buf = ''
	wanted = 4096

	count = 1

	while True:
		if wanted > 0:
			if wanted < 4096:
				wanted = 4096
			s = os.read(fd, wanted)
			if len(s) == 0:
				break

			buf += s
			wanted = 0

		buflen = len(buf)
		startpos = string.find(buf, msg_start)
		if startpos < 0:
			wanted = 8
			continue

		sizepos = startpos + 4
		blkpos = startpos + 8
		if blkpos > buflen:
			wanted = 8
			continue

		blksize = struct.unpack("<i", buf[sizepos:blkpos])[0]
		if (blkpos + blksize) > buflen:
			wanted = 8 + blksize
			continue

		ser_blk = buf[blkpos:blkpos+blksize]
		buf = buf[blkpos+blksize:]

		f = cStringIO.StringIO(ser_blk)
		block = CBlock()
		block.deserialize(f)

		count += 1

		skip_load = (count < start)
		if skip_load:
			if ((count % 10000) == 0):
				print "skiping: %d" % count
			continue

		if (end > -1) and (count >= end):
			print "Exit!"
			sys.exit(0)	

		ret = chaindb.putblock(block)

		height = chaindb.getheight()

		#if count == 778:
		#	print repr(block)

		heightidx = ChainDb.HeightIdx()
                heightidx.deserialize(chaindb.height(str(height)))
                blkhash = heightidx.blocks[0]



		skiped = False
		scanned = False
		
		#skip_scan = (height < skip_scan_height)	
		#if not skip_scan:
		#	if ret:
		#		scanned = scan_vtx(chaindb,block)
		
		strBlkHash = hex(blkhash).replace('0x','').replace('L','')
		print "Count: %d Putblock: %s Height: %d BlockHash: %s" % (count,ret,height,strBlkHash)

	print "tell: %d" % fd.tell()
	return count
Example #47
0
 def msg_deser(cls, f, protover=PROTO_VERSION):
     c = cls()
     c.block = CBlock.stream_deserialize(f)
     return c
Example #48
0
# construct txout
txout = CTxOut()
txout.nValue = 5000000000
txout.scriptPubKey = binascii.unhexlify(scriptPubKeyHex)

# create transaction
tx = CTransaction()
tx.vin.append(txin)
tx.vout.append(txout)
tx.calc_sha256()
#print tx
#print "Transaction: ", tx.is_valid()
#print "hash: ", hex(tx.sha256)
#print "Hash: ", "0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"

block = CBlock()
block.nVersion = 1
block.hashPrevBlock = 0
block.hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
block.nTime    = 1231006505
block.nBits    = 0x1f00ffff
block.vtx = [tx]


i = 0
#target = 6901641034498895230248057944249341782018790077074986006051269912821760
target = uint256_from_compact(block.nBits)
print "Target: \t%064x" % target
for i in xrange(1000000000000000):
    block.nNonce   = i
    block.sha256 = None
	def connect(self):
		self.send_lock.acquire()
		self.recv_transaction_cache = FlaggedArraySet(1000)
		self.send_transaction_cache = FlaggedArraySet(1000)
		self.relay_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.relay_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
		try:
			try:
				self.relay_sock.connect((self.server, 8336))
				self.relay_sock.sendall(pack('>3I', self.MAGIC_BYTES, self.VERSION_TYPE, len(self.VERSION_STRING)))
				self.relay_sock.sendall(self.VERSION_STRING)
			finally:
				self.send_lock.release()

			while True:
				msg_header = unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL))
				if msg_header[0] != self.MAGIC_BYTES:
					raise ProtocolError("Invalid magic bytes: " + str(msg_header[0]) + " != " +  str(self.MAGIC_BYTES))
				if msg_header[2] > 1000000:
					raise ProtocolError("Got message too large: " + str(msg_header[2]))

				if msg_header[1] == self.VERSION_TYPE:
					version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					if version != self.VERSION_STRING:
						raise ProtocolError("Got back unknown version type " + str(version))
					print("Connected to relay node with protocol version " + str(version))
				elif msg_header[1] == self.BLOCK_TYPE:
					if msg_header[2] > 10000:
						raise ProtocolError("Got a BLOCK message with far too many transactions: " + str(msg_header[2]))

					wire_bytes = 3 * 4

					header_data = self.relay_sock.recv(80, socket.MSG_WAITALL)
					wire_bytes += 80
					self.data_recipient.provide_block_header(header_data)
					if deserialize_utils:
						header = CBlockHeader.deserialize(header_data)
						print("Got block header: " + str(b2lx(header.GetHash())))

					if msg_header[2] < 0xfd:
						block_data = header_data + pack('B', msg_header[2])
					elif msg_header[2] < 0xffff:
						block_data = header_data + b'\xfd' + pack('<H', msg_header[2])
					elif msg_header[2] < 0xffffffff:
						block_data = header_data + b'\xfe' + pack('<I', msg_header[2])
					else:
						raise ProtocolError("WTF?????")

					for i in range(0, msg_header[2]):
						index = unpack('>H', self.relay_sock.recv(2, socket.MSG_WAITALL))[0]
						wire_bytes += 2
						if index == 0xffff:
							data_length = unpack('>HB', self.relay_sock.recv(3, socket.MSG_WAITALL))
							wire_bytes += 3
							data_length = data_length[0] << 8 | data_length[1]
							if data_length > 1000000:
								raise ProtocolError("Got in-block transaction of size > MAX_BLOCK_SIZE: " + str(dat_length))
							transaction_data = self.relay_sock.recv(data_length, socket.MSG_WAITALL)
							wire_bytes += data_length
							if deserialize_utils:
								transaction = CTransaction.deserialize(transaction_data)
								print("Got in-block full transaction: " + str(b2lx(transaction.GetHash())) + " of length " + str(data_length))
							else:
								print("Got in-block full transaction of length " + str(data_length))
							block_data += transaction_data
						else:
							transaction_data = self.recv_transaction_cache.get_by_index(index)
							if transaction_data is None:
								raise ProtocolError("Got index for a transaction we didn't have")
							self.recv_transaction_cache.remove(transaction_data)
							block_data += transaction_data

					self.data_recipient.provide_block(block_data)

					if deserialize_utils:
						print("Got full block " + str(b2lx(header.GetHash())) + " with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes")
						block = CBlock.deserialize(block_data)
						print("Deserialized full block " + str(b2lx(block.GetHash())))
					else:
						print("Got full block with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes")

					if unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL)) != (self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0):
						raise ProtocolError("Invalid END_BLOCK message after block")

				elif msg_header[1] == self.TRANSACTION_TYPE:
					if msg_header[2] > self.MAX_RELAY_TRANSACTION_BYTES and (self.recv_transaction_cache.get_flag_count() >= self.MAX_EXTRA_OVERSIZE_TRANSACTIONS or msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES):
						raise ProtocolError("Got a freely relayed transaction too large (" + str(msg_header[2]) + ") bytes")
					transaction_data = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					self.recv_transaction_cache.add(transaction_data, msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES)

					self.data_recipient.provide_transaction(transaction_data)

					if deserialize_utils:
						transaction = CTransaction.deserialize(transaction_data)
						print("Got transaction: " + str(b2lx(transaction.GetHash())))
					else:
						print("Got transaction of length " + str(msg_header[2]))

				elif msg_header[1] == self.MAX_VERSION_TYPE:
					version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					print("Relay network now uses version " + str(version) + " (PLEASE UPGRADE)")

				else:
					raise ProtocolError("Unknown message type: " + str(msg_header[1]))

		except (OSError, socket.error) as err:
			print("Lost connect to relay node:", err)
			self.reconnect()
		except ProtocolError as err:
			print("Error processing data from relay node:", err)
			self.reconnect()
		except Exception as err:
			print("Unknown error processing data from relay node:", err)
			self.reconnect()
Example #50
0
def getblock(block_hash):
    block_hex = BACKEND().getblock(block_hash)
    return CBlock.deserialize(util.unhexlify(block_hex))