def commit_and_notify(remote, wallets, reward_recipient): run = asyncio.get_event_loop().run_until_complete coinbase_puzzle_hash = reward_recipient.get_new_puzzlehash() fees_puzzle_hash = reward_recipient.get_new_puzzlehash() r = run( remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash)) body = r.get("body") additions = list(additions_for_body(body)) removals = removals_for_body(body) removals = [ Coin.from_bytes(run(remote.hash_preimage(hash=x))) for x in removals ] tip = run(remote.get_tip()) index = int(tip["tip_index"]) for wallet in wallets: if isinstance(wallet, RLWallet): spend_bundle = wallet.notify(additions, removals, index) else: spend_bundle = wallet.notify(additions, removals) if spend_bundle is not None: for bun in spend_bundle: _ = run(remote.push_tx(tx=bun))
async def process_blocks(wallet, ledger_api, last_known_header, current_header_hash): r = await ledger_api.hash_preimage(hash=current_header_hash) header = Header.from_bytes(r) body = Body.from_bytes(await ledger_api.hash_preimage(hash=header.body_hash)) if header.previous_hash != last_known_header: await process_blocks(wallet, ledger_api, last_known_header, header.previous_hash) print(f'processing block {HeaderHash(header)}') additions = list(additions_for_body(body)) removals = removals_for_body(body) removals = [ Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals ] wallet.notify(additions, removals) clawback_coins = [coin for coin in additions if wallet.is_in_escrow(coin)] if len(clawback_coins) != 0: print(f'WARNING! Coins from this wallet have been moved to escrow!\n' f'Attempting to send a clawback for these coins:') for coin in clawback_coins: print(f'Coin ID: {coin.name()}, Amount: {coin.amount}') transaction = wallet.generate_clawback_transaction(clawback_coins) r = await ledger_api.push_tx(tx=transaction) if type(r) is RemoteError: print('Clawback failed') else: print('Clawback transaction submitted')
async def update_ledger(wallet, ledger_api, most_recent_header): if most_recent_header is None: r = await ledger_api.get_all_blocks() else: r = await ledger_api.get_recent_blocks(most_recent_header=most_recent_header) update_list = BodyList.from_bytes(r) for body in update_list: additions = list(additions_for_body(body)) print(additions) removals = removals_for_body(body) removals = [Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals] wallet.notify(additions, removals)
async def new_block(wallet, ledger_api): coinbase_puzzle_hash = wallet.get_new_puzzlehash() fees_puzzle_hash = wallet.get_new_puzzlehash() r = await ledger_api.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) body = r["body"] # breakpoint() most_recent_header = r['header'] # breakpoint() additions = list(additions_for_body(body)) removals = removals_for_body(body) removals = [Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals] wallet.notify(additions, removals) return most_recent_header
async def get_coin_age(coin, ledger_api, header_hash): r = await ledger_api.get_tip() if r['genesis_hash'] == header_hash: return float('-inf') r = await ledger_api.hash_preimage(hash=header_hash) header = Header.from_bytes(r) body = Body.from_bytes(await ledger_api.hash_preimage(hash=header.body_hash)) additions = list(additions_for_body(body)) if coin in additions: return 0 return 1 + await get_coin_age(coin, ledger_api, header.previous_hash)
def commit_and_notify(remote, wallets, reward_recipient): run = asyncio.get_event_loop().run_until_complete coinbase_puzzle_hash = reward_recipient.get_new_puzzlehash() fees_puzzle_hash = reward_recipient.get_new_puzzlehash() r = run(remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash)) body = r.get("body") additions = list(additions_for_body(body)) removals = [Coin.from_bytes(run(remote.hash_preimage(hash=x))) for x in removals_for_body(body)] for wallet in wallets: wallet.notify(additions, removals) return additions, removals
async def process_blocks(wallet, ledger_api, last_known_header, current_header_hash): r = await ledger_api.hash_preimage(hash=current_header_hash) header = Header.from_bytes(r) body = Body.from_bytes(await ledger_api.hash_preimage(hash=header.body_hash)) if header.previous_hash != last_known_header: await process_blocks(wallet, ledger_api, last_known_header, header.previous_hash) print(f'processing block {HeaderHash(header)}') additions = list(additions_for_body(body)) removals = removals_for_body(body) removals = [ Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals ] wallet.notify(additions, removals)
async def update_ledger(wallet, ledger_api, most_recent_header): if most_recent_header is None: r = await ledger_api.get_all_blocks() else: r = await ledger_api.get_recent_blocks(most_recent_header=most_recent_header) update_list = BodyList.from_bytes(r) tip = await ledger_api.get_tip() index = int(tip["tip_index"]) for body in update_list: additions = list(additions_for_body(body)) removals = removals_for_body(body) removals = [Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals] spend_bundle_list = wallet.notify(additions, removals, index) if spend_bundle_list is not None: for spend_bundle in spend_bundle_list: _ = await ledger_api.push_tx(tx=spend_bundle) return most_recent_header
async def get_unspent_coins(ledger_api, header_hash): r = await ledger_api.get_tip() if r['genesis_hash'] == header_hash: return set() r = await ledger_api.hash_preimage(hash=header_hash) header = Header.from_bytes(r) unspent_coins = await get_unspent_coins(ledger_api, header.previous_hash) body = Body.from_bytes(await ledger_api.hash_preimage(hash=header.body_hash)) additions = list(additions_for_body(body)) unspent_coins.update(additions) removals = removals_for_body(body) removals = [ Coin.from_bytes(await ledger_api.hash_preimage(hash=x)) for x in removals ] unspent_coins.difference_update(removals) return unspent_coins
async def sync(self): """ Get blocks from ledger sim and make a note of new and spent coins that are "interesting". """ headers = [] tip_dict = await self._ledger_sim.get_tip() genesis_hash = tip_dict["genesis_hash"] header_hash = tip_dict["tip_hash"] header_index = tip_dict["tip_index"] while True: if header_hash == genesis_hash: break if len(self._header_list ) >= header_index and header_hash == HeaderHash( self._header_list[header_index - 1]): break preimage = await self._ledger_sim.hash_preimage(hash=header_hash) header = Header.from_bytes(preimage) headers.append(header) header_hash = header.previous_hash header_index -= 1 await self.rollback_to_block(header_index) new_block_count = len(headers) while headers: header = headers.pop() preimage = await self._ledger_sim.hash_preimage( hash=header.body_hash) body = Body.from_bytes(preimage) additions = [ _ for _ in additions_for_body(body) if _.puzzle_hash in self._interested_puzzled_hashes ] removals = [ _ for _ in removals_for_body(body) if _ in self._interested_puzzled_hashes ] await apply_deltas(header_index, additions, removals, self, self) self._header_list.append(header) header_index += 1 return new_block_count
async def client_test(path): remote = await proxy_for_unix_connection(path) # test preimage API failure case _ = await remote.hash_preimage(hash=b'0' * 32) assert _ is None # farm a block coinbase_puzzle_hash = puzzle_hash_for_index(1) fees_puzzle_hash = puzzle_hash_for_index(6) r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) coinbase_coin = body.coinbase_coin r = await remote.all_unspents() print("unspents = %s" % r.get("unspents")) # add a SpendBundle conditions = standard_conditions() spend_bundle = spend_coin(coinbase_coin, conditions, 1) # break the signature if 0: sig = spend_bundle.aggregated_signature.sig sig = sig[:-1] + bytes([0]) spend_bundle = spend_bundle.__class__(spend_bundle.coin_solutions, sig) _ = await remote.push_tx(tx=spend_bundle) print(_) my_new_coins = spend_bundle.additions() coinbase_puzzle_hash = puzzle_hash_for_index(2) # farm another block, locking in the spend r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) print(header) print(body) my_new_coins_2 = tuple(additions_for_body(body)) assert my_new_coins == my_new_coins_2[2:] # ensure we spent the coin removals = removals_for_body(body) assert len(removals) == 1 expected_coin_id = 'dfef63a0c650fb6121f1ecc2e031a46ee4f7d933aaf7b583dfdcd6cd0ba52fdd' assert repr(removals[0]) == f'<CoinPointer: {expected_coin_id}>' # add a SpendBundle input_coin = my_new_coins[0] conditions = standard_conditions() spend_bundle = spend_coin(coin=input_coin, conditions=conditions, index=0) _ = await remote.push_tx(tx=spend_bundle) import pprint pprint.pprint(_) assert repr(_).startswith("RemoteError") r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") print(header) print(body) for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) r = await remote.all_unspents() print("unspents = %s" % r.get("unspents")) r = await remote.get_tip() print(r) header_hash = r["tip_hash"] header = await header_hash.obj(remote) assert r["tip_index"] == 3 assert r["genesis_hash"] == bytes([0] * 32) # a bad SpendBundle input_coin = my_new_coins[1] spend_bundle = spend_coin(input_coin, [], 2) _ = await remote.push_tx(tx=spend_bundle) expected_program_id = "3b8f716b029bc6c658e73ac071a4ed8da2d73b8f4181db37cf1c40527bb27835" assert str(_) == ("exception: (<Err.WRONG_PUZZLE_HASH: 8>, " "Coin(parent_coin_info=<CoinPointer: " f"{expected_coin_id}>," f" puzzle_hash=<ProgramPointer: {expected_program_id}>, " "amount=2000))")
async def client_test(path): remote = await proxy_for_unix_connection(path) # test preimage API failure case _ = await remote.hash_preimage(hash=b'0' * 32) assert _ is None # farm a block coinbase_puzzle_hash = puzzle_hash_for_index(1) fees_puzzle_hash = puzzle_hash_for_index(6) r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) coinbase_coin = body.coinbase_coin r = await remote.all_unspents() print("unspents = %s" % r.get("unspents")) # add a SpendBundle conditions = standard_conditions() spend_bundle = spend_coin(coinbase_coin, conditions, 1) # break the signature if 0: sig = spend_bundle.aggregated_signature.sig sig = sig[:-1] + bytes([0]) spend_bundle = spend_bundle.__class__(spend_bundle.coin_solutions, sig) _ = await remote.push_tx(tx=spend_bundle) print(_) my_new_coins = spend_bundle.additions() coinbase_puzzle_hash = puzzle_hash_for_index(2) # farm another block, locking in the spend r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) print(header) print(body) my_new_coins_2 = tuple(additions_for_body(body)) assert my_new_coins == my_new_coins_2[2:] # ensure we spent the coin removals = removals_for_body(body) assert len(removals) == 1 expected_coin_id = '67476d53f3ce4a19d7bdf5f73c524477ab1721ce68e1eccd76982f226c26e9fa' assert repr(removals[0]) == f'<CoinPointer: {expected_coin_id}>' # add a SpendBundle input_coin = my_new_coins[0] conditions = standard_conditions() spend_bundle = spend_coin(coin=input_coin, conditions=conditions, index=0) _ = await remote.push_tx(tx=spend_bundle) import pprint pprint.pprint(_) assert repr(_).startswith("RemoteError") r = await remote.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash, fees_puzzle_hash=fees_puzzle_hash) header = r.get("header") body = r.get("body") print(header) print(body) for _ in [header, body]: hh = std_hash(_) r1 = await remote.hash_preimage(hash=hh) assert r1 == bytes(_) r = await remote.all_unspents() print("unspents = %s" % r.get("unspents")) r = await remote.get_tip() print(r) header_hash = r["tip_hash"] header = await header_hash.obj(remote) assert r["tip_index"] == 3 assert r["genesis_hash"] == bytes([0] * 32) # a bad SpendBundle input_coin = my_new_coins[1] spend_bundle = spend_coin(input_coin, [], 2) _ = await remote.push_tx(tx=spend_bundle) expected_program_id = "cfeeb3a79949bf76dbc13580313c96a3742e31d0a17c55ae70eae502164c7d07" assert str(_) == ("exception: (<Err.WRONG_PUZZLE_HASH: 8>, " "Coin(parent_coin_info=<CoinPointer: " f"{expected_coin_id}>," f" puzzle_hash=<ProgramPointer: {expected_program_id}>, " "amount=2000))")