def load_pool_config(root_path: Path) -> List[PoolWalletConfig]: config = load_config(root_path, "config.yaml") ret_list: List[PoolWalletConfig] = [] if "pool_list" in config["pool"]: for pool_config_dict in config["pool"]["pool_list"]: try: pool_config = PoolWalletConfig( bytes32.from_hexstr(pool_config_dict["launcher_id"]), pool_config_dict["pool_url"], pool_config_dict["payout_instructions"], bytes32.from_hexstr( pool_config_dict["target_puzzle_hash"]), bytes32.from_hexstr( pool_config_dict["p2_singleton_puzzle_hash"]), G1Element.from_bytes( hexstr_to_bytes(pool_config_dict["owner_public_key"])), G1Element.from_bytes( hexstr_to_bytes( pool_config_dict["authentication_public_key"])), ) ret_list.append(pool_config) except Exception as e: log.error(f"Exception loading config: {pool_config_dict} {e}") return ret_list
async def resolve(self) -> PlotKeys: if self.resolved_keys is not None: return self.resolved_keys keychain_proxy: Optional[KeychainProxy] = None if self.connect_to_daemon: keychain_proxy = await connect_to_keychain_and_validate(self.root_path, self.log) else: keychain_proxy = wrap_local_keychain(Keychain(), log=self.log) farmer_public_key: G1Element if self.farmer_public_key is not None: farmer_public_key = G1Element.from_bytes(bytes.fromhex(self.farmer_public_key)) else: farmer_public_key = await self.get_farmer_public_key(keychain_proxy) pool_public_key: Optional[G1Element] = None if self.pool_public_key is not None: if self.pool_contract_address is not None: raise RuntimeError("Choose one of pool_contract_address and pool_public_key") pool_public_key = G1Element.from_bytes(bytes.fromhex(self.pool_public_key)) else: if self.pool_contract_address is None: # If nothing is set, farms to the provided key (or the first key) pool_public_key = await self.get_pool_public_key(keychain_proxy) self.resolved_keys = PlotKeys(farmer_public_key, pool_public_key, self.pool_contract_address) return self.resolved_keys
def parse_plot_info(memo: bytes) -> Tuple[G1Element, G1Element, PrivateKey]: # Parses the plot info bytes into keys assert len(memo) == (48 + 48 + 32) return ( G1Element.from_bytes(memo[:48]), G1Element.from_bytes(memo[48:96]), PrivateKey.from_bytes(memo[96:]), )
def pkm_pairs_for_conditions_dict( conditions_dict: Dict[ConditionOpcode, List[ConditionVarPair]], coin_name: bytes32 = None, ) -> List[Tuple[G1Element, bytes]]: ret: List[Tuple[G1Element, bytes]] = [] for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG, []): # TODO: check types # assert len(_) == 3 assert cvp.var2 is not None ret.append((G1Element.from_bytes(cvp.var1), cvp.var2)) if coin_name is not None: for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []): ret.append((G1Element.from_bytes(cvp.var1), cvp.var2 + coin_name)) return ret
def test_stream(self): for _ in range(1, 64): p = PrivateKey.from_bytes(_.to_bytes(32, "big")).get_g1() blob = bytes(p) p1 = G1Element.from_bytes(blob) self.assertEqual(len(blob), 48) self.assertEqual(p, p1)
async def get_derivation_record( self, index: uint32, wallet_id: uint32, hardened: bool ) -> Optional[DerivationRecord]: """ Returns the derivation record by index and wallet id. """ if hardened: hard = 1 else: hard = 0 cursor = await self.db_connection.execute( "SELECT * FROM derivation_paths WHERE derivation_index=? and wallet_id=? and hardened=?;", (index, wallet_id, hard), ) row = await cursor.fetchone() await cursor.close() if row is not None and row[0] is not None: return DerivationRecord( uint32(row[0]), bytes32.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), WalletType(row[3]), uint32(row[4]), bool(row[5]), ) return None
def test_cached_bls(self): n_keys = 10 seed = b"a" * 31 sks = [AugSchemeMPL.key_gen(seed + bytes([i])) for i in range(n_keys)] pks = [bytes(sk.get_g1()) for sk in sks] msgs = [("msg-%d" % (i,)).encode() for i in range(n_keys)] sigs = [AugSchemeMPL.sign(sk, msg) for sk, msg in zip(sks, msgs)] agg_sig = AugSchemeMPL.aggregate(sigs) pks_half = pks[: n_keys // 2] msgs_half = msgs[: n_keys // 2] sigs_half = sigs[: n_keys // 2] agg_sig_half = AugSchemeMPL.aggregate(sigs_half) assert AugSchemeMPL.aggregate_verify([G1Element.from_bytes(pk) for pk in pks], msgs, agg_sig) # Verify with empty cache and populate it assert cached_bls.aggregate_verify(pks_half, msgs_half, agg_sig_half, True) # Verify with partial cache hit assert cached_bls.aggregate_verify(pks, msgs, agg_sig, True) # Verify with full cache hit assert cached_bls.aggregate_verify(pks, msgs, agg_sig) # Use a small cache which can not accommodate all pairings local_cache = LRUCache(n_keys // 2) # Verify signatures and cache pairings one at a time for pk, msg, sig in zip(pks_half, msgs_half, sigs_half): assert cached_bls.aggregate_verify([pk], [msg], sig, True, local_cache) # Verify the same messages with aggregated signature (full cache hit) assert cached_bls.aggregate_verify(pks_half, msgs_half, agg_sig_half, False, local_cache) # Verify more messages (partial cache hit) assert cached_bls.aggregate_verify(pks, msgs, agg_sig, False, local_cache)
async def get_farmer_records_for_p2_singleton_phs(self, puzzle_hashes: Set[bytes32]) -> List[FarmerRecord]: if len(puzzle_hashes) == 0: return [] puzzle_hashes_db = tuple([ph.hex() for ph in list(puzzle_hashes)]) cursor = await self.connection.execute( f'SELECT * from farmer WHERE p2_singleton_puzzle_hash in ({"?," * (len(puzzle_hashes_db) - 1)}?) ', puzzle_hashes_db, ) rows = await cursor.fetchall() records: List[FarmerRecord] = [] for row in rows: record = FarmerRecord( bytes.fromhex(row[0]), G1Element.from_bytes(bytes.fromhex(row[1])), bytes.fromhex(row[2]), row[3], bytes.fromhex(row[4]), row[5], bytes.fromhex(row[6]), row[7], row[8], bytes.fromhex(row[9]), True if row[10] == 1 else False, ) records.append(record) return records
def __init__( self, root_path: Path, farmer_config: Dict, pool_config: Dict, keychain: Keychain, consensus_constants: ConsensusConstants, ): self._root_path = root_path self.config = farmer_config # Keep track of all sps, keyed on challenge chain signage point hash self.sps: Dict[bytes32, List[farmer_protocol.NewSignagePoint]] = {} # Keep track of harvester plot identifier (str), target sp index, and PoSpace for each challenge self.proofs_of_space: Dict[bytes32, List[Tuple[str, ProofOfSpace]]] = {} # Quality string to plot identifier and challenge_hash, for use with harvester.RequestSignatures self.quality_str_to_identifiers: Dict[bytes32, Tuple[str, bytes32, bytes32, bytes32]] = {} # number of responses to each signage point self.number_of_responses: Dict[bytes32, int] = {} # A dictionary of keys to time added. These keys refer to keys in the above 4 dictionaries. This is used # to periodically clear the memory self.cache_add_time: Dict[bytes32, uint64] = {} self.cache_clear_task: asyncio.Task self.constants = consensus_constants self._shut_down = False self.server: Any = None self.keychain = keychain self.state_changed_callback: Optional[Callable] = None self.log = log all_sks = self.keychain.get_all_private_keys() self._private_keys = [master_sk_to_farmer_sk(sk) for sk, _ in all_sks] + [ master_sk_to_pool_sk(sk) for sk, _ in all_sks ] if len(self.get_public_keys()) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # This is the farmer configuration self.farmer_target_encoded = self.config["xch_target_address"] self.farmer_target = decode_puzzle_hash(self.farmer_target_encoded) self.pool_public_keys = [G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"]] # This is the pool configuration, which should be moved out to the pool once it exists self.pool_target_encoded = pool_config["xch_target_address"] self.pool_target = decode_puzzle_hash(self.pool_target_encoded) self.pool_sks_map: Dict = {} for key in self.get_private_keys(): self.pool_sks_map[bytes(key.get_g1())] = key assert len(self.farmer_target) == 32 assert len(self.pool_target) == 32 if len(self.pool_sks_map) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str)
async def did_recovery_spend(self, request): wallet_id = int(request["wallet_id"]) wallet: DIDWallet = self.service.wallet_state_manager.wallets[ wallet_id] if len(request["attest_filenames"] ) < wallet.did_info.num_of_backup_ids_needed: return {"success": False, "reason": "insufficient messages"} ( info_list, message_spend_bundle, ) = await wallet.load_attest_files_for_recovery_spend( request["attest_filenames"]) if "pubkey" in request: pubkey = G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])) else: assert wallet.did_info.temp_pubkey is not None pubkey = wallet.did_info.temp_pubkey if "puzhash" in request: puzhash = hexstr_to_bytes(request["puzhash"]) else: assert wallet.did_info.temp_puzhash is not None puzhash = wallet.did_info.temp_puzhash success = await wallet.recovery_spend( wallet.did_info.temp_coin, puzhash, info_list, pubkey, message_spend_bundle, ) return {"success": success}
async def get_derivation_record( self, index: uint32, wallet_id: uint32) -> Optional[DerivationRecord]: """ Returns the derivation record by index and wallet id. """ cursor = await self.db_connection.execute( "SELECT * FROM derivation_paths WHERE derivation_index=? and wallet_id=?;", ( index, wallet_id, ), ) row = await cursor.fetchone() await cursor.close() if row is not None and row[0] is not None: return DerivationRecord( row[0], bytes.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), row[3], row[4], ) return None
def puzzle(): # public key --> puzzle pb = "b95e11eccf667b4312588094db0725257f4ce440835d808ed749c9ec39dc5c3afbfdfda7bbf24f2adb58335e848a7a94" g: G1Element = G1Element.from_bytes(bytes.fromhex(pb)) puzzle = puzzle_for_pk(g) h = "ff02ffff01ff02ffff01ff02ffff03ff0bffff01ff02ffff03ffff09ff05ffff1dff0bffff1effff0bff0bffff02ff06ffff04ff02ffff04ff17ff8080808080808080ffff01ff02ff17ff2f80ffff01ff088080ff0180ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff17ff80808080ff80808080ffff02ff17ff2f808080ff0180ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0a76f5e6a0fdb34124b18b492de6cb6ba637571df77c7e8be29a8e9127c4b94cee5cf385ad0c867b67d762fece5993a7eff018080" return str(puzzle) == h
async def test_create_new_pool_wallet_farm_to_pool(self, one_wallet_node_and_rpc, fee): client, wallet_node_0, full_node_api = one_wallet_node_and_rpc wallet_0 = wallet_node_0.wallet_state_manager.main_wallet our_ph = await wallet_0.get_new_puzzlehash() summaries_response = await client.get_wallets() for summary in summaries_response: if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET: assert False creation_tx: TransactionRecord = await client.create_new_pool_wallet( our_ph, "http://pool.example.com", 10, "localhost:5000", "new", "FARMING_TO_POOL", fee) await time_out_assert( 10, full_node_api.full_node.mempool_manager.get_spendbundle, creation_tx.spend_bundle, creation_tx.name, ) await self.farm_blocks(full_node_api, our_ph, 6) assert full_node_api.full_node.mempool_manager.get_spendbundle( creation_tx.name) is None summaries_response = await client.get_wallets() wallet_id: Optional[int] = None for summary in summaries_response: if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET: wallet_id = summary["id"] assert wallet_id is not None status: PoolWalletInfo = (await client.pw_status(wallet_id))[0] assert status.current.state == PoolSingletonState.FARMING_TO_POOL.value assert status.target is None assert status.current.owner_pubkey == G1Element.from_bytes( bytes.fromhex( "b286bbf7a10fa058d2a2a758921377ef00bb7f8143e1bd40dd195ae918dbef42cfc481140f01b9eae13b430a0c8fe304" )) assert status.current.pool_url == "http://pool.example.com" assert status.current.relative_lock_height == 10 assert status.current.version == 1 # Check that config has been written properly full_config: Dict = load_config( wallet_0.wallet_state_manager.root_path, "config.yaml") pool_list: List[Dict] = full_config["pool"]["pool_list"] assert len(pool_list) == 1 pool_config = pool_list[0] assert ( pool_config["authentication_public_key"] == "0xb3c4b513600729c6b2cf776d8786d620b6acc88f86f9d6f489fa0a0aff81d634262d5348fb7ba304db55185bb4c5c8a4" ) # It can be one of multiple launcher IDs, due to selecting a different coin assert pool_config["launcher_id"] in { "0x78a1eadf583a2f27a129d7aeba076ec6a5200e1ec8225a72c9d4180342bf91a7", "0x2bcab0310e78a7ab04e251ac6bdd5dfc80ce6895132e64f97265029db3d8309a", "0x09edf686c318c138cd3461c38e9b4e10e7f21fc476a0929b4480e126b6efcb81", } assert pool_config["pool_url"] == "http://pool.example.com"
def get_pubkey_from_innerpuz(innerpuz: Program) -> G1Element: ret = uncurry_innerpuz(innerpuz) if ret is not None: pubkey_program = ret[0] else: raise ValueError("Unable to extract pubkey") pubkey = G1Element.from_bytes(pubkey_program.as_atom()) return pubkey
def parse_plot_info(memo: bytes) -> Tuple[Union[G1Element, bytes32], G1Element, PrivateKey]: # Parses the plot info bytes into keys if len(memo) == (48 + 48 + 32): # This is a public key memo return ( G1Element.from_bytes(memo[:48]), G1Element.from_bytes(memo[48:96]), PrivateKey.from_bytes(memo[96:]), ) elif len(memo) == (32 + 48 + 32): # This is a pool_contract_puzzle_hash memo return ( bytes32(memo[:32]), G1Element.from_bytes(memo[32:80]), PrivateKey.from_bytes(memo[80:]), ) else: raise ValueError(f"Invalid number of bytes {len(memo)}")
def pkm_pairs_for_conditions_dict( conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]], coin_name: bytes32, additional_data: bytes) -> List[Tuple[G1Element, bytes]]: assert coin_name is not None ret: List[Tuple[G1Element, bytes]] = [] for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_UNSAFE, []): assert len(cwa.vars) == 2 assert cwa.vars[0] is not None and cwa.vars[1] is not None ret.append((G1Element.from_bytes(cwa.vars[0]), cwa.vars[1])) for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []): assert len(cwa.vars) == 2 assert cwa.vars[0] is not None and cwa.vars[1] is not None ret.append((G1Element.from_bytes(cwa.vars[0]), cwa.vars[1] + coin_name + additional_data)) return ret
def row_to_record(self, row) -> DerivationRecord: return DerivationRecord( uint32(row[0]), bytes32.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), WalletType(row[3]), uint32(row[4]), bool(row[6]), )
def test_schemes(): # fmt: off seed = bytes([ 0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18, 102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22 ]) # fmt: on msg = bytes([100, 2, 254, 88, 90, 45, 23]) msg2 = bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) sk = BasicSchemeMPL.key_gen(seed) pk = sk.get_g1() assert sk == PrivateKey.from_bytes(bytes(sk)) assert pk == G1Element.from_bytes(bytes(pk)) for Scheme in (BasicSchemeMPL, AugSchemeMPL, PopSchemeMPL): sig = Scheme.sign(sk, msg) assert sig == G2Element.from_bytes(bytes(sig)) assert Scheme.verify(pk, msg, sig) seed = bytes([1]) + seed[1:] sk1 = BasicSchemeMPL.key_gen(seed) pk1 = sk1.get_g1() seed = bytes([2]) + seed[1:] sk2 = BasicSchemeMPL.key_gen(seed) pk2 = sk2.get_g1() for Scheme in (BasicSchemeMPL, AugSchemeMPL, PopSchemeMPL): # Aggregate same message agg_pk = pk1 + pk2 if Scheme is AugSchemeMPL: sig1 = Scheme.sign(sk1, msg, agg_pk) sig2 = Scheme.sign(sk2, msg, agg_pk) else: sig1 = Scheme.sign(sk1, msg) sig2 = Scheme.sign(sk2, msg) agg_sig = Scheme.aggregate([sig1, sig2]) assert Scheme.verify(agg_pk, msg, agg_sig) # Aggregate different message sig1 = Scheme.sign(sk1, msg) sig2 = Scheme.sign(sk2, msg2) agg_sig = Scheme.aggregate([sig1, sig2]) assert Scheme.aggregate_verify([pk1, pk2], [msg, msg2], agg_sig) # HD keys child = Scheme.derive_child_sk(sk1, 123) childU = Scheme.derive_child_sk_unhardened(sk1, 123) childUPk = Scheme.derive_child_pk_unhardened(pk1, 123) sig_child = Scheme.sign(child, msg) assert Scheme.verify(child.get_g1(), msg, sig_child) sigU_child = Scheme.sign(childU, msg) assert Scheme.verify(childUPk, msg, sigU_child)
def op_point_add(items): cost = POINT_ADD_BASE_COST p = G1Element.generator() * 0 for _ in items.as_iter(): try: p += G1Element.from_bytes(_.as_atom()) cost += POINT_ADD_COST_PER_ARG except Exception as ex: raise EvalError("point_add expects blob, got %s: %s" % (_, ex), items) return cost, items.to(p)
async def get_keys_pk(self, clawback_pubkey: bytes): """ Return keys for pubkey """ index_for_pubkey = await self.wallet_state_manager.puzzle_store.index_for_pubkey( G1Element.from_bytes(clawback_pubkey)) if index_for_pubkey is None: raise Exception("index_for_pubkey is None") private = master_sk_to_wallet_sk(self.private_key, index_for_pubkey) pubkey = private.get_g1() return pubkey, private
def op_point_add(items: SExp): cost = POINT_ADD_BASE_COST p = G1Element() for _ in items.as_iter(): if _.pair: raise EvalError("point_add on list", _) try: p += G1Element.from_bytes(_.as_atom()) cost += POINT_ADD_COST_PER_ARG except Exception as ex: raise EvalError("point_add expects blob, got %s: %s" % (_, ex), items) return malloc_cost(cost, items.to(p))
def __init__( self, farmer_config: Dict, pool_config: Dict, keychain: Keychain, consensus_constants: ConsensusConstants, ): self.config = farmer_config self.harvester_responses_proofs: Dict[Tuple, ProofOfSpace] = {} self.harvester_responses_proof_hash_to_info: Dict[bytes32, Tuple] = {} self.header_hash_to_pos: Dict[bytes32, ProofOfSpace] = {} self.challenges: Dict[ uint128, List[farmer_protocol.ProofOfSpaceFinalized]] = {} self.challenge_to_weight: Dict[bytes32, uint128] = {} self.challenge_to_height: Dict[bytes32, uint32] = {} self.challenge_to_best_iters: Dict[bytes32, uint64] = {} self.challenge_to_estimates: Dict[bytes32, List[float]] = {} self.seen_challenges: Set[bytes32] = set() self.unfinished_challenges: Dict[uint128, List[bytes32]] = {} self.current_weight: uint128 = uint128(0) self.proof_of_time_estimate_ips: uint64 = uint64(100000) self.constants = consensus_constants self._shut_down = False self.server = None self.keychain = keychain self.state_changed_callback: Optional[Callable] = None if len(self._get_public_keys()) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # This is the farmer configuration self.wallet_target = decode_puzzle_hash( self.config["xch_target_address"]) self.pool_public_keys = [ G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"] ] # This is the pool configuration, which should be moved out to the pool once it exists self.pool_target = decode_puzzle_hash( pool_config["xch_target_address"]) self.pool_sks_map: Dict = {} for key in self._get_private_keys(): self.pool_sks_map[bytes(key.get_g1())] = key assert len(self.wallet_target) == 32 assert len(self.pool_target) == 32 if len(self.pool_sks_map) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str)
def _get_pk_and_entropy(self, user: str) -> Optional[Tuple[G1Element, bytes]]: """ Returns the keychain conntents for a specific 'user' (key index). The contents include an G1Element and the entropy required to generate the private key. Note that generating the actual private key also requires the passphrase. """ read_str = keyring.get_password(self._get_service(), user) if read_str is None or len(read_str) == 0: return None str_bytes = bytes.fromhex(read_str) return ( G1Element.from_bytes(str_bytes[: G1Element.SIZE]), str_bytes[G1Element.SIZE :], # flake8: noqa )
def _row_to_farmer_record(row) -> FarmerRecord: return FarmerRecord( bytes.fromhex(row[0]), bytes.fromhex(row[1]), row[2], bytes.fromhex(row[3]), G1Element.from_bytes(bytes.fromhex(row[4])), CoinSpend.from_bytes(row[5]), PoolState.from_bytes(row[6]), row[7], row[8], row[9], True if row[10] == 1 else False, )
def get_pubkey_from_member_inner_puzzle(inner_puzzle: Program) -> G1Element: args = uncurry_pool_member_inner_puzzle(inner_puzzle) if args is not None: ( _inner_f, _target_puzzle_hash, _p2_singleton_hash, pubkey_program, _pool_reward_prefix, _escape_puzzlehash, ) = args else: raise ValueError("Unable to extract pubkey") pubkey = G1Element.from_bytes(pubkey_program.as_atom()) return pubkey
def verify(args): if args.message is None: print("Please specify the message argument -d") quit() if args.public_key is None: print("Please specify the public_key argument -p") quit() if args.signature is None: print("Please specify the signature argument -s") quit() assert args.message is not None assert args.public_key is not None assert args.signature is not None message = bytes(args.message, "utf-8") public_key = G1Element.from_bytes(bytes.fromhex(args.public_key)) signature = G2Element.from_bytes(bytes.fromhex(args.signature)) print(AugSchemeMPL.verify(public_key, message, signature))
async def setup_keys(self): self.all_root_sks: List[PrivateKey] = [ sk for sk, _ in await self.get_all_private_keys() ] self._private_keys = [ master_sk_to_farmer_sk(sk) for sk in self.all_root_sks ] + [master_sk_to_pool_sk(sk) for sk in self.all_root_sks] if len(self.get_public_keys()) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # This is the farmer configuration self.farmer_target_encoded = self.config["xch_target_address"] self.farmer_target = decode_puzzle_hash(self.farmer_target_encoded) self.pool_public_keys = [ G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"] ] # This is the self pooling configuration, which is only used for original self-pooled plots self.pool_target_encoded = self.pool_config["xch_target_address"] self.pool_target = decode_puzzle_hash(self.pool_target_encoded) self.pool_sks_map: Dict = {} for key in self.get_private_keys(): self.pool_sks_map[bytes(key.get_g1())] = key assert len(self.farmer_target) == 32 assert len(self.pool_target) == 32 if len(self.pool_sks_map) == 0: error_str = "No keys exist. Please run 'chia keys generate' or open the UI." raise RuntimeError(error_str) # The variables below are for use with an actual pool # From p2_singleton_puzzle_hash to pool state dict self.pool_state: Dict[bytes32, Dict] = {} # From public key bytes to PrivateKey self.authentication_keys: Dict[bytes, PrivateKey] = {} # Last time we updated pool_state based on the config file self.last_config_access_time: uint64 = uint64(0) self.harvester_cache: Dict[str, Dict[str, HarvesterCacheEntry]] = {}
async def did_create_attest(self, request): wallet_id = int(request["wallet_id"]) wallet: DIDWallet = self.service.wallet_state_manager.wallets[wallet_id] info = await wallet.get_info_for_recovery() coin = hexstr_to_bytes(request["coin_name"]) pubkey = G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])) spend_bundle = await wallet.create_attestment( coin, hexstr_to_bytes(request["puzhash"]), pubkey, request["filename"] ) if spend_bundle is not None: return { "success": True, "message_spend_bundle": bytes(spend_bundle).hex(), "info": [info[0].hex(), info[1].hex(), info[2]], } else: return {"success": False}
def batch_verification(): numIters = 100000 sig_bytes = [] pk_bytes = [] ms = [] for i in range(numIters): message = b"%d" % i sk: PrivateKey = AugSchemeMPL.key_gen(secrets.token_bytes(32)) pk: G1Element = sk.get_g1() sig: G2Element = AugSchemeMPL.sign(sk, message) sig_bytes.append(bytes(sig)) pk_bytes.append(bytes(pk)) ms.append(message) pks = [] start = startStopwatch(); for pk in pk_bytes: pks.append(G1Element.from_bytes(pk)) endStopwatch("Public key validation", start, numIters); sigs = [] start = startStopwatch() for sig in sig_bytes: sigs.append(G2Element.from_bytes(sig)) endStopwatch("Signature validation", start, numIters); start = startStopwatch() aggSig = AugSchemeMPL.aggregate(sigs) endStopwatch("Aggregation", start, numIters); start = startStopwatch() ok = AugSchemeMPL.aggregate_verify(pks, ms, aggSig); endStopwatch("Batch verification", start, numIters); if not ok: print("aggregate_verification failed!") sys.exit(1)
async def get_derivation_record_for_puzzle_hash(self, puzzle_hash: str) -> Optional[DerivationRecord]: """ Returns the derivation record by index and wallet id. """ cursor = await self.db_connection.execute( "SELECT * FROM derivation_paths WHERE puzzle_hash=?;", (puzzle_hash,), ) row = await cursor.fetchone() await cursor.close() if row is not None and row[0] is not None: return DerivationRecord( row[0], bytes.fromhex(row[2]), G1Element.from_bytes(bytes.fromhex(row[1])), row[3], row[4], ) return None