[LABS-311] Extract track_new_launcher_id from dl_track_new (#20320)

* Add optional creation to `get_dl_wallet`

* Extract `track_new_launcher_id` from `dl_track_new`
This commit is contained in:
Matt Hauff
2026-01-09 12:04:29 -08:00
committed by GitHub
parent 428e26cf5b
commit baf8bd05c0
3 changed files with 51 additions and 46 deletions
+26 -1
View File
@@ -210,7 +210,7 @@ class DataLayerWallet:
return coin_states[0]
# This is the entry point for non-owned singletons
async def track_new_launcher_id(
async def _track_new_launcher_id(
self,
launcher_id: bytes32,
peer: WSChiaConnection,
@@ -863,6 +863,31 @@ class DataLayerWallet:
await self.wallet_state_manager.dl_store.delete_singleton_records_by_launcher_id(launcher_id)
await self.wallet_state_manager.dl_store.delete_launcher(launcher_id)
async def track_new_launcher_id(
self,
launcher_id: bytes32,
peer: WSChiaConnection | None = None,
spend: CoinSpend | None = None,
height: uint32 | None = None,
) -> None:
if peer is None:
peer_list = self.wallet_state_manager.wallet_node.get_full_node_peers_in_order()
else:
peer_list = [peer]
peer_length = len(peer_list)
for i, peer_to_try in enumerate(peer_list):
try:
await self._track_new_launcher_id(
launcher_id,
peer_to_try,
spend,
height,
)
except LauncherCoinNotFoundError as e:
if i == peer_length - 1:
raise e # raise the error if we've tried all peers
continue # try some other peers, maybe someone has it
###########
# UTILITY #
###########
+17 -36
View File
@@ -14,9 +14,8 @@ from chia_rs.sized_ints import uint16, uint32, uint64
from clvm_tools.binutils import assemble
from chia.consensus.block_rewards import calculate_base_farmer_reward
from chia.data_layer.data_layer_errors import LauncherCoinNotFoundError
from chia.data_layer.data_layer_util import DLProof, VerifyProofResponse, dl_verify_proof
from chia.data_layer.data_layer_wallet import DataLayerWallet, Mirror
from chia.data_layer.data_layer_wallet import Mirror
from chia.pools.pool_wallet import PoolWallet
from chia.pools.pool_wallet_info import (
FARMING_TO_POOL,
@@ -3410,11 +3409,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
try:
dl_wallet = self.service.wallet_state_manager.get_dl_wallet()
except ValueError:
async with self.service.wallet_state_manager.lock:
dl_wallet = await DataLayerWallet.create_new_dl_wallet(self.service.wallet_state_manager)
dl_wallet = await self.service.wallet_state_manager.get_dl_wallet(create_if_not_found=True)
async with self.service.wallet_state_manager.lock:
launcher_id = await dl_wallet.generate_new_reporter(
@@ -3432,25 +3427,11 @@ class WalletRpcApi:
"""Initialize the DataLayer Wallet (only one can exist)"""
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
try:
dl_wallet = self.service.wallet_state_manager.get_dl_wallet()
except ValueError:
async with self.service.wallet_state_manager.lock:
dl_wallet = await DataLayerWallet.create_new_dl_wallet(
self.service.wallet_state_manager,
)
peer_list = self.service.get_full_node_peers_in_order()
peer_length = len(peer_list)
for i, peer in enumerate(peer_list):
try:
await dl_wallet.track_new_launcher_id(
request.launcher_id,
peer,
)
except LauncherCoinNotFoundError as e:
if i == peer_length - 1:
raise e # raise the error if we've tried all peers
continue # try some other peers, maybe someone has it
await (await self.service.wallet_state_manager.get_dl_wallet(create_if_not_found=True)).track_new_launcher_id(
request.launcher_id
)
return Empty()
@marshal
@@ -3459,7 +3440,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
dl_wallet = self.service.wallet_state_manager.get_dl_wallet()
dl_wallet = await self.service.wallet_state_manager.get_dl_wallet()
await dl_wallet.stop_tracking_singleton(request.launcher_id)
return Empty()
@@ -3469,7 +3450,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
record = await wallet.get_latest_singleton(request.launcher_id, request.only_confirmed)
return DLLatestSingletonResponse(record)
@@ -3479,7 +3460,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
records = await wallet.get_singletons_by_root(request.launcher_id, request.root)
return DLSingletonsByRootResponse(records)
@@ -3495,7 +3476,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
async with self.service.wallet_state_manager.lock:
await wallet.create_update_state_spend(
request.launcher_id,
@@ -3524,7 +3505,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise RuntimeError("not initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
async with self.service.wallet_state_manager.lock:
# TODO: This method should optionally link the singletons with announcements.
# Otherwise spends are vulnerable to signature subtraction.
@@ -3551,7 +3532,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
additional_kwargs = {}
if request.min_generation is not None:
@@ -3570,7 +3551,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
singletons = await wallet.get_owned_singletons()
return DLOwnedSingletonsResponse(singletons, uint32(len(singletons)))
@@ -3581,7 +3562,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
wallet = self.service.wallet_state_manager.get_dl_wallet()
wallet = await self.service.wallet_state_manager.get_dl_wallet()
return DLGetMirrorsResponse(await wallet.get_mirrors_for_launcher(request.launcher_id))
@tx_endpoint(push=True)
@@ -3596,7 +3577,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
dl_wallet = self.service.wallet_state_manager.get_dl_wallet()
dl_wallet = await self.service.wallet_state_manager.get_dl_wallet()
async with self.service.wallet_state_manager.lock:
await dl_wallet.create_new_mirror(
request.launcher_id,
@@ -3625,7 +3606,7 @@ class WalletRpcApi:
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
dl_wallet = self.service.wallet_state_manager.get_dl_wallet()
dl_wallet = await self.service.wallet_state_manager.get_dl_wallet()
async with self.service.wallet_state_manager.lock:
await dl_wallet.delete_mirror(
request.coin_id,
+8 -9
View File
@@ -1702,7 +1702,7 @@ class WalletStateManager:
elif coin_state.created_height is not None:
wallet_identifier, coin_data = await self.determine_coin_type(peer, coin_state, fork_height)
try:
dl_wallet = self.get_dl_wallet()
dl_wallet = await self.get_dl_wallet()
except ValueError:
pass
else:
@@ -2014,12 +2014,7 @@ class WalletStateManager:
and inner_puzhash is not None
and (await self.puzzle_store.puzzle_hash_exists(inner_puzhash))
):
try:
dl_wallet = self.get_dl_wallet()
except ValueError:
dl_wallet = await DataLayerWallet.create_new_dl_wallet(
self,
)
dl_wallet = await self.get_dl_wallet(create_if_not_found=True)
await dl_wallet.track_new_launcher_id(
child.coin.name(),
peer,
@@ -2609,14 +2604,18 @@ class WalletStateManager:
return puzzle_hash
def get_dl_wallet(self) -> DataLayerWallet:
async def get_dl_wallet(self, *, create_if_not_found: bool = False) -> DataLayerWallet:
for wallet in self.wallets.values():
if wallet.type() == WalletType.DATA_LAYER.value:
assert isinstance(wallet, DataLayerWallet), (
f"WalletType.DATA_LAYER should be a DataLayerWallet instance got: {type(wallet).__name__}"
)
return wallet
raise ValueError("DataLayerWallet not available")
if create_if_not_found:
async with self.lock:
return await DataLayerWallet.create_new_dl_wallet(self)
else:
raise ValueError("DataLayerWallet not available")
async def get_or_create_vc_wallet(self) -> VCWallet:
for _, wallet in self.wallets.items():