Skip to content

Commit

Permalink
Merge pull request #136 from xch-dev/clawbacks
Browse files Browse the repository at this point in the history
Clawbacks
  • Loading branch information
Rigidity authored Dec 4, 2024
2 parents 509953a + 3ad74a3 commit 75d6779
Show file tree
Hide file tree
Showing 23 changed files with 633 additions and 47 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/chia-sdk-driver/src/driver_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ pub enum DriverError {

#[error("custom driver error: {0}")]
Custom(String),

#[error("invalid merkle proof")]
InvalidMerkleProof,
}
12 changes: 8 additions & 4 deletions crates/chia-sdk-driver/src/layers.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
mod augmented_condition_layer;
mod cat_layer;
mod did_layer;
mod nft_ownership_layer;
mod nft_state_layer;
mod p2_curried_layer;
mod p2_delegated_conditions_layer;
mod p2_delegated_singleton_layer;
mod p2_one_of_many;
mod p2_singleton;
mod p2_one_of_many_layer;
mod p2_singleton_layer;
mod royalty_transfer_layer;
mod settlement_layer;
mod singleton_layer;
mod standard_layer;

pub use augmented_condition_layer::*;
pub use cat_layer::*;
pub use did_layer::*;
pub use nft_ownership_layer::*;
pub use nft_state_layer::*;
pub use p2_curried_layer::*;
pub use p2_delegated_conditions_layer::*;
pub use p2_delegated_singleton_layer::*;
pub use p2_one_of_many::*;
pub use p2_singleton::*;
pub use p2_one_of_many_layer::*;
pub use p2_singleton_layer::*;
pub use royalty_transfer_layer::*;
pub use settlement_layer::*;
pub use singleton_layer::*;
Expand Down
68 changes: 68 additions & 0 deletions crates/chia-sdk-driver/src/layers/augmented_condition_layer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use chia_sdk_types::{
AugmentedConditionArgs, AugmentedConditionSolution, Condition, AUGMENTED_CONDITION_PUZZLE_HASH,
};
use clvm_traits::{FromClvm, ToClvm};
use clvmr::{Allocator, NodePtr};

use crate::{DriverError, Layer, Puzzle, SpendContext};

/// The augmented condition [`Layer`] allows for adding a condition to a puzzle's output.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AugmentedConditionLayer<T, I> {
pub condition: Condition<T>,
pub inner_puzzle: I,
}

impl<T, I> Layer for AugmentedConditionLayer<T, I>
where
T: ToClvm<Allocator> + FromClvm<Allocator> + Clone,
I: Layer,
{
type Solution = AugmentedConditionSolution<NodePtr>;

fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
let Some(puzzle) = puzzle.as_curried() else {
return Ok(None);
};

if puzzle.mod_hash != AUGMENTED_CONDITION_PUZZLE_HASH {
return Ok(None);
}

let args = AugmentedConditionArgs::<T, Puzzle>::from_clvm(allocator, puzzle.args)?;
let Some(inner_layer) = I::parse_puzzle(allocator, args.inner_puzzle)? else {
return Ok(None);
};

Ok(Some(Self {
condition: args.condition,
inner_puzzle: inner_layer,
}))
}

fn parse_solution(
allocator: &Allocator,
solution: NodePtr,
) -> Result<Self::Solution, DriverError> {
Ok(AugmentedConditionSolution::<NodePtr>::from_clvm(
allocator, solution,
)?)
}

fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
let inner_puzzle = self.inner_puzzle.construct_puzzle(ctx)?;
let curried = ctx.curry(AugmentedConditionArgs {
condition: self.condition.clone(),
inner_puzzle,
})?;
ctx.alloc(&curried)
}

fn construct_solution(
&self,
ctx: &mut SpendContext,
solution: Self::Solution,
) -> Result<NodePtr, DriverError> {
ctx.alloc(&solution)
}
}
56 changes: 56 additions & 0 deletions crates/chia-sdk-driver/src/layers/p2_curried_layer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use chia_protocol::Bytes32;
use chia_sdk_types::{P2CurriedArgs, P2CurriedSolution, P2_CURRIED_PUZZLE_HASH};
use clvm_traits::FromClvm;
use clvmr::{Allocator, NodePtr};

use crate::{DriverError, Layer, Puzzle, SpendContext};

/// The p2 curried [`Layer`] allows for .
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct P2CurriedLayer {
pub puzzle_hash: Bytes32,
}

impl Layer for P2CurriedLayer {
type Solution = P2CurriedSolution<NodePtr, NodePtr>;

fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
let Some(puzzle) = puzzle.as_curried() else {
return Ok(None);
};

if puzzle.mod_hash != P2_CURRIED_PUZZLE_HASH {
return Ok(None);
}

let args = P2CurriedArgs::from_clvm(allocator, puzzle.args)?;

Ok(Some(Self {
puzzle_hash: args.puzzle_hash,
}))
}

fn parse_solution(
allocator: &Allocator,
solution: NodePtr,
) -> Result<Self::Solution, DriverError> {
Ok(P2CurriedSolution::<NodePtr, NodePtr>::from_clvm(
allocator, solution,
)?)
}

fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
let curried = ctx.curry(P2CurriedArgs {
puzzle_hash: self.puzzle_hash,
})?;
ctx.alloc(&curried)
}

fn construct_solution(
&self,
ctx: &mut SpendContext,
solution: Self::Solution,
) -> Result<NodePtr, DriverError> {
ctx.alloc(&solution)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
use chia_protocol::Bytes32;
use chia_sdk_types::{P2OneOfManyArgs, P2OneOfManySolution, P2_ONE_OF_MANY_PUZZLE_HASH};
use clvm_traits::FromClvm;
use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash};
use clvmr::{Allocator, NodePtr};

use crate::{DriverError, Layer, Puzzle, SpendContext};

/// The p2 1 of n [`Layer`] allows for picking from several delegated puzzles at runtime without revealing up front.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct P2OneOfMany {
pub struct P2OneOfManyLayer {
/// The merkle root used to lookup the delegated puzzle as part of the solution.
pub merkle_root: Bytes32,
}

impl Layer for P2OneOfMany {
impl P2OneOfManyLayer {
pub fn new(merkle_root: Bytes32) -> Self {
Self { merkle_root }
}
}

impl Layer for P2OneOfManyLayer {
type Solution = P2OneOfManySolution<NodePtr, NodePtr>;

fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
Expand Down Expand Up @@ -54,3 +61,13 @@ impl Layer for P2OneOfMany {
ctx.alloc(&solution)
}
}

impl ToTreeHash for P2OneOfManyLayer {
fn tree_hash(&self) -> TreeHash {
CurriedProgram {
program: P2_ONE_OF_MANY_PUZZLE_HASH,
args: P2OneOfManyArgs::new(self.merkle_root),
}
.tree_hash()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use crate::{DriverError, Layer, Puzzle, Spend, SpendContext};
/// The p2 singleton [`Layer`] allows for requiring that a
/// singleton be spent alongside this coin to authorize it.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct P2Singleton {
pub struct P2SingletonLayer {
pub launcher_id: Bytes32,
}

impl P2Singleton {
impl P2SingletonLayer {
pub fn new(launcher_id: Bytes32) -> Self {
Self { launcher_id }
}
Expand Down Expand Up @@ -55,7 +55,7 @@ impl P2Singleton {
}
}

impl Layer for P2Singleton {
impl Layer for P2SingletonLayer {
type Solution = P2SingletonSolution;

fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
Expand Down Expand Up @@ -100,7 +100,7 @@ impl Layer for P2Singleton {
}
}

impl ToTreeHash for P2Singleton {
impl ToTreeHash for P2SingletonLayer {
fn tree_hash(&self) -> TreeHash {
P2SingletonArgs::curry_tree_hash(self.launcher_id)
}
Expand Down Expand Up @@ -129,7 +129,7 @@ mod tests {
let launcher_id = launcher.coin().coin_id();
let (create_singleton, singleton) = launcher.spend(ctx, puzzle_hash, ())?;

let p2_singleton = P2Singleton::new(launcher_id);
let p2_singleton = P2SingletonLayer::new(launcher_id);
let p2_singleton_hash = p2_singleton.tree_hash().into();

p2.spend(
Expand Down
2 changes: 0 additions & 2 deletions crates/chia-sdk-driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ mod driver_error;
mod hashed_ptr;
mod layer;
mod layers;
mod merkle_tree;
mod primitives;
mod puzzle;
mod spend;
Expand All @@ -15,7 +14,6 @@ pub use driver_error::*;
pub use hashed_ptr::*;
pub use layer::*;
pub use layers::*;
pub use merkle_tree::*;
pub use primitives::*;
pub use puzzle::*;
pub use spend::*;
Expand Down
2 changes: 2 additions & 0 deletions crates/chia-sdk-driver/src/primitives.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
mod cat;
mod clawback;
mod did;
mod intermediate_launcher;
mod launcher;
mod nft;

pub use cat::*;
pub use clawback::*;
pub use did::*;
pub use intermediate_launcher::*;
pub use launcher::*;
Expand Down
Loading

0 comments on commit 75d6779

Please sign in to comment.