async def test_agg_sig_condition(self, two_nodes): num_blocks = 2 wallet_a = WalletTool() coinbase_puzzlehash = wallet_a.get_new_puzzlehash() wallet_receiver = WalletTool() receiver_puzzlehash = wallet_receiver.get_new_puzzlehash() blocks = bt.get_consecutive_blocks( test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash ) full_node_1, full_node_2, server_1, server_2 = two_nodes block = blocks[1] async for _ in full_node_1.respond_block( full_node_protocol.RespondBlock(block) ): pass unsigned: List[ Tuple[Program, CoinSolution] ] = wallet_a.generate_unsigned_transaction( 1000, receiver_puzzlehash, block.header.data.coinbase, {}, 0 ) assert len(unsigned) == 1 puzzle, solution = unsigned[0] code_ = [puzzle, solution.solution] sexp = Program.to(code_) err, con, cost = conditions_for_solution(sexp) assert con is not None conditions_dict = conditions_by_opcode(con) hash_key_pairs = hash_key_pairs_for_conditions_dict( conditions_dict, solution.coin.name() ) assert len(hash_key_pairs) == 1 pk_pair: BLSSignature.PkMessagePair = hash_key_pairs[0] assert pk_pair.message_hash == solution.solution.first().get_tree_hash() spend_bundle = wallet_a.sign_transaction(unsigned) assert spend_bundle is not None tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction( spend_bundle ) async for _ in full_node_1.respond_transaction(tx): outbound: OutboundMessage = _ # Maybe transaction means that it's accepted in mempool assert outbound.message.function == "new_transaction" sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name()) assert sb is spend_bundle
async def test_short_sync_with_transactions_wallet(self, wallet_node): full_node_1, wallet_node, server_1, server_2 = wallet_node wallet_a = wallet_node.wallet_state_manager.main_wallet wallet_a_dummy = WalletTool() wallet_b = WalletTool() coinbase_puzzlehash = await wallet_a.get_new_puzzlehash() coinbase_puzzlehash_rest = wallet_b.get_new_puzzlehash() puzzle_hashes = [ await wallet_a.get_new_puzzlehash() for _ in range(10) ] puzzle_hashes.append(wallet_b.get_new_puzzlehash()) blocks = bt.get_consecutive_blocks(test_constants, 3, [], 10, b"", coinbase_puzzlehash) for block in blocks: [ _ async for _ in full_node_1.respond_block( full_node_protocol.RespondBlock(block)) ] await asyncio.sleep(2) await server_2.start_client( PeerInfo("localhost", uint16(server_1._port)), None) await asyncio.sleep(2) assert (wallet_node.wallet_state_manager.block_records[ wallet_node.wallet_state_manager.lca].height == 1) server_2.global_connections.close_all_connections() dic_h = {} prev_coin = blocks[1].header.data.coinbase for i in range(11): pk, sk = await wallet_a.wallet_state_manager.get_keys( prev_coin.puzzle_hash) transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction( 1000, puzzle_hashes[i], prev_coin, {}, 0, secretkey=sk) spend_bundle = await wallet_a.sign_transaction(transaction_unsigned ) block_spendbundle = SpendBundle.aggregate([spend_bundle]) program = best_solution_program(block_spendbundle) aggsig = block_spendbundle.aggregated_signature prev_coin = Coin(prev_coin.name(), puzzle_hashes[i], uint64(1000)) dic_h[i + 4] = (program, aggsig) blocks = bt.get_consecutive_blocks(test_constants, 13, blocks, 10, b"", coinbase_puzzlehash_rest, dic_h) # Move chain to height 16, with consecutive transactions in blocks 4 to 14 for block in blocks: async for _ in full_node_1.respond_block( full_node_protocol.RespondBlock(block)): pass # Do a short sync from 0 to 14 await server_2.start_client( PeerInfo("localhost", uint16(server_1._port)), None) start = time.time() broke = False while time.time() - start < 60: if (wallet_node.wallet_state_manager.block_records[ wallet_node.wallet_state_manager.lca].height >= 14 # Tip at 16, LCA at 14 ): broke = True break await asyncio.sleep(0.1) if not broke: raise Exception( f"Took too long to process blocks, stopped at: {time.time() - start}" ) server_2.global_connections.close_all_connections() # 2 block rewards and 3 fees assert await wallet_a.get_confirmed_balance() == ( blocks[1].header.data.coinbase.amount * 2) + (blocks[1].header.data.fees_coin.amount * 3) # All of our coins are spent and puzzle hashes present for puzzle_hash in puzzle_hashes[:-1]: records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash( puzzle_hash) assert len(records) == 1 assert records[0].spent and not records[0].coinbase # Then do the same but in a reorg chain dic_h = {} prev_coin = blocks[1].header.data.coinbase for i in range(11): pk, sk = await wallet_a.wallet_state_manager.get_keys( prev_coin.puzzle_hash) transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction( 1000, puzzle_hashes[i], prev_coin, {}, 0, secretkey=sk) spend_bundle = await wallet_a.sign_transaction(transaction_unsigned ) block_spendbundle = SpendBundle.aggregate([spend_bundle]) program = best_solution_program(block_spendbundle) aggsig = block_spendbundle.aggregated_signature prev_coin = Coin(prev_coin.name(), puzzle_hashes[i], uint64(1000)) dic_h[i + 4] = (program, aggsig) blocks = bt.get_consecutive_blocks( test_constants, 31, blocks[:4], 10, b"this is a reorg", coinbase_puzzlehash_rest, dic_h, ) # Move chain to height 34, with consecutive transactions in blocks 4 to 14 for block in blocks: async for _ in full_node_1.respond_block( full_node_protocol.RespondBlock(block)): pass # Do a sync from 0 to 22 await server_2.start_client( PeerInfo("localhost", uint16(server_1._port)), None) broke = False while time.time() - start < 60: if (wallet_node.wallet_state_manager.block_records[ wallet_node.wallet_state_manager.lca].height >= 28 # Tip at 34, LCA at least 28 ): broke = True break await asyncio.sleep(0.1) if not broke: raise Exception( f"Took too long to process blocks, stopped at: {time.time() - start}" ) server_2.global_connections.close_all_connections() # 2 block rewards and 3 fees assert await wallet_a.get_confirmed_balance() == ( blocks[1].header.data.coinbase.amount * 2) + (blocks[1].header.data.fees_coin.amount * 3) # All of our coins are spent and puzzle hashes present for puzzle_hash in puzzle_hashes[:-1]: records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash( puzzle_hash) assert len(records) == 1 assert records[0].spent and not records[0].coinbase # Test spending the rewards earned in reorg new_coinbase_puzzlehash = await wallet_a.get_new_puzzlehash() another_puzzlehash = await wallet_a.get_new_puzzlehash() dic_h = {} pk, sk = await wallet_a.wallet_state_manager.get_keys( new_coinbase_puzzlehash) coinbase_coin = create_coinbase_coin(25, new_coinbase_puzzlehash, uint64(14000000000000)) transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction( 7000000000000, another_puzzlehash, coinbase_coin, {}, 0, secretkey=sk) spend_bundle = await wallet_a.sign_transaction(transaction_unsigned) block_spendbundle = SpendBundle.aggregate([spend_bundle]) program = best_solution_program(block_spendbundle) aggsig = block_spendbundle.aggregated_signature dic_h[26] = (program, aggsig) # Farm a block (25) to ourselves blocks = bt.get_consecutive_blocks( test_constants, 1, blocks[:25], 10, b"this is yet another reorg", new_coinbase_puzzlehash, ) # Brings height up to 40, with block 31 having half our reward spent to us blocks = bt.get_consecutive_blocks( test_constants, 15, blocks, 10, b"this is yet another reorg more blocks", coinbase_puzzlehash_rest, dic_h, ) for block in blocks: async for _ in full_node_1.respond_block( full_node_protocol.RespondBlock(block)): pass await server_2.start_client( PeerInfo("localhost", uint16(server_1._port)), None) broke = False while time.time() - start < 60: if (wallet_node.wallet_state_manager.block_records[ wallet_node.wallet_state_manager.lca].height >= 38 # Tip at 40, LCA at 38 ): broke = True break await asyncio.sleep(0.1) if not broke: raise Exception( f"Took too long to process blocks, stopped at: {time.time() - start}" ) # 2 block rewards and 4 fees, plus 7000000000000 coins assert (await wallet_a.get_confirmed_balance() == (blocks[1].header.data.coinbase.amount * 2) + (blocks[1].header.data.fees_coin.amount * 4) + 7000000000000) records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash( new_coinbase_puzzlehash) # Fee and coinbase assert len(records) == 2 assert records[0].spent != records[1].spent assert records[0].coinbase == records[1].coinbase records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash( another_puzzlehash) assert len(records) == 1 assert not records[0].spent assert not records[0].coinbase