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_traits::clvm_tuple;
6use clvm_utils::{ToTreeHash, TreeHash};
7use clvmr::NodePtr;
8
9use crate::{
10    DriverError, RewardDistributor, RewardDistributorConstants, SingletonAction, Spend,
11    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 spend(
35        self,
36        ctx: &mut SpendContext,
37        distributor: &mut RewardDistributor,
38        update_time: u64,
39    ) -> Result<Conditions, DriverError> {
40        // calculate announcement needed to ensure everything's happening as expected
41        let my_state = distributor.pending_spend.latest_state.1;
42        let mut new_epoch_announcement =
43            clvm_tuple!(update_time, my_state.round_time_info.epoch_end)
44                .tree_hash()
45                .to_vec();
46        new_epoch_announcement.insert(0, b's');
47        let new_epoch_conditions = Conditions::new().assert_puzzle_announcement(announcement_id(
48            distributor.coin.puzzle_hash,
49            new_epoch_announcement,
50        ));
51
52        // spend self
53        let action_solution = ctx.alloc(&RewardDistributorSyncActionSolution { update_time })?;
54        let action_puzzle = Self::construct_puzzle(ctx)?;
55
56        distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?;
57        Ok(new_epoch_conditions)
58    }
59}