Example #1
0
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))
Example #2
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 #3
0
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)
Example #4
0
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
Example #5
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 #6
0
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)
Example #8
0
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
Example #9
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 #10
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
Example #11
0
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))")