def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]): sigs = [] solution: Program puzzle: Program for puzzle, solution in spends: # type: ignore # noqa pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash) code_ = [puzzle, solution.solution] sexp = Program.to(code_) err, con, cost = conditions_for_solution(sexp) if not con: return conditions_dict = conditions_by_opcode(con) for _, msg in pkm_pairs_for_conditions_dict( conditions_dict, bytes(solution.coin)): signature = AugSchemeMPL.sign(secretkey, msg) sigs.append(signature) aggsig = AugSchemeMPL.aggregate(sigs) solution_list: List[CoinSolution] = [ CoinSolution(coin_solution.coin, Program.to([puzzle, coin_solution.solution])) for (puzzle, coin_solution) in spends ] spend_bundle = SpendBundle(solution_list, aggsig) return spend_bundle
async def test_agg_sig_condition(self, two_nodes): reward_ph = WALLET_A.get_new_puzzlehash() full_node_1, full_node_2, server_1, server_2 = two_nodes blocks = await full_node_1.get_all_full_blocks() start_height = blocks[-1].height blocks = bt.get_consecutive_blocks( 3, block_list_input=blocks, guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, ) for block in blocks: await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block)) await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3) # this code has been changed to use generate_test_spend_bundle # not quite sure why all the gymnastics are being performed coin = list(blocks[-1].get_included_reward_coins())[0] spend_bundle_0 = generate_test_spend_bundle(coin) unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions assert len(unsigned) == 1 coin_solution: CoinSolution = unsigned[0] err, con, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution) assert con is not None
def test_1(): puzzle_program_1 = puzzle_program_for_index(uint32(1)) puzzle_program_2 = puzzle_program_for_index(uint32(2)) conditions = Program.to([ make_create_coin_condition(std_hash(bytes(pp)), amount) for pp, amount in [(puzzle_program_1, 1000), (puzzle_program_2, 2000)] ]) assert conditions is not None puzzle_reveal = p2_delegated_puzzle.puzzle_reveal_for_conditions( conditions) solution = p2_delegated_puzzle.solution_for_conditions(conditions) error, output_conditions, cost = conditions_for_solution( puzzle_reveal, solution) assert error is None from pprint import pprint assert output_conditions is not None output_conditions_dict = conditions_by_opcode(output_conditions) pprint(output_conditions_dict) input_coin_info_hash = bytes([0] * 32) created_outputs_for_conditions_dict(output_conditions_dict, input_coin_info_hash) aggsigs = aggsig_in_conditions_dict(output_conditions_dict) pprint(aggsigs)
def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]): sigs = [] solution: Program puzzle: Program for puzzle, solution in spends: # type: ignore # noqa pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash) secretkey = BLSPrivateKey(secretkey) code_ = [puzzle, solution.solution] sexp = Program.to(code_) err, con, cost = conditions_for_solution(sexp) if not con: return conditions_dict = conditions_by_opcode(con) for _ in hash_key_pairs_for_conditions_dict( conditions_dict, bytes(solution.coin)): signature = secretkey.sign(_.message_hash) sigs.append(signature) aggsig = BLSSignature.aggregate(sigs) solution_list: List[CoinSolution] = [ CoinSolution(coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])) for (puzzle, coin_solution) in spends ] spend_bundle = SpendBundle(solution_list, aggsig) return spend_bundle
def signature_for_solution(self, coin_solution: CoinSolution) -> AugSchemeMPL: signatures = [] err, conditions, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution) assert conditions is not None conditions_dict = conditions_by_opcode(conditions) for public_key, message_hash in pkm_pairs_for_conditions_dict(conditions_dict, coin_solution.coin.name()): signature = self.sign(bytes(public_key), message_hash) signatures.append(signature) return AugSchemeMPL.aggregate(signatures)
def signature_for_solution(self, solution, coin_name): signatures = [] conditions = conditions_for_solution(solution) assert conditions[1] is not None conditions_dict = conditions_by_opcode(conditions[1]) for _ in hash_key_pairs_for_conditions_dict(conditions_dict, coin_name): signature = self.sign(_) signatures.append(signature) return BLSSignature.aggregate(signatures)
def signature_for_solution(self, solution, coin_name): signatures = [] conditions = conditions_for_solution(solution) assert conditions[1] is not None conditions_dict = conditions_by_opcode(conditions[1]) for pk, msg in pkm_pairs_for_conditions_dict(conditions_dict, coin_name): signature = self.sign(pk, msg) signatures.append(signature) return AugSchemeMPL.aggregate(signatures)
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_agg_sig_condition(self, two_nodes): num_blocks = 2 blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"") 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 # this code has been changed to use generate_test_spend_bundle # not quite sure why all the gymnastics are being performed spend_bundle_0 = generate_test_spend_bundle( block.get_coinbase(), ) unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions assert len(unsigned) == 1 coin_solution = unsigned[0] err, con, cost = conditions_for_solution(coin_solution.solution) assert con is not None puzzle, solution = list(coin_solution.solution.as_iter()) conditions_dict = conditions_by_opcode(con) pkm_pairs = pkm_pairs_for_conditions_dict( conditions_dict, coin_solution.coin.name() ) assert len(pkm_pairs) == 1 assert pkm_pairs[0][1] == 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
def sign_transaction(self, coin_solutions: List[CoinSolution]) -> SpendBundle: signatures = [] solution: Program puzzle: Program for coin_solution in coin_solutions: # type: ignore # noqa secret_key = self.get_private_key_for_puzzle_hash(coin_solution.coin.puzzle_hash) synthetic_secret_key = calculate_synthetic_secret_key(secret_key, DEFAULT_HIDDEN_PUZZLE_HASH) err, con, cost = conditions_for_solution(coin_solution.solution) if not con: raise ValueError(err) conditions_dict = conditions_by_opcode(con) for _, msg in pkm_pairs_for_conditions_dict(conditions_dict, bytes(coin_solution.coin.name())): signature = AugSchemeMPL.sign(synthetic_secret_key, msg) signatures.append(signature) aggsig = AugSchemeMPL.aggregate(signatures) spend_bundle = SpendBundle(coin_solutions, aggsig) return spend_bundle
async def sign_transaction( self, spends: List[Tuple[Program, CoinSolution]] ) -> Optional[SpendBundle]: signatures = [] for puzzle, solution in spends: # Get keys keys = await self.wallet_state_manager.get_keys(solution.coin.puzzle_hash) if not keys: self.log.error( f"Sign transaction failed, No Keys for puzzlehash {solution.coin.puzzle_hash}" ) return None pubkey, secretkey = keys secretkey = BLSPrivateKey(secretkey) code_ = [puzzle, solution.solution] sexp = clvm.to_sexp_f(code_) # Get AGGSIG conditions err, con, cost = conditions_for_solution(sexp) if err or not con: self.log.error(f"Sign transcation failed, con:{con}, error: {err}") return None conditions_dict = conditions_by_opcode(con) # Create signature for pk_message in hash_key_pairs_for_conditions_dict( conditions_dict, bytes(solution.coin) ): signature = secretkey.sign(pk_message.message_hash) signatures.append(signature) # Aggregate signatures aggsig = BLSSignature.aggregate(signatures) solution_list: List[CoinSolution] = [ CoinSolution( coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution]) ) for (puzzle, coin_solution) in spends ] spend_bundle = SpendBundle(solution_list, aggsig) return spend_bundle
async def test_agg_sig_condition(self, two_nodes): num_blocks = 2 wallet_a = bt.get_pool_wallet_tool() wallet_receiver = WalletTool() receiver_puzzlehash = wallet_receiver.get_new_puzzlehash() blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"") 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[CoinSolution] = wallet_a.generate_unsigned_transaction( 1000, receiver_puzzlehash, block.get_coinbase(), {}, 0) assert len(unsigned) == 1 coin_solution = unsigned[0] err, con, cost = conditions_for_solution(coin_solution.solution) assert con is not None puzzle, solution = list(coin_solution.solution.as_iter()) conditions_dict = conditions_by_opcode(con) pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict, coin_solution.coin.name()) assert len(pkm_pairs) == 1 assert pkm_pairs[0][1] == 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