chia_sdk_driver/actions/
update_did.rs1use chia_protocol::Bytes32;
2
3use crate::{Deltas, DriverError, HashedPtr, Id, SpendAction, SpendContext, Spends};
4
5#[derive(Debug, Clone, Copy)]
6pub struct UpdateDidAction {
7 pub id: Id,
8 pub new_recovery_list_hash: Option<Option<Bytes32>>,
9 pub new_num_verifications_required: Option<u64>,
10 pub new_metadata: Option<HashedPtr>,
11}
12
13impl UpdateDidAction {
14 pub fn new(
15 id: Id,
16 new_recovery_list_hash: Option<Option<Bytes32>>,
17 new_num_verifications_required: Option<u64>,
18 new_metadata: Option<HashedPtr>,
19 ) -> Self {
20 Self {
21 id,
22 new_recovery_list_hash,
23 new_num_verifications_required,
24 new_metadata,
25 }
26 }
27}
28
29impl SpendAction for UpdateDidAction {
30 fn calculate_delta(&self, deltas: &mut Deltas, _index: usize) {
31 let did = deltas.update(self.id);
32 did.input += 1;
33 did.output += 1;
34 }
35
36 fn spend(
37 &self,
38 _ctx: &mut SpendContext,
39 spends: &mut Spends,
40 _index: usize,
41 ) -> Result<(), DriverError> {
42 let did = spends
43 .dids
44 .get_mut(&self.id)
45 .ok_or(DriverError::InvalidAssetId)?
46 .last_mut()?;
47
48 if let Some(new_recovery_list_hash) = self.new_recovery_list_hash {
49 did.child_info.recovery_list_hash = new_recovery_list_hash;
50 }
51
52 if let Some(new_num_verifications_required) = self.new_num_verifications_required {
53 did.child_info.num_verifications_required = new_num_verifications_required;
54 }
55
56 if let Some(new_metadata) = self.new_metadata {
57 did.child_info.metadata = new_metadata;
58 }
59
60 Ok(())
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use anyhow::Result;
67 use chia_sdk_test::Simulator;
68 use indexmap::indexmap;
69
70 use crate::{Action, Relation, BURN_PUZZLE_HASH};
71
72 use super::*;
73
74 #[test]
75 fn test_action_update_did() -> Result<()> {
76 let mut sim = Simulator::new();
77 let mut ctx = SpendContext::new();
78
79 let alice = sim.bls(1);
80
81 let metadata = ctx.alloc_hashed(&"Hello, world!")?;
82 let hint = ctx.hint(BURN_PUZZLE_HASH)?;
83
84 let mut spends = Spends::new(alice.puzzle_hash);
85 spends.add(alice.coin);
86
87 let deltas = spends.apply(
88 &mut ctx,
89 &[
90 Action::create_empty_did(),
91 Action::update_did(
92 Id::New(0),
93 Some(Some(Bytes32::default())),
94 Some(2),
95 Some(metadata),
96 ),
97 Action::burn(Id::New(0), 1, hint),
98 ],
99 )?;
100
101 let outputs = spends.finish_with_keys(
102 &mut ctx,
103 &deltas,
104 Relation::None,
105 &indexmap! { alice.puzzle_hash => alice.pk },
106 )?;
107
108 sim.spend_coins(ctx.take(), &[alice.sk])?;
109
110 let did = outputs.dids[&Id::New(0)];
111 assert_ne!(sim.coin_state(did.coin.coin_id()), None);
112 assert_eq!(did.info.recovery_list_hash, Some(Bytes32::default()));
113 assert_eq!(did.info.num_verifications_required, 2);
114 assert_eq!(did.info.metadata, metadata);
115 assert_eq!(did.info.p2_puzzle_hash, BURN_PUZZLE_HASH);
116 assert_eq!(did.coin.amount, 1);
117
118 Ok(())
119 }
120}