예제 #1
0
	def handle_readbuf(self):
		netid = self.server.netid
		while self.ac_in_buffer:
			if self.ac_in_buffer[:4] != netid:
				p = self.ac_in_buffer.find(netid)
				if p == -1:
					p = asynchat.find_prefix_at_end(self.ac_in_buffer, netid)
					if p:
						self.ac_in_buffer = self.ac_in_buffer[-p:]
					else:
						self.ac_in_buffer = b''
					break
				self.ac_in_buffer = self.ac_in_buffer[p:]
			
			cmd = self.ac_in_buffer[4:0x10].rstrip(b'\0').decode('utf8')
			payloadLen = unpack('<L', self.ac_in_buffer[0x10:0x14])[0]
			if payloadLen > MAX_PACKET_PAYLOAD:
				raise RuntimeError('Packet payload is too long (%d bytes)' % (payloadLen,))
			payloadEnd = payloadLen + 0x18
			if len(self.ac_in_buffer) < payloadEnd:
				# Don't have the whole packet yet
				break
			
			method = 'doCmd_' + cmd
			cksum = self.ac_in_buffer[0x14:0x18]
			payload = self.ac_in_buffer[0x18:payloadEnd]
			self.ac_in_buffer = self.ac_in_buffer[payloadEnd:]
			
			realcksum = dblsha(payload)[:4]
			if realcksum != cksum:
				self.logger.debug('Wrong checksum on `%s\' message (%s vs actual:%s); ignoring' % (cmd, b2a_hex(cksum), b2a_hex(realcksum)))
				return
			
			if hasattr(self, method):
				getattr(self, method)(payload)
예제 #2
0
	def withFirst(self, f):
		if isinstance(f, Txn):
			f = f.txid
		steps = self._steps
		for s in steps:
			f = dblsha(f + s)
		return f
예제 #3
0
 def recalculate(self, detailed=False):
     L = self.data
     steps = []
     if detailed:
         detail = []
         PreL = []
         StartL = 0
     else:
         detail = None
         PreL = [None]
         StartL = 2
     Ll = len(L)
     if isinstance(L[1] if Ll > 1 else L[0], Txn):
         L = list(map(lambda a: a.txid if a else a, L))
     else:
         L = list(L)
     if detailed or Ll > 1:
         while True:
             if detailed:
                 detail += L
             if Ll == 1:
                 break
             steps.append(L[1])
             if Ll % 2:
                 L += [L[-1]]
             L = PreL + [
                 dblsha(L[i] + L[i + 1]) for i in range(StartL, Ll, 2)
             ]
             Ll = len(L)
     self._steps = steps
     self.detail = detail
예제 #4
0
 def withFirst(self, f):
     if isinstance(f, Txn):
         f = f.txid
     steps = self._steps
     for s in steps:
         f = dblsha(f + s)
     return f
예제 #5
0
	def recalculate(self, detailed=False):
		L = self.data
		steps = []
		if detailed:
			detail = []
			PreL = []
			StartL = 0
		else:
			detail = None
			PreL = [None]
			StartL = 2
		Ll = len(L)
		if detailed or Ll > 1:
			if isinstance(L[1] if Ll > 1 else L[0], Txn):
				L = list(map(lambda a: a.txid if a else a, L))
			while True:
				if detailed:
					detail += L
				if Ll == 1:
					break
				steps.append(L[1])
				if Ll % 2:
					L += [L[-1]]
				L = PreL + [dblsha(L[i] + L[i + 1]) for i in range(StartL, Ll, 2)]
				Ll = len(L)
		self._steps = steps
		self.detail = detail
예제 #6
0
파일: node.py 프로젝트: vlamer/eloipool
    def makeMessage(self, cmd, payload=b""):
        cmd = cmd.encode("utf8")
        assert len(cmd) <= 12
        cmd += b"\0" * (12 - len(cmd))

        cksum = dblsha(payload)[:4]
        payloadLen = pack("<L", len(payload))
        return self.netid + cmd + payloadLen + cksum + payload
예제 #7
0
	def makeMessage(self, cmd, payload = b''):
		cmd = cmd.encode('utf8')
		assert len(cmd) <= 12
		cmd += b'\0' * (12 - len(cmd))
		
		cksum = dblsha(payload)[:4]
		payloadLen = pack('<L', len(payload))
		return self.netid + cmd + payloadLen + cksum + payload
예제 #8
0
파일: txn.py 프로젝트: luke-jr/eloipool
	def idhash(self):
		if self.data[4:6] == b'\0\1':
			if hasattr(self, 'txid'):
				del self.txid
			raise NotImplementedError
		self.txid = dblsha(self.data)
		if hasattr(self, 'witness_hash'):
			del self.witness_hash
예제 #9
0
    def makeMessage(self, cmd, payload=b''):
        cmd = cmd.encode('utf8')
        assert len(cmd) <= 12
        cmd += b'\0' * (12 - len(cmd))

        cksum = dblsha(payload)[:4]
        payloadLen = pack('<L', len(payload))
        return self.netid + cmd + payloadLen + cksum + payload
예제 #10
0
 def idhash(self):
     if self.data[4:6] == b'\0\1':
         if hasattr(self, 'txid'):
             del self.txid
         raise NotImplementedError
     self.txid = dblsha(self.data)
     if hasattr(self, 'witness_hash'):
         del self.witness_hash
예제 #11
0
def _Address2PKH(addr):
    try:
        addr = b58decode(addr, 25)
    except:
        return None
    if addr is None:
        return None
    ver = addr[0]
    cksumA = addr[-4:]
    cksumB = dblsha(addr[:-4])[:4]
    if cksumA != cksumB:
        return None
    return (ver, addr[1:-4])
예제 #12
0
def CalculateWitnessCommitment(txnobjs, nonce, force=False):
	gentx_withash = nonce
	withashes = (gentx_withash,) + tuple(a.get_witness_hash() for a in txnobjs[1:])
	
	if not force:
		txids = (gentx_withash,) + tuple(a.txid for a in txnobjs[1:])
		if withashes == txids:
			# Unnecessary
			return None
	
	wmr = MerkleTree(data=withashes).merkleRoot()
	commitment = util.dblsha(wmr + nonce)
	return commitment
예제 #13
0
파일: script.py 프로젝트: luke-jr/eloipool
def _Address2PKH(addr):
	try:
		addr = b58decode(addr, 25)
	except:
		return None
	if addr is None:
		return None
	ver = addr[0]
	cksumA = addr[-4:]
	cksumB = dblsha(addr[:-4])[:4]
	if cksumA != cksumB:
		return None
	return (ver, addr[1:-4])
예제 #14
0
    def handle_readbuf(self):
        netid = self.server.netid
        while self.ac_in_buffer:
            if self.ac_in_buffer[:4] != netid:
                p = self.ac_in_buffer.find(netid)
                if p == -1:
                    p = asynchat.find_prefix_at_end(self.ac_in_buffer, netid)
                    if p:
                        self.ac_in_buffer = self.ac_in_buffer[-p:]
                    else:
                        self.ac_in_buffer = b''
                    break
                self.ac_in_buffer = self.ac_in_buffer[p:]

            cmd = self.ac_in_buffer[4:0x10].rstrip(b'\0').decode('utf8')
            payloadLen = unpack('<L', self.ac_in_buffer[0x10:0x14])[0]
            if payloadLen > MAX_PACKET_PAYLOAD:
                raise RuntimeError('Packet payload is too long (%d bytes)' %
                                   (payloadLen, ))
            payloadEnd = payloadLen + 0x18
            if len(self.ac_in_buffer) < payloadEnd:
                # Don't have the whole packet yet
                break

            method = 'doCmd_' + cmd
            cksum = self.ac_in_buffer[0x14:0x18]
            payload = self.ac_in_buffer[0x18:payloadEnd]
            self.ac_in_buffer = self.ac_in_buffer[payloadEnd:]

            realcksum = dblsha(payload)[:4]
            if realcksum != cksum:
                self.logger.debug(
                    'Wrong checksum on `%s\' message (%s vs actual:%s); ignoring'
                    % (cmd, b2a_hex(cksum), b2a_hex(realcksum)))
                return

            if hasattr(self, method):
                getattr(self, method)(payload)
예제 #15
0
def buildStratumData(share, merkleroot):
	(prevBlock, height, bits) = MM.currentBlock
	
	data = b'\x02\0\0\0'
	data += prevBlock
	data += merkleroot
	data += share['ntime'][::-1]
	data += bits
	data += share['nonce'][::-1]

	share['bits'] = b2a_hex(bits[::-1]).decode('utf8')
	share['height'] = height
	share['merkleroot'] = b2a_hex(merkleroot[::-1]).decode('utf8')
	share['prevblock'] = b2a_hex(prevBlock[::-1]).decode('utf8')
	share['blkhash'] = b2a_hex(dblsha(data)[::-1]).decode('utf8')
	if ScryptCoin:
		share['crypto'] = 'scrypt'
	else:
		share['crypto'] = 'sha256'
	share['coin'] = CryptoCoin
	share['server'] = ServerName
	# do not touch!
	share['data'] = data
	return data
예제 #16
0
def checkShare(share):
    shareTime = share["time"] = time()

    username = share["username"]
    isstratum = False
    if "data" in share:
        # getwork/GBT
        checkData(share)
        data = share["data"]

        if username not in workLog:
            raise RejectedShare("unknown-user")
        MWL = workLog[username]

        shareMerkleRoot = data[36:68]
        if "blkdata" in share:
            pl = share["blkdata"]
            (txncount, pl) = varlenDecode(pl)
            cbtxn = bitcoin.txn.Txn(pl)
            othertxndata = cbtxn.disassemble(retExtra=True)
            coinbase = cbtxn.getCoinbase()
            wliPos = coinbase[0] + 2
            wliLen = coinbase[wliPos - 1]
            wli = coinbase[wliPos : wliPos + wliLen]
            mode = "MC"
            moden = 1
        else:
            wli = shareMerkleRoot
            mode = "MRD"
            moden = 0
            coinbase = None
    else:
        # Stratum
        isstratum = True
        wli = share["jobid"]
        buildStratumData(share, b"\0" * 32)
        mode = "MC"
        moden = 1
        othertxndata = b""
        if None not in workLog:
            # We haven't yet sent any stratum work for this block
            raise RejectedShare("unknown-work")
        MWL = workLog[None]

    if wli not in MWL:
        raise RejectedShare("unknown-work")
    (wld, issueT) = MWL[wli]
    share[mode] = wld

    share["issuetime"] = issueT

    (workMerkleTree, workCoinbase) = wld[1:3]
    share["merkletree"] = workMerkleTree
    if "jobid" in share:
        cbtxn = deepcopy(workMerkleTree.data[0])
        coinbase = workCoinbase + share["extranonce1"] + share["extranonce2"]
        cbtxn.setCoinbase(coinbase)
        cbtxn.assemble()
        data = buildStratumData(share, workMerkleTree.withFirst(cbtxn))
        shareMerkleRoot = data[36:68]

    if data in DupeShareHACK:
        raise RejectedShare("duplicate")
    DupeShareHACK[data] = None

    blkhash = dblsha(data)
    if blkhash[28:] != b"\0\0\0\0":
        raise RejectedShare("H-not-zero")
    blkhashn = LEhash2int(blkhash)

    global networkTarget
    logfunc = getattr(checkShare.logger, "info" if blkhashn <= networkTarget else "debug")
    logfunc("BLKHASH: %64x" % (blkhashn,))
    logfunc(" TARGET: %64x" % (networkTarget,))

    # NOTE: this isn't actually needed for MC mode, but we're abusing it for a trivial share check...
    txlist = workMerkleTree.data
    txlist = [deepcopy(txlist[0])] + txlist[1:]
    cbtxn = txlist[0]
    cbtxn.setCoinbase(coinbase or workCoinbase)
    cbtxn.assemble()

    if blkhashn <= networkTarget:
        logfunc("Submitting upstream")
        RBDs.append(deepcopy((data, txlist, share.get("blkdata", None), workMerkleTree, share, wld)))
        if not moden:
            payload = assembleBlock(data, txlist)
        else:
            payload = share["data"]
            if len(othertxndata):
                payload += share["blkdata"]
            else:
                payload += assembleBlock(data, txlist)[80:]
        logfunc("Real block payload: %s" % (b2a_hex(payload).decode("utf8"),))
        RBPs.append(payload)
        threading.Thread(target=blockSubmissionThread, args=(payload, blkhash, share)).start()
        bcnode.submitBlock(payload)
        if config.DelayLogForUpstream:
            share["upstreamRejectReason"] = PendingUpstream
        else:
            share["upstreamRejectReason"] = None
            share["upstreamResult"] = True
        MM.updateBlock(blkhash)

        # Gotwork hack...
    if gotwork and blkhashn <= config.GotWorkTarget:
        try:
            coinbaseMrkl = cbtxn.data
            coinbaseMrkl += blkhash
            steps = workMerkleTree._steps
            coinbaseMrkl += pack("B", len(steps))
            for step in steps:
                coinbaseMrkl += step
            coinbaseMrkl += b"\0\0\0\0"
            info = {}
            info["hash"] = b2a_hex(blkhash).decode("ascii")
            info["header"] = b2a_hex(data).decode("ascii")
            info["coinbaseMrkl"] = b2a_hex(coinbaseMrkl).decode("ascii")
            thr = threading.Thread(target=submitGotwork, args=(info,))
            thr.daemon = True
            thr.start()
        except:
            checkShare.logger.warning("Failed to build gotwork request")

    if "target" in share:
        workTarget = share["target"]
    elif len(wld) > 6:
        workTarget = wld[6]
    else:
        workTarget = None

    if workTarget is None:
        workTarget = config.ShareTarget
    if blkhashn > workTarget:
        raise RejectedShare("high-hash")
    share["target"] = workTarget
    share["_targethex"] = "%064x" % (workTarget,)

    shareTimestamp = unpack("<L", data[68:72])[0]
    if shareTime < issueT - 120:
        raise RejectedShare("stale-work")
    if shareTimestamp < shareTime - 300:
        raise RejectedShare("time-too-old")
    if shareTimestamp > shareTime + 7200:
        raise RejectedShare("time-too-new")

    if moden:
        cbpre = workCoinbase
        cbpreLen = len(cbpre)
        if coinbase[:cbpreLen] != cbpre:
            raise RejectedShare("bad-cb-prefix")

            # Filter out known "I support" flags, to prevent exploits
        for ff in (b"/P2SH/", b"NOP2SH", b"p2sh/CHV", b"p2sh/NOCHV"):
            if coinbase.find(ff) > max(-1, cbpreLen - len(ff)):
                raise RejectedShare("bad-cb-flag")

        if len(coinbase) > 100:
            raise RejectedShare("bad-cb-length")

        if shareMerkleRoot != workMerkleTree.withFirst(cbtxn):
            raise RejectedShare("bad-txnmrklroot")

        if len(othertxndata):
            allowed = assembleBlock(data, txlist)[80:]
            if allowed != share["blkdata"]:
                raise RejectedShare("bad-txns")

    if config.DynamicTargetting and username in userStatus:
        # NOTE: userStatus[username] only doesn't exist across restarts
        status = userStatus[username]
        target = status[0] or config.ShareTarget
        if target == workTarget:
            userStatus[username][2] += 1
        else:
            userStatus[username][2] += float(target) / workTarget
        if isstratum and userStatus[username][2] > config.DynamicTargetGoal * 2:
            stratumsrv.quickDifficultyUpdate(username)
예제 #17
0
	def idhash(self):
		self.txid = dblsha(self.data)
예제 #18
0
def checkShare(share):
    global rskLastReceivedShareTime
    global rskSubmittedShares

    shareTime = share['time'] = time()

    username = share['username']
    checkQuickDiffAdjustment = False
    if 'data' in share:
        # getwork/GBT
        data = share['data']

        shareMerkleRoot = data[36:68]
        if 'blkdata' in share:
            pl = share['blkdata']
            (txncount, pl) = varlenDecode(pl)
            cbtxn = bitcoin.txn.Txn(pl)
            othertxndata = cbtxn.disassemble(retExtra=True)
            coinbase = cbtxn.getCoinbase()
            wliPos = coinbase[0] + 2
            wliLen = coinbase[wliPos - 1]
            wli = coinbase[wliPos:wliPos + wliLen]
            mode = 'MC'
            moden = 1
        else:
            wli = shareMerkleRoot
            mode = 'MRD'
            moden = 0
            coinbase = None

        (wld, issueT) = LookupWork(username, wli)
        checkData(share, wld)
    else:
        # Stratum
        checkQuickDiffAdjustment = config.DynamicTargetQuick
        wli = share['jobid']
        (wld, issueT) = LookupWork(None, wli)
        mode = 'MC'
        moden = 1
        othertxndata = b''

    share[mode] = wld

    share['issuetime'] = issueT

    (workMerkleTree, workCoinbase) = wld[1:3]
    share['merkletree'] = workMerkleTree
    if 'jobid' in share:
        cbtxn = deepcopy(workMerkleTree.data[0])
        coinbase = workCoinbase + share['extranonce1'] + share['extranonce2']
        cbtxn.setCoinbase(coinbase)
        cbtxn.assemble()
        data = buildStratumData(share, workMerkleTree.withFirst(cbtxn),
                                workMerkleTree.MP['_BlockVersionBytes'])
        shareMerkleRoot = data[36:68]

    if data in DupeShareHACK:
        raise RejectedShare('duplicate')
    DupeShareHACK[data] = None

    blkhash = dblsha(data)

    if not hasattr(config, 'DEV_MODE_ON') or not config.DEV_MODE_ON:
        if not _reachesLowestDifficulty(blkhash):

            if len(share[mode]) >= 4:
                # currentblock may be changed, so we retry looking up some previous block saved (in RKS could be usefull prev blocks).
                blockToUse = (share[mode][3], share[mode][0], share[mode][4])
                retryData = buildStratumData(
                    share, workMerkleTree.withFirst(cbtxn),
                    workMerkleTree.MP['_BlockVersionBytes'], blockToUse)

                shareMerkleRoot = retryData[36:68]

                blkhash = dblsha(retryData)

                # retryData could be equal than data so we check again previous conditions
                if retryData == data or not _reachesLowestDifficulty(blkhash):
                    raise RejectedShare('H-not-zero')

                data = retryData
                DupeShareHACK[data] = None

            else:
                raise RejectedShare('H-not-zero')

    blkhashn = LEhash2int(blkhash)

    global networkTarget
    logfunc = getattr(checkShare.logger,
                      'info' if blkhashn <= networkTarget else 'debug')
    logfunc('BLKHASH: %64x' % (blkhashn, ))
    logfunc(' TARGET: %64x' % (networkTarget, ))

    # NOTE: this isn't actually needed for MC mode, but we're abusing it for a trivial share check...
    txlist = workMerkleTree.data
    txlist = [
        deepcopy(txlist[0]),
    ] + txlist[1:]
    cbtxn = txlist[0]
    cbtxn.setCoinbase(coinbase or workCoinbase)
    cbtxn.assemble()

    rootstockBlockHash = None
    rootstockTarget = None

    if hasattr(workMerkleTree, "rootstockBlockInfo"
               ) and workMerkleTree.rootstockBlockInfo is not None:
        rootstockBlockHash = workMerkleTree.rootstockBlockInfo[0]
        if hasattr(config, 'DEV_MODE_ON') and config.DEV_MODE_ON:
            rootstockTarget = bdiff2target(config.RSK_ELOIPOOL_DIFF)
        else:
            rootstockTarget = workMerkleTree.rootstockBlockInfo[1]

    submitRootstock = rootstockTarget is not None and blkhashn <= rootstockTarget

    if rskLastReceivedShareTime is None:
        rskLastReceivedShareTime = int(round(time() * 1000))
        rskSubmittedShares = 0
    lastReceivedShareTimeNow = int(round(time() * 1000))

    if lastReceivedShareTimeNow - rskLastReceivedShareTime >= 1000:
        rskSubmittedShares = 0
        rskLastReceivedShareTime = lastReceivedShareTimeNow

    checkShare.logger.info(
        "ROOTSTOCK_DEBUG: RSKValidShare: {0} {1} {2}".format(
            blkhashn, rootstockTarget, submitRootstock))
    if lastReceivedShareTimeNow - rskLastReceivedShareTime < 1000 and rskSubmittedShares < 1 and submitRootstock:
        rskSubmittedShares += 1
    else:
        submitRootstock = False

    submitBitcoin = blkhashn <= networkTarget
    #checkShare.logger.info("ROOTSTOCK_DEBUG: BTCValidShare: {0} {1} {2}".format(blkhashn, networkTarget, submitBitcoin))

    if submitBitcoin or submitRootstock:
        if submitBitcoin:
            share['BTC_SOLUTION'] = True
            logfunc("Submitting upstream")
            RBDs.append(
                deepcopy((data, txlist, share.get('blkdata', None),
                          workMerkleTree, share, wld)))

        if not moden:
            payload = assembleBlock(data, txlist)
        else:
            payload = share['data']
            if len(othertxndata):
                payload += share['blkdata']
            else:
                payload += assembleBlock(data, txlist)[80:]

        if submitRootstock:
            share['RSK_SOLUTION'] = True

            blockhashHexRskSubmit = b2a_hex(blkhash).decode('ascii')
            blockheaderHexRskSubmit = b2a_hex(share['data']).decode('ascii')
            coinbaseHexRskSubmit = b2a_hex(cbtxn.data).decode('ascii')

            coinbaseHashHexRskSubmit = b2a_hex(cbtxn.txid).decode('ascii')
            merkleHashesRskSubmit = [
                b2a_hex(x).decode('ascii') for x in workMerkleTree._steps
            ]
            merkleHashesRskSubmit.insert(0, coinbaseHashHexRskSubmit)
            merkleHashesRskSubmit = ' '.join(merkleHashesRskSubmit)

            txnCountRskSubmit = hex(len(txlist))[2:]
            threading.Thread(target=rootstockSubmissionThread,
                             args=(blockhashHexRskSubmit,
                                   blockheaderHexRskSubmit,
                                   coinbaseHexRskSubmit, merkleHashesRskSubmit,
                                   txnCountRskSubmit, share)).start()

        if not submitBitcoin:
            return

        logfunc('Real block payload: %s' % (b2a_hex(payload).decode('utf8'), ))
        RBPs.append(payload)
        threading.Thread(target=blockSubmissionThread,
                         args=(payload, blkhash, share)).start()
        bcnode.submitBlock(payload)
        if config.DelayLogForUpstream:
            share['upstreamRejectReason'] = PendingUpstream
        else:
            share['upstreamRejectReason'] = None
            share['upstreamResult'] = True
        MM.updateBlock(blkhash)

    # Gotwork hack...
    if gotwork and blkhashn <= config.GotWorkTarget:
        try:
            coinbaseMrkl = cbtxn.data
            coinbaseMrkl += blkhash
            steps = workMerkleTree._steps
            coinbaseMrkl += pack('B', len(steps))
            for step in steps:
                coinbaseMrkl += step
            coinbaseMrkl += b"\0\0\0\0"
            info = {}
            info['hash'] = b2a_hex(blkhash).decode('ascii')
            info['header'] = b2a_hex(data).decode('ascii')
            info['coinbaseMrkl'] = b2a_hex(coinbaseMrkl).decode('ascii')
            thr = threading.Thread(target=submitGotwork, args=(info, ))
            thr.daemon = True
            thr.start()
        except:
            checkShare.logger.warning('Failed to build gotwork request')

    if 'target' in share:
        workTarget = share['target']
    elif len(wld) > 6:
        workTarget = wld[6]
    else:
        workTarget = None

    if workTarget is None:
        workTarget = config.ShareTarget
    if blkhashn > workTarget:
        raise RejectedShare('high-hash')
    share['target'] = workTarget
    share['_targethex'] = '%064x' % (workTarget, )

    shareTimestamp = unpack('<L', data[68:72])[0]
    if shareTime < issueT - config.StaleWorkTimeout:
        raise RejectedShare('stale-work')
    if shareTimestamp < shareTime - 300:
        raise RejectedShare('time-too-old')
    if shareTimestamp > shareTime + 7200:
        raise RejectedShare('time-too-new')

    if moden:
        cbpre = workCoinbase
        cbpreLen = len(cbpre)
        if coinbase[:cbpreLen] != cbpre:
            raise RejectedShare('bad-cb-prefix')

        # Filter out known "I support" flags, to prevent exploits
        for ff in (b'/P2SH/', b'NOP2SH', b'p2sh/CHV', b'p2sh/NOCHV'):
            if coinbase.find(ff) > max(-1, cbpreLen - len(ff)):
                raise RejectedShare('bad-cb-flag')

        if len(coinbase) > 100:
            raise RejectedShare('bad-cb-length')

        if shareMerkleRoot != workMerkleTree.withFirst(cbtxn):
            raise RejectedShare('bad-txnmrklroot')

        if len(othertxndata):
            allowed = assembleBlock(data, txlist)[80:]
            if allowed != share['blkdata']:
                raise RejectedShare('bad-txns')

    if config.DynamicTargetting and username in userStatus:
        # NOTE: userStatus[username] only doesn't exist across restarts
        status = userStatus[username]
        target = status[0] or config.ShareTarget
        if target == workTarget:
            userStatus[username][2] += 1
        else:
            userStatus[username][2] += float(target) / workTarget
        if checkQuickDiffAdjustment and userStatus[username][
                2] > config.DynamicTargetGoal * 2:
            stratumsrv.quickDifficultyUpdate(username)
예제 #19
0
파일: txn.py 프로젝트: luke-jr/eloipool
	def withash(self):
		self.witness_hash = dblsha(self.data)
예제 #20
0
def checkShare(share):
    shareTime = share['time'] = time()

    username = share['username']
    if 'data' in share:
        # getwork/GBT
        checkData(share)
        data = share['data']

        if username not in workLog:
            raise RejectedShare('unknown-user')
        MWL = workLog[username]

        shareMerkleRoot = data[36:68]
        if 'blkdata' in share:
            pl = share['blkdata']
            (txncount, pl) = varlenDecode(pl)
            cbtxn = bitcoin.txn.Txn(pl)
            othertxndata = cbtxn.disassemble(retExtra=True)
            coinbase = cbtxn.getCoinbase()
            wliPos = coinbase[0] + 2
            wliLen = coinbase[wliPos - 1]
            wli = coinbase[wliPos:wliPos + wliLen]
            mode = 'MC'
            moden = 1
        else:
            wli = shareMerkleRoot
            mode = 'MRD'
            moden = 0
            coinbase = None
    else:
        # Stratum
        MWL = workLog[None]
        wli = share['jobid']
        buildStratumData(share, b'\0' * 32)
        mode = 'MC'
        moden = 1
        othertxndata = b''

    if wli not in MWL:
        raise RejectedShare('unknown-work')
    (wld, issueT) = MWL[wli]
    share[mode] = wld

    share['issuetime'] = issueT

    (workMerkleTree, workCoinbase) = wld[1:3]
    share['merkletree'] = workMerkleTree
    if 'jobid' in share:
        cbtxn = deepcopy(workMerkleTree.data[0])
        coinbase = workCoinbase + share['extranonce1'] + share['extranonce2']
        cbtxn.setCoinbase(coinbase)
        cbtxn.assemble()
        data = buildStratumData(share, workMerkleTree.withFirst(cbtxn))
        shareMerkleRoot = data[36:68]

    if data in DupeShareHACK:
        raise RejectedShare('duplicate')
    DupeShareHACK[data] = None

    blkhash = dblsha(data)
    if blkhash[28:] != b'\0\0\0\0':
        raise RejectedShare('H-not-zero')
    blkhashn = LEhash2int(blkhash)

    global networkTarget
    logfunc = getattr(checkShare.logger,
                      'info' if blkhashn <= networkTarget else 'debug')
    logfunc('BLKHASH: %64x' % (blkhashn, ))
    logfunc(' TARGET: %64x' % (networkTarget, ))

    # NOTE: this isn't actually needed for MC mode, but we're abusing it for a trivial share check...
    txlist = workMerkleTree.data
    txlist = [
        deepcopy(txlist[0]),
    ] + txlist[1:]
    cbtxn = txlist[0]
    cbtxn.setCoinbase(coinbase or workCoinbase)
    cbtxn.assemble()

    if blkhashn <= networkTarget:
        logfunc("Submitting upstream")
        RBDs.append(
            deepcopy(
                (data, txlist, share.get('blkdata',
                                         None), workMerkleTree, share, wld)))
        if not moden:
            payload = assembleBlock(data, txlist)
        else:
            payload = share['data']
            if len(othertxndata):
                payload += share['blkdata']
            else:
                payload += assembleBlock(data, txlist)[80:]
        logfunc('Real block payload: %s' % (b2a_hex(payload).decode('utf8'), ))
        RBPs.append(payload)
        threading.Thread(target=blockSubmissionThread,
                         args=(payload, blkhash, share)).start()
        bcnode.submitBlock(payload)
        if config.DelayLogForUpstream:
            share['upstreamRejectReason'] = PendingUpstream
        else:
            share['upstreamRejectReason'] = None
            share['upstreamResult'] = True
        MM.updateBlock(blkhash)

    # Gotwork hack...
    if gotwork and blkhashn <= config.GotWorkTarget:
        try:
            coinbaseMrkl = cbtxn.data
            coinbaseMrkl += blkhash
            steps = workMerkleTree._steps
            coinbaseMrkl += pack('B', len(steps))
            for step in steps:
                coinbaseMrkl += step
            coinbaseMrkl += b"\0\0\0\0"
            info = {}
            info['hash'] = b2a_hex(blkhash).decode('ascii')
            info['header'] = b2a_hex(data).decode('ascii')
            info['coinbaseMrkl'] = b2a_hex(coinbaseMrkl).decode('ascii')
            thr = threading.Thread(target=submitGotwork, args=(info, ))
            thr.daemon = True
            thr.start()
        except:
            checkShare.logger.warning('Failed to build gotwork request')

    if 'target' in share:
        workTarget = share['target']
    elif len(wld) > 6:
        workTarget = wld[6]
    else:
        workTarget = None

    if workTarget is None:
        workTarget = config.ShareTarget
    if blkhashn > workTarget:
        raise RejectedShare('high-hash')
    share['target'] = workTarget
    share['_targethex'] = '%064x' % (workTarget, )

    shareTimestamp = unpack('<L', data[68:72])[0]
    if shareTime < issueT - 120:
        raise RejectedShare('stale-work')
    if shareTimestamp < shareTime - 300:
        raise RejectedShare('time-too-old')
    if shareTimestamp > shareTime + 7200:
        raise RejectedShare('time-too-new')

    if config.DynamicTargetting and username in userStatus:
        # NOTE: userStatus[username] only doesn't exist across restarts
        status = userStatus[username]
        target = status[0] or config.ShareTarget
        if target == workTarget:
            userStatus[username][2] += 1
        else:
            userStatus[username][2] += float(target) / workTarget

    if moden:
        cbpre = workCoinbase
        cbpreLen = len(cbpre)
        if coinbase[:cbpreLen] != cbpre:
            raise RejectedShare('bad-cb-prefix')

        # Filter out known "I support" flags, to prevent exploits
        for ff in (b'/P2SH/', b'NOP2SH', b'p2sh/CHV', b'p2sh/NOCHV'):
            if coinbase.find(ff) > max(-1, cbpreLen - len(ff)):
                raise RejectedShare('bad-cb-flag')

        if len(coinbase) > 100:
            raise RejectedShare('bad-cb-length')

        if shareMerkleRoot != workMerkleTree.withFirst(cbtxn):
            raise RejectedShare('bad-txnmrklroot')

        if len(othertxndata):
            allowed = assembleBlock(data, txlist)[80:]
            if allowed != share['blkdata']:
                raise RejectedShare('bad-txns')
예제 #21
0
def checkShare(share):
	shareTime = share['time'] = time()
	
	username = share['username']
	if 'data' in share:
		# getwork/GBT
		checkData(share)
		data = share['data']
		
		if username not in workLog:
			raise RejectedShare('unknown-user')
		MWL = workLog[username]
		
		shareMerkleRoot = data[36:68]
		if 'blkdata' in share:
			pl = share['blkdata']
			(txncount, pl) = varlenDecode(pl)
			cbtxn = bitcoin.txn.Txn(pl)
			othertxndata = cbtxn.disassemble(retExtra=True)
			coinbase = cbtxn.getCoinbase()
			wliPos = coinbase[0] + 2
			wliLen = coinbase[wliPos - 1]
			wli = coinbase[wliPos:wliPos+wliLen]
			mode = 'MC'
			moden = 1
		else:
			wli = shareMerkleRoot
			mode = 'MRD'
			moden = 0
			coinbase = None
	else:
		# Stratum
		MWL = workLog[None]
		wli = share['jobid']
		buildStratumData(share, b'\0' * 32)
		mode = 'MC'
		moden = 1
		othertxndata = b''
	
	if wli not in MWL:
		raise RejectedShare('unknown-work')
	(wld, issueT) = MWL[wli]
	share[mode] = wld
	
	share['issuetime'] = issueT
	
	(workMerkleTree, workCoinbase) = wld[1:3]
	share['merkletree'] = workMerkleTree
	if 'jobid' in share:
		cbtxn = deepcopy(workMerkleTree.data[0])
		coinbase = workCoinbase + share['extranonce1'] + share['extranonce2']
		cbtxn.setCoinbase(coinbase)
		cbtxn.assemble()
		data = buildStratumData(share, workMerkleTree.withFirst(cbtxn))
		shareMerkleRoot = data[36:68]
	
	if data in DupeShareHACK:
		raise RejectedShare('duplicate')
	DupeShareHACK[data] = None
	
	blkhash = dblsha(data)
	if blkhash[28:] != b'\0\0\0\0':
		raise RejectedShare('H-not-zero')
	blkhashn = LEhash2int(blkhash)
	
	global networkTarget
	logfunc = getattr(checkShare.logger, 'info' if blkhashn <= networkTarget else 'debug')
	logfunc('BLKHASH: %64x' % (blkhashn,))
	logfunc(' TARGET: %64x' % (networkTarget,))
	
	# NOTE: this isn't actually needed for MC mode, but we're abusing it for a trivial share check...
	txlist = workMerkleTree.data
	txlist = [deepcopy(txlist[0]),] + txlist[1:]
	cbtxn = txlist[0]
	cbtxn.setCoinbase(coinbase or workCoinbase)
	cbtxn.assemble()
	
	if blkhashn <= networkTarget:
		logfunc("Submitting upstream")
		RBDs.append( deepcopy( (data, txlist, share.get('blkdata', None), workMerkleTree, share, wld) ) )
		if not moden:
			payload = assembleBlock(data, txlist)
		else:
			payload = share['data']
			if len(othertxndata):
				payload += share['blkdata']
			else:
				payload += assembleBlock(data, txlist)[80:]
		logfunc('Real block payload: %s' % (b2a_hex(payload).decode('utf8'),))
		RBPs.append(payload)
		threading.Thread(target=blockSubmissionThread, args=(payload, blkhash, share)).start()
		bcnode.submitBlock(payload)
		if config.DelayLogForUpstream:
			share['upstreamRejectReason'] = PendingUpstream
		else:
			share['upstreamRejectReason'] = None
			share['upstreamResult'] = True
		MM.updateBlock(blkhash)
	
	# Gotwork hack...
	if gotwork and blkhashn <= config.GotWorkTarget:
		try:
			coinbaseMrkl = cbtxn.data
			coinbaseMrkl += blkhash
			steps = workMerkleTree._steps
			coinbaseMrkl += pack('B', len(steps))
			for step in steps:
				coinbaseMrkl += step
			coinbaseMrkl += b"\0\0\0\0"
			info = {}
			info['hash'] = b2a_hex(blkhash).decode('ascii')
			info['header'] = b2a_hex(data).decode('ascii')
			info['coinbaseMrkl'] = b2a_hex(coinbaseMrkl).decode('ascii')
			thr = threading.Thread(target=submitGotwork, args=(info,))
			thr.daemon = True
			thr.start()
		except:
			checkShare.logger.warning('Failed to build gotwork request')
	
	if 'target' in share:
		workTarget = share['target']
	elif len(wld) > 6:
		workTarget = wld[6]
	else:
		workTarget = None
	
	if workTarget is None:
		workTarget = config.ShareTarget
	if blkhashn > workTarget:
		raise RejectedShare('high-hash')
	share['target'] = workTarget
	share['_targethex'] = '%064x' % (workTarget,)
	
	shareTimestamp = unpack('<L', data[68:72])[0]
	if shareTime < issueT - 120:
		raise RejectedShare('stale-work')
	if shareTimestamp < shareTime - 300:
		raise RejectedShare('time-too-old')
	if shareTimestamp > shareTime + 7200:
		raise RejectedShare('time-too-new')
	
	if config.DynamicTargetting and username in userStatus:
		# NOTE: userStatus[username] only doesn't exist across restarts
		status = userStatus[username]
		target = status[0] or config.ShareTarget
		if target == workTarget:
			userStatus[username][2] += 1
		else:
			userStatus[username][2] += float(target) / workTarget
	
	if moden:
		cbpre = workCoinbase
		cbpreLen = len(cbpre)
		if coinbase[:cbpreLen] != cbpre:
			raise RejectedShare('bad-cb-prefix')
		
		# Filter out known "I support" flags, to prevent exploits
		for ff in (b'/P2SH/', b'NOP2SH', b'p2sh/CHV', b'p2sh/NOCHV'):
			if coinbase.find(ff) > max(-1, cbpreLen - len(ff)):
				raise RejectedShare('bad-cb-flag')
		
		if len(coinbase) > 100:
			raise RejectedShare('bad-cb-length')
		
		if shareMerkleRoot != workMerkleTree.withFirst(cbtxn):
			raise RejectedShare('bad-txnmrklroot')
		
		if len(othertxndata):
			allowed = assembleBlock(data, txlist)[80:]
			if allowed != share['blkdata']:
				raise RejectedShare('bad-txns')
예제 #22
0
 def withash(self):
     self.witness_hash = dblsha(self.data)
예제 #23
0
파일: txn.py 프로젝트: passoir/eloipool
 def idhash(self):
     self.txid = dblsha(self.data)