def make_proof_deserializable(proof: list): proof_deserializable = [] for item in proof: try: left: str = item["left"] proof_deserializable.append({"left": Hash32.fromhex(left)}) except KeyError: right: str = item["right"] proof_deserializable.append({"right": Hash32.fromhex(right)}) return proof_deserializable
def make_proof_serializable(proof: list): proof_serializable = [] for item in proof: try: left = Hash32(item["left"]) proof_serializable.append({"left": left.hex_0x()}) except KeyError: right = Hash32(item["right"]) proof_serializable.append({"right": right.hex_0x()}) return proof_serializable
def count_votes(self, block_hash: Hash32): # count votes vote = self._blockmanager.candidate_blocks.get_vote(block_hash) if not vote.get_result(block_hash.hex(), conf.VOTING_RATIO): return True # vote not complete yet self.__stop_broadcast_send_unconfirmed_block_timer()
def create_icx_origin_v3(self, is_raw_data=False): params = dict() params["version"] = "0x3" params["from"] = self.address params["to"] = self.to_address params["value"] = hex(int(self.value * ICX_FACTOR)) params["stepLimit"] = "0x3000000" params["timestamp"] = hex(utils.get_now_time_stamp()) params["nonce"] = "0x0" params["nid"] = self.nid if self.message is not None: params["dataType"] = "message" params["data"] = self.message.encode('utf-8').hex() hash_for_sign = self.__hash_generators["0x3"].generate_hash(params) params["signature"] = self.create_signature(hash_for_sign) if self.is_logging: logging.debug(f"icx_sendTransaction params for v3: {params}") self.__last_tx_hash = Hash32(hash_for_sign).hex_0x() icx_origin = dict() icx_origin["jsonrpc"] = "2.0" icx_origin["method"] = "icx_sendTransaction" icx_origin["id"] = random.randrange(0, 100000) icx_origin["params"] = params return icx_origin if is_raw_data else params
async def __get_block(self, block_data_filter, block_hash, block_height, tx_data_filter): blockchain = self._channel_service.block_manager.get_blockchain() if block_hash == "" and block_height == -1: block_hash = blockchain.last_block.header.hash.hex() block_filter = re.sub(r'\s', '', block_data_filter).split(",") tx_filter = re.sub(r'\s', '', tx_data_filter).split(",") block = None confirm_info = b'' fail_response_code = None if block_hash: block = blockchain.find_block_by_hash(block_hash) confirm_info = blockchain.find_confirm_info_by_hash( Hash32.fromhex(block_hash, True)) if block is None: fail_response_code = message_code.Response.fail_wrong_block_hash elif block_height != -1: block = blockchain.find_block_by_height(block_height) confirm_info = blockchain.find_confirm_info_by_height(block_height) if block is None: fail_response_code = message_code.Response.fail_wrong_block_height else: fail_response_code = message_code.Response.fail_wrong_block_hash return block, block_filter, block_hash, bytes( confirm_info), fail_response_code, tx_filter
async def get_receipt_proof(self, tx_hash: str) -> Union[list, dict]: blockchain = self._channel_service.block_manager.get_blockchain() try: proof = blockchain.get_receipt_proof(Hash32.fromhex(tx_hash)) except Exception as e: return make_error_response(JsonError.INVALID_PARAMS, str(e)) try: return make_proof_serializable(proof) except Exception as e: return make_error_response(JsonError.INTERNAL_ERROR, str(e))
async def prove_tx(self, tx_hash: str, proof: list) -> Union[str, dict]: blockchain = self._channel_service.block_manager.get_blockchain() try: proof = make_proof_deserializable(proof) except Exception as e: return make_error_response(JsonError.INTERNAL_ERROR, str(e)) try: return "0x1" if blockchain.prove_transaction( Hash32.fromhex(tx_hash), proof) else "0x0" except Exception as e: return make_error_response(JsonError.INVALID_PARAMS, str(e))
def __init__(self, block_hash: Hash32): """Recommend use factory methods(from_*) instead direct this. """ if ObjectManager().channel_service: audience = ObjectManager().channel_service.peer_manager else: audience = None self.start_time = util.get_time_stamp() # timestamp self.hash = block_hash self.vote = Vote(block_hash.hex(), audience) self.__block = None
def prove_transaction(self, tx_hash: Hash32, proof: list): try: tx_info = self.find_tx_info(tx_hash.hex()) except KeyError: raise RuntimeError(f"Tx does not exist.") block_hash = tx_info["block_hash"] block = self.find_block_by_hash(block_hash) if block.header.version == "0.1a": raise RuntimeError(f"Block version({block.header.version}) of the Tx does not support proof.") block_prover = BlockProver.new(block.header.version, None, BlockProverType.Transaction) # Do not need txs return block_prover.prove(tx_hash, block.header.transaction_hash, proof)
def get_transaction_proof(self, tx_hash: Hash32): try: tx_info = self.find_tx_info(tx_hash.hex()) except KeyError: raise RuntimeError(f"Tx does not exist.") block_hash = tx_info["block_hash"] block = self.find_block_by_hash(block_hash) if block.header.version == "0.1a": raise RuntimeError(f"Block version({block.header.version}) of the Tx does not support proof.") block_prover = BlockProver.new(block.header.version, block.body.transactions, BlockProverType.Transaction) return block_prover.get_proof(tx_hash)
def score_invoke(self, _block: Block) -> dict or None: method = "icx_sendTransaction" transactions = [] for tx in _block.body.transactions.values(): tx_serializer = TransactionSerializer.new( tx.version, self.block_manager.get_blockchain().tx_versioner) transaction = { "method": method, "params": tx_serializer.to_full_data(tx) } transactions.append(transaction) request = { 'block': { 'blockHeight': _block.header.height, 'blockHash': _block.header.hash.hex(), 'prevBlockHash': _block.header.prev_hash.hex() if _block.header.prev_hash else '', 'timestamp': _block.header.timestamp }, 'transactions': transactions } request = convert_params(request, ParamType.invoke) stub = StubCollection().icon_score_stubs[ChannelProperty().name] response = stub.sync_task().invoke(request) response_to_json_query(response) tx_receipts = response["txResults"] block_builder = BlockBuilder.from_new( _block, self.__block_manager.get_blockchain().tx_versioner) block_builder.reset_cache() block_builder.peer_id = _block.header.peer_id block_builder.signature = _block.header.signature block_builder.commit_state = { ChannelProperty().name: response['stateRootHash'] } block_builder.state_hash = Hash32( bytes.fromhex(response['stateRootHash'])) block_builder.receipts = tx_receipts block_builder.reps = self.get_rep_ids() new_block = block_builder.build() return new_block, tx_receipts
def prove_receipt(self, tx_hash: Hash32, proof: list): try: tx_info = self.find_tx_info(tx_hash.hex()) except KeyError: raise RuntimeError(f"Tx does not exist.") tx_result = tx_info["result"] block_hash = tx_info["block_hash"] block = self.find_block_by_hash(block_hash) if block.header.version == "0.1a": raise RuntimeError(f"Block version({block.header.version}) of the Tx does not support proof.") block_prover = BlockProver.new(block.header.version, None, BlockProverType.Receipt) # Do not need receipts receipt_hash = block_prover.to_hash32(tx_result) return block_prover.prove(receipt_hash, block.header.receipt_hash, proof)
def get_receipt_proof(self, tx_hash: Hash32): try: tx_info = self.find_tx_info(tx_hash.hex()) except KeyError: raise RuntimeError(f"Tx does not exist.") tx_result = tx_info["result"] block_hash = tx_info["block_hash"] block = self.find_block_by_hash(block_hash) if block.header.version == "0.1a": raise RuntimeError(f"Block version({block.header.version}) of the Tx does not support proof.") tx_results = (self.find_tx_info(tx_hash)["result"] for tx_hash in block.body.transactions) block_prover = BlockProver.new(block.header.version, tx_results, BlockProverType.Receipt) receipt_hash = block_prover.to_hash32(tx_result) return block_prover.get_proof(receipt_hash)
def vote_unconfirmed_block(self, peer_id, group_id, block_hash: Hash32, vote_code) -> None: block_manager = self._channel_service.block_manager util.logger.spam(f"channel_inner_service:VoteUnconfirmedBlock " f"({ChannelProperty().name}) block_hash({block_hash})") util.logger.debug("Peer vote to : " + block_hash.hex()[:8] + " " + str(vote_code) + f"from {peer_id[:8]}") self._channel_service.block_manager.candidate_blocks.add_vote( block_hash, group_id, peer_id, (False, True)[vote_code == message_code.Response.success_validate_block] ) consensus = block_manager.consensus_algorithm if isinstance(consensus, ConsensusSiever) and self._channel_service.state_machine.state == "BlockGenerate": consensus.count_votes(block_hash)
def create_icx_origin(self, is_raw_data=False): params = dict() params["from"] = self.address params["to"] = self.to_address params["value"] = hex(int(self.value * ICX_FACTOR)) params["fee"] = hex(int(self.fee * ICX_FACTOR)) params["timestamp"] = str(utils.get_now_time_stamp()) tx_hash = Hash32(self.__hash_generators["0x2"].generate_hash(params)) params["tx_hash"] = tx_hash.hex() params["signature"] = self.create_signature(tx_hash) icx_origin = dict() icx_origin["jsonrpc"] = "2.0" icx_origin["method"] = "icx_sendTransaction" icx_origin["id"] = random.randrange(0, 100000) icx_origin["params"] = params self.__last_tx_hash = tx_hash.hex_0x() if self.is_logging: logging.debug(f"icx_sendTransaction params for v2: {params}") return icx_origin if is_raw_data else params
def test_block_v0_3(self): private_auth = test_util.create_default_peer_auth() tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new("0.3", tx_versioner) for i in range(1000): tx_builder = TransactionBuilder.new("0x3", tx_versioner) tx_builder.private_key = private_auth.private_key tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new(tx.version, tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } block_builder.peer_private_key = private_auth.private_key block_builder.height = 0 block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ ExternalAddress.fromhex_address(private_auth.address) ] block_builder.next_leader = ExternalAddress.fromhex( "hx00112233445566778899aabbccddeeff00112233") block = block_builder.build() block_verifier = BlockVerifier.new("0.3", tx_versioner) block_verifier.invoke_func = lambda b: (block, dummy_receipts) block_verifier.verify(block, None, None, block.header.peer_id, reps=block_builder.reps) block_serializer = BlockSerializer.new("0.3", tx_versioner) block_serialized = block_serializer.serialize(block) block_deserialized = block_serializer.deserialize(block_serialized) assert block.header == block_deserialized.header # FIXME : confirm_prev_block not serialized # assert block.body == block_deserialized.body tx_hashes = list(block.body.transactions) tx_index = random.randrange(0, len(tx_hashes)) block_prover = BlockProver.new(block.header.version, tx_hashes, BlockProverType.Transaction) tx_proof = block_prover.get_proof(tx_index) assert block_prover.prove(tx_hashes[tx_index], block.header.transaction_hash, tx_proof) block_prover = BlockProver.new(block.header.version, block_builder.receipts, BlockProverType.Receipt) receipt_proof = block_prover.get_proof(tx_index) receipt_hash = block_prover.to_hash32(block_builder.receipts[tx_index]) assert block_prover.prove(receipt_hash, block.header.receipt_hash, receipt_proof)
def test_genesis_hash_compatibility(self): genesis_init_data = { "transaction_data": { "accounts": [{ "name": "god", "address": "hxebf3a409845cd09dcb5af31ed5be5e34e2af9433", "balance": "0x2961ffa20dd47f5c4700000" }, { "name": "treasury", "address": "hxd5775948cb745525d28ec8c1f0c84d73b38c78d4", "balance": "0x0" }, { "name": "test1", "address": "hx670e692ffd3d5587c36c3a9d8442f6d2a8fcc795", "balance": "0x0" }, { "name": "test2", "address": "hxdc8d79453ba6516bc140b7f53b6b9a012da7ff10", "balance": "0x0" }, { "name": "test3", "address": "hxbedeeadea922dc7f196e22eaa763fb01aab0b64c", "balance": "0x0" }, { "name": "test4", "address": "hxa88d8addc6495e4c21b0dda5b0bf6c9108c98da6", "balance": "0x0" }, { "name": "test5", "address": "hx0260cc5b8777485b04e9dc938b1ee949910f41e1", "balance": "0x0" }, { "name": "test6", "address": "hx09e89b468a1cdfdd24441668204911502fa3add9", "balance": "0x0" }, { "name": "test7", "address": "hxeacd884f0e0b5b2e4a6b4ee87fa5184ab9f25cbe", "balance": "0x0" }, { "name": "test8", "address": "hxa943122f57c7c2af7416c1f2e1af46838ad0958f", "balance": "0x0" }, { "name": "test9", "address": "hxc0519e1c56030be070afc89fbf05783c89b15e2f", "balance": "0x0" }, { "name": "test10", "address": "hxcebc788d5b922b356a1dccadc384d36964e87165", "balance": "0x0" }, { "name": "test11", "address": "hx7f8f432ffdb5fc1d2df6dd452ca52eb719150f3c", "balance": "0x0" }, { "name": "test12", "address": "hxa6c4468032824092ecdb3de2bb66947d69e07b59", "balance": "0x0" }, { "name": "test13", "address": "hxc26d0b28b11732b38c0a2c0634283730258f272a", "balance": "0x0" }, { "name": "test14", "address": "hx695ddb2d1e78f012e3e271e95ffbe4cc8fcd133b", "balance": "0x0" }, { "name": "test15", "address": "hx80ab6b11b5d5c80448d011d10fb1a579c57e0a6c", "balance": "0x0" }, { "name": "test16", "address": "hxa9c7881a53f2245ed12238412940c6f54874c4e3", "balance": "0x0" }, { "name": "test17", "address": "hx4e53cffe116baaff5e1940a6a0c14ad54f7534f2", "balance": "0x0" }, { "name": "test18", "address": "hxbbef9e3942d3d5d83b5293b3cbc20940b459e3eb", "balance": "0x0" }], "message": "A rHizomE has no beGInning Or enD; it is alWays IN the miDDle, between tHings, interbeing, intermeZzO. ThE tree is fiLiatioN, but the rhizome is alliance, uniquelY alliance. The tree imposes the verb \"to be\" but the fabric of the rhizome is the conJUNction, \"AnD ... and ...and...\"THis conJunction carriEs enouGh force to shaKe and uproot the verb \"to be.\" Where are You goIng? Where are you coMing from? What are you heading for? These are totally useless questions.\n\n- 『Mille Plateaux』, Gilles Deleuze & Felix Guattari\n\n\"Hyperconnect the world\"" } } genesis_hash_generator = build_hash_generator(0, "genesis_tx") genesis_tx_hash = genesis_hash_generator.generate_hash( genesis_init_data["transaction_data"]) self.assertEqual( genesis_tx_hash, Hash32.fromhex( "6dbc389370253739f28b8c236f4e7acdcfcdb9cfe8386c32d809114d5b00ac65" ))