Example #1
0
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')
Example #2
0
def farm_new_block(previous_header: HeaderHash, previous_signature: Signature,
                   block_index: int, proof_of_space: ProofOfSpace,
                   spend_bundle: SpendBundle, coinbase_coin: Coin,
                   coinbase_signature: BLSSignature,
                   fees_puzzle_hash: ProgramHash, timestamp: uint64):
    """
    Steps:
        - collect up a consistent set of removals and solutions
        - run solutions to get the additions
        - select a timestamp = max(now, minimum_legal_timestamp)
        - create blank extension data
        - collect up coinbase coin with coinbase signature (if solo mining, we get these locally)
        - return Header, Body
    """

    program_cost = 0

    assert validate_spend_bundle_signature(spend_bundle)
    solution_program = best_solution_program(spend_bundle)
    extension_data = std_hash(b'')

    block_index_hash = block_index.to_bytes(32, "big")
    fees_coin = Coin(block_index_hash, fees_puzzle_hash, spend_bundle.fees())
    body = Body(coinbase_signature, coinbase_coin, fees_coin, solution_program,
                program_cost, spend_bundle.aggregated_signature)

    header = Header(previous_header, previous_signature, timestamp,
                    proof_of_space, body, extension_data)
    return header, body
Example #3
0
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)
Example #4
0
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
Example #5
0
 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