def test_body_mr(self): expected_body_mr = "a501d7500373bae88158d5e7062ca178528cc8d405c31f28352a548e5841e9e8" block = FactoidBlock.unmarshal( bytes.fromhex(TestFactoidBlock.test_data)) assert block.body.merkle_root.hex( ) == expected_body_mr, "{} != {}".format(block.body.merkle_root.hex(), expected_body_mr)
def test_unmarshal(self): expected_body_mr = "a501d7500373bae88158d5e7062ca178528cc8d405c31f28352a548e5841e9e8" expected_prev_keymr = "cecedf84a5851a0cd532657bb3074e4efb46a34c504f2f148fd1c312e284a9ab" expected_prev_ledger_keymr = "6d58d473d967e15458ddb9385fdf67ff1969fa7719f907a74e128083734acd2d" expected_ec_exchange_rate = 16500 expected_height = 199535 expected_tx_count = 4 block = FactoidBlock.unmarshal( bytes.fromhex(TestFactoidBlock.test_data)) assert block.header.body_mr.hex() == expected_body_mr assert block.header.prev_keymr.hex() == expected_prev_keymr assert block.header.prev_ledger_keymr.hex( ) == expected_prev_ledger_keymr assert block.header.ec_exchange_rate == expected_ec_exchange_rate assert block.header.height == expected_height assert block.header.tx_count == expected_tx_count tx_count = 0 for minute, transactions in block.body.transactions.items(): tx_count += len(transactions) assert tx_count == expected_tx_count
def unmarshal(cls, raw: bytes): msg_type, data = raw[0], raw[1:] if msg_type != cls.TYPE: raise ValueError("Invalid message type ({})".format(msg_type)) timestamp, data = data[:6], data[6:] directory_block, data = DirectoryBlock.unmarshal_with_remainder(data) admin_block, data = AdminBlock.unmarshal_with_remainder(data) factoid_block, data = FactoidBlock.unmarshal_with_remainder(data) entry_credit_block, data = EntryCreditBlock.unmarshal_with_remainder( data) entry_block_count, data = struct.unpack(">I", data[:4])[0], data[4:] entry_blocks = [] for i in range(entry_block_count): entry_block, data = EntryBlock.unmarshal_with_remainder(data) entry_blocks.append(entry_block) entry_count, data = struct.unpack(">I", data[:4])[0], data[4:] entries = [] for i in range(entry_count): entry_size, data = struct.unpack(">I", data[:4])[0], data[4:] entry, data = Entry.unmarshal(data[:entry_size]), data[entry_size:] entries.append(entry) signatures = primitives.FullSignatureList.unmarshal(data) return DirectoryBlockState( timestamp=timestamp, directory_block=directory_block, admin_block=admin_block, factoid_block=factoid_block, entry_credit_block=entry_credit_block, entry_blocks=entry_blocks, entries=entries, signatures=signatures, )
def test_keymr(self): expected_keymr = "2568dbcd243487097dedc9764f4fa48079455de4bdb95ed844b99e2f9556bf7f" block = FactoidBlock.unmarshal( bytes.fromhex(TestFactoidBlock.test_data)) assert block.keymr.hex() == expected_keymr, "{} != {}".format( block.keymr.hex(), expected_keymr)
def test_marshal(self): block = FactoidBlock.unmarshal( bytes.fromhex(TestFactoidBlock.test_data)) assert block.marshal().hex() == TestFactoidBlock.test_data
def fill_and_write_template(template_path, tx_id): with open(template_path) as f: template = Template(f.read()) try: tx = factomd.transaction(tx_id) fb = factomd.factoid_block_by_keymr(tx["includedintransactionblock"]) except (InvalidParams, KeyError): print("Transaction with the given ID not found!") sys.exit(1) tx_height = tx["includedindirectoryblockheight"] factoid_block = FactoidBlock.unmarshal(bytes.fromhex(fb["rawdata"])) fb_leaves = utils.factoid_block_body_leaves(factoid_block) fb_body_mt = utils.build_merkle_tree([fb_leaves]) fb_body_mr = utils.compute_merkle_root(fb_leaves) db = factomd.directory_block_by_height(tx_height) db_entries = db["dblock"]["dbentries"] leaves = [] for db_entry in db_entries: leaves.append(bytes.fromhex(db_entry["chainid"])) leaves.append(bytes.fromhex(db_entry["keymr"])) db_mt = utils.build_merkle_tree([leaves]) directory_block = DirectoryBlock.unmarshal(bytes.fromhex(db["rawdata"])) anchors = factomd.anchors(directory_block.keymr) # Convert the transaction to a factom_core.block_elements.FactoidTransaction # object tx = find_factoid_tx_in_block(tx_id, factoid_block) assert len(tx.outputs) == 1, "Transaction must have a single output" params = {} params["tx_timestamp"] = str("0x{}".format( tx.timestamp.to_bytes(6, "big").hex())) params["addresses_count"] = [ len(tx.inputs), len(tx.outputs), len(tx.ec_purchases) ] params["addresses"] = list( "0x{}".format(v["fct_address"].hex()) for v in it.chain(tx.inputs, tx.outputs, tx.ec_purchases)) params["amounts"] = list( v["value"] for v in it.chain(tx.inputs, tx.outputs, tx.ec_purchases)) params["public_keys"] = list("0x{}".format(v.public_key.hex()) for v in tx.rcds) signatures = [] for rcd in tx.rcds: signature = rcd.signature signatures.append("0x{}".format(signature[:32].hex())) signatures.append("0x{}".format(signature[32:].hex())) params["signatures"] = signatures params["expected_tx_hash"] = "0x{}".format(tx.hash.hex()) params["tx_block_height"] = tx_height path, pos = compute_merkle_path_and_pos(fb_body_mt, tx.hash) params["tx_path"] = path params["tx_path_positions"] = pos path, pos = compute_merkle_path_and_pos(db_mt, factoid_block.keymr) params["fblock_path"] = path params["fblock_path_positions"] = pos path, pos = zip(*utils.build_merkle_path_from_anchors(anchors)) params["dblock_path"] = list(map(lambda v: "0x{}".format(v.hex()), path)) params["dblock_path_positions"] = list(pos) params["header_hashes_and_merkle_roots"] = [ "0x{}".format( hashlib.sha256(factoid_block.header.marshal()).hexdigest()), "0x{}".format(factoid_block.body.merkle_root.hex()), "0x{}".format( hashlib.sha256(directory_block.header.marshal()).hexdigest()), "0x{}".format(directory_block.body.merkle_root.hex()), ] with open("../js/claim_eth_request.js", "w") as f: print(template.substitute(**params), file=f)
def put_factoid_block(self, block: blocks.FactoidBlock): sub_db = self._db.prefixed_db(FACTOID_BLOCK_NUMBER) sub_db.put(struct.pack(">I", block.header.height), block.keymr) sub_db = self._db.prefixed_db(FACTOID_BLOCK) sub_db.put(block.keymr, block.marshal())