preliminary passing tests

This commit is contained in:
Kyle Altendorf 2022-06-06 21:47:50 -04:00
parent 4ad6ff8b55
commit 3eca9eb2f5
No known key found for this signature in database
GPG Key ID: 5715D880FF005192
9 changed files with 148 additions and 9 deletions

View File

@ -346,6 +346,9 @@ class DataLayer:
async with self.subscription_lock:
return await self.data_store.get_subscriptions()
async def get_owned_stores(self) -> List[SingletonRecord]:
return await self.wallet_rpc.dl_owned_singletons()
async def get_kv_diff(self, tree_id: bytes32, hash_1: bytes32, hash_2: bytes32) -> Set[DiffData]:
return await self.data_store.get_kv_diff(tree_id, hash_1, hash_2)

View File

@ -639,6 +639,26 @@ class DataLayerWallet:
return singleton_record, parent_lineage
async def get_owned_singletons(self) -> List[SingletonRecord]:
launcher_ids = await self.wallet_state_manager.dl_store.get_all_launchers()
collected = []
for launcher_id in launcher_ids:
# TODO: only confirmed?
singleton_record = await self.wallet_state_manager.dl_store.get_latest_singleton(launcher_id=launcher_id)
assert singleton_record is not None
inner_puzzle_derivation: Optional[
DerivationRecord
] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
singleton_record.inner_puzzle_hash
)
if inner_puzzle_derivation is not None:
collected.append(singleton_record)
return collected
###########
# SYNCING #
###########

View File

@ -263,22 +263,16 @@ class DataLayerStore:
return Coin(bytes32(row[1][0:32]), bytes32(row[1][32:64]), uint64(int.from_bytes(row[1][64:72], "big")))
return None
async def get_all_launchers(self) -> List[Coin]:
async def get_all_launchers(self) -> List[bytes32]:
"""
Checks DB for all launchers.
"""
cursor = await self.db_connection.execute("SELECT * from launchers")
cursor = await self.db_connection.execute("SELECT id from launchers")
rows = await cursor.fetchall()
await cursor.close()
coins: List[Coin] = []
for row in rows:
coins.append(
Coin(bytes32(row[1][0:32]), bytes32(row[1][32:64]), uint64(int.from_bytes(row[1][64:72], "big")))
)
return coins
return [bytes32(row[0]) for row in rows]
async def delete_launcher(self, launcher_id: bytes32) -> None:
c = await self.db_connection.execute("DELETE FROM launchers WHERE id=?", (launcher_id,))

View File

@ -53,6 +53,7 @@ class DataLayerRpcApi:
def get_routes(self) -> Dict[str, Callable[[Any], Any]]:
return {
"/create_data_store": self.create_data_store,
"/get_owned_stores": self.get_owned_stores,
"/batch_update": self.batch_update,
"/get_value": self.get_value,
"/get_keys_values": self.get_keys_values,
@ -75,6 +76,12 @@ class DataLayerRpcApi:
txs, value = await self.service.create_store(uint64(fee))
return {"txs": txs, "id": value.hex()}
async def get_owned_stores(self, request: Dict[str, Any]) -> Dict[str, Any]:
if self.service is None:
raise Exception("Data layer not created")
singleton_records = await self.service.get_owned_stores()
return {"launcher_ids": [singleton.launcher_id.hex() for singleton in singleton_records]}
async def get_value(self, request: Dict[str, Any]) -> Dict[str, Any]:
store_id = bytes32.from_hexstr(request["id"])
key = hexstr_to_bytes(request["key"])

View File

@ -137,6 +137,7 @@ class WalletRpcApi:
"/dl_update_root": self.dl_update_root,
"/dl_update_multiple": self.dl_update_multiple,
"/dl_history": self.dl_history,
"/dl_owned_singletons": self.dl_owned_singletons,
}
async def _state_changed(self, *args) -> List[WsRpcMessage]:
@ -1630,3 +1631,19 @@ class WalletRpcApi:
return {"history": history_json, "count": len(history_json)}
raise ValueError("No DataLayer wallet has been initialized")
async def dl_owned_singletons(self, request) -> Dict:
"""Get all owned singleton records"""
if self.service.wallet_state_manager is None:
raise ValueError("The wallet service is not currently initialized")
for _, wallet in self.service.wallet_state_manager.wallets.items():
if WalletType(wallet.type()) == WalletType.DATA_LAYER:
break
else:
raise ValueError("No DataLayer wallet has been initialized")
singletons = await wallet.get_owned_singletons()
singletons_json = [singleton.to_json_dict() for singleton in singletons]
return {"singletons": singletons_json, "count": len(singletons_json)}

View File

@ -561,3 +561,7 @@ class WalletRpcClient(RpcClient):
response = await self.fetch("dl_history", request)
return [SingletonRecord.from_json_dict(single) for single in response["history"]]
async def dl_owned_singletons(self) -> List[SingletonRecord]:
response = await self.fetch(path="dl_owned_singletons", request_json={})
return [SingletonRecord.from_json_dict(singleton) for singleton in response["singletons"]]

View File

@ -634,3 +634,40 @@ async def test_batch_update_matches_single_operations(one_wallet_node_and_rpc: n
root_3 = await data_rpc_api.get_roots({"ids": [store_id.hex()]})
batch_hash = root_3["root_hashes"][0]["hash"]
assert batch_hash == expected_res_hash
@pytest.mark.asyncio
async def test_get_owned_stores(one_wallet_node_and_rpc: nodes_with_port, bt: BlockTools) -> None:
wallet_node, full_node_api, wallet_rpc_port = one_wallet_node_and_rpc
num_blocks = 4
assert wallet_node.server is not None
await wallet_node.server.start_client(PeerInfo("localhost", uint16(full_node_api.server._port)), None)
assert wallet_node.wallet_state_manager is not None
ph = await wallet_node.wallet_state_manager.main_wallet.get_new_puzzlehash()
for i in range(0, num_blocks):
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
await asyncio.sleep(0.5)
funds = sum(
[calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, num_blocks)]
)
await time_out_assert(15, wallet_node.wallet_state_manager.main_wallet.get_confirmed_balance, funds)
async for data_layer in init_data_layer(wallet_rpc_port=wallet_rpc_port, bt=bt):
data_rpc_api = DataLayerRpcApi(data_layer)
expected_launcher_ids = []
for _ in range(3):
res = await data_rpc_api.create_data_store({})
assert res is not None
launcher_id = bytes32.from_hexstr(res["id"])
expected_launcher_ids.append(launcher_id)
for i in range(0, num_blocks):
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
await asyncio.sleep(0.5)
response = await data_rpc_api.get_owned_stores(request={})
launcher_ids = sorted(bytes32.from_hexstr(id) for id in response["launcher_ids"])
assert launcher_ids == sorted(expected_launcher_ids)

View File

@ -111,6 +111,59 @@ class TestDLWallet:
await time_out_assert(10, wallet_0.get_unconfirmed_balance, 0)
await time_out_assert(10, wallet_0.get_confirmed_balance, 0)
@pytest.mark.parametrize(
"trusted",
[True, False],
)
@pytest.mark.asyncio
async def test_get_owned_singletons(self, wallet_node: SimulatorsAndWallets, trusted: bool) -> None:
full_nodes, wallets = wallet_node
full_node_api = full_nodes[0]
full_node_server = full_node_api.server
wallet_node_0, server_0 = wallets[0]
assert wallet_node_0.wallet_state_manager is not None
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
if trusted:
wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
else:
wallet_node_0.config["trusted_peers"] = {}
await server_0.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
funds = await full_node_api.farm_blocks(count=2, wallet=wallet_0)
await time_out_assert(10, wallet_0.get_unconfirmed_balance, funds)
await time_out_assert(10, wallet_0.get_confirmed_balance, funds)
async with wallet_node_0.wallet_state_manager.lock:
dl_wallet = await DataLayerWallet.create_new_dl_wallet(wallet_node_0.wallet_state_manager, wallet_0)
nodes = [Program.to("thing").get_tree_hash(), Program.to([8]).get_tree_hash()]
current_tree = MerkleTree(nodes)
current_root = current_tree.calculate_root()
expected_launcher_ids = set()
for i in range(0, 2):
dl_record, std_record, launcher_id = await dl_wallet.generate_new_reporter(
current_root, fee=uint64(1999999999999)
)
expected_launcher_ids.add(launcher_id)
assert await dl_wallet.get_latest_singleton(launcher_id) is not None
await wallet_node_0.wallet_state_manager.add_pending_transaction(dl_record)
await wallet_node_0.wallet_state_manager.add_pending_transaction(std_record)
await full_node_api.process_transaction_records(records=[dl_record, std_record])
await time_out_assert(15, is_singleton_confirmed, True, dl_wallet, launcher_id)
await asyncio.sleep(0.5)
owned_singletons = await dl_wallet.get_owned_singletons()
owned_launcher_ids = sorted(singleton.launcher_id for singleton in owned_singletons)
assert owned_launcher_ids == sorted(expected_launcher_ids)
@pytest.mark.parametrize(
"trusted",
[True, False],

View File

@ -245,6 +245,10 @@ class TestWalletRpc:
await client_2.dl_stop_tracking(launcher_id)
assert await client_2.dl_latest_singleton(lid) is None
owned_singletons = await client.dl_owned_singletons()
owned_launcher_ids = sorted(singleton.launcher_id for singleton in owned_singletons)
assert owned_launcher_ids == sorted([launcher_id, launcher_id_2, launcher_id_3])
finally:
# Checks that the RPC manages to stop the node
client.close()