mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-24 10:05:29 -05:00
Added get_coin_records_by_parent_id(s) (#7310)
* Added new RPCs to get coins by their parent * Got rid of the individual request in favor of requiring a list of puzzle hashes
This commit is contained in:
@@ -192,6 +192,33 @@ class CoinStore:
|
||||
coins.add(CoinRecord(coin, row[1], row[2], row[3], row[4], row[8]))
|
||||
return list(coins)
|
||||
|
||||
async def get_coin_records_by_parent_ids(
|
||||
self,
|
||||
include_spent_coins: bool,
|
||||
parent_ids: List[bytes32],
|
||||
start_height: uint32 = uint32(0),
|
||||
end_height: uint32 = uint32((2 ** 32) - 1),
|
||||
) -> List[CoinRecord]:
|
||||
if len(parent_ids) == 0:
|
||||
return []
|
||||
|
||||
coins = set()
|
||||
parent_ids_db = tuple([pid.hex() for pid in parent_ids])
|
||||
cursor = await self.coin_record_db.execute(
|
||||
f'SELECT * from coin_record WHERE coin_parent in ({"?," * (len(parent_ids_db) - 1)}?) '
|
||||
f"AND confirmed_index>=? AND confirmed_index<? "
|
||||
f"{'' if include_spent_coins else 'AND spent=0'}",
|
||||
parent_ids_db + (start_height, end_height),
|
||||
)
|
||||
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
await cursor.close()
|
||||
for row in rows:
|
||||
coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
|
||||
coins.add(CoinRecord(coin, row[1], row[2], row[3], row[4], row[8]))
|
||||
return list(coins)
|
||||
|
||||
async def rollback_to_block(self, block_index: int):
|
||||
"""
|
||||
Note that block_index can be negative, in which case everything is rolled back
|
||||
|
||||
@@ -43,6 +43,7 @@ class FullNodeRpcApi:
|
||||
"/get_coin_records_by_puzzle_hash": self.get_coin_records_by_puzzle_hash,
|
||||
"/get_coin_records_by_puzzle_hashes": self.get_coin_records_by_puzzle_hashes,
|
||||
"/get_coin_record_by_name": self.get_coin_record_by_name,
|
||||
"/get_coin_records_by_parent_ids": self.get_coin_records_by_parent_ids,
|
||||
"/push_tx": self.push_tx,
|
||||
"/get_puzzle_and_solution": self.get_puzzle_and_solution,
|
||||
# Mempool
|
||||
@@ -463,6 +464,28 @@ class FullNodeRpcApi:
|
||||
|
||||
return {"coin_record": coin_record}
|
||||
|
||||
async def get_coin_records_by_parent_ids(self, request: Dict) -> Optional[Dict]:
|
||||
"""
|
||||
Retrieves the coins for given parent coin IDs, by default returns unspent coins.
|
||||
"""
|
||||
if "parent_ids" not in request:
|
||||
raise ValueError("Parent IDs not in request")
|
||||
kwargs: Dict[str, Any] = {
|
||||
"include_spent_coins": False,
|
||||
"parent_ids": [hexstr_to_bytes(ph) for ph in request["parent_ids"]],
|
||||
}
|
||||
if "start_height" in request:
|
||||
kwargs["start_height"] = uint32(request["start_height"])
|
||||
if "end_height" in request:
|
||||
kwargs["end_height"] = uint32(request["end_height"])
|
||||
|
||||
if "include_spent_coins" in request:
|
||||
kwargs["include_spent_coins"] = request["include_spent_coins"]
|
||||
|
||||
coin_records = await self.service.blockchain.coin_store.get_coin_records_by_parent_ids(**kwargs)
|
||||
|
||||
return {"coin_records": coin_records}
|
||||
|
||||
async def push_tx(self, request: Dict) -> Optional[Dict]:
|
||||
if "spend_bundle" not in request:
|
||||
raise ValueError("Spend bundle not in request")
|
||||
|
||||
@@ -117,6 +117,24 @@ class FullNodeRpcClient(RpcClient):
|
||||
for coin in (await self.fetch("get_coin_records_by_puzzle_hashes", d))["coin_records"]
|
||||
]
|
||||
|
||||
async def get_coin_records_by_parent_ids(
|
||||
self,
|
||||
parent_ids: List[bytes32],
|
||||
include_spent_coins: bool = True,
|
||||
start_height: Optional[int] = None,
|
||||
end_height: Optional[int] = None,
|
||||
) -> List:
|
||||
parent_ids_hex = [pid.hex() for pid in parent_ids]
|
||||
d = {"parent_ids": parent_ids_hex, "include_spent_coins": include_spent_coins}
|
||||
if start_height is not None:
|
||||
d["start_height"] = start_height
|
||||
if end_height is not None:
|
||||
d["end_height"] = end_height
|
||||
return [
|
||||
CoinRecord.from_json_dict(coin)
|
||||
for coin in (await self.fetch("get_coin_records_by_parent_ids", d))["coin_records"]
|
||||
]
|
||||
|
||||
async def get_additions_and_removals(self, header_hash: bytes32) -> Tuple[List[CoinRecord], List[CoinRecord]]:
|
||||
try:
|
||||
response = await self.fetch("get_additions_and_removals", {"header_hash": header_hash.hex()})
|
||||
|
||||
@@ -113,6 +113,12 @@ class TestRpc:
|
||||
print(coins)
|
||||
assert len(coins) >= 1
|
||||
|
||||
pid = list(blocks[-1].get_included_reward_coins())[0].parent_coin_info
|
||||
pid_2 = list(blocks[-1].get_included_reward_coins())[1].parent_coin_info
|
||||
coins = await client.get_coin_records_by_parent_ids([pid, pid_2])
|
||||
print(coins)
|
||||
assert len(coins) == 2
|
||||
|
||||
additions, removals = await client.get_additions_and_removals(blocks[-1].header_hash)
|
||||
assert len(additions) >= 2 and len(removals) == 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user