示例#1
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
示例#2
0
def test_1():
    puzzle_program_0 = puzzle_program_for_index(0)
    puzzle_program_1 = puzzle_program_for_index(1)
    puzzle_program_2 = puzzle_program_for_index(2)

    conditions = [make_create_coin_condition(std_hash(bytes(pp)), amount) for pp, amount in [
        (puzzle_program_1, 1000), (puzzle_program_2, 2000),
    ]]

    puzzle_hash_solution = p2_delegated_puzzle.solution_for_conditions(puzzle_program_0, conditions)

    output_conditions = conditions_for_solution(puzzle_hash_solution)
    from pprint import pprint
    output_conditions_dict = conditions_by_opcode(output_conditions)
    pprint(output_conditions_dict)
    input_coin_info_hash = bytes([0] * 32)
    additions = created_outputs_for_conditions_dict(output_conditions_dict, input_coin_info_hash)
    print(additions)
    assert len(additions) == 2
示例#3
0
def farm_block(previous_header, previous_signature, block_number,
               proof_of_space, spend_bundle, coinbase_puzzle_hash, reward):

    fees_puzzle_hash = puzzle_hash_for_index(3)

    coinbase_coin, coinbase_signature = create_coinbase_coin_and_signature(
        block_number, coinbase_puzzle_hash, reward,
        proof_of_space.pool_public_key)

    timestamp = int(1e10) + 300 * block_number
    header, body = farm_new_block(previous_header, previous_signature,
                                  block_number, proof_of_space, spend_bundle,
                                  coinbase_coin, coinbase_signature,
                                  fees_puzzle_hash, timestamp)

    header_signature = sign_header(header, proof_of_space.plot_public_key)

    bad_bls_public_key = BLSPublicKey.from_bytes(public_key_bytes_for_index(9))

    bad_eor_public_key = EORPrivateKey(std_hash(bytes([5]))).public_key()

    hkp = header_signature.aggsig_pair(proof_of_space.plot_public_key,
                                       HeaderHash(header))
    _ = header_signature.validate([hkp])
    assert _

    hkp = header_signature.aggsig_pair(bad_eor_public_key, HeaderHash(header))
    assert not header_signature.validate([hkp])

    hkp = body.coinbase_signature.aggsig_pair(proof_of_space.pool_public_key,
                                              body.coinbase_coin.name())
    assert body.coinbase_signature.validate([hkp])

    hkp = body.coinbase_signature.aggsig_pair(bad_bls_public_key,
                                              body.coinbase_coin.name())
    assert not body.coinbase_signature.validate([hkp])
    return header, header_signature, body
示例#4
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))")
示例#6
0
async def client_test(path):

    remote = await proxy_for_unix_connection(path)

    payments = [
        (puzzle_hash_for_index(0), 1000),
        (puzzle_hash_for_index(1), 2000),
    ]

    conditions = conditions_for_payment(payments)
    coinbase_puzzle_hash = ProgramHash(puzzle_for_conditions(conditions))

    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

    new_coinbase_puzzle_hash = puzzle_hash_for_index(5)

    # farm a few blocks
    for _ in range(5):
        r = await remote.next_block(
            coinbase_puzzle_hash=new_coinbase_puzzle_hash,
            fees_puzzle_hash=fees_puzzle_hash,
        )

        assert "header" in r

    # spend the coinbase coin

    solution = solution_for_conditions(conditions)
    spend_bundle = build_spend_bundle(coinbase_coin, solution)

    r = await remote.push_tx(tx=spend_bundle)
    assert r["response"].startswith("accepted")

    # farm a few blocks
    for _ in range(5):
        r = await remote.next_block(
            coinbase_puzzle_hash=new_coinbase_puzzle_hash,
            fees_puzzle_hash=fees_puzzle_hash,
        )

        assert "header" in r

    r = await remote.push_tx(tx=spend_bundle)
    assert r.args[0].startswith("exception: (<Err.DOUBLE_SPEND")

    r = await remote.all_unspents()
    coin_names = r["unspents"]
    coin_name = coin_names[0]
    assert coin_name == coinbase_coin.name()

    unspent = await remote.unspent_for_coin_name(coin_name=coin_name)
    assert unspent.spent_block_index == 7
示例#7
0
import asyncio

from chiasim.hack.keys import (conditions_for_payment,
                               public_key_bytes_for_index,
                               puzzle_hash_for_index, spend_coin)
from chiasim.hashable import (std_hash, EORPrivateKey, HeaderHash,
                              ProofOfSpace, BLSPublicKey, Signature,
                              SpendBundle)
from chiasim.farming import farm_new_block, get_plot_public_key, sign_header
from chiasim.pool import create_coinbase_coin_and_signature, get_pool_public_key
from chiasim.storage import RAM_DB
from chiasim.validation import ChainView, validate_spend_bundle_signature
from chiasim.wallet.deltas import removals_for_body

GENESIS_BLOCK = std_hash(bytes([0]))


def farm_block(previous_header, previous_signature, block_number,
               proof_of_space, spend_bundle, coinbase_puzzle_hash, reward):

    fees_puzzle_hash = puzzle_hash_for_index(3)

    coinbase_coin, coinbase_signature = create_coinbase_coin_and_signature(
        block_number, coinbase_puzzle_hash, reward,
        proof_of_space.pool_public_key)

    timestamp = int(1e10) + 300 * block_number
    header, body = farm_new_block(previous_header, previous_signature,
                                  block_number, proof_of_space, spend_bundle,
                                  coinbase_coin, coinbase_signature,
                                  fees_puzzle_hash, timestamp)