Skip to content

Commit

Permalink
[CHIA-1316] Port VC Endpoints to @marshal decorator (#18970)
Browse files Browse the repository at this point in the history
* Port `vc_mint`

* Port `vc_spend`

* Port `vc_revoke`

* Port `vc_get`

* Port `vc_get_list`

* Port `vc_add_proofs`

* Port `vc_get_proofs_for_root`

* address comments by @altendky
  • Loading branch information
Quexington authored Dec 12, 2024
1 parent 3ab83f0 commit be0a77d
Show file tree
Hide file tree
Showing 7 changed files with 455 additions and 292 deletions.
129 changes: 77 additions & 52 deletions chia/_tests/cmds/wallet/test_vcs.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
from __future__ import annotations

from pathlib import Path
from typing import Any, Optional, cast

from chia_rs import Coin

from chia._tests.cmds.cmd_test_utils import TestRpcClients, TestWalletRpcClient, logType, run_cli_command_and_assert
from chia._tests.cmds.wallet.test_consts import FINGERPRINT_ARG, STD_TX, STD_UTX, get_bytes32
from chia.rpc.wallet_request_types import VCMintResponse, VCRevokeResponse, VCSpendResponse
from chia.rpc.wallet_request_types import (
VCAddProofs,
VCGet,
VCGetList,
VCGetListResponse,
VCGetProofsForRoot,
VCGetProofsForRootResponse,
VCGetResponse,
VCMint,
VCMintResponse,
VCProofsRPC,
VCProofWithHash,
VCRecordWithCoinID,
VCRevoke,
VCRevokeResponse,
VCSpend,
VCSpendResponse,
)
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.bech32m import encode_puzzle_hash
from chia.util.ints import uint32, uint64
Expand All @@ -29,14 +45,13 @@ def test_vcs_mint(capsys: object, get_test_cli_clients: tuple[TestRpcClients, Pa
class VcsMintRpcClient(TestWalletRpcClient):
async def vc_mint(
self,
did_id: bytes32,
request: VCMint,
tx_config: TXConfig,
target_address: Optional[bytes32] = None,
fee: uint64 = uint64(0),
push: bool = True,
timelock_info: ConditionValidTimes = ConditionValidTimes(),
) -> VCMintResponse:
self.add_to_log("vc_mint", (did_id, tx_config, target_address, fee, push, timelock_info))
self.add_to_log(
"vc_mint", (request.did_id, tx_config, request.target_address, request.fee, request.push, timelock_info)
)

return VCMintResponse(
[STD_UTX],
Expand Down Expand Up @@ -81,7 +96,7 @@ async def vc_mint(
]
run_cli_command_and_assert(capsys, root_dir, command_args, assert_list)
expected_calls: logType = {
"vc_mint": [(did_bytes, DEFAULT_TX_CONFIG, target_bytes, 500000000000, True, test_condition_valid_times)]
"vc_mint": [(did_id, DEFAULT_TX_CONFIG, target_addr, 500000000000, True, test_condition_valid_times)]
}
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)

Expand All @@ -91,22 +106,25 @@ def test_vcs_get(capsys: object, get_test_cli_clients: tuple[TestRpcClients, Pat

# set RPC Client
class VcsGetRpcClient(TestWalletRpcClient):
async def vc_get_list(self, start: int = 0, count: int = 50) -> tuple[list[VCRecord], dict[str, Any]]:
class FakeVC:
def __init__(self) -> None:
self.launcher_id = get_bytes32(3)
self.coin = Coin(get_bytes32(1), get_bytes32(2), uint64(12345678))
self.inner_puzzle_hash = get_bytes32(3)
self.proof_hash = get_bytes32(4)

def __getattr__(self, item: str) -> Any:
if item == "vc":
return self

self.add_to_log("vc_get_list", (start, count))
proofs = {get_bytes32(1).hex(): ["proof here"]}
records = [cast(VCRecord, FakeVC())]
return records, proofs
async def vc_get_list(self, request: VCGetList) -> VCGetListResponse:
self.add_to_log("vc_get_list", (request.start, request.end))
proofs = [VCProofWithHash(get_bytes32(1), VCProofsRPC([("proof here", "")]))]
records = [
VCRecordWithCoinID(
VerifiedCredential(
STD_TX.removals[0],
LineageProof(None, None, None),
VCLineageProof(None, None, None, None),
bytes32([3] * 32),
bytes32.zeros,
bytes32([1] * 32),
None,
),
uint32(0),
bytes32.zeros,
)
]
return VCGetListResponse(records, proofs)

inst_rpc_client = VcsGetRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand All @@ -115,7 +133,7 @@ def __getattr__(self, item: str) -> Any:
assert_list = [
f"Proofs:\n- {get_bytes32(1).hex()}\n - proof here",
f"Launcher ID: {get_bytes32(3).hex()}",
f"Inner Address: {encode_puzzle_hash(get_bytes32(3), 'xch')}",
f"Inner Address: {encode_puzzle_hash(bytes32.zeros, 'xch')}",
]
run_cli_command_and_assert(capsys, root_dir, command_args, assert_list)
expected_calls: logType = {"vc_get_list": [(10, 10)]}
Expand All @@ -129,18 +147,22 @@ def test_vcs_update_proofs(capsys: object, get_test_cli_clients: tuple[TestRpcCl
class VcsUpdateProofsRpcClient(TestWalletRpcClient):
async def vc_spend(
self,
vc_id: bytes32,
request: VCSpend,
tx_config: TXConfig,
new_puzhash: Optional[bytes32] = None,
new_proof_hash: Optional[bytes32] = None,
provider_inner_puzhash: Optional[bytes32] = None,
fee: uint64 = uint64(0),
push: bool = True,
timelock_info: ConditionValidTimes = ConditionValidTimes(),
) -> VCSpendResponse:
self.add_to_log(
"vc_spend",
(vc_id, tx_config, new_puzhash, new_proof_hash, provider_inner_puzhash, fee, push, timelock_info),
(
request.vc_id,
tx_config,
request.new_puzhash,
request.new_proof_hash,
request.provider_inner_puzhash,
request.fee,
request.push,
timelock_info,
),
)
return VCSpendResponse([STD_UTX], [STD_TX])

Expand Down Expand Up @@ -192,8 +214,8 @@ def test_vcs_add_proof_reveal(capsys: object, get_test_cli_clients: tuple[TestRp

# set RPC Client
class VcsAddProofRevealRpcClient(TestWalletRpcClient):
async def vc_add_proofs(self, proofs: dict[str, Any]) -> None:
self.add_to_log("vc_add_proofs", (proofs,))
async def vc_add_proofs(self, request: VCAddProofs) -> None:
self.add_to_log("vc_add_proofs", (request.to_json_dict()["proofs"],))

inst_rpc_client = VcsAddProofRevealRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand All @@ -215,9 +237,9 @@ def test_vcs_get_proofs_for_root(capsys: object, get_test_cli_clients: tuple[Tes

# set RPC Client
class VcsGetProofsForRootRpcClient(TestWalletRpcClient):
async def vc_get_proofs_for_root(self, root: bytes32) -> dict[str, Any]:
self.add_to_log("vc_get_proofs_for_root", (root,))
return {"test_proof": "1", "test_proof2": "1"}
async def vc_get_proofs_for_root(self, request: VCGetProofsForRoot) -> VCGetProofsForRootResponse:
self.add_to_log("vc_get_proofs_for_root", (request.root,))
return VCGetProofsForRootResponse([("test_proof", "1"), ("test_proof2", "1")])

inst_rpc_client = VcsGetProofsForRootRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand All @@ -236,28 +258,31 @@ def test_vcs_revoke(capsys: object, get_test_cli_clients: tuple[TestRpcClients,

# set RPC Client
class VcsRevokeRpcClient(TestWalletRpcClient):
async def vc_get(self, vc_id: bytes32) -> Optional[VCRecord]:
self.add_to_log("vc_get", (vc_id,))

class FakeVC:
def __init__(self) -> None:
self.coin = Coin(get_bytes32(1), get_bytes32(2), uint64(12345678))
async def vc_get(self, request: VCGet) -> VCGetResponse:
self.add_to_log("vc_get", (request.vc_id,))

def __getattr__(self, item: str) -> Any:
if item == "vc":
return self

return cast(VCRecord, FakeVC())
return VCGetResponse(
VCRecord(
VerifiedCredential(
Coin(get_bytes32(1), get_bytes32(2), uint64(12345678)),
LineageProof(),
VCLineageProof(),
bytes32.zeros,
bytes32.zeros,
bytes32.zeros,
None,
),
uint32(0),
)
)

async def vc_revoke(
self,
vc_parent_id: bytes32,
request: VCRevoke,
tx_config: TXConfig,
fee: uint64 = uint64(0),
push: bool = True,
timelock_info: ConditionValidTimes = ConditionValidTimes(),
) -> VCRevokeResponse:
self.add_to_log("vc_revoke", (vc_parent_id, tx_config, fee, push, timelock_info))
self.add_to_log("vc_revoke", (request.vc_parent_id, tx_config, request.fee, request.push, timelock_info))
return VCRevokeResponse([STD_UTX], [STD_TX])

inst_rpc_client = VcsRevokeRpcClient()
Expand Down
56 changes: 39 additions & 17 deletions chia/_tests/wallet/cat_wallet/test_trades.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
from chia.consensus.cost_calculator import NPCResult
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.full_node.bundle_tools import simple_solution_generator
from chia.rpc.wallet_request_types import VCAddProofs, VCGetList, VCGetProofsForRoot, VCMint, VCSpend
from chia.types.blockchain_format.program import INFINITE_COST, Program
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.spend_bundle import SpendBundle
from chia.util.bech32m import encode_puzzle_hash
from chia.util.hash import std_hash
from chia.util.ints import uint32, uint64
from chia.wallet.cat_wallet.cat_wallet import CATWallet
Expand Down Expand Up @@ -237,12 +239,22 @@ async def test_cat_trades(
# Mint some VCs that can spend the CR-CATs
vc_record_maker = (
await client_maker.vc_mint(
did_id_maker, wallet_environments.tx_config, target_address=await wallet_maker.get_new_puzzlehash()
VCMint(
did_id=encode_puzzle_hash(did_id_maker, "did"),
target_address=encode_puzzle_hash(await wallet_maker.get_new_puzzlehash(), "txch"),
push=True,
),
wallet_environments.tx_config,
)
).vc_record
vc_record_taker = (
await client_taker.vc_mint(
did_id_taker, wallet_environments.tx_config, target_address=await wallet_taker.get_new_puzzlehash()
VCMint(
did_id=encode_puzzle_hash(did_id_taker, "did"),
target_address=encode_puzzle_hash(await wallet_taker.get_new_puzzlehash(), "txch"),
push=True,
),
wallet_environments.tx_config,
)
).vc_record
await wallet_environments.process_pending_states(
Expand Down Expand Up @@ -274,17 +286,23 @@ async def test_cat_trades(
proofs_maker = VCProofs({"foo": "1", "bar": "1", "zap": "1"})
proof_root_maker: bytes32 = proofs_maker.root()
await client_maker.vc_spend(
vc_record_maker.vc.launcher_id,
VCSpend(
vc_id=vc_record_maker.vc.launcher_id,
new_proof_hash=proof_root_maker,
push=True,
),
wallet_environments.tx_config,
new_proof_hash=proof_root_maker,
)

proofs_taker = VCProofs({"foo": "1", "bar": "1", "zap": "1"})
proof_root_taker: bytes32 = proofs_taker.root()
await client_taker.vc_spend(
vc_record_taker.vc.launcher_id,
VCSpend(
vc_id=vc_record_taker.vc.launcher_id,
new_proof_hash=proof_root_taker,
push=True,
),
wallet_environments.tx_config,
new_proof_hash=proof_root_taker,
)
await wallet_environments.process_pending_states(
[
Expand Down Expand Up @@ -374,17 +392,21 @@ async def test_cat_trades(
)

if credential_restricted:
await client_maker.vc_add_proofs(proofs_maker.key_value_pairs)
assert await client_maker.vc_get_proofs_for_root(proof_root_maker) == proofs_maker.key_value_pairs
vc_records, fetched_proofs = await client_maker.vc_get_list()
assert len(vc_records) == 1
assert fetched_proofs[proof_root_maker.hex()] == proofs_maker.key_value_pairs

await client_taker.vc_add_proofs(proofs_taker.key_value_pairs)
assert await client_taker.vc_get_proofs_for_root(proof_root_taker) == proofs_taker.key_value_pairs
vc_records, fetched_proofs = await client_taker.vc_get_list()
assert len(vc_records) == 1
assert fetched_proofs[proof_root_taker.hex()] == proofs_taker.key_value_pairs
await client_maker.vc_add_proofs(VCAddProofs.from_vc_proofs(proofs_maker))
assert (
await client_maker.vc_get_proofs_for_root(VCGetProofsForRoot(proof_root_maker))
).to_vc_proofs().key_value_pairs == proofs_maker.key_value_pairs
get_list_reponse = await client_maker.vc_get_list(VCGetList())
assert len(get_list_reponse.vc_records) == 1
assert get_list_reponse.proof_dict[proof_root_maker] == proofs_maker.key_value_pairs

await client_taker.vc_add_proofs(VCAddProofs.from_vc_proofs(proofs_taker))
assert (
await client_taker.vc_get_proofs_for_root(VCGetProofsForRoot(proof_root_taker))
).to_vc_proofs().key_value_pairs == proofs_taker.key_value_pairs
get_list_reponse = await client_taker.vc_get_list(VCGetList())
assert len(get_list_reponse.vc_records) == 1
assert get_list_reponse.proof_dict[proof_root_taker] == proofs_taker.key_value_pairs

# Add the taker's CAT to the maker's wallet
if credential_restricted:
Expand Down
Loading

0 comments on commit be0a77d

Please sign in to comment.