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 do_spend_coin(wallet, storage, input): """ UI to spend a coin. """ coins = [] while True: coin_str = input("Enter hex id of coin to spend> ") if len(coin_str) == 0: break coin_name = bytes.fromhex(coin_str) preimage = await storage.hash_preimage(hash=coin_name) if preimage is None: print(f"can't find coin id {coin_name.hex()}") continue coin = Coin.from_bytes(preimage) coin_puzzle_hash_hex = coin.puzzle_hash.hex() print(f"coin puzzle hash is {coin_puzzle_hash_hex}") coins.append(coin) if len(coins) == 0: return dest_address = "14c56fdefb47e2208de54b6c609a907c522348c96e8cfb41c7a8c75f44835dd9" print(f"sending 1 coin to {dest_address}, rest fees") # create an unfinalized SpendBundle pst = spend_coin(wallet, coins, dest_address) pst_encoded = bytes(pst) print(pst_encoded.hex()) # keep requesting signatures until finalized sigs = [] while True: sig_str = input("Enter a signature> ") try: sig = BLSSignature.from_bytes(bytes.fromhex(sig_str)) except Exception as ex: print("failed: %s" % ex) continue sigs.append(sig) sigs = list(set(sigs)) spend_bundle, summary_list = finalize_pst(wallet, pst, sigs) if spend_bundle: break for summary in summary_list: print( "coin %s has %d of %d sigs" % (summary[0].name(), len(summary[2]), summary[3]) ) print("spend bundle = %s" % bytes(spend_bundle).hex()) # optionally send to ledger sim r = input(f"Send to ledger sim? (y/n)> ") if r.lower().startswith("y"): r = await storage.ledger_sim().push_tx(tx=spend_bundle) return spend_bundle
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 all_coins_and_unspents(storage): """ Query the ledger sim instance for all coins and unspents. """ coins = [] unspents = [] coin_name_unspent_pairs = [_ async for _ in storage.all_unspents()] for coin_name, unspent in coin_name_unspent_pairs: preimage = await storage.hash_preimage(hash=coin_name) coin = Coin.from_bytes(preimage) unspents.append(unspent) coins.append(coin) return coins, unspents
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