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