def do_multisig(selectors, fuzz_coin=None, fuzz_signature=None): payments = [ (puzzle_hash_for_index(0), 1000), (puzzle_hash_for_index(1), 2000), ] conditions = conditions_for_payment(payments) pks = [public_key_bytes_for_index(_) for _ in range(1, 4)] M = 2 puzzle_program = p2_m_of_n_delegate_direct.puzzle_for_m_of_public_key_list( M, pks) puzzle_hash = ProgramHash(puzzle_program) def solution_maker(coin, remote): print(coin.name()) if fuzz_coin: coin = fuzz_coin(remote, puzzle_hash) print(coin.name()) id_condition = make_assert_my_coin_id_condition(coin.name()) delegated_puzzle = p2_conditions.puzzle_for_conditions( conditions + [id_condition]) delegated_solution = p2_delegated_conditions.solution_for_conditions( delegated_puzzle, []) solution = p2_m_of_n_delegate_direct.solution_for_delegated_puzzle( M, pks, selectors, delegated_puzzle, delegated_solution) return solution run_test(puzzle_hash, payments, solution_maker, fuzz_signature)
def default_payments_and_conditions(initial_index=1): payments = [ (puzzle_hash_for_index(initial_index + 1), initial_index * 1000), (puzzle_hash_for_index(initial_index + 2), (initial_index + 1) * 1000), ] conditions = conditions_for_payment(payments) return payments, conditions
def farm_spendable_coin(remote, puzzle_hash=puzzle_hash_for_index(0)): run = asyncio.get_event_loop().run_until_complete r = run( remote.next_block(coinbase_puzzle_hash=puzzle_hash, fees_puzzle_hash=puzzle_hash_for_index(1))) body = r.get("body") coinbase_coin = body.coinbase_coin return coinbase_coin
def test_farm_block_one_spendbundle(): REWARD = 10000 unspent_db = RAM_DB() chain_view = ChainView.for_genesis_hash(GENESIS_BLOCK, unspent_db) pos = ProofOfSpace(get_pool_public_key(), get_plot_public_key()) puzzle_hash = puzzle_hash_for_index(1) empty_spend_bundle = SpendBundle.aggregate([]) header, header_signature, body = farm_block(GENESIS_BLOCK, Signature.zero(), 1, pos, empty_spend_bundle, puzzle_hash, REWARD) coinbase_coin = body.coinbase_coin conditions = standard_conditions() spend_bundle = spend_coin(coin=coinbase_coin, conditions=conditions, index=1) header, header_signature, body = farm_block(GENESIS_BLOCK, Signature.zero(), 1, pos, spend_bundle, puzzle_hash, REWARD) removals = removals_for_body(body) assert len(removals) == 1 assert removals[0] == list(spend_bundle.coin_solutions)[0].coin.name() run = asyncio.get_event_loop().run_until_complete additions, removals = run( chain_view.accept_new_block(header, unspent_db, REWARD, 0)) assert len(additions) == 4 assert len(removals) == 1
def test_farm_two_blocks(): """ In this test, we farm two blocks: one empty block, then one block which spends the coinbase transaction from the empty block. """ REWARD = 10000 unspent_db = RAM_DB() chain_view = ChainView.for_genesis_hash(GENESIS_BLOCK, unspent_db) assert chain_view.genesis_hash == GENESIS_BLOCK assert chain_view.tip_hash == HeaderHash(GENESIS_BLOCK) assert chain_view.tip_index == 0 assert chain_view.unspent_db == unspent_db pos_1 = ProofOfSpace(get_pool_public_key(), get_plot_public_key()) puzzle_hash = puzzle_hash_for_index(1) empty_spend_bundle = SpendBundle.aggregate([]) header, header_signature, body = farm_block(GENESIS_BLOCK, Signature.zero(), 1, pos_1, empty_spend_bundle, puzzle_hash, REWARD) run = asyncio.get_event_loop().run_until_complete additions, removals = run( chain_view.accept_new_block(header, unspent_db, REWARD, 0)) assert len(additions) == 2 assert len(removals) == 0 # TODO: check additions assert additions[1].puzzle_hash == body.fees_coin.puzzle_hash assert additions[1].amount == 0 chain_view = run( chain_view.augment_chain_view(header, header_signature, unspent_db, unspent_db, REWARD, 0)) assert chain_view.genesis_hash == GENESIS_BLOCK assert chain_view.tip_hash == HeaderHash(header) assert chain_view.tip_index == 1 assert chain_view.unspent_db == unspent_db conditions = standard_conditions() spend_bundle_2 = spend_coin(coin=additions[0], conditions=conditions, index=1) assert validate_spend_bundle_signature(spend_bundle_2) pos_2 = ProofOfSpace(get_pool_public_key(1), get_plot_public_key()) header_2, header_signature_2, body_2 = farm_block(header, header_signature, 2, pos_2, spend_bundle_2, puzzle_hash, REWARD) print(header_2) print(header_signature_2) removals = removals_for_body(body_2) assert len(removals) == 1 assert removals[0] == list(spend_bundle_2.coin_solutions)[0].coin.name()
def do_pubkey(fuzz_coin=None): payments = [ (puzzle_hash_for_index(0), 1000), (puzzle_hash_for_index(1), 2000), ] conditions = conditions_for_payment(payments) pk = public_key_bytes_for_index(1) puzzle_program = p2_delegated_conditions.puzzle_for_pk(pk) puzzle_hash = ProgramHash(puzzle_program) def solution_maker(coin, remote): if fuzz_coin: coin = fuzz_coin(remote, puzzle_hash) id_condition = make_assert_my_coin_id_condition(coin.name()) return p2_delegated_conditions.solution_for_conditions( puzzle_program, conditions + [id_condition]) run_test(puzzle_hash, payments, solution_maker)
def test_farm_block_empty(): REWARD = 10000 unspent_db = RAM_DB() chain_view = ChainView.for_genesis_hash(GENESIS_BLOCK, unspent_db) pos = ProofOfSpace(get_pool_public_key(), get_plot_public_key()) puzzle_hash = puzzle_hash_for_index(1) spend_bundle = SpendBundle.aggregate([]) header, header_signature, body = farm_block(GENESIS_BLOCK, Signature.zero(), 1, pos, spend_bundle, puzzle_hash, REWARD) removals = removals_for_body(body) assert len(removals) == 0 run = asyncio.get_event_loop().run_until_complete additions, removals = run( chain_view.accept_new_block(header, unspent_db, REWARD, 0)) assert len(additions) == 2 assert len(removals) == 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
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))")
def standard_conditions(): conditions = conditions_for_payment([ (puzzle_hash_for_index(0), 1000), (puzzle_hash_for_index(1), 2000), ]) return conditions
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