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 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)
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