예제 #1
0
    def process_block(self, block, auth):
        logger.debug('process_block %s' % util.b2h(block))

        hash = self.net.hash_block_header(block[:80])
        target = self._get_target(auth['difficulty'])
        logger.debug('hash %s' % util.b2h(hash))
        logger.debug('target %s' % util.b2h(target))

        hash_long = util.bytes_to_long(hash)
        target_long = util.bytes_to_long(target)
        if hash_long > target_long:
            logger.debug("Hash is bigger than target")
            return False

        real_target = util.bytes_to_long(
            util.h2b(self.block_template['target']))
        logger.debug('real target %s' % self.block_template['target'])

        database.share_accepted(auth['id'])
        if hash_long < real_target:
            logger.debug("Found block candidate")
            for i in self.tx:
                block += i.raw_tx
            logger.debug("Submitting %s" % util.b2h(block))

            result = self.net.submitblock(util.b2h(block))
            if result is None:
                database.block_found(auth['id'], self.block_template['height'])
                self.block_event.set()

        return True
예제 #2
0
파일: work.py 프로젝트: dlunch/poolserver
    def process_block(self, block, auth):
        logger.debug('process_block %s' % util.b2h(block))

        hash = self.net.hash_block_header(block[:80])
        target = self._get_target(auth['difficulty'])
        logger.debug('hash %s' % util.b2h(hash))
        logger.debug('target %s' % util.b2h(target))

        hash_long = util.bytes_to_long(hash)
        target_long = util.bytes_to_long(target)
        if hash_long > target_long:
            logger.debug("Hash is bigger than target")
            return False

        real_target = util.bytes_to_long(
            util.h2b(self.block_template['target']))
        logger.debug('real target %s' % self.block_template['target'])

        database.share_accepted(auth['id'])
        if hash_long < real_target:
            logger.debug("Found block candidate")
            for i in self.tx:
                block += i.raw_tx
            logger.debug("Submitting %s" % util.b2h(block))

            result = self.net.submitblock(util.b2h(block))
            if result is None:
                database.block_found(auth['id'],
                                     self.block_template['height'])
                self.block_event.set()

        return True
예제 #3
0
파일: work.py 프로젝트: dlunch/poolserver
    def getwork(self, params, uri, auth):
        if len(params) > 0:
            block = util.h2b(params[0])
            merkle_root = block[36:68]

            if merkle_root not in self.work_data:
                logger.error("Unknown worker submission")
                return False
            coinbase_tx = self.work_data[merkle_root].raw_tx
            block += util.encode_size(len(self.tx) + 1)
            block += coinbase_tx

            result = self.process_block(block, auth)

            del self.work_data[merkle_root]
            return result

        if uri == config.longpoll_uri:
            event = gevent.event.Event()
            self.add_longpoll_event(event)
            event.wait()

        coinbase_tx = self.create_coinbase_tx(
            util.h2b(self.get_work_id()), b'')
        merkle_root = MerkleTree.merkle_root_from_branch(
            coinbase_tx.raw_tx, self.merkle_branches)
        ntime = struct.pack(b'<I', self.block_template['curtime'])
        block_header = self.create_block_header(merkle_root, ntime,
                                                b'\x00\x00\x00\x00')
        block_header += (b"\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x80")

        self.work_data[merkle_root] = coinbase_tx

        # To little endian
        block_header = b''.join([block_header[x:x+4][::-1]
                                for x in range(0, len(block_header), 4)])
        target = util.b2h(self._get_target(auth['difficulty'])[::-1])
        block_header = util.b2h(block_header)
        #TODO midstate, hash1 (deprecated)
        return {'data': block_header,
                'target': target}
예제 #4
0
    def getwork(self, params, uri, auth):
        if len(params) > 0:
            block = util.h2b(params[0])
            merkle_root = block[36:68]

            if merkle_root not in self.work_data:
                logger.error("Unknown worker submission")
                return False
            coinbase_tx = self.work_data[merkle_root].raw_tx
            block += util.encode_size(len(self.tx) + 1)
            block += coinbase_tx

            result = self.process_block(block, auth)

            del self.work_data[merkle_root]
            return result

        if uri == config.longpoll_uri:
            event = gevent.event.Event()
            self.add_longpoll_event(event)
            event.wait()

        coinbase_tx = self.create_coinbase_tx(util.h2b(self.get_work_id()),
                                              b'')
        merkle_root = MerkleTree.merkle_root_from_branch(
            coinbase_tx.raw_tx, self.merkle_branches)
        ntime = struct.pack(b'<I', self.block_template['curtime'])
        block_header = self.create_block_header(merkle_root, ntime,
                                                b'\x00\x00\x00\x00')
        block_header += (b"\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                         b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x80")

        self.work_data[merkle_root] = coinbase_tx

        # To little endian
        block_header = b''.join([
            block_header[x:x + 4][::-1] for x in range(0, len(block_header), 4)
        ])
        target = util.b2h(self._get_target(auth['difficulty'])[::-1])
        block_header = util.b2h(block_header)
        #TODO midstate, hash1 (deprecated)
        return {'data': block_header, 'target': target}
예제 #5
0
    def getblocktemplate(self, params, uri, auth):
        """For worker"""

        longpollid = 'init'
        mode = 'template'  # For older client
        data = None
        for i in params:
            if 'longpollid' in i:
                longpollid = i['longpollid']
            if 'mode' in i:
                mode = i['mode']
            if 'data' in i:
                data = i['data']
        if mode == 'submit':
            try:
                block = util.h2b(data)
                sizelen, tx_size = util.decode_size(block[80:89])
                ptr = 80 + sizelen

                txlen = CoinbaseTransaction.verify(block[ptr:],
                                                   self.generation_pubkey)
                result = self.process_block(block[:ptr + txlen], auth)
                if result:
                    return None
            except:
                logger.error("Exception while processing block")
                logger.error(traceback.format_exc())
            return 'Rejected'

        if longpollid != 'init' or uri == config.longpoll_uri:
            event = gevent.event.Event()
            self.add_longpoll_event(event)
            event.wait()
            longpollid = self.get_work_id()
        coinbase_tx = self.create_coinbase_tx(b'', b'')
        block_template = {
            k: self.block_template[k]
            for k in self.block_template
            if k not in ['coinbasevalue', 'coinbaseaux', 'coinbaseflags']
        }

        block_template['target'] = util.b2h(
            self._get_target(auth['difficulty']))
        block_template['mutable'] = ["coinbase/append", "submit/coinbase"]
        block_template['transactions'] = [x.serialize() for x in self.tx]
        block_template['coinbasetxn'] = coinbase_tx.serialize()

        #Long polling extension
        block_template['longpollid'] = longpollid
        block_template['expires'] = 120
        block_template['submitold'] = True
        block_template['longpolluri'] = config.longpoll_uri

        return block_template
예제 #6
0
파일: work.py 프로젝트: dlunch/poolserver
    def getblocktemplate(self, params, uri, auth):
        """For worker"""

        longpollid = 'init'
        mode = 'template'  # For older client
        data = None
        for i in params:
            if 'longpollid' in i:
                longpollid = i['longpollid']
            if 'mode' in i:
                mode = i['mode']
            if 'data' in i:
                data = i['data']
        if mode == 'submit':
            try:
                block = util.h2b(data)
                sizelen, tx_size = util.decode_size(block[80:89])
                ptr = 80 + sizelen

                txlen = CoinbaseTransaction.verify(block[ptr:],
                                                   self.generation_pubkey)
                result = self.process_block(block[:ptr+txlen], auth)
                if result:
                    return None
            except:
                logger.error("Exception while processing block")
                logger.error(traceback.format_exc())
            return 'Rejected'

        if longpollid != 'init' or uri == config.longpoll_uri:
            event = gevent.event.Event()
            self.add_longpoll_event(event)
            event.wait()
            longpollid = self.get_work_id()
        coinbase_tx = self.create_coinbase_tx(b'', b'')
        block_template = {k: self.block_template[k]
                          for k in self.block_template
                          if k not in
                          ['coinbasevalue', 'coinbaseaux', 'coinbaseflags']}

        block_template['target'] = util.b2h(
            self._get_target(auth['difficulty']))
        block_template['mutable'] = ["coinbase/append", "submit/coinbase"]
        block_template['transactions'] = [x.serialize() for x in self.tx]
        block_template['coinbasetxn'] = coinbase_tx.serialize()

        #Long polling extension
        block_template['longpollid'] = longpollid
        block_template['expires'] = 120
        block_template['submitold'] = True
        block_template['longpolluri'] = config.longpoll_uri

        return block_template
예제 #7
0
파일: work.py 프로젝트: dlunch/poolserver
    def get_stratum_work(self, extranonce1):
        result = []
        result.append(self.get_work_id())  # Job id
        prevblockhash = util.h2b(
            self.block_template['previousblockhash'])[::-1]
        prevblockhash = b''.join([prevblockhash[x:x+4][::-1]
                                 for x in range(0, len(prevblockhash), 4)])
        result.append(util.b2h(prevblockhash))

        coinbase_tx = self.create_coinbase_tx(
            extranonce1, b'\x00\x00\x00\x00')
        coinbase_data = bytearray(coinbase_tx.raw_tx)
        orig_len = coinbase_data[41]
        firstpart_len = orig_len - 4 - config.extranonce2_size
        result.append(util.b2h(coinbase_data[:42+firstpart_len]))
        result.append(util.b2h(coinbase_data[42+orig_len:]))
        result.append([util.b2h(x) for x in self.merkle_branches])
        result.append(util.b2h(
                      struct.pack(b'>I', self.block_template['version'])))
        result.append(self.block_template['bits'])
        result.append(util.b2h(
                      struct.pack(b'>I', self.block_template['curtime'])))
        result.append(True)

        return result
예제 #8
0
    def get_stratum_work(self, extranonce1):
        result = []
        result.append(self.get_work_id())  # Job id
        prevblockhash = util.h2b(
            self.block_template['previousblockhash'])[::-1]
        prevblockhash = b''.join([
            prevblockhash[x:x + 4][::-1]
            for x in range(0, len(prevblockhash), 4)
        ])
        result.append(util.b2h(prevblockhash))

        coinbase_tx = self.create_coinbase_tx(extranonce1, b'\x00\x00\x00\x00')
        coinbase_data = bytearray(coinbase_tx.raw_tx)
        orig_len = coinbase_data[41]
        firstpart_len = orig_len - 4 - config.extranonce2_size
        result.append(util.b2h(coinbase_data[:42 + firstpart_len]))
        result.append(util.b2h(coinbase_data[42 + orig_len:]))
        result.append([util.b2h(x) for x in self.merkle_branches])
        result.append(
            util.b2h(struct.pack(b'>I', self.block_template['version'])))
        result.append(self.block_template['bits'])
        result.append(
            util.b2h(struct.pack(b'>I', self.block_template['curtime'])))
        result.append(True)

        return result
예제 #9
0
    def __init__(self, block_template, generation_pubkey, extranonce1,
                 extranonce2):
        #BIP 0034
        coinbase_script = util.encode_height(block_template['height'])

        if 'coinbaseaux' in block_template:
            for i in block_template['coinbaseaux']:
                data = util.h2b(block_template['coinbaseaux'][i])
                coinbase_script += data
        if 'coinbaseflags' in block_template:
            data = util.h2b(block_template['coinbaseflags'])
            coinbase_script += data

        coinbase_script += extranonce1
        coinbase_script += extranonce2

        if 'coinbasevalue' in block_template:
            coinbase_value = block_template['coinbasevalue']
        else:
            tx = Transaction(block_template['coinbasetxn'])
            coinbase_value = tx.output[0]['value']

        output_script = b'\x76\xa9\x14' + generation_pubkey + b'\x88\xac'

        result = b'\x01\x00\x00\x00'  # Version
        result += b'\x01'  # In counter(1)
        result += b'\x00' * 32  # Input(None)
        result += b'\xff\xff\xff\xff'  # Input Index (None)
        result += util.encode_size(len(coinbase_script))
        result += coinbase_script
        result += b'\xff\xff\xff\xff'  # Sequence
        result += b'\x01'  # Out counter(1)
        result += struct.pack(b'<Q', coinbase_value)
        result += util.encode_size(len(output_script))
        result += output_script
        result += b'\x00\x00\x00\x00'  # Lock time

        self.raw_tx = result
        logger.debug('Generated coinbase transaction %s' %
                     util.b2h(self.raw_tx))
예제 #10
0
파일: work.py 프로젝트: dlunch/poolserver
 def get_work_id(self):
     self.seq += 1
     return util.b2h(struct.pack(b'<I', self.seq))
예제 #11
0
 def serialize(self):
     return {'data': util.b2h(self.raw_tx)}
예제 #12
0
 def serialize(self):
     return {'data': util.b2h(self.raw_tx)}
예제 #13
0
 def mining_subscribe(self, params, uri, auth):
     self.pusher = gevent.spawn(self.block_pusher)
     nonce1 = util.b2h(self.extranonce1)
     return [['mining.notify', 'ae6812eb4cd7735a302a8a9dd95cf71f'],
             nonce1, config.extranonce2_size]
예제 #14
0
 def mining_get_transactions(self, params, uri, auth):
     return [util.b2h(x.raw_tx) for x in self.work.tx]
예제 #15
0
 def get_work_id(self):
     self.seq += 1
     return util.b2h(struct.pack(b'<I', self.seq))