Skip to main content

chia_sdk_driver/layers/action_layer/actions/reward_distributor/
sync.rs

1use chia_sdk_types::{
2    Conditions, announcement_id,
3    puzzles::{RewardDistributorSyncActionArgs, RewardDistributorSyncActionSolution},
4};
5use clvm_utils::{ToTreeHash, TreeHash};
6use clvmr::NodePtr;
7
8use crate::{
9    DriverError, RewardDistributor, RewardDistributorConstants,
10    RewardDistributorCreatedAnnouncementPrefix, RewardDistributorStateTransition,
11    RewardDistributorSyncActionLog, SingletonAction, Spend, SpendContext,
12};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct RewardDistributorSyncAction {}
16
17impl ToTreeHash for RewardDistributorSyncAction {
18    fn tree_hash(&self) -> TreeHash {
19        RewardDistributorSyncActionArgs::curry_tree_hash()
20    }
21}
22
23impl SingletonAction<RewardDistributor> for RewardDistributorSyncAction {
24    fn from_constants(_constants: &RewardDistributorConstants) -> Self {
25        Self {}
26    }
27}
28
29impl RewardDistributorSyncAction {
30    fn construct_puzzle(ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
31        ctx.alloc_mod::<RewardDistributorSyncActionArgs>()
32    }
33
34    pub fn get_log(
35        ctx: &SpendContext,
36        solution: NodePtr,
37        changes: RewardDistributorStateTransition,
38    ) -> Result<RewardDistributorSyncActionLog, DriverError> {
39        let solution = ctx.extract::<RewardDistributorSyncActionSolution>(solution)?;
40
41        Ok(RewardDistributorSyncActionLog {
42            update_time: solution.update_time,
43            changes,
44        })
45    }
46
47    pub fn spend(
48        self,
49        ctx: &mut SpendContext,
50        distributor: &mut RewardDistributor,
51        update_time: u64,
52    ) -> Result<Conditions, DriverError> {
53        // calculate announcement needed to ensure everything's happening as expected
54        let my_state = distributor.pending_spend.latest_state.1;
55        let new_epoch_announcement = RewardDistributorCreatedAnnouncementPrefix::sync(
56            update_time,
57            my_state.round_time_info.epoch_end,
58        );
59        let new_epoch_conditions = Conditions::new().assert_puzzle_announcement(announcement_id(
60            distributor.coin.puzzle_hash,
61            new_epoch_announcement,
62        ));
63
64        // spend self
65        let action_solution = ctx.alloc(&RewardDistributorSyncActionSolution { update_time })?;
66        let action_puzzle = Self::construct_puzzle(ctx)?;
67
68        distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?;
69        Ok(new_epoch_conditions)
70    }
71}