Example #1
0
def _test():
    if not hasattr(bytes, 'fromhex'):
        return
    from binascii import b2a_hex
    mt = MerkleTree([None] + [
        bytes.fromhex(a) for a in [
            '999d2c8bb6bda0bf784d9ebeb631d711dbbbfe1bc006ea13d6ad0d6a2649a971',
            '3f92594d5a3d7b4df29d7dd7c46a0dac39a96e751ba0fc9bab5435ea5e22a19d',
            'a5633f03855f541d8e60a6340fc491d49709dc821f3acb571956a856637adcb6',
            '28d97c850eaf917a4c76c02474b05b70a197eaefb468d21c22ed110afe8ec9e0',
        ]
    ])
    assert (
        b'82293f182d5db07d08acf334a5a907012bbb9990851557ac0ec028116081bd5a' ==
        b2a_hex(
            mt.withFirst(
                bytes.fromhex(
                    'd43b669fb42cfa84695b844c0402d410213faa4f3e66cb7248f688ff19d5e5f7'
                ))))

    d = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    dh = b"C\xeczW\x9fUa\xa4*~\x967\xadAVg'5\xa6X\xbe'R\x18\x18\x01\xf7#\xba3\x16\xd2"
    t = Txn(d)
    m = MerkleTree([t])
    assert m.merkleRoot() == dh
    u = Txn.new()
    u.addInput((b' ' * 32, 0), b'')
    u.assemble()
    m.data.append(u)
    m.recalculate()
    mr = b"q\xe1\x9a3'\x0f>\xbfTv\xc8\x90\x81\x802\xe3\xb7u\x96\xddjP4\xe3\x19\xf3\xf0\xc5A4\xc0\xdb"
    assert m.merkleRoot() == mr
    step = b'\xb0\x91t\x84%\x9dg\x827\xc5\xbf\x94\xf0"\x94\xafN[\x0c\xeelF\xd9\x1b\x13q\xd3\xdf\x83\xe6\x01g'
    assert m._steps == [step]
    m.recalculate(detailed=True)
    assert m.detail == [dh, step, mr]
    m = MerkleTree([t.txid, u.txid])
    assert m.merkleRoot() == mr
    assert m._steps == [step]
    m.recalculate(detailed=True)
    assert m.detail == [dh, step, mr]
Example #2
0
	def _ProcessGBT(self, MP, TS = None):
		oMP = MP
		MP = deepcopy(MP)
		
		if MP['version'] & 0xe0000000 != 0x20000000:
			self.logger.error('Template from \'%s\' has non-BIP9 block version (%x)' % (TS['name'], MP['version']))
			return None
		
		ISupportAllRules = True
		for ruleflag in MP['rules']:
			(MandatoryRule, rule) = SplitRuleFlag(ruleflag)
			if rule not in SupportedRules:
				ISupportAllRules = False
				if MandatoryRule:
					self.logger.error('Template from \'%s\' strictly requires unsupported rule \'%s\'', TS['name'], rule)
					return None
				else:
					self.logger.warning('Template from \'%s\' loosely requires unsupported rule \'%s\'', TS['name'], rule)
		
		MP['_filtered_vbavailable'] = {}
		for ruleflag in MP['vbavailable']:
			rulebit = MP['vbavailable'][ruleflag]
			rulemask = (1 << rulebit)
			if MP['version'] & rulemask:
				MP['_filtered_vbavailable'][ruleflag] = rulebit
		
		prevBlock = bytes.fromhex(MP['previousblockhash'])[::-1]
		if 'height' not in MP:
			MP['height'] = TS['access'].getinfo()['blocks'] + 1
		height = MP['height']
		bits = bytes.fromhex(MP['bits'])[::-1]
		(MP['_bits'], MP['_prevBlock']) = (bits, prevBlock)
		MP['_BlockVersionBytes'] = struct.pack('<L', MP['version'])
		if (prevBlock, height, bits) != self.currentBlock and (self.currentBlock[1] is None or height > self.currentBlock[1]):
			self.updateBlock(prevBlock, height, bits, _HBH=(MP['previousblockhash'], MP['bits']))
		
		txnlist = MP['transactions']
		if len(txnlist) and isinstance(txnlist[0], dict):
			txninfo = txnlist
			txnlist = tuple(a['data'] for a in txnlist)
		elif 'transactionfees' in MP:
			# Backward compatibility with pre-BIP22 gmp_fees branch
			txninfo = [{'fee':a} for a in MP['transactionfees']]
		else:
			# Backward compatibility with pre-BIP22 hex-only (bitcoind <0.7, Eloipool <future)
			txninfo = [{}] * len(txnlist)
		# TODO: cache Txn or at least txid from previous merkle roots?
		txnlist = [a for a in map(bytes.fromhex, txnlist)]
		
		self._makeBlockSafe(MP, txnlist, txninfo)
		if len(MP['transactions']) != len(txnlist) and not ISupportAllRules:
			self.logger.error('Template from \'%s\' should be trimmed, but requires unsupported rule(s)', TS['name'])
			return None
		
		txnobjs = [None]
		for i in range(len(txnlist)):
			iinfo = txninfo[i]
			ka = {}
			if 'txid' in iinfo:
				ka['txid'] = bytes.fromhex(iinfo['txid'])[::-1]
			txnobjs.append(Txn(data=txnlist[i], **ka))
		
		witness_commitment = CalculateWitnessCommitment(txnobjs, self.WitnessNonce, force=self.ForceWitnessCommitment)
		
		cbtxn = self.makeCoinbaseTxn(MP['coinbasevalue'], prevBlockHex = MP['previousblockhash'], witness_commitment=witness_commitment)
		cbtxn.setCoinbase(b'\0\0')
		cbtxn.assemble()
		txnobjs[0] = cbtxn
		
		txnobjs = list(txnobjs)
		newMerkleTree = MerkleTree(txnobjs)
		newMerkleTree.POTInfo = MP.get('POTInfo')
		newMerkleTree.MP = MP
		newMerkleTree.oMP = oMP
		newMerkleTree.witness_commitment = witness_commitment
		
		return newMerkleTree