chia_sdk_driver/layers/mips/
delegated_puzzle_feeder_layer.rs1use chia_puzzles::DELEGATED_PUZZLE_FEEDER_HASH;
2use chia_sdk_types::puzzles::{DelegatedPuzzleFeederArgs, DelegatedPuzzleFeederSolution};
3use clvm_traits::FromClvm;
4use clvmr::{Allocator, NodePtr};
5
6use crate::{DriverError, Layer, Puzzle, SpendContext};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct DelegatedPuzzleFeederLayer<I> {
10 pub inner_puzzle: I,
11}
12
13impl<I> DelegatedPuzzleFeederLayer<I> {
14 pub fn new(inner_puzzle: I) -> Self {
15 Self { inner_puzzle }
16 }
17}
18
19impl<I> Layer for DelegatedPuzzleFeederLayer<I>
20where
21 I: Layer,
22{
23 type Solution = DelegatedPuzzleFeederSolution<NodePtr, NodePtr, I::Solution>;
24
25 fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
26 let inner_puzzle = self.inner_puzzle.construct_puzzle(ctx)?;
27 ctx.curry(DelegatedPuzzleFeederArgs::new(inner_puzzle))
28 }
29
30 fn construct_solution(
31 &self,
32 ctx: &mut SpendContext,
33 solution: Self::Solution,
34 ) -> Result<NodePtr, DriverError> {
35 let inner_solution = self
36 .inner_puzzle
37 .construct_solution(ctx, solution.inner_solution)?;
38 ctx.alloc(&DelegatedPuzzleFeederSolution::new(
39 solution.delegated_puzzle,
40 solution.delegated_solution,
41 inner_solution,
42 ))
43 }
44
45 fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError>
46 where
47 Self: Sized,
48 {
49 let Some(curried) = puzzle.as_curried() else {
50 return Ok(None);
51 };
52
53 if curried.mod_hash != DELEGATED_PUZZLE_FEEDER_HASH.into() {
54 return Ok(None);
55 }
56
57 let args = DelegatedPuzzleFeederArgs::<Puzzle>::from_clvm(allocator, curried.args)?;
58
59 let Some(inner_puzzle) = I::parse_puzzle(allocator, args.inner_puzzle)? else {
60 return Ok(None);
61 };
62
63 Ok(Some(Self::new(inner_puzzle)))
64 }
65
66 fn parse_solution(
67 allocator: &Allocator,
68 solution: NodePtr,
69 ) -> Result<Self::Solution, DriverError> {
70 let solution = DelegatedPuzzleFeederSolution::<NodePtr, NodePtr, NodePtr>::from_clvm(
71 allocator, solution,
72 )?;
73
74 let inner_solution = I::parse_solution(allocator, solution.inner_solution)?;
75
76 Ok(DelegatedPuzzleFeederSolution::new(
77 solution.delegated_puzzle,
78 solution.delegated_solution,
79 inner_solution,
80 ))
81 }
82}