From 9a9baa2ab955884d4c870c8a0042aa3d54ba283d Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 10:29:28 +0300 Subject: [PATCH 01/65] from_spend --- src/layers/actions/catalog/refund.rs | 13 ++ src/layers/actions/catalog/register.rs | 25 +++- src/primitives/catalog_registry.rs | 196 ++++++++++++++++++++----- 3 files changed, 195 insertions(+), 39 deletions(-) diff --git a/src/layers/actions/catalog/refund.rs b/src/layers/actions/catalog/refund.rs index 11f8f128..77d86af3 100644 --- a/src/layers/actions/catalog/refund.rs +++ b/src/layers/actions/catalog/refund.rs @@ -56,6 +56,19 @@ impl CatalogRefundAction { .to_clvm(ctx)?) } + pub fn spent_slot_value_from_solution( + &self, + ctx: &SpendContext, + solution: NodePtr, + ) -> Result, DriverError> { + let params = CatalogRefundActionSolution::::from_clvm(ctx, solution)?; + + Ok(params.neighbors.map(|neighbors| CatalogSlotValue { + asset_id: params.tail_hash, + neighbors, + })) + } + #[allow(clippy::too_many_arguments)] pub fn spend( self, diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index 3f3b306b..da0388a3 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -69,7 +69,28 @@ impl CatalogRegisterAction { .to_clvm(ctx)?) } - pub fn get_slot_values_from_solution( + pub fn get_spent_slot_values_from_solution( + &self, + ctx: &SpendContext, + solution: NodePtr, + ) -> Result<[CatalogSlotValue; 2], DriverError> { + let params = CatalogRegisterActionSolution::::from_clvm(ctx, solution)?; + + Ok([ + CatalogSlotValue::new( + params.left_tail_hash, + params.left_left_tail_hash, + params.right_tail_hash, + ), + CatalogSlotValue::new( + params.right_tail_hash, + params.left_tail_hash, + params.right_right_tail_hash, + ), + ]) + } + + pub fn get_created_slot_values_from_solution( &self, ctx: &SpendContext, solution: NodePtr, @@ -160,7 +181,7 @@ impl CatalogRegisterAction { let my_solution = my_solution.to_clvm(ctx)?; let my_puzzle = self.construct_puzzle(ctx)?; - let slot_values = self.get_slot_values_from_solution(ctx, my_solution)?; + let slot_values = self.get_created_slot_values_from_solution(ctx, my_solution)?; catalog.insert(Spend::new(my_puzzle, my_solution)); // spend slots diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index e0c6cf5c..f5b0ecd3 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -1,19 +1,42 @@ use chia::{ clvm_utils::ToTreeHash, - protocol::{Bytes32, Coin}, + protocol::{Bytes32, Coin, CoinSpend}, puzzles::{singleton::SingletonSolution, LineageProof, Proof}, }; use chia_wallet_sdk::driver::{DriverError, Layer, Puzzle, Spend, SpendContext}; -use clvm_traits::FromClvm; +use clvm_traits::{clvm_list, match_tuple, FromClvm}; use clvmr::{Allocator, NodePtr}; -use crate::{Action, ActionLayer, ActionLayerSolution, CatalogRegisterAction, Registry}; +use crate::{ + Action, ActionLayer, ActionLayerSolution, CatalogRefundAction, CatalogRegisterAction, + DelegatedStateAction, Registry, +}; use super::{ CatalogRegistryConstants, CatalogRegistryInfo, CatalogRegistryState, CatalogSlotValue, Slot, SlotInfo, SlotProof, }; +#[derive(Debug, Clone)] +pub struct CatalogPendingSpendInfo { + pub actions: Vec, + pub created_slots: Vec, + pub spent_slots: Vec, + + pub latest_state: (NodePtr, CatalogRegistryState), +} + +impl CatalogPendingSpendInfo { + pub fn new(latest_state: CatalogRegistryState) -> Self { + Self { + actions: vec![], + created_slots: vec![], + spent_slots: vec![], + latest_state: (NodePtr::NIL, latest_state), + } + } +} + #[derive(Debug, Clone)] #[must_use] pub struct CatalogRegistry { @@ -21,8 +44,7 @@ pub struct CatalogRegistry { pub proof: Proof, pub info: CatalogRegistryInfo, - pub pending_actions: Vec, - pub pending_slots: Vec>, + pub pending_spend: CatalogPendingSpendInfo, } impl CatalogRegistry { @@ -31,13 +53,143 @@ impl CatalogRegistry { coin, proof, info, - pending_actions: vec![], - pending_slots: vec![], + pending_spend: CatalogPendingSpendInfo::new(info.state), } } } impl CatalogRegistry { + pub fn pending_info_delta_from_spend( + ctx: &mut SpendContext, + action_spend: Spend, + current_state_and_ephemeral: (NodePtr, CatalogRegistryState), + constants: CatalogRegistryConstants, + ) -> Result< + ( + (NodePtr, CatalogRegistryState), + Vec, // created slot values + Vec, // spent slot values + ), + DriverError, + > { + let mut created_slots = vec![]; + let mut spent_slots = vec![]; + + let register_action = CatalogRegisterAction::from_constants(&constants); + let register_hash = register_action.tree_hash(); + + let refund_action = CatalogRefundAction::from_constants(&constants); + let refund_hash = refund_action.tree_hash(); + + let delegated_state_action = + >::from_constants(&constants); + let delegated_state_hash = delegated_state_action.tree_hash(); + + let actual_solution = ctx.alloc(&clvm_list!( + current_state_and_ephemeral, + action_spend.solution + ))?; + + let output = ctx.run(action_spend.puzzle, actual_solution)?; + let (new_state_and_ephemeral, _) = + ctx.extract::(output)?; + + let raw_action_hash = ctx.tree_hash(action_spend.puzzle); + + if raw_action_hash == register_hash { + spent_slots.extend( + register_action.get_spent_slot_values_from_solution(ctx, action_spend.solution)?, + ); + + created_slots.extend( + register_action + .get_created_slot_values_from_solution(ctx, action_spend.solution)?, + ); + } else if raw_action_hash == refund_hash { + if let Some(spent_slot) = + refund_action.spent_slot_value_from_solution(ctx, action_spend.solution)? + { + spent_slots.push(spent_slot); + } + } else if raw_action_hash != delegated_state_hash { + // delegated state action has no effect on slots + return Err(DriverError::InvalidMerkleProof); + } + + Ok((new_state_and_ephemeral, created_slots, spent_slots)) + } + + pub fn pending_info_from_spend( + ctx: &mut SpendContext, + solution: NodePtr, + initial_state: CatalogRegistryState, + constants: CatalogRegistryConstants, + ) -> Result { + let solution = ctx.extract::>(solution)?; + + let mut created_slots = vec![]; + let mut spent_slots = vec![]; + + let mut state_incl_ephemeral: (NodePtr, CatalogRegistryState) = + (NodePtr::NIL, initial_state); + + let inner_solution = ActionLayer::::parse_solution( + ctx, + solution.inner_solution, + )?; + + for raw_action in inner_solution.action_spends.iter() { + let res = Self::pending_info_delta_from_spend( + ctx, + *raw_action, + state_incl_ephemeral, + constants, + )?; + + state_incl_ephemeral = res.0; + created_slots.extend(res.1); + spent_slots.extend(res.2); + } + + Ok(CatalogPendingSpendInfo { + actions: inner_solution.action_spends, + created_slots, + spent_slots, + latest_state: state_incl_ephemeral, + }) + } + + pub fn from_spend( + ctx: &mut SpendContext, + spend: CoinSpend, + constants: CatalogRegistryConstants, + ) -> Result, DriverError> { + let coin = spend.coin; + let puzzle_ptr = ctx.alloc(&spend.puzzle_reveal)?; + let puzzle = Puzzle::parse(ctx, puzzle_ptr); + let solution_ptr = ctx.alloc(&spend.solution)?; + + let Some(info) = CatalogRegistryInfo::parse(ctx, puzzle, constants)? else { + return Ok(None); + }; + + let proof = Proof::Lineage(LineageProof { + parent_parent_coin_info: coin.parent_coin_info, + parent_inner_puzzle_hash: info.inner_puzzle_hash().into(), + parent_amount: coin.amount, + }); + + let pending_spend = + Self::pending_info_from_spend(ctx, solution_ptr, info.state, constants)?; + + Ok(Some(CatalogRegistry { + coin, + proof, + info, + pending_spend, + })) + } + pub fn from_parent_spend( allocator: &mut Allocator, parent_coin: Coin, @@ -170,36 +322,6 @@ impl CatalogRegistry { .collect() } - pub fn get_new_slots_from_spend( - &self, - ctx: &mut SpendContext, - solution: NodePtr, - ) -> Result>, DriverError> { - let solution = ctx.extract::>(solution)?; - - let mut slot_infos = vec![]; - - let register_action = CatalogRegisterAction::from_constants(&self.info.constants); - let register_hash = register_action.tree_hash(); - - let inner_solution = ActionLayer::::parse_solution( - ctx, - solution.inner_solution, - )?; - - for raw_action in inner_solution.action_spends { - let raw_action_hash = ctx.tree_hash(raw_action.puzzle); - - if raw_action_hash == register_hash { - slot_infos.extend( - register_action.get_slot_values_from_solution(ctx, raw_action.solution)?, - ); - } - } - - Ok(self.created_slot_values_to_slots(slot_infos)) - } - pub fn add_pending_slots(&mut self, slots: Vec>) { for slot in slots { self.pending_slots From 467a468cccdac5e2d8cd5fd6defafe8b39b912fe Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 10:43:10 +0300 Subject: [PATCH 02/65] almost --- src/primitives/catalog_registry.rs | 105 +++++++++++++---------------- 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index f5b0ecd3..04132fd9 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -4,8 +4,8 @@ use chia::{ puzzles::{singleton::SingletonSolution, LineageProof, Proof}, }; use chia_wallet_sdk::driver::{DriverError, Layer, Puzzle, Spend, SpendContext}; -use clvm_traits::{clvm_list, match_tuple, FromClvm}; -use clvmr::{Allocator, NodePtr}; +use clvm_traits::{clvm_list, match_tuple}; +use clvmr::NodePtr; use crate::{ Action, ActionLayer, ActionLayerSolution, CatalogRefundAction, CatalogRegisterAction, @@ -121,22 +121,18 @@ impl CatalogRegistry { pub fn pending_info_from_spend( ctx: &mut SpendContext, - solution: NodePtr, + inner_solution: NodePtr, initial_state: CatalogRegistryState, constants: CatalogRegistryConstants, ) -> Result { - let solution = ctx.extract::>(solution)?; - let mut created_slots = vec![]; let mut spent_slots = vec![]; let mut state_incl_ephemeral: (NodePtr, CatalogRegistryState) = (NodePtr::NIL, initial_state); - let inner_solution = ActionLayer::::parse_solution( - ctx, - solution.inner_solution, - )?; + let inner_solution = + ActionLayer::::parse_solution(ctx, inner_solution)?; for raw_action in inner_solution.action_spends.iter() { let res = Self::pending_info_delta_from_spend( @@ -173,14 +169,11 @@ impl CatalogRegistry { return Ok(None); }; - let proof = Proof::Lineage(LineageProof { - parent_parent_coin_info: coin.parent_coin_info, - parent_inner_puzzle_hash: info.inner_puzzle_hash().into(), - parent_amount: coin.amount, - }); + let solution = ctx.extract::>(solution_ptr)?; + let proof = solution.lineage_proof; let pending_spend = - Self::pending_info_from_spend(ctx, solution_ptr, info.state, constants)?; + Self::pending_info_from_spend(ctx, solution.inner_solution, info.state, constants)?; Ok(Some(CatalogRegistry { coin, @@ -190,45 +183,57 @@ impl CatalogRegistry { })) } + pub fn child_lineage_proof(&self) -> LineageProof { + LineageProof { + parent_parent_coin_info: self.coin.parent_coin_info, + parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), + parent_amount: self.coin.amount, + } + } + pub fn from_parent_spend( - allocator: &mut Allocator, - parent_coin: Coin, - parent_puzzle: Puzzle, - parent_solution: NodePtr, + ctx: &mut SpendContext, + parent_spend: CoinSpend, constants: CatalogRegistryConstants, ) -> Result, DriverError> where Self: Sized, { - let Some(parent_info) = CatalogRegistryInfo::parse(allocator, parent_puzzle, constants)? + let Some(parent_registry) = CatalogRegistry::from_spend(ctx, parent_spend, constants)? else { return Ok(None); }; - let proof = Proof::Lineage(LineageProof { - parent_parent_coin_info: parent_coin.parent_coin_info, - parent_inner_puzzle_hash: parent_info.inner_puzzle_hash().into(), - parent_amount: parent_coin.amount, - }); - - let parent_solution = SingletonSolution::::from_clvm(allocator, parent_solution)?; - let new_state = ActionLayer::::get_new_state( - allocator, - parent_info.state, - parent_solution.inner_solution, - )?; + let proof = Proof::Lineage(parent_registry.child_lineage_proof()); - let new_info = parent_info.with_state(new_state); - let new_coin = Coin::new(parent_coin.coin_id(), new_info.puzzle_hash().into(), 1); + let new_info = parent_registry + .info + .with_state(parent_registry.pending_spend.latest_state.1); + let new_coin = Coin::new( + parent_registry.coin.coin_id(), + new_info.puzzle_hash().into(), + 1, + ); Ok(Some(CatalogRegistry { coin: new_coin, proof, info: new_info, - pending_actions: vec![], - pending_slots: vec![], + pending_spend: CatalogPendingSpendInfo::new(new_info.state), })) } + + pub fn child(&self, child_state: CatalogRegistryState) -> Self { + let new_info = self.info.with_state(child_state); + let new_coin = Coin::new(self.coin.coin_id(), new_info.puzzle_hash().into(), 1); + + CatalogRegistry { + coin: new_coin, + proof: Proof::Lineage(self.child_lineage_proof()), + info: new_info, + pending_spend: CatalogPendingSpendInfo::new(new_info.state), + } + } } impl Registry for CatalogRegistry { @@ -243,11 +248,13 @@ impl CatalogRegistry { let puzzle = layers.construct_puzzle(ctx)?; let action_puzzle_hashes = self - .pending_actions + .pending_spend + .actions .iter() .map(|a| ctx.tree_hash(a.puzzle).into()) .collect::>(); + let child = self.child(self.pending_spend.latest_state.1); let solution = layers.construct_solution( ctx, SingletonSolution { @@ -263,7 +270,7 @@ impl CatalogRegistry { .ok_or(DriverError::Custom( "Couldn't build proofs for one or more actions".to_string(), ))?, - action_spends: self.pending_actions, + action_spends: self.pending_spend.actions, finalizer_solution: NodePtr::NIL, }, }, @@ -272,27 +279,7 @@ impl CatalogRegistry { let my_spend = Spend::new(puzzle, solution); ctx.spend(self.coin, my_spend)?; - let my_puzzle = Puzzle::parse(ctx, my_spend.puzzle); - let new_self = CatalogRegistry::from_parent_spend( - ctx, - self.coin, - my_puzzle, - my_spend.solution, - self.info.constants, - )? - .ok_or(DriverError::Custom( - "Couldn't parse child registry".to_string(), - ))?; - - Ok(new_self) - } - - pub fn insert(&mut self, action_spend: Spend) { - self.pending_actions.push(action_spend); - } - - pub fn insert_multiple(&mut self, action_spends: Vec) { - self.pending_actions.extend(action_spends); + Ok(child) } pub fn new_action(&self) -> A From 498157d71abf31261efe3a6224403715941cc373 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 10:54:56 +0300 Subject: [PATCH 03/65] looks so much better --- src/layers/actions/catalog/refund.rs | 3 +- src/layers/actions/catalog/register.rs | 8 ++- src/primitives/catalog_registry.rs | 75 ++++++++++++++++---------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/layers/actions/catalog/refund.rs b/src/layers/actions/catalog/refund.rs index 77d86af3..7a96e3e2 100644 --- a/src/layers/actions/catalog/refund.rs +++ b/src/layers/actions/catalog/refund.rs @@ -103,6 +103,7 @@ impl CatalogRefundAction { // if there's a slot, spend it if let Some(slot) = slot { + let slot = catalog.actual_slot(slot); slot.spend(ctx, spender_inner_puzzle_hash)?; } @@ -126,7 +127,7 @@ impl CatalogRefundAction { let action_solution = action_solution.to_clvm(ctx)?; let action_puzzle = self.construct_puzzle(ctx)?; - catalog.insert(Spend::new(action_puzzle, action_solution)); + catalog.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(secure_conditions) } } diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index da0388a3..c7e26c40 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -163,6 +163,7 @@ impl CatalogRegisterAction { nft.spend(ctx, eve_nft_inner_spend)?; // finally, spend self + let (left_slot, right_slot) = catalog.actual_neigbors(tail_hash, left_slot, right_slot); let my_solution = CatalogRegisterActionSolution { cat_maker_reveal: DefaultCatMakerArgs::get_puzzle( ctx, @@ -182,7 +183,7 @@ impl CatalogRegisterAction { let my_puzzle = self.construct_puzzle(ctx)?; let slot_values = self.get_created_slot_values_from_solution(ctx, my_solution)?; - catalog.insert(Spend::new(my_puzzle, my_solution)); + catalog.insert_action_spend(ctx, Spend::new(my_puzzle, my_solution))?; // spend slots left_slot.spend(ctx, my_inner_puzzle_hash)?; @@ -193,7 +194,10 @@ impl CatalogRegisterAction { catalog.coin.puzzle_hash, register_announcement, )), - catalog.created_slot_values_to_slots(slot_values.to_vec()), + slot_values + .into_iter() + .map(|s| catalog.created_slot_value_to_slot(s)) + .collect(), )) } } diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index 04132fd9..508b7c73 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -289,32 +289,19 @@ impl CatalogRegistry { A::from_constants(&self.info.constants) } - pub fn created_slot_values_to_slots( + pub fn created_slot_value_to_slot( &self, - slot_values: Vec, - ) -> Vec> { + slot_value: CatalogSlotValue, + ) -> Slot { let proof = SlotProof { parent_parent_info: self.coin.parent_coin_info, parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), }; - slot_values - .into_iter() - .map(|slot_value| { - Slot::new( - proof, - SlotInfo::from_value(self.info.constants.launcher_id, 0, slot_value), - ) - }) - .collect() - } - - pub fn add_pending_slots(&mut self, slots: Vec>) { - for slot in slots { - self.pending_slots - .retain(|s| s.info.value.asset_id != slot.info.value.asset_id); - self.pending_slots.push(slot); - } + Slot::new( + proof, + SlotInfo::from_value(self.info.constants.launcher_id, 0, slot_value), + ) } pub fn actual_neigbors( @@ -326,19 +313,51 @@ impl CatalogRegistry { let mut left = on_chain_left_slot; let mut right = on_chain_right_slot; - let new_slot_value = - CatalogSlotValue::new(new_tail_hash, Bytes32::default(), Bytes32::default()); - - for slot in self.pending_slots.iter() { - if slot.info.value < new_slot_value && slot.info.value >= left.info.value { - left = slot.clone(); + for slot_value in self.pending_spend.created_slots.iter() { + if slot_value.asset_id < new_tail_hash + && slot_value.asset_id >= left.info.value.asset_id + { + left = self.created_slot_value_to_slot(*slot_value); } - if slot.info.value > new_slot_value && slot.info.value <= right.info.value { - right = slot.clone(); + if slot_value.asset_id > new_tail_hash + && slot_value.asset_id <= right.info.value.asset_id + { + right = self.created_slot_value_to_slot(*slot_value); } } (left, right) } + + pub fn actual_slot(&self, slot: Slot) -> Slot { + let mut slot = slot; + for slot_value in self.pending_spend.created_slots.iter() { + if slot.info.value.asset_id == slot_value.asset_id { + slot = self.created_slot_value_to_slot(*slot_value); + } + } + + slot + } + + pub fn insert_action_spend( + &mut self, + ctx: &mut SpendContext, + action_spend: Spend, + ) -> Result<(), DriverError> { + let res = Self::pending_info_delta_from_spend( + ctx, + action_spend, + self.pending_spend.latest_state, + self.info.constants, + )?; + + self.pending_spend.latest_state = res.0; + self.pending_spend.created_slots.extend(res.1); + self.pending_spend.spent_slots.extend(res.2); + self.pending_spend.actions.push(action_spend); + + Ok(()) + } } From 866e9d93ad0c70f27561ccac5e38cecb1702cef6 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 11:07:54 +0300 Subject: [PATCH 04/65] better testing --- src/cli/verifications/sync_data.rs | 7 +----- src/drivers.rs | 35 +++++++++++++++++++++++++- src/layers/actions/catalog/refund.rs | 10 +++++++- src/layers/actions/catalog/register.rs | 6 ++--- src/primitives/catalog_registry.rs | 19 ++++++-------- 5 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/cli/verifications/sync_data.rs b/src/cli/verifications/sync_data.rs index 0a52b260..f37a8a95 100644 --- a/src/cli/verifications/sync_data.rs +++ b/src/cli/verifications/sync_data.rs @@ -41,14 +41,9 @@ pub async fn get_latest_data_for_asset_id( possible_prelauncher_record.coin.parent_coin_info, ))?; - let puzzle_ptr = ctx.alloc(&catalog_spend_maybe.puzzle_reveal)?; - let puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = ctx.alloc(&catalog_spend_maybe.solution)?; if let Ok(Some(_reg)) = CatalogRegistry::from_parent_spend( ctx, - catalog_spend_maybe.coin, - puzzle, - solution_ptr, + catalog_spend_maybe, CatalogRegistryConstants::get(testnet11), ) { prelauncher_coin_id = Some(possible_prelauncher_record.coin.coin_id()); diff --git a/src/drivers.rs b/src/drivers.rs index 92b69fcd..3e7ede99 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1169,6 +1169,20 @@ mod tests { slot.cloned(), )?; + // check refund action created/spent slots function + let created_slots = catalog.pending_spend.created_slots.clone(); + let spent_slots = catalog.pending_spend.spent_slots.clone(); + if slot.is_some() { + assert_eq!(created_slots.len(), 1); + assert_eq!(created_slots[0], slot.unwrap().info.value); + + assert_eq!(spent_slots.len(), 1); + assert_eq!(spent_slots[0], slot.unwrap().info.value); + } else { + assert_eq!(created_slots.len(), 0); + assert_eq!(spent_slots.len(), 0); + } + let new_catalog = catalog.finish_spend(ctx)?; ensure_conditions_met(ctx, sim, secure_cond, 0)?; @@ -1419,7 +1433,7 @@ mod tests { delegated_state_action_solution.other_singleton_inner_puzzle_hash, )?; - catalog.insert(action_spend); + catalog.insert_action_spend(ctx, action_spend)?; catalog = catalog.finish_spend(ctx)?; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "update_price", &[user_bls.sk.clone()])?; @@ -1438,6 +1452,18 @@ mod tests { }, )?; + // check register action created/spent slots function + let created_slots: Vec> = catalog + .pending_spend + .created_slots + .iter() + .map(|s| catalog.created_slot_value_to_slot(*s)) + .collect(); + let spent_slots = catalog.pending_spend.spent_slots.clone(); + assert_eq!(spent_slots.len(), 2); + assert_eq!(spent_slots[0], left_slot.info.value); + assert_eq!(spent_slots[1], right_slot.info.value); + catalog = catalog.finish_spend(ctx)?; ensure_conditions_met(ctx, &mut sim, secure_cond.clone(), 1)?; @@ -1450,6 +1476,13 @@ mod tests { && s.info.value_hash != right_slot.info.value_hash }); slots.extend(new_slots); + + created_slots.into_iter().for_each(|s| { + assert!(sim + .coin_state(s.coin.coin_id()) + .map(|c| c.spent_height) + .is_some()); + }); } assert_eq!( diff --git a/src/layers/actions/catalog/refund.rs b/src/layers/actions/catalog/refund.rs index 7a96e3e2..08d5ed1b 100644 --- a/src/layers/actions/catalog/refund.rs +++ b/src/layers/actions/catalog/refund.rs @@ -56,7 +56,7 @@ impl CatalogRefundAction { .to_clvm(ctx)?) } - pub fn spent_slot_value_from_solution( + pub fn spent_slot_value( &self, ctx: &SpendContext, solution: NodePtr, @@ -69,6 +69,14 @@ impl CatalogRefundAction { })) } + pub fn created_slot_value( + &self, + ctx: &SpendContext, + solution: NodePtr, + ) -> Result, DriverError> { + self.spent_slot_value(ctx, solution) + } + #[allow(clippy::too_many_arguments)] pub fn spend( self, diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index c7e26c40..4daa74b6 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -69,7 +69,7 @@ impl CatalogRegisterAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_values_from_solution( + pub fn spent_slot_values( &self, ctx: &SpendContext, solution: NodePtr, @@ -90,7 +90,7 @@ impl CatalogRegisterAction { ]) } - pub fn get_created_slot_values_from_solution( + pub fn created_slot_values( &self, ctx: &SpendContext, solution: NodePtr, @@ -182,7 +182,7 @@ impl CatalogRegisterAction { let my_solution = my_solution.to_clvm(ctx)?; let my_puzzle = self.construct_puzzle(ctx)?; - let slot_values = self.get_created_slot_values_from_solution(ctx, my_solution)?; + let slot_values = self.created_slot_values(ctx, my_solution)?; catalog.insert_action_spend(ctx, Spend::new(my_puzzle, my_solution))?; // spend slots diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index 508b7c73..1ae8dab8 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -97,19 +97,16 @@ impl CatalogRegistry { let raw_action_hash = ctx.tree_hash(action_spend.puzzle); if raw_action_hash == register_hash { - spent_slots.extend( - register_action.get_spent_slot_values_from_solution(ctx, action_spend.solution)?, - ); - - created_slots.extend( - register_action - .get_created_slot_values_from_solution(ctx, action_spend.solution)?, - ); + spent_slots.extend(register_action.spent_slot_values(ctx, action_spend.solution)?); + + created_slots.extend(register_action.created_slot_values(ctx, action_spend.solution)?); } else if raw_action_hash == refund_hash { - if let Some(spent_slot) = - refund_action.spent_slot_value_from_solution(ctx, action_spend.solution)? - { + if let (Some(spent_slot), Some(created_slot)) = ( + refund_action.spent_slot_value(ctx, action_spend.solution)?, + refund_action.created_slot_value(ctx, action_spend.solution)?, + ) { spent_slots.push(spent_slot); + created_slots.push(created_slot); } } else if raw_action_hash != delegated_state_hash { // delegated state action has no effect on slots From 51cb8ead907024080bff625965bcf4f2405c21dd Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 11:11:13 +0300 Subject: [PATCH 05/65] almost done, now to syncing --- .../catalog/broadcast_catalog_state_update.rs | 2 +- src/cli/catalog/continue_launch.rs | 3 +- src/cli/catalog/quick_sync.rs | 29 +++++-------------- src/cli/catalog/unroll_state_scheduler.rs | 2 +- src/cli/verifications/sync_data.rs | 2 +- src/primitives/catalog_registry.rs | 4 +-- 6 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/cli/catalog/broadcast_catalog_state_update.rs b/src/cli/catalog/broadcast_catalog_state_update.rs index 17a28dfc..e3c0e8fa 100644 --- a/src/cli/catalog/broadcast_catalog_state_update.rs +++ b/src/cli/catalog/broadcast_catalog_state_update.rs @@ -89,7 +89,7 @@ pub async fn catalog_broadcast_state_update( new_state, medieval_vault_inner_ph.into(), )?; - catalog.insert(inner_spend); + catalog.insert_action_spend(&mut ctx, inner_spend)?; let mut _new_catalog = catalog.finish_spend(&mut ctx)?; multisig_broadcast_thing_finish( diff --git a/src/cli/catalog/continue_launch.rs b/src/cli/catalog/continue_launch.rs index 3c7a3648..ca7ed226 100644 --- a/src/cli/catalog/continue_launch.rs +++ b/src/cli/catalog/continue_launch.rs @@ -510,7 +510,7 @@ pub async fn catalog_continue_launch( let eve_nft_inner_puzzle = initial_cat_inner_puzzle_ptr(&mut ctx, &cats[i])?; - let (sec_conds, new_slots) = catalog.new_action::().spend( + let (sec_conds, _new_slots) = catalog.new_action::().spend( &mut ctx, &mut catalog, tail_hash, @@ -524,7 +524,6 @@ pub async fn catalog_continue_launch( )?; security_coin_conditions = security_coin_conditions.extend(sec_conds); - catalog.add_pending_slots(new_slots); } let _new_catalog = catalog.finish_spend(&mut ctx)?; diff --git a/src/cli/catalog/quick_sync.rs b/src/cli/catalog/quick_sync.rs index b0db20d3..704fb840 100644 --- a/src/cli/catalog/quick_sync.rs +++ b/src/cli/catalog/quick_sync.rs @@ -1,9 +1,8 @@ use chia::protocol::CoinSpend; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{Puzzle, SpendContext}, + driver::SpendContext, }; -use clvmr::serde::node_from_bytes; use crate::{CatalogRegistry, CatalogRegistryConstants, CliError}; @@ -42,18 +41,9 @@ pub async fn quick_sync_catalog( ))?; let mut temp_ctx = SpendContext::new(); - let puzzle_ptr = node_from_bytes(&mut temp_ctx, &next_spend.puzzle_reveal)?; - let puzzle = Puzzle::parse(&temp_ctx, puzzle_ptr); - let solution_ptr = node_from_bytes(&mut temp_ctx, &next_spend.solution)?; - - let catalog_maybe = CatalogRegistry::from_parent_spend( - &mut temp_ctx, - next_spend.coin, - puzzle, - solution_ptr, - constants, - ) - .unwrap_or_default(); + let catalog_maybe = + CatalogRegistry::from_parent_spend(&mut temp_ctx, &next_spend, constants) + .unwrap_or_default(); if catalog_maybe.is_some() { coin_spend = Some(next_spend); break; @@ -61,14 +51,9 @@ pub async fn quick_sync_catalog( } if let Some(coin_spend) = coin_spend { - let puzzle_ptr = node_from_bytes(ctx, &coin_spend.puzzle_reveal)?; - let puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = node_from_bytes(ctx, &coin_spend.solution)?; - - CatalogRegistry::from_parent_spend(ctx, coin_spend.coin, puzzle, solution_ptr, constants)? - .ok_or(CliError::Custom( - "Tried to unwrap CATalog but couldn't".to_string(), - )) + CatalogRegistry::from_parent_spend(ctx, &coin_spend, constants)?.ok_or(CliError::Custom( + "Tried to unwrap CATalog but couldn't".to_string(), + )) } else { Err(CliError::Custom("Could not find CATalog coin".to_string())) } diff --git a/src/cli/catalog/unroll_state_scheduler.rs b/src/cli/catalog/unroll_state_scheduler.rs index fb37e7ce..5534149a 100644 --- a/src/cli/catalog/unroll_state_scheduler.rs +++ b/src/cli/catalog/unroll_state_scheduler.rs @@ -89,7 +89,7 @@ pub async fn catalog_unroll_state_scheduler( new_state, state_scheduler.info.inner_puzzle_hash().into(), )?; - catalog.insert(catalog_action_spend); + catalog.insert_action_spend(&mut ctx, catalog_action_spend)?; let catalog_inner_ph = catalog.info.inner_puzzle_hash(); let _new_catalog = catalog.finish_spend(&mut ctx)?; diff --git a/src/cli/verifications/sync_data.rs b/src/cli/verifications/sync_data.rs index f37a8a95..8e1fec84 100644 --- a/src/cli/verifications/sync_data.rs +++ b/src/cli/verifications/sync_data.rs @@ -43,7 +43,7 @@ pub async fn get_latest_data_for_asset_id( if let Ok(Some(_reg)) = CatalogRegistry::from_parent_spend( ctx, - catalog_spend_maybe, + &catalog_spend_maybe, CatalogRegistryConstants::get(testnet11), ) { prelauncher_coin_id = Some(possible_prelauncher_record.coin.coin_id()); diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index 1ae8dab8..aa8d4a21 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -154,7 +154,7 @@ impl CatalogRegistry { pub fn from_spend( ctx: &mut SpendContext, - spend: CoinSpend, + spend: &CoinSpend, constants: CatalogRegistryConstants, ) -> Result, DriverError> { let coin = spend.coin; @@ -190,7 +190,7 @@ impl CatalogRegistry { pub fn from_parent_spend( ctx: &mut SpendContext, - parent_spend: CoinSpend, + parent_spend: &CoinSpend, constants: CatalogRegistryConstants, ) -> Result, DriverError> where From b85f8403486ec5ee99afd8938227e85113b02c17 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 11:20:13 +0300 Subject: [PATCH 06/65] quick sync w/ mempool support --- src/cli/catalog/quick_sync.rs | 46 +++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/cli/catalog/quick_sync.rs b/src/cli/catalog/quick_sync.rs index 704fb840..a46fc016 100644 --- a/src/cli/catalog/quick_sync.rs +++ b/src/cli/catalog/quick_sync.rs @@ -42,19 +42,49 @@ pub async fn quick_sync_catalog( let mut temp_ctx = SpendContext::new(); let catalog_maybe = - CatalogRegistry::from_parent_spend(&mut temp_ctx, &next_spend, constants) - .unwrap_or_default(); + CatalogRegistry::from_parent_spend(&mut temp_ctx, &next_spend, constants)?; if catalog_maybe.is_some() { coin_spend = Some(next_spend); break; } } - if let Some(coin_spend) = coin_spend { - CatalogRegistry::from_parent_spend(ctx, &coin_spend, constants)?.ok_or(CliError::Custom( - "Tried to unwrap CATalog but couldn't".to_string(), - )) - } else { - Err(CliError::Custom("Could not find CATalog coin".to_string())) + let Some(coin_spend) = coin_spend else { + return Err(CliError::Custom("Could not find CATalog coin".to_string())); + }; + let on_chain_catalog = CatalogRegistry::from_parent_spend(ctx, &coin_spend, constants)?.ok_or( + CliError::Custom("Could not parse CATalog spend".to_string()), + )?; + + let Some(mut mempool_items) = client + .get_mempool_items_by_coin_name(on_chain_catalog.coin.coin_id()) + .await? + .mempool_items + else { + return Ok(on_chain_catalog); + }; + + if mempool_items.len() == 0 { + return Ok(on_chain_catalog); + } + + let mempool_item = mempool_items.remove(0); + let mut catalog = on_chain_catalog; + loop { + let Some(catalog_spend) = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|c| c.coin.coin_id() == catalog.coin.coin_id()) + else { + break; + }; + + let Some(new_catalog) = CatalogRegistry::from_spend(ctx, catalog_spend, constants)? else { + break; + }; + catalog = new_catalog; } + + Ok(catalog) } From bb3d6d402f3f7fb83b61dfd27801c5a29986cfc2 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 11:29:41 +0300 Subject: [PATCH 07/65] fix sync --- src/cli/catalog/sync.rs | 57 ++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index 09fe1933..c3b85f22 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use chia::{ clvm_utils::{tree_hash, ToTreeHash}, protocol::{Bytes32, Coin}, @@ -59,15 +61,10 @@ pub async fn sync_catalog( return Err(CliError::CoinNotSpent(last_coin_id)); }; - let puzzle_ptr = ctx.alloc(&coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = ctx.alloc(&coin_spend.solution)?; if !skip_db_save { if let Some(ref prev_catalog) = catalog { - let new_slots = prev_catalog.get_new_slots_from_spend(ctx, solution_ptr)?; - - for slot in new_slots.iter() { - let asset_id = slot.info.value.asset_id; + for slot_value in prev_catalog.pending_spend.spent_slots.iter() { + let asset_id = slot_value.asset_id; if let Some(previous_value_hash) = db.get_catalog_indexed_slot_value(asset_id).await? @@ -82,27 +79,45 @@ pub async fn sync_catalog( } } - for slot in new_slots { - db.save_catalog_indexed_slot_value( - slot.info.value.asset_id, - slot.info.value_hash, - ) - .await?; - db.save_slot(ctx, slot, 0).await?; + let mut processed_values = HashSet::::new(); + for slot_value in prev_catalog.pending_spend.spent_slots.iter() { + let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); + if processed_values.contains(&slot_value_hash) { + continue; + } + processed_values.insert(slot_value_hash); + + // same slot can be created and spent mutliple times in the same block + let no_spent = prev_catalog + .pending_spend + .spent_slots + .iter() + .filter(|sv| sv == &slot_value) + .count(); + let no_created = prev_catalog + .pending_spend + .created_slots + .iter() + .filter(|sv| sv == &slot_value) + .count(); + if no_spent != no_created { + continue; + } + + db.save_catalog_indexed_slot_value(slot_value.asset_id, slot_value_hash) + .await?; + db.save_slot(ctx, prev_catalog.created_slot_value_to_slot(*slot_value), 0) + .await?; } } } - if let Some(some_catalog) = CatalogRegistry::from_parent_spend( - ctx, - coin_record.coin, - parent_puzzle, - solution_ptr, - constants, - )? { + if let Some(some_catalog) = CatalogRegistry::from_parent_spend(ctx, &coin_spend, constants)? + { last_coin_id = some_catalog.coin.coin_id(); catalog = Some(some_catalog); } else if coin_record.coin.coin_id() == constants.launcher_id { + let solution_ptr = ctx.alloc(&coin_spend.solution)?; let solution = ctx.extract::>(solution_ptr)?; let catalog_eve_coin = Coin::new(constants.launcher_id, solution.singleton_puzzle_hash, 1); From 1e1d2c3af8f6c5fbbc7284e97486faa4f8b6e0ca Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 11:35:04 +0300 Subject: [PATCH 08/65] no more warnings or errors --- src/cli/catalog/quick_sync.rs | 2 +- src/cli/catalog/verify_deployment.rs | 21 +++++++-------------- src/primitives/catalog_registry.rs | 1 + 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/cli/catalog/quick_sync.rs b/src/cli/catalog/quick_sync.rs index a46fc016..1dcbb747 100644 --- a/src/cli/catalog/quick_sync.rs +++ b/src/cli/catalog/quick_sync.rs @@ -64,7 +64,7 @@ pub async fn quick_sync_catalog( return Ok(on_chain_catalog); }; - if mempool_items.len() == 0 { + if mempool_items.is_empty() { return Ok(on_chain_catalog); } diff --git a/src/cli/catalog/verify_deployment.rs b/src/cli/catalog/verify_deployment.rs index 994c47ce..cccc57f5 100644 --- a/src/cli/catalog/verify_deployment.rs +++ b/src/cli/catalog/verify_deployment.rs @@ -204,14 +204,15 @@ pub async fn catalog_verify_deployment(testnet11: bool) -> Result<(), CliError> break; }; - let solution = node_from_bytes(&mut ctx, &coin_spend.solution)?; - let new_slots = catalog.get_new_slots_from_spend(&mut ctx, solution)?; + catalog = + CatalogRegistry::from_spend(&mut ctx, &coin_spend, catalog.info.constants)?.unwrap(); + let new_slot_values = &catalog.pending_spend.created_slots; while cat_index < cats_to_launch.len() { let top_cat = &cats_to_launch[cat_index]; - let found = new_slots + let found = new_slot_values .iter() - .find(|slot| slot.info.value.asset_id == top_cat.asset_id); + .find(|slot_value| slot_value.asset_id == top_cat.asset_id); if found.is_some() { cat_index += 1; @@ -269,16 +270,8 @@ pub async fn catalog_verify_deployment(testnet11: bool) -> Result<(), CliError> } } - let puzzle_ptr = node_from_bytes(&mut ctx, &coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(&ctx, puzzle_ptr); - catalog = CatalogRegistry::from_parent_spend( - &mut ctx, - catalog.coin, - parent_puzzle, - solution, - catalog.info.constants, - )? - .unwrap(); + // this coin's confirmed, move to the child + catalog = catalog.child(catalog.pending_spend.latest_state.1); } if cat_index < cats_to_launch.len() { diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index aa8d4a21..2ccc7c8e 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -59,6 +59,7 @@ impl CatalogRegistry { } impl CatalogRegistry { + #[allow(clippy::type_complexity)] pub fn pending_info_delta_from_spend( ctx: &mut SpendContext, action_spend: Spend, From d603a49d19ca584592ccbbff559b6553701d9df3 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 12:44:28 +0300 Subject: [PATCH 09/65] about to change a lot of stuff for handles --- src/layers/actions/xchandles/expire.rs | 4 +- src/layers/actions/xchandles/extend.rs | 4 +- src/layers/actions/xchandles/oracle.rs | 4 +- src/layers/actions/xchandles/refund.rs | 4 +- src/layers/actions/xchandles/register.rs | 4 +- src/layers/actions/xchandles/update.rs | 4 +- src/primitives/xchandles_registry.rs | 403 +++++++++++++---------- 7 files changed, 237 insertions(+), 190 deletions(-) diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index 0b124a74..f4a3e31b 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -59,7 +59,7 @@ impl XchandlesExpireAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_value_from_solution( + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, ) -> Result { @@ -85,7 +85,7 @@ impl XchandlesExpireAction { )) } - pub fn get_created_slot_value_from_solution( + pub fn created_slot_value( ctx: &mut SpendContext, solution: NodePtr, ) -> Result { diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index ba418d73..0d855042 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -49,7 +49,7 @@ impl XchandlesExtendAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_value_from_solution( + pub fn spent_slot_value( ctx: &mut SpendContext, solution: NodePtr, ) -> Result { @@ -73,7 +73,7 @@ impl XchandlesExtendAction { )) } - pub fn get_created_slot_value_from_solution( + pub fn created_slot_value( ctx: &mut SpendContext, solution: NodePtr, ) -> Result { diff --git a/src/layers/actions/xchandles/oracle.rs b/src/layers/actions/xchandles/oracle.rs index 094dcbd0..9f6a52ff 100644 --- a/src/layers/actions/xchandles/oracle.rs +++ b/src/layers/actions/xchandles/oracle.rs @@ -42,7 +42,7 @@ impl XchandlesOracleAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_value_from_solution( + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, ) -> Result { @@ -51,7 +51,7 @@ impl XchandlesOracleAction { Ok(slot_value) } - pub fn get_created_slot_value(spent_slot_value: XchandlesSlotValue) -> XchandlesSlotValue { + pub fn created_slot_value(spent_slot_value: XchandlesSlotValue) -> XchandlesSlotValue { spent_slot_value } diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index 6c85bc75..f59a1b5d 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -56,7 +56,7 @@ impl XchandlesRefundAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_value_from_solution( + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, ) -> Result, DriverError> { @@ -68,7 +68,7 @@ impl XchandlesRefundAction { Ok(solution.slot_value) } - pub fn get_created_slot_value( + pub fn created_slot_value( spent_slot_value: Option, ) -> Option { spent_slot_value // nothing changed; just oracle diff --git a/src/layers/actions/xchandles/register.rs b/src/layers/actions/xchandles/register.rs index 8d536bf5..095d6421 100644 --- a/src/layers/actions/xchandles/register.rs +++ b/src/layers/actions/xchandles/register.rs @@ -57,7 +57,7 @@ impl XchandlesRegisterAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_values_from_solution( + pub fn spent_slot_values( ctx: &SpendContext, solution: NodePtr, ) -> Result<[XchandlesSlotValue; 2], DriverError> { @@ -89,7 +89,7 @@ impl XchandlesRegisterAction { ]) } - pub fn get_created_slot_values_from_solution( + pub fn created_slot_values( ctx: &mut SpendContext, solution: NodePtr, ) -> Result<[XchandlesSlotValue; 3], DriverError> { diff --git a/src/layers/actions/xchandles/update.rs b/src/layers/actions/xchandles/update.rs index c8d10d0c..cd84062b 100644 --- a/src/layers/actions/xchandles/update.rs +++ b/src/layers/actions/xchandles/update.rs @@ -44,7 +44,7 @@ impl XchandlesUpdateAction { .to_clvm(ctx)?) } - pub fn get_spent_slot_value_from_solution( + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, ) -> Result { @@ -53,7 +53,7 @@ impl XchandlesUpdateAction { Ok(solution.current_slot_value) } - pub fn get_created_slot_value_from_solution( + pub fn created_slot_value( ctx: &mut SpendContext, solution: NodePtr, ) -> Result { diff --git a/src/primitives/xchandles_registry.rs b/src/primitives/xchandles_registry.rs index 9ebe9e44..bb89eb43 100644 --- a/src/primitives/xchandles_registry.rs +++ b/src/primitives/xchandles_registry.rs @@ -1,6 +1,6 @@ use chia::{ clvm_utils::ToTreeHash, - protocol::{Bytes, Bytes32, Coin}, + protocol::{Bytes, Bytes32, Coin, CoinSpend}, puzzles::{singleton::SingletonSolution, LineageProof, Proof}, }; use chia_puzzle_types::singleton::{LauncherSolution, SingletonArgs}; @@ -12,9 +12,9 @@ use clvm_traits::{clvm_list, match_tuple, FromClvm, ToClvm}; use clvmr::{Allocator, NodePtr}; use crate::{ - eve_singleton_inner_puzzle, Action, ActionLayer, ActionLayerSolution, CliError, - DelegatedStateAction, Registry, XchandlesExpireAction, XchandlesExtendAction, - XchandlesOracleAction, XchandlesRefundAction, XchandlesRegisterAction, XchandlesUpdateAction, + eve_singleton_inner_puzzle, Action, ActionLayer, ActionLayerSolution, DelegatedStateAction, + Registry, XchandlesExpireAction, XchandlesExtendAction, XchandlesOracleAction, + XchandlesRefundAction, XchandlesRegisterAction, XchandlesUpdateAction, }; use super::{ @@ -22,12 +22,24 @@ use super::{ XchandlesSlotValue, }; -#[derive(Debug, Clone, Default)] -pub struct XchandlesRegistryPendingItems { +#[derive(Debug, Clone)] +pub struct XchandlesPendingSpendInfo { pub actions: Vec, - pub spent_slots: Vec, pub created_slots: Vec, + + pub latest_state: (NodePtr, XchandlesRegistryState), +} + +impl XchandlesPendingSpendInfo { + pub fn new(latest_state: XchandlesRegistryState) -> Self { + Self { + actions: vec![], + created_slots: vec![], + spent_slots: vec![], + latest_state: (NodePtr::NIL, latest_state), + } + } } #[derive(Debug, Clone)] @@ -37,7 +49,7 @@ pub struct XchandlesRegistry { pub proof: Proof, pub info: XchandlesRegistryInfo, - pub pending_items: XchandlesRegistryPendingItems, + pub pending_spend: XchandlesPendingSpendInfo, } impl XchandlesRegistry { @@ -46,7 +58,7 @@ impl XchandlesRegistry { coin, proof, info, - pending_items: XchandlesRegistryPendingItems::default(), + pending_spend: XchandlesPendingSpendInfo::new(info.state), } } } @@ -57,46 +69,227 @@ impl Registry for XchandlesRegistry { } impl XchandlesRegistry { + #[allow(clippy::type_complexity)] + pub fn pending_info_delta_from_spend( + ctx: &mut SpendContext, + action_spend: Spend, + current_state_and_ephemeral: (NodePtr, XchandlesRegistryState), + constants: XchandlesConstants, + ) -> Result< + ( + (NodePtr, XchandlesRegistryState), // pending state + Vec, // created slot values + Vec, // spent slot values + ), + DriverError, + > { + let mut created_slots = vec![]; + let mut spent_slots = vec![]; + + let expire_action = XchandlesExpireAction::from_constants(&constants); + let expire_action_hash = expire_action.tree_hash(); + + let extend_action = XchandlesExtendAction::from_constants(&constants); + let extend_action_hash = extend_action.tree_hash(); + + let oracle_action = XchandlesOracleAction::from_constants(&constants); + let oracle_action_hash = oracle_action.tree_hash(); + + let register_action = XchandlesRegisterAction::from_constants(&constants); + let register_action_hash = register_action.tree_hash(); + + let update_action = XchandlesUpdateAction::from_constants(&constants); + let update_action_hash = update_action.tree_hash(); + + let refund_action = XchandlesRefundAction::from_constants(&constants); + let refund_action_hash = refund_action.tree_hash(); + + let delegated_state_action = + >::from_constants(&constants); + let delegated_state_action_hash = delegated_state_action.tree_hash(); + + let actual_solution = ctx.alloc(&clvm_list!( + current_state_and_ephemeral, + action_spend.solution + ))?; + + let output = ctx.run(action_spend.puzzle, actual_solution)?; + let (new_state_and_ephemeral, _) = + ctx.extract::(output)?; + + let raw_action_hash = ctx.tree_hash(action_spend.puzzle); + + if raw_action_hash == extend_action_hash { + spent_slots.push(XchandlesExtendAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + created_slots.push(XchandlesExtendAction::created_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == oracle_action_hash { + let slot_value = XchandlesOracleAction::spent_slot_value(ctx, action_spend.solution)?; + + spent_slots.push(slot_value.clone()); + created_slots.push(slot_value); + } else if raw_action_hash == update_action_hash { + spent_slots.push(XchandlesUpdateAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + created_slots.push(XchandlesUpdateAction::created_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == refund_action_hash { + if let Some(slot_value) = + XchandlesRefundAction::spent_slot_value(ctx, action_spend.solution)? + { + spent_slots.push(slot_value.clone()); + created_slots.push(slot_value); + }; + } else if raw_action_hash == expire_action_hash { + spent_slots.push(XchandlesExpireAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + created_slots.push(XchandlesExpireAction::created_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == register_action_hash { + spent_slots.extend(XchandlesRegisterAction::spent_slot_values( + ctx, + action_spend.solution, + )?); + created_slots.extend(XchandlesRegisterAction::created_slot_values( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash != delegated_state_action_hash { + // delegated state action has no effect on slots + return Err(DriverError::InvalidMerkleProof); + } + + Ok((new_state_and_ephemeral, created_slots, spent_slots)) + } + + pub fn pending_info_from_spend( + ctx: &mut SpendContext, + inner_solution: NodePtr, + initial_state: XchandlesRegistryState, + constants: XchandlesConstants, + ) -> Result { + let mut created_slots = vec![]; + let mut spent_slots = vec![]; + + let mut state_incl_ephemeral: (NodePtr, XchandlesRegistryState) = + (NodePtr::NIL, initial_state); + + let inner_solution = + ActionLayer::::parse_solution(ctx, inner_solution)?; + + for raw_action in inner_solution.action_spends.iter() { + let res = Self::pending_info_delta_from_spend( + ctx, + *raw_action, + state_incl_ephemeral, + constants, + )?; + + state_incl_ephemeral = res.0; + created_slots.extend(res.1); + spent_slots.extend(res.2); + } + + Ok(XchandlesPendingSpendInfo { + actions: inner_solution.action_spends, + created_slots, + spent_slots, + latest_state: state_incl_ephemeral, + }) + } + + pub fn from_spend( + ctx: &mut SpendContext, + spend: &CoinSpend, + constants: XchandlesConstants, + ) -> Result, DriverError> { + let coin = spend.coin; + let puzzle_ptr = ctx.alloc(&spend.puzzle_reveal)?; + let puzzle = Puzzle::parse(ctx, puzzle_ptr); + let solution_ptr = ctx.alloc(&spend.solution)?; + + let Some(info) = XchandlesRegistryInfo::parse(ctx, puzzle, constants)? else { + return Ok(None); + }; + + let solution = ctx.extract::>(solution_ptr)?; + let proof = solution.lineage_proof; + + let pending_spend = + Self::pending_info_from_spend(ctx, solution.inner_solution, info.state, constants)?; + + Ok(Some(XchandlesRegistry { + coin, + proof, + info, + pending_spend, + })) + } + + pub fn child_lineage_proof(&self) -> LineageProof { + LineageProof { + parent_parent_coin_info: self.coin.parent_coin_info, + parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), + parent_amount: self.coin.amount, + } + } + pub fn from_parent_spend( - allocator: &mut Allocator, - parent_coin: Coin, - parent_puzzle: Puzzle, - parent_solution: NodePtr, + ctx: &mut SpendContext, + parent_spend: &CoinSpend, constants: XchandlesConstants, ) -> Result, DriverError> where Self: Sized, { - let Some(parent_info) = XchandlesRegistryInfo::parse(allocator, parent_puzzle, constants)? - else { + let Some(parent_registry) = Self::from_spend(ctx, parent_spend, constants)? else { return Ok(None); }; - let proof = Proof::Lineage(LineageProof { - parent_parent_coin_info: parent_coin.parent_coin_info, - parent_inner_puzzle_hash: parent_info.inner_puzzle_hash().into(), - parent_amount: parent_coin.amount, - }); + let proof = Proof::Lineage(parent_registry.child_lineage_proof()); - let parent_solution = SingletonSolution::::from_clvm(allocator, parent_solution)?; - let new_state = ActionLayer::::get_new_state( - allocator, - parent_info.state, - parent_solution.inner_solution, - )?; - - let new_info = parent_info.with_state(new_state); - - let new_coin = Coin::new(parent_coin.coin_id(), new_info.puzzle_hash().into(), 1); + let new_info = parent_registry + .info + .with_state(parent_registry.pending_spend.latest_state.1); + let new_coin = Coin::new( + parent_registry.coin.coin_id(), + new_info.puzzle_hash().into(), + 1, + ); Ok(Some(XchandlesRegistry { coin: new_coin, proof, info: new_info, - pending_items: XchandlesRegistryPendingItems::default(), + pending_spend: XchandlesPendingSpendInfo::new(new_info.state), })) } + pub fn child(&self, child_state: XchandlesRegistryState) -> Self { + let new_info = self.info.with_state(child_state); + let new_coin = Coin::new(self.coin.coin_id(), new_info.puzzle_hash().into(), 1); + + XchandlesRegistry { + coin: new_coin, + proof: Proof::Lineage(self.child_lineage_proof()), + info: new_info, + pending_spend: XchandlesPendingSpendInfo::new(new_info.state), + } + } + // Also returns initial registration asset id #[allow(clippy::type_complexity)] pub fn from_launcher_solution( @@ -190,7 +383,7 @@ impl XchandlesRegistry { coin: registry_coin, proof, info, - pending_items: XchandlesRegistryPendingItems::default(), + pending_spend: XchandlesPendingSpendInfo::new(info.state), }, slots, initial_registration_asset_id, @@ -304,152 +497,6 @@ impl XchandlesRegistry { Ok(state.1) } - pub async fn get_pending_items_from_spend( - &self, - ctx: &mut SpendContext, - solution: NodePtr, - ) -> Result { - let solution = ctx.extract::>(solution)?; - let inner_solution = ActionLayer::::parse_solution( - ctx, - solution.inner_solution, - )?; - - let mut actions: Vec = vec![]; - let mut spent_slots: Vec = vec![]; - let mut created_slots: Vec = vec![]; - - let expire_action = XchandlesExpireAction::from_constants(&self.info.constants); - let expire_action_hash = expire_action.tree_hash(); - - let extend_action = XchandlesExtendAction::from_constants(&self.info.constants); - let extend_action_hash = extend_action.tree_hash(); - - let oracle_action = XchandlesOracleAction::from_constants(&self.info.constants); - let oracle_action_hash = oracle_action.tree_hash(); - - let register_action = XchandlesRegisterAction::from_constants(&self.info.constants); - let register_action_hash = register_action.tree_hash(); - - let update_action = XchandlesUpdateAction::from_constants(&self.info.constants); - let update_action_hash = update_action.tree_hash(); - - let refund_action = XchandlesRefundAction::from_constants(&self.info.constants); - let refund_action_hash = refund_action.tree_hash(); - - let delegated_state_action = - >::from_constants( - &self.info.constants, - ); - let delegated_state_action_hash = delegated_state_action.tree_hash(); - - let mut current_state = (NodePtr::NIL, self.info.state); - for raw_action in inner_solution.action_spends { - actions.push(Spend::new(raw_action.puzzle, raw_action.solution)); - - let actual_solution = ctx.alloc(&clvm_list!(current_state, raw_action.solution))?; - - let action_output = - run_puzzle(ctx, raw_action.puzzle, actual_solution).map_err(DriverError::from)?; - (current_state, _) = ctx - .extract::( - action_output, - )?; - - let raw_action_hash = ctx.tree_hash(raw_action.puzzle); - - if raw_action_hash == delegated_state_action_hash { - // slots were not created or spent - continue; - } - - if raw_action_hash == extend_action_hash { - let spent_slot_value = XchandlesExtendAction::get_spent_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - let new_slot_value = XchandlesExtendAction::get_created_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - spent_slots.push(spent_slot_value); - created_slots.push(new_slot_value); - } else if raw_action_hash == oracle_action_hash { - let spent_slot_value = XchandlesOracleAction::get_spent_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - spent_slots.push(spent_slot_value.clone()); - created_slots.push(spent_slot_value); - } else if raw_action_hash == update_action_hash { - let spent_slot_value = XchandlesUpdateAction::get_spent_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - let new_slot_value = XchandlesUpdateAction::get_created_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - spent_slots.push(spent_slot_value); - created_slots.push(new_slot_value); - } else if raw_action_hash == refund_action_hash { - let Some(spent_slot_value) = - XchandlesRefundAction::get_spent_slot_value_from_solution( - ctx, - raw_action.solution, - )? - else { - continue; - }; - - spent_slots.push(spent_slot_value.clone()); - created_slots.push(spent_slot_value); - } else if raw_action_hash == expire_action_hash { - let spent_slot_value = XchandlesExpireAction::get_spent_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - let new_slot_value = XchandlesExpireAction::get_created_slot_value_from_solution( - ctx, - raw_action.solution, - )?; - - spent_slots.push(spent_slot_value); - created_slots.push(new_slot_value); - } else if raw_action_hash == register_action_hash { - // register - let spent_slot_values = - XchandlesRegisterAction::get_spent_slot_values_from_solution( - ctx, - raw_action.solution, - )?; - - let new_slot_values = - XchandlesRegisterAction::get_created_slot_values_from_solution( - ctx, - raw_action.solution, - )?; - - spent_slots.extend(spent_slot_values); - created_slots.extend(new_slot_values); - } else { - return Err(CliError::Custom("Unknown action".to_string())); - } - } - - Ok(XchandlesRegistryPendingItems { - actions, - spent_slots, - created_slots, - }) - } - pub fn actual_neigbors( &self, new_handle_hash: Bytes32, From 0da406c222c474f27eb374d5e0bcdc916f725fd3 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 12:53:20 +0300 Subject: [PATCH 10/65] registry error fix --- src/primitives/xchandles_registry.rs | 129 +++++++++++---------------- 1 file changed, 51 insertions(+), 78 deletions(-) diff --git a/src/primitives/xchandles_registry.rs b/src/primitives/xchandles_registry.rs index bb89eb43..9e2883c6 100644 --- a/src/primitives/xchandles_registry.rs +++ b/src/primitives/xchandles_registry.rs @@ -1,15 +1,12 @@ use chia::{ clvm_utils::ToTreeHash, - protocol::{Bytes, Bytes32, Coin, CoinSpend}, + protocol::{Bytes32, Coin, CoinSpend}, puzzles::{singleton::SingletonSolution, LineageProof, Proof}, }; use chia_puzzle_types::singleton::{LauncherSolution, SingletonArgs}; -use chia_wallet_sdk::{ - driver::{DriverError, Layer, Puzzle, Spend, SpendContext}, - types::run_puzzle, -}; -use clvm_traits::{clvm_list, match_tuple, FromClvm, ToClvm}; -use clvmr::{Allocator, NodePtr}; +use chia_wallet_sdk::driver::{DriverError, Layer, Puzzle, Spend, SpendContext}; +use clvm_traits::{clvm_list, match_tuple}; +use clvmr::NodePtr; use crate::{ eve_singleton_inner_puzzle, Action, ActionLayer, ActionLayerSolution, DelegatedStateAction, @@ -399,12 +396,13 @@ impl XchandlesRegistry { let puzzle = layers.construct_puzzle(ctx)?; let action_puzzle_hashes = self - .pending_items + .pending_spend .actions .iter() .map(|a| ctx.tree_hash(a.puzzle).into()) .collect::>(); + let child = self.child(self.pending_spend.latest_state.1); let solution = layers.construct_solution( ctx, SingletonSolution { @@ -420,7 +418,7 @@ impl XchandlesRegistry { .ok_or(DriverError::Custom( "Couldn't build proofs for one or more actions".to_string(), ))?, - action_spends: self.pending_items.actions, + action_spends: self.pending_spend.actions, finalizer_solution: NodePtr::NIL, }, }, @@ -429,27 +427,7 @@ impl XchandlesRegistry { let my_spend = Spend::new(puzzle, solution); ctx.spend(self.coin, my_spend)?; - let my_puzzle = Puzzle::parse(ctx, my_spend.puzzle); - let new_self = XchandlesRegistry::from_parent_spend( - ctx, - self.coin, - my_puzzle, - my_spend.solution, - self.info.constants, - )? - .ok_or(DriverError::Custom( - "Couldn't parse child registry".to_string(), - ))?; - - Ok(new_self) - } - - pub fn insert(&mut self, action_spend: Spend) { - self.pending_items.actions.push(action_spend); - } - - pub fn insert_multiple(&mut self, action_spends: Vec) { - self.pending_items.actions.extend(action_spends); + Ok(child) } pub fn new_action(&self) -> A @@ -459,42 +437,19 @@ impl XchandlesRegistry { A::from_constants(&self.info.constants) } - pub fn created_slot_values_to_slots( + pub fn created_slot_value_to_slot( &self, - slot_values: Vec, - ) -> Vec> { + slot_value: XchandlesSlotValue, + ) -> Slot { let proof = SlotProof { parent_parent_info: self.coin.parent_coin_info, parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), }; - slot_values - .into_iter() - .map(|slot_value| { - Slot::new( - proof, - SlotInfo::from_value(self.info.constants.launcher_id, 0, slot_value), - ) - }) - .collect() - } - - pub fn get_latest_pending_state( - &self, - allocator: &mut Allocator, - ) -> Result { - let mut state = (NodePtr::NIL, self.info.state); - - for action in self.pending_items.actions.iter() { - let actual_solution = clvm_list!(state, action.solution).to_clvm(allocator)?; - - let output = run_puzzle(allocator, action.puzzle, actual_solution)?; - (state, _) = ::from_clvm( - allocator, output, - )?; - } - - Ok(state.1) + Slot::new( + proof, + SlotInfo::from_value(self.info.constants.launcher_id, 0, slot_value), + ) } pub fn actual_neigbors( @@ -506,33 +461,51 @@ impl XchandlesRegistry { let mut left = on_chain_left_slot; let mut right = on_chain_right_slot; - let new_slot_value = XchandlesSlotValue::new( - new_handle_hash, - Bytes32::default(), - Bytes32::default(), - 0, - Bytes32::default(), - Bytes::default(), - ); - - for slot_value in self.pending_items.created_slots.iter() { - if slot_value.handle_hash < new_slot_value.handle_hash + for slot_value in self.pending_spend.created_slots.iter() { + if slot_value.handle_hash < new_handle_hash && slot_value.handle_hash >= left.info.value.handle_hash { - left = self - .created_slot_values_to_slots(vec![slot_value.clone()]) - .remove(0); + left = self.created_slot_value_to_slot(slot_value.clone()); } - if slot_value.handle_hash > new_slot_value.handle_hash + if slot_value.handle_hash > new_handle_hash && slot_value.handle_hash <= right.info.value.handle_hash { - right = self - .created_slot_values_to_slots(vec![slot_value.clone()]) - .remove(0); + right = self.created_slot_value_to_slot(slot_value.clone()); } } (left, right) } + + pub fn actual_slot(&self, slot: Slot) -> Slot { + let mut slot = slot; + for slot_value in self.pending_spend.created_slots.iter() { + if slot.info.value.handle_hash == slot_value.handle_hash { + slot = self.created_slot_value_to_slot(slot_value.clone()); + } + } + + slot + } + + pub fn insert_action_spend( + &mut self, + ctx: &mut SpendContext, + action_spend: Spend, + ) -> Result<(), DriverError> { + let res = Self::pending_info_delta_from_spend( + ctx, + action_spend, + self.pending_spend.latest_state, + self.info.constants, + )?; + + self.pending_spend.latest_state = res.0; + self.pending_spend.created_slots.extend(res.1); + self.pending_spend.spent_slots.extend(res.2); + self.pending_spend.actions.push(action_spend); + + Ok(()) + } } From 578dc62cf784e127f31b1be681bded5d14b84072 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 13:07:39 +0300 Subject: [PATCH 11/65] update actions to support RBF --- src/layers/actions/xchandles/expire.rs | 17 +++-------- src/layers/actions/xchandles/extend.rs | 18 ++++-------- src/layers/actions/xchandles/oracle.rs | 14 +++------ src/layers/actions/xchandles/refund.rs | 24 ++++----------- src/layers/actions/xchandles/register.rs | 37 ++++++------------------ src/layers/actions/xchandles/update.rs | 16 ++-------- 6 files changed, 30 insertions(+), 96 deletions(-) diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index f4a3e31b..277946c2 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -142,6 +142,7 @@ impl XchandlesExpireAction { )?; // spend self + let slot = registry.actual_slot(slot); let action_solution = XchandlesExpireActionSolution { cat_maker_puzzle_reveal: DefaultCatMakerArgs::get_puzzle( ctx, @@ -177,18 +178,10 @@ impl XchandlesExpireAction { .to_clvm(ctx)?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); - let new_slot_value = Self::get_created_slot_value_from_solution(ctx, action_solution)?; - registry - .pending_items - .created_slots - .push(new_slot_value.clone()); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; + let new_slot_value = Self::created_slot_value(ctx, action_solution)?; // spend slot - registry - .pending_items - .spent_slots - .push(slot.info.value.clone()); slot.spend(ctx, my_inner_puzzle_hash)?; let mut expire_ann: Vec = expire_ann.to_vec(); @@ -196,9 +189,7 @@ impl XchandlesExpireAction { Ok(( Conditions::new() .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, expire_ann)), - registry - .created_slot_values_to_slots(vec![new_slot_value.clone()]) - .remove(0), + registry.created_slot_value_to_slot(new_slot_value.clone()), )) } } diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index 0d855042..d1aff4c3 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -123,6 +123,8 @@ impl XchandlesExtendAction { base_handle_price, registration_period, )?; + + let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&XchandlesExtendActionSolution { pricing_puzzle_reveal, pricing_solution: XchandlesFactorPricingSolution { @@ -137,7 +139,7 @@ impl XchandlesExtendAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; let renew_amount = XchandlesFactorPricingPuzzleArgs::get_price(base_handle_price, &handle, num_periods); @@ -154,28 +156,18 @@ impl XchandlesExtendAction { }; // spend slot - registry - .pending_items - .spent_slots - .push(slot.info.value.clone()); slot.spend(ctx, spender_inner_puzzle_hash)?; let mut extend_ann: Vec = clvm_tuple!(renew_amount, handle).tree_hash().to_vec(); extend_ann.insert(0, b'e'); - let new_slot_value = Self::get_created_slot_value_from_solution(ctx, action_solution)?; - registry - .pending_items - .created_slots - .push(new_slot_value.clone()); + let new_slot_value = Self::created_slot_value(ctx, action_solution)?; Ok(( notarized_payment, Conditions::new() .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, extend_ann)), - registry - .created_slot_values_to_slots(vec![new_slot_value]) - .remove(0), + registry.created_slot_value_to_slot(new_slot_value.clone()), )) } } diff --git a/src/layers/actions/xchandles/oracle.rs b/src/layers/actions/xchandles/oracle.rs index 9f6a52ff..866b27c9 100644 --- a/src/layers/actions/xchandles/oracle.rs +++ b/src/layers/actions/xchandles/oracle.rs @@ -62,19 +62,15 @@ impl XchandlesOracleAction { slot: Slot, ) -> Result<(Conditions, Slot), DriverError> { // spend self + let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&slot.info.value)?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot = Self::get_created_slot_value(slot.info.value.clone()); - registry.pending_items.created_slots.push(new_slot.clone()); + let new_slot = Self::created_slot_value(slot.info.value.clone()); // spend slot - registry - .pending_items - .spent_slots - .push(slot.info.value.clone()); slot.spend(ctx, registry.info.inner_puzzle_hash().into())?; let mut oracle_ann = new_slot.tree_hash().to_vec(); @@ -82,9 +78,7 @@ impl XchandlesOracleAction { Ok(( Conditions::new() .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, oracle_ann)), - registry - .created_slot_values_to_slots(vec![new_slot.clone()]) - .remove(0), + registry.created_slot_value_to_slot(new_slot.clone()), )) } } diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index f59a1b5d..166bf136 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -96,6 +96,7 @@ impl XchandlesRefundAction { )?; // spend self + let slot = slot.map(|s| registry.actual_slot(s)); let action_solution = XchandlesRefundActionSolution { precommited_cat_maker_reveal: DefaultCatMakerArgs::get_puzzle( ctx, @@ -123,31 +124,16 @@ impl XchandlesRefundAction { .to_clvm(ctx)?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot_value = if let Some(slot) = &slot { - let slot_value = slot.info.value.clone(); - - registry - .pending_items - .created_slots - .push(slot_value.clone()); - - Some( - registry - .created_slot_values_to_slots(vec![slot_value.clone()]) - .remove(0), - ) + let new_slot = if let Some(slot) = &slot { + Some(registry.created_slot_value_to_slot(slot.info.value.clone())) } else { None }; // if there's a slot, spend it if let Some(slot) = slot { - registry - .pending_items - .spent_slots - .push(slot.info.value.clone()); slot.spend(ctx, my_inner_puzzle_hash)?; } @@ -156,7 +142,7 @@ impl XchandlesRefundAction { registry.coin.puzzle_hash, refund_announcement, )), - new_slot_value, + new_slot, )) } } diff --git a/src/layers/actions/xchandles/register.rs b/src/layers/actions/xchandles/register.rs index 095d6421..242c449b 100644 --- a/src/layers/actions/xchandles/register.rs +++ b/src/layers/actions/xchandles/register.rs @@ -148,6 +148,7 @@ impl XchandlesRegisterAction { ) -> Result<(Conditions, [Slot; 3]), DriverError> { let handle: String = precommit_coin.value.handle.clone(); let handle_hash: Bytes32 = handle.tree_hash().into(); + let (left_slot, right_slot) = registry.actual_neigbors(handle_hash, left_slot, right_slot); let secret = precommit_coin.value.secret; let start_time = precommit_coin.value.start_time; @@ -206,45 +207,25 @@ impl XchandlesRegisterAction { .to_clvm(ctx)?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; // spend slots - registry - .pending_items - .spent_slots - .push(left_slot.info.value.clone()); - registry - .pending_items - .spent_slots - .push(right_slot.info.value.clone()); - left_slot.spend(ctx, my_inner_puzzle_hash)?; right_slot.spend(ctx, my_inner_puzzle_hash)?; - let new_slots_values = Self::get_created_slot_values_from_solution(ctx, action_solution)?; - - registry - .pending_items - .created_slots - .push(new_slots_values[0].clone()); - registry - .pending_items - .created_slots - .push(new_slots_values[1].clone()); - registry - .pending_items - .created_slots - .push(new_slots_values[2].clone()); + let [new_left_slot, new_slot, new_right_slot] = + Self::created_slot_values(ctx, action_solution)?; Ok(( Conditions::new().assert_puzzle_announcement(announcement_id( registry.coin.puzzle_hash, register_announcement, )), - registry - .created_slot_values_to_slots(new_slots_values.to_vec()) - .try_into() - .unwrap(), + [ + registry.created_slot_value_to_slot(new_left_slot), + registry.created_slot_value_to_slot(new_slot), + registry.created_slot_value_to_slot(new_right_slot), + ], )) } } diff --git a/src/layers/actions/xchandles/update.rs b/src/layers/actions/xchandles/update.rs index cd84062b..caa66ca1 100644 --- a/src/layers/actions/xchandles/update.rs +++ b/src/layers/actions/xchandles/update.rs @@ -75,6 +75,7 @@ impl XchandlesUpdateAction { announcer_inner_puzzle_hash: Bytes32, ) -> Result<(Conditions, Slot), DriverError> { // spend self + let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&XchandlesUpdateActionSolution { current_slot_value: slot.info.value.clone(), new_data: XchandlesDataValue { @@ -85,7 +86,7 @@ impl XchandlesUpdateAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert(Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution)); let new_slot_value = slot .info @@ -93,11 +94,6 @@ impl XchandlesUpdateAction { .clone() .with_data(new_owner_launcher_id, new_resolved_data.clone()); - registry - .pending_items - .created_slots - .push(new_slot_value.clone()); - // spend slot let my_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); @@ -108,10 +104,6 @@ impl XchandlesUpdateAction { .tree_hash() .into(); - registry - .pending_items - .spent_slots - .push(slot.info.value.clone()); slot.spend(ctx, my_inner_puzzle_hash)?; Ok(( @@ -120,9 +112,7 @@ impl XchandlesUpdateAction { msg.into(), vec![ctx.alloc(®istry.coin.puzzle_hash)?], ), - registry - .created_slot_values_to_slots(vec![new_slot_value.clone()]) - .remove(0), + registry.created_slot_value_to_slot(new_slot_value), )) } } From 3dfabeea5c72000da3530c14a854093f1fe93dbe Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 13:14:10 +0300 Subject: [PATCH 12/65] update quick sync to support mempool --- src/cli/xchandles/quick_sync.rs | 70 ++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/cli/xchandles/quick_sync.rs b/src/cli/xchandles/quick_sync.rs index ef35d06b..f5cde4b9 100644 --- a/src/cli/xchandles/quick_sync.rs +++ b/src/cli/xchandles/quick_sync.rs @@ -1,9 +1,8 @@ use chia::protocol::{Bytes32, CoinSpend}; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{Puzzle, SpendContext}, + driver::SpendContext, }; -use clvmr::serde::node_from_bytes; use crate::{CliError, Db, XchandlesRegistry}; @@ -73,36 +72,53 @@ pub async fn quick_sync_xchandles( ))?; let mut temp_ctx = SpendContext::new(); - let puzzle_ptr = node_from_bytes(&mut temp_ctx, &next_spend.puzzle_reveal)?; - let puzzle = Puzzle::parse(&temp_ctx, puzzle_ptr); - let solution_ptr = node_from_bytes(&mut temp_ctx, &next_spend.solution)?; - - let xchandles_maybe = XchandlesRegistry::from_parent_spend( - &mut temp_ctx, - next_spend.coin, - puzzle, - solution_ptr, - constants, - ) - .unwrap_or_default(); - if xchandles_maybe.is_some() { + if let Ok(Some(_xchandles_maybe)) = + XchandlesRegistry::from_parent_spend(&mut temp_ctx, &next_spend, constants) + { coin_spend = Some(next_spend); break; } } - if let Some(coin_spend) = coin_spend { - let puzzle_ptr = node_from_bytes(ctx, &coin_spend.puzzle_reveal)?; - let puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = node_from_bytes(ctx, &coin_spend.solution)?; + let coin_spend = coin_spend.ok_or(CliError::Custom( + "Could not find XCHandles registry".to_string(), + ))?; - XchandlesRegistry::from_parent_spend(ctx, coin_spend.coin, puzzle, solution_ptr, constants)? - .ok_or(CliError::Custom( - "Tried to unwrap XCHandles but couldn't".to_string(), - )) - } else { - Err(CliError::Custom( - "Could not find XCHandles registry".to_string(), - )) + let on_chain_registry = XchandlesRegistry::from_parent_spend(ctx, &coin_spend, constants)? + .ok_or(CliError::Custom( + "Could not parse latest XCHandles registry".to_string(), + ))?; + + let Some(mut mempool_items) = client + .get_mempool_items_by_coin_name(on_chain_registry.coin.coin_id()) + .await? + .mempool_items + else { + return Ok(on_chain_registry); + }; + + if mempool_items.is_empty() { + return Ok(on_chain_registry); } + + let mempool_item = mempool_items.remove(0); + let mut registry = on_chain_registry; + loop { + let Some(registry_spend) = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|c| c.coin.coin_id() == registry.coin.coin_id()) + else { + break; + }; + + let Some(new_registry) = XchandlesRegistry::from_spend(ctx, registry_spend, constants)? + else { + break; + }; + registry = new_registry; + } + + Ok(registry) } From 596a2596ae2f85dd21bffe9857b9f5675fc66463 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 14:03:40 +0300 Subject: [PATCH 13/65] so much better sync --- src/cli/catalog/quick_sync.rs | 34 +-- src/cli/catalog/sync.rs | 309 ++++++++++++-------- src/cli/xchandles/sync.rs | 92 +++--- src/cli/xchandles/unroll_state_scheduler.rs | 2 +- src/cli/xchandles/verify_deployment.rs | 13 +- 5 files changed, 244 insertions(+), 206 deletions(-) diff --git a/src/cli/catalog/quick_sync.rs b/src/cli/catalog/quick_sync.rs index 1dcbb747..fc3ae859 100644 --- a/src/cli/catalog/quick_sync.rs +++ b/src/cli/catalog/quick_sync.rs @@ -4,7 +4,7 @@ use chia_wallet_sdk::{ driver::SpendContext, }; -use crate::{CatalogRegistry, CatalogRegistryConstants, CliError}; +use crate::{mempool_catalog_maybe, CatalogRegistry, CatalogRegistryConstants, CliError}; pub async fn quick_sync_catalog( client: &CoinsetClient, @@ -56,35 +56,5 @@ pub async fn quick_sync_catalog( CliError::Custom("Could not parse CATalog spend".to_string()), )?; - let Some(mut mempool_items) = client - .get_mempool_items_by_coin_name(on_chain_catalog.coin.coin_id()) - .await? - .mempool_items - else { - return Ok(on_chain_catalog); - }; - - if mempool_items.is_empty() { - return Ok(on_chain_catalog); - } - - let mempool_item = mempool_items.remove(0); - let mut catalog = on_chain_catalog; - loop { - let Some(catalog_spend) = mempool_item - .spend_bundle - .coin_spends - .iter() - .find(|c| c.coin.coin_id() == catalog.coin.coin_id()) - else { - break; - }; - - let Some(new_catalog) = CatalogRegistry::from_spend(ctx, catalog_spend, constants)? else { - break; - }; - catalog = new_catalog; - } - - Ok(catalog) + mempool_catalog_maybe(ctx, on_chain_catalog, client).await } diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index c3b85f22..c6f57eab 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -6,8 +6,8 @@ use chia::{ puzzles::{singleton::LauncherSolution, LineageProof, Proof}, }; use chia_wallet_sdk::{ - coinset::{ChiaRpcClient, CoinRecord, CoinsetClient}, - driver::{Layer, Puzzle, SingletonLayer, SpendContext}, + coinset::{ChiaRpcClient, CoinsetClient}, + driver::{DriverError, Layer, Puzzle, SingletonLayer, SpendContext}, types::{Condition, Conditions}, }; use clvmr::NodePtr; @@ -23,123 +23,67 @@ pub async fn sync_catalog( ctx: &mut SpendContext, constants: CatalogRegistryConstants, ) -> Result { - let last_unspent_coin_info = db - .get_last_unspent_singleton_coin(constants.launcher_id) - .await?; + let (mut catalog, mut skip_save): (CatalogRegistry, bool) = + if let Some((_coin_id, parent_coin_id)) = db + .get_last_unspent_singleton_coin(constants.launcher_id) + .await? + { + let parent_record = client + .get_coin_record_by_name(parent_coin_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(parent_coin_id))?; - let last_spent_coin_id: Bytes32 = - if let Some((_coin_id, parent_coin_id)) = last_unspent_coin_info { - parent_coin_id - } else { - constants.launcher_id - }; + let parent_spend = client + .get_puzzle_and_solution(parent_coin_id, Some(parent_record.spent_block_index)) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(parent_coin_id))?; - let mut last_coin_id = last_spent_coin_id; - let mut catalog: Option = None; - loop { - let coin_record_response = client.get_coin_record_by_name(last_coin_id).await?; - let Some(coin_record) = coin_record_response.coin_record else { - return Err(CliError::CoinNotFound(last_coin_id)); - }; - if !coin_record.spent { - break; - } - - let skip_db_save = last_coin_id == last_spent_coin_id; - if !skip_db_save { - db.save_singleton_coin(constants.launcher_id, coin_record) - .await?; - } - - let puzzle_and_solution_resp = client - .get_puzzle_and_solution( - coin_record.coin.coin_id(), - Some(coin_record.spent_block_index), + ( + CatalogRegistry::from_parent_spend(ctx, &parent_spend, constants)?.ok_or( + CliError::Custom("Could not parse latest spent CATalog registry".to_string()), + )?, + false, ) - .await?; - let Some(coin_spend) = puzzle_and_solution_resp.coin_solution else { - return Err(CliError::CoinNotSpent(last_coin_id)); - }; - - if !skip_db_save { - if let Some(ref prev_catalog) = catalog { - for slot_value in prev_catalog.pending_spend.spent_slots.iter() { - let asset_id = slot_value.asset_id; - - if let Some(previous_value_hash) = - db.get_catalog_indexed_slot_value(asset_id).await? - { - db.mark_slot_as_spent( - constants.launcher_id, - 0, - previous_value_hash, - coin_record.spent_block_index, - ) - .await?; - } - } - - let mut processed_values = HashSet::::new(); - for slot_value in prev_catalog.pending_spend.spent_slots.iter() { - let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); - if processed_values.contains(&slot_value_hash) { - continue; - } - processed_values.insert(slot_value_hash); - - // same slot can be created and spent mutliple times in the same block - let no_spent = prev_catalog - .pending_spend - .spent_slots - .iter() - .filter(|sv| sv == &slot_value) - .count(); - let no_created = prev_catalog - .pending_spend - .created_slots - .iter() - .filter(|sv| sv == &slot_value) - .count(); - if no_spent != no_created { - continue; - } + } else { + // No result -> sync from launcher + let launcher_record = client + .get_coin_record_by_name(constants.launcher_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(constants.launcher_id))?; - db.save_catalog_indexed_slot_value(slot_value.asset_id, slot_value_hash) - .await?; - db.save_slot(ctx, prev_catalog.created_slot_value_to_slot(*slot_value), 0) - .await?; - } - } - } + let launcher_spend = client + .get_puzzle_and_solution( + constants.launcher_id, + Some(launcher_record.spent_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(constants.launcher_id))?; - if let Some(some_catalog) = CatalogRegistry::from_parent_spend(ctx, &coin_spend, constants)? - { - last_coin_id = some_catalog.coin.coin_id(); - catalog = Some(some_catalog); - } else if coin_record.coin.coin_id() == constants.launcher_id { - let solution_ptr = ctx.alloc(&coin_spend.solution)?; + let solution_ptr = ctx.alloc(&launcher_spend.solution)?; let solution = ctx.extract::>(solution_ptr)?; let catalog_eve_coin = Coin::new(constants.launcher_id, solution.singleton_puzzle_hash, 1); let catalog_eve_coin_id = catalog_eve_coin.coin_id(); - let eve_coin_puzzle_and_solution_resp = client + let eve_coin_spend = client .get_puzzle_and_solution( catalog_eve_coin_id, - Some(coin_record.confirmed_block_index), + Some(launcher_record.confirmed_block_index), ) - .await?; - let Some(eve_coin_spend) = eve_coin_puzzle_and_solution_resp.coin_solution else { - break; - }; + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(catalog_eve_coin_id))?; let eve_coin_puzzle_ptr = ctx.alloc(&eve_coin_spend.puzzle_reveal)?; let eve_coin_puzzle = Puzzle::parse(ctx, eve_coin_puzzle_ptr); - let Some(eve_coin_puzzle) = - SingletonLayer::::parse_puzzle(ctx, eve_coin_puzzle)? - else { - break; - }; + let eve_coin_puzzle = SingletonLayer::::parse_puzzle(ctx, eve_coin_puzzle)? + .ok_or(DriverError::Custom( + "Could not parse eve CATalog coin puzzle".to_string(), + ))?; let eve_coin_inner_puzzle_hash = tree_hash(ctx, eve_coin_puzzle.inner_puzzle); @@ -157,7 +101,9 @@ pub async fn sync_catalog( } }) else { - break; + return Err(CliError::Custom( + "Could not find odd create coin in CATalog eve coin".to_string(), + )); }; let (decoded_launcher_id, (_decoded_asset_id, (initial_state, ()))) = @@ -165,7 +111,7 @@ pub async fn sync_catalog( odd_create_coin.memos.unwrap().value, )?; if decoded_launcher_id != constants.launcher_id { - break; + return Err(CliError::Custom("CATalog launcher ID mismatch".to_string())); } let new_coin = Coin::new( @@ -221,31 +167,142 @@ pub async fn sync_catalog( ) .await?; - db.save_singleton_coin( - constants.launcher_id, - CoinRecord { - coin: new_coin, - coinbase: false, - confirmed_block_index: coin_record.spent_block_index, - spent: false, - spent_block_index: 0, - timestamp: 0, - }, - ) - .await?; + // do NOT save eve coin - we're going through this path until + // first CATalog is spent + // db.save_singleton_coin( + // constants.launcher_id, + // CoinRecord { + // coin: new_coin, + // coinbase: false, + // confirmed_block_index: launcher_record.confirmed_block_index, + // spent: false, + // spent_block_index: 0, + // timestamp: 0, + // }, + // ) + // .await?; + + (new_catalog, true) + }; + + loop { + let coin_record = client + .get_coin_record_by_name(catalog.coin.coin_id()) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(catalog.coin.coin_id()))?; - last_coin_id = new_catalog.coin.coin_id(); - catalog = Some(new_catalog); - } else if coin_record.coin.parent_coin_info == constants.launcher_id { - last_coin_id = constants.launcher_id; + if skip_save { + skip_save = false; } else { + db.save_singleton_coin(constants.launcher_id, coin_record) + .await?; + } + + if !coin_record.spent { break; - }; + } + + let coin_spend = client + .get_puzzle_and_solution( + coin_record.coin.coin_id(), + Some(coin_record.spent_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.coin_id()))?; + + catalog = CatalogRegistry::from_spend(ctx, &coin_spend, constants)?.ok_or( + CliError::Custom("Could not parse new CATalog registry spend".to_string()), + )?; + + for slot_value in catalog.pending_spend.spent_slots.iter() { + let asset_id = slot_value.asset_id; + + if let Some(previous_value_hash) = db.get_catalog_indexed_slot_value(asset_id).await? { + db.mark_slot_as_spent( + constants.launcher_id, + 0, + previous_value_hash, + coin_record.spent_block_index, + ) + .await?; + } + } + + let mut processed_values = HashSet::::new(); + for slot_value in catalog.pending_spend.spent_slots.iter() { + let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); + if processed_values.contains(&slot_value_hash) { + continue; + } + processed_values.insert(slot_value_hash); + + // same slot can be created and spent mutliple times in the same block + let no_spent = catalog + .pending_spend + .spent_slots + .iter() + .filter(|sv| sv == &slot_value) + .count(); + let no_created = catalog + .pending_spend + .created_slots + .iter() + .filter(|sv| sv == &slot_value) + .count(); + if no_spent != no_created { + continue; + } + + db.save_catalog_indexed_slot_value(slot_value.asset_id, slot_value_hash) + .await?; + db.save_slot(ctx, catalog.created_slot_value_to_slot(*slot_value), 0) + .await?; + } + + catalog = catalog.child(catalog.pending_spend.latest_state.1); + } + + mempool_catalog_maybe(ctx, catalog, client).await +} + +pub async fn mempool_catalog_maybe( + ctx: &mut SpendContext, + on_chain_catalog: CatalogRegistry, + client: &CoinsetClient, +) -> Result { + let Some(mut mempool_items) = client + .get_mempool_items_by_coin_name(on_chain_catalog.coin.coin_id()) + .await? + .mempool_items + else { + return Ok(on_chain_catalog); + }; + + if mempool_items.is_empty() { + return Ok(on_chain_catalog); } - if let Some(catalog) = catalog { - Ok(catalog) - } else { - Err(CliError::CoinNotFound(last_coin_id)) + let mempool_item = mempool_items.remove(0); + let mut catalog = on_chain_catalog; + loop { + let Some(catalog_spend) = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|c| c.coin.coin_id() == catalog.coin.coin_id()) + else { + break; + }; + + let Some(new_catalog) = + CatalogRegistry::from_spend(ctx, catalog_spend, catalog.info.constants)? + else { + break; + }; + catalog = new_catalog; } + + Ok(catalog) } diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index dd3e356f..5cfc6d0a 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use chia::{clvm_utils::ToTreeHash, protocol::Bytes32}; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinRecord, CoinsetClient}, @@ -48,42 +50,6 @@ pub async fn sync_xchandles( return Err(CliError::CoinNotSpent(last_coin_id)); }; - let puzzle_ptr = ctx.alloc(&coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = ctx.alloc(&coin_spend.solution)?; - if !skip_db_save { - if let Some(ref prev_registry) = registry { - let pending_items = prev_registry - .get_pending_items_from_spend(ctx, solution_ptr) - .await?; - - for value in pending_items.spent_slots.iter() { - db.mark_slot_as_spent( - launcher_id, - 0, - value.tree_hash().into(), - coin_record.spent_block_index, - ) - .await?; - - // no need to actually delete handle indexed value, as - // all actions will overwrite (not remove) the handle - // from the list - } - - for slot in prev_registry.created_slot_values_to_slots(pending_items.created_slots) - { - db.save_xchandles_indexed_slot_value( - slot.info.launcher_id, - slot.info.value.handle_hash, - slot.info.value_hash, - ) - .await?; - db.save_slot(ctx, slot, 0).await?; - } - } - } - if coin_record.coin.coin_id() == launcher_id { let Some(( new_registry, @@ -166,6 +132,60 @@ pub async fn sync_xchandles( } }; + let registry = XchandlesRegistry::from_spend(ctx, &coin_spend, constants)?; + if !skip_db_save { + if let Some(ref prev_registry) = registry { + for value in prev_registry.pending_spend.spent_slots { + db.mark_slot_as_spent( + launcher_id, + 0, + value.tree_hash().into(), + coin_record.spent_block_index, + ) + .await?; + + // no need to actually delete handle indexed value, as + // all actions will overwrite (not remove) the handle + // from the list + } + + let mut processed_values = HashSet::::new(); + for slot_value in prev_registry.pending_spend.created_slots { + let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); + if processed_values.contains(&slot_value_hash) { + continue; + } + processed_values.insert(slot_value_hash); + + // same slot can be created and spent mutliple times in the same block + let no_spent = prev_registry + .pending_spend + .spent_slots + .iter() + .filter(|sv| sv.tree_hash().into() == slot_value_hash) + .count(); + let no_created = prev_registry + .pending_spend + .created_slots + .iter() + .filter(|sv| sv.tree_hash().into() == slot_value_hash) + .count(); + if no_spent != no_created { + continue; + } + + db.save_xchandles_indexed_slot_value( + prev_registry.info.constants.launcher_id, + slot_value.handle_hash, + slot_value_hash, + ) + .await?; + db.save_slot(ctx, prev_registry.created_slot_value_to_slot(slot_value), 0) + .await?; + } + } + } + if let Some(some_registry) = XchandlesRegistry::from_parent_spend( ctx, coin_record.coin, diff --git a/src/cli/xchandles/unroll_state_scheduler.rs b/src/cli/xchandles/unroll_state_scheduler.rs index c2540e3d..f34364c6 100644 --- a/src/cli/xchandles/unroll_state_scheduler.rs +++ b/src/cli/xchandles/unroll_state_scheduler.rs @@ -124,7 +124,7 @@ pub async fn xchandles_unroll_state_scheduler( new_state, state_scheduler.info.inner_puzzle_hash().into(), )?; - registry.insert(registry_action_spend); + registry.insert_action_spend(&mut ctx, registry_action_spend)?; let registry_inner_ph = registry.info.inner_puzzle_hash(); let _new_registry = registry.finish_spend(&mut ctx)?; diff --git a/src/cli/xchandles/verify_deployment.rs b/src/cli/xchandles/verify_deployment.rs index 8f841f7e..41170616 100644 --- a/src/cli/xchandles/verify_deployment.rs +++ b/src/cli/xchandles/verify_deployment.rs @@ -2,7 +2,7 @@ use chia::clvm_utils::ToTreeHash; use chia_puzzle_types::singleton::SingletonSolution; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Layer, Puzzle, SpendContext}, + driver::{Layer, SpendContext}, utils::Address, }; use clvmr::{serde::node_from_bytes, NodePtr}; @@ -137,16 +137,7 @@ pub async fn xchandles_verify_deployment( handle_index += 1; } - let puzzle_ptr = node_from_bytes(&mut ctx, &coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(&ctx, puzzle_ptr); - registry = XchandlesRegistry::from_parent_spend( - &mut ctx, - registry.coin, - parent_puzzle, - solution, - registry.info.constants, - )? - .unwrap(); + registry = registry.child(registry.pending_spend.latest_state.1); } if handle_index < handles_to_launch.len() { From 21e51a5da318d5886fd6be6baa15570666acffac Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 14:16:01 +0300 Subject: [PATCH 14/65] more sync stuff --- src/cli/xchandles/quick_sync.rs | 35 +--- src/cli/xchandles/sync.rs | 327 +++++++++++++++++--------------- 2 files changed, 172 insertions(+), 190 deletions(-) diff --git a/src/cli/xchandles/quick_sync.rs b/src/cli/xchandles/quick_sync.rs index f5cde4b9..6146727f 100644 --- a/src/cli/xchandles/quick_sync.rs +++ b/src/cli/xchandles/quick_sync.rs @@ -4,7 +4,7 @@ use chia_wallet_sdk::{ driver::SpendContext, }; -use crate::{CliError, Db, XchandlesRegistry}; +use crate::{mempool_registry_maybe, CliError, Db, XchandlesRegistry}; pub async fn quick_sync_xchandles( client: &CoinsetClient, @@ -89,36 +89,5 @@ pub async fn quick_sync_xchandles( "Could not parse latest XCHandles registry".to_string(), ))?; - let Some(mut mempool_items) = client - .get_mempool_items_by_coin_name(on_chain_registry.coin.coin_id()) - .await? - .mempool_items - else { - return Ok(on_chain_registry); - }; - - if mempool_items.is_empty() { - return Ok(on_chain_registry); - } - - let mempool_item = mempool_items.remove(0); - let mut registry = on_chain_registry; - loop { - let Some(registry_spend) = mempool_item - .spend_bundle - .coin_spends - .iter() - .find(|c| c.coin.coin_id() == registry.coin.coin_id()) - else { - break; - }; - - let Some(new_registry) = XchandlesRegistry::from_spend(ctx, registry_spend, constants)? - else { - break; - }; - registry = new_registry; - } - - Ok(registry) + mempool_registry_maybe(ctx, on_chain_registry, client).await } diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index 5cfc6d0a..7d12dc5b 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -2,11 +2,11 @@ use std::collections::HashSet; use chia::{clvm_utils::ToTreeHash, protocol::Bytes32}; use chia_wallet_sdk::{ - coinset::{ChiaRpcClient, CoinRecord, CoinsetClient}, - driver::{Puzzle, SpendContext}, + coinset::{ChiaRpcClient, CoinsetClient}, + driver::SpendContext, }; -use crate::{CliError, Db, XchandlesConstants, XchandlesRegistry}; +use crate::{CliError, Db, XchandlesRegistry}; pub async fn sync_xchandles( client: &CoinsetClient, @@ -14,52 +14,47 @@ pub async fn sync_xchandles( ctx: &mut SpendContext, launcher_id: Bytes32, ) -> Result { - let last_unspent_coin_info = db.get_last_unspent_singleton_coin(launcher_id).await?; + let (mut registry, mut skip_save): (XchandlesRegistry, bool) = + if let (Some((_coin_id, parent_coin_id)), Some(constants)) = ( + db.get_last_unspent_singleton_coin(launcher_id).await?, + db.get_xchandles_configuration(ctx, launcher_id).await?, + ) { + let parent_record = client + .get_coin_record_by_name(parent_coin_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(parent_coin_id))?; - let last_spent_coin_id: Bytes32 = - if let Some((_coin_id, parent_coin_id)) = last_unspent_coin_info { - parent_coin_id - } else { - launcher_id - }; + let parent_spend = client + .get_puzzle_and_solution(parent_coin_id, Some(parent_record.spent_block_index)) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(parent_coin_id))?; - let mut last_coin_id = last_spent_coin_id; - let mut registry: Option = None; - let mut constants: Option = None; - loop { - let coin_record_response = client.get_coin_record_by_name(last_coin_id).await?; - let Some(coin_record) = coin_record_response.coin_record else { - return Err(CliError::CoinNotFound(last_coin_id)); - }; - if !coin_record.spent { - break; - } + ( + XchandlesRegistry::from_parent_spend(ctx, &parent_spend, constants)?.ok_or( + CliError::Custom("Could not parse latest spent CATalog registry".to_string()), + )?, + false, + ) + } else { + let launcher_record = client + .get_coin_record_by_name(launcher_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(launcher_id))?; - let skip_db_save = last_coin_id == last_spent_coin_id; - if !skip_db_save { - db.save_singleton_coin(launcher_id, coin_record).await?; - } + let launcher_spend = client + .get_puzzle_and_solution(launcher_id, Some(launcher_record.spent_block_index)) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(launcher_id))?; - let puzzle_and_solution_resp = client - .get_puzzle_and_solution( - coin_record.coin.coin_id(), - Some(coin_record.spent_block_index), - ) - .await?; - let Some(coin_spend) = puzzle_and_solution_resp.coin_solution else { - return Err(CliError::CoinNotSpent(last_coin_id)); - }; + let solution_ptr = ctx.alloc(&launcher_spend.solution)?; - if coin_record.coin.coin_id() == launcher_id { - let Some(( - new_registry, - initial_slots, - _initial_registration_asset_id, - _initial_base_price, - )) = XchandlesRegistry::from_launcher_solution(ctx, coin_record.coin, solution_ptr)? - else { - return Err(CliError::CoinNotFound(last_coin_id)); - }; + let (registry, initial_slots, _initial_registration_asset_id, _initial_base_price) = + XchandlesRegistry::from_launcher_solution(ctx, launcher_record.coin, solution_ptr)? + .ok_or(CliError::CoinNotFound(launcher_id))?; db.save_slot(ctx, initial_slots[0].clone(), 0).await?; db.save_xchandles_indexed_slot_value( @@ -77,132 +72,150 @@ pub async fn sync_xchandles( ) .await?; - db.save_singleton_coin( + // do NOT save eve coin in db + // db.save_singleton_coin( + // launcher_id, + // CoinRecord { + // coin: launcher_record.coin, + // coinbase: false, + // confirmed_block_index: launcher_record.spent_block_index, + // spent: false, + // spent_block_index: 0, + // timestamp: 0, + // }, + // ) + // .await?; + + (registry, true) + }; + + loop { + let coin_record = client + .get_coin_record_by_name(registry.coin.coin_id()) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(registry.coin.coin_id()))?; + + if skip_save { + skip_save = false; + } else { + db.save_singleton_coin(registry.info.constants.launcher_id, coin_record) + .await?; + } + + if !coin_record.spent { + break; + } + + let coin_spend = client + .get_puzzle_and_solution( + coin_record.coin.coin_id(), + Some(coin_record.spent_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.coin_id()))?; + + registry = XchandlesRegistry::from_spend(ctx, &coin_spend, registry.info.constants)? + .ok_or(CliError::Custom( + "Could not parse new XCHandles registry spend".to_string(), + ))?; + + for value in registry.pending_spend.spent_slots.iter() { + db.mark_slot_as_spent( launcher_id, - CoinRecord { - coin: new_registry.coin, - coinbase: false, - confirmed_block_index: coin_record.spent_block_index, - spent: false, - spent_block_index: 0, - timestamp: 0, - }, + 0, + value.tree_hash().into(), + coin_record.spent_block_index, ) .await?; - last_coin_id = new_registry.coin.coin_id(); - constants = Some(new_registry.info.constants); - registry = Some(new_registry); - continue; - } else if coin_record.coin.parent_coin_info == launcher_id { - last_coin_id = launcher_id; - continue; + // no need to actually delete handle indexed value, as + // all actions will overwrite (not remove) the handle + // from the list } - let constants = if let Some(cts) = constants { - cts - } else { - // look for constants from launcher spend - let launcher_record = client - .get_coin_record_by_name(launcher_id) - .await? - .coin_record - .ok_or(CliError::CoinNotFound(launcher_id))?; + let mut processed_values = HashSet::::new(); + for slot_value in registry.pending_spend.created_slots.iter() { + let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); + if processed_values.contains(&slot_value_hash) { + continue; + } + processed_values.insert(slot_value_hash); + + // same slot can be created and spent mutliple times in the same block + let no_spent = registry + .pending_spend + .spent_slots + .iter() + .filter(|sv| sv.tree_hash() == slot_value_hash.into()) + .count(); + let no_created = registry + .pending_spend + .created_slots + .iter() + .filter(|sv| sv.tree_hash() == slot_value_hash.into()) + .count(); + if no_spent != no_created { + continue; + } - let launcher_spend = client - .get_puzzle_and_solution(launcher_id, Some(launcher_record.spent_block_index)) - .await? - .coin_solution - .ok_or(CliError::CoinNotSpent(launcher_id))?; + db.save_xchandles_indexed_slot_value( + registry.info.constants.launcher_id, + slot_value.handle_hash, + slot_value_hash, + ) + .await?; + db.save_slot( + ctx, + registry.created_slot_value_to_slot(slot_value.clone()), + 0, + ) + .await?; + } - let solution_ptr = ctx.alloc(&launcher_spend.solution)?; + registry = registry.child(registry.pending_spend.latest_state.1); + } - if let Some(( - new_registry, - _initial_slots, - _initial_registration_asset_id, - _initial_base_price, - )) = - XchandlesRegistry::from_launcher_solution(ctx, launcher_record.coin, solution_ptr)? - { - constants = Some(new_registry.info.constants); - new_registry.info.constants - } else { - return Err(CliError::ConstantsNotSet); - } - }; + mempool_registry_maybe(ctx, registry, client).await +} - let registry = XchandlesRegistry::from_spend(ctx, &coin_spend, constants)?; - if !skip_db_save { - if let Some(ref prev_registry) = registry { - for value in prev_registry.pending_spend.spent_slots { - db.mark_slot_as_spent( - launcher_id, - 0, - value.tree_hash().into(), - coin_record.spent_block_index, - ) - .await?; - - // no need to actually delete handle indexed value, as - // all actions will overwrite (not remove) the handle - // from the list - } - - let mut processed_values = HashSet::::new(); - for slot_value in prev_registry.pending_spend.created_slots { - let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); - if processed_values.contains(&slot_value_hash) { - continue; - } - processed_values.insert(slot_value_hash); - - // same slot can be created and spent mutliple times in the same block - let no_spent = prev_registry - .pending_spend - .spent_slots - .iter() - .filter(|sv| sv.tree_hash().into() == slot_value_hash) - .count(); - let no_created = prev_registry - .pending_spend - .created_slots - .iter() - .filter(|sv| sv.tree_hash().into() == slot_value_hash) - .count(); - if no_spent != no_created { - continue; - } - - db.save_xchandles_indexed_slot_value( - prev_registry.info.constants.launcher_id, - slot_value.handle_hash, - slot_value_hash, - ) - .await?; - db.save_slot(ctx, prev_registry.created_slot_value_to_slot(slot_value), 0) - .await?; - } - } - } +pub async fn mempool_registry_maybe( + ctx: &mut SpendContext, + on_chain_registry: XchandlesRegistry, + client: &CoinsetClient, +) -> Result { + let Some(mut mempool_items) = client + .get_mempool_items_by_coin_name(on_chain_registry.coin.coin_id()) + .await? + .mempool_items + else { + return Ok(on_chain_registry); + }; + + if mempool_items.is_empty() { + return Ok(on_chain_registry); + } - if let Some(some_registry) = XchandlesRegistry::from_parent_spend( - ctx, - coin_record.coin, - parent_puzzle, - solution_ptr, - constants, - )? { - last_coin_id = some_registry.coin.coin_id(); - registry = Some(some_registry); - } else { + let mempool_item = mempool_items.remove(0); + let mut registry = on_chain_registry; + loop { + let Some(registry_spend) = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|c| c.coin.coin_id() == registry.coin.coin_id()) + else { break; }; - } - if let Some(registry) = registry { - Ok(registry) - } else { - Err(CliError::CoinNotFound(last_coin_id)) + let Some(new_registry) = + XchandlesRegistry::from_spend(ctx, registry_spend, registry.info.constants)? + else { + break; + }; + registry = new_registry; } + + Ok(registry) } From e08e50f9997bcca8668ba0bfee46fa8f7271007f Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 14:22:30 +0300 Subject: [PATCH 15/65] error in tests :| --- src/drivers.rs | 91 ++++++++++++++------------ src/layers/actions/xchandles/refund.rs | 8 +-- src/layers/actions/xchandles/update.rs | 2 +- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index 3e7ede99..95208c68 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1666,14 +1666,14 @@ mod tests { pricing_solution, slot, )?; - assert_eq!( - used_slot_value_hash, - XchandlesRefundAction::get_spent_slot_value_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1].solution - )? - .map(|s| s.tree_hash().into()) - ); + if let Some(used_slot_value_hash) = used_slot_value_hash { + assert_eq!( + used_slot_value_hash, + registry.pending_spend.spent_slots[registry.pending_spend.spent_slots.len() - 1] + .tree_hash() + .into() + ); + } let new_registry = registry.finish_spend(ctx)?; @@ -1977,7 +1977,7 @@ mod tests { delegated_state_action_solution.other_singleton_inner_puzzle_hash, )?; - registry.insert(action_spend); + registry.insert_action_spend(ctx, action_spend)?; registry = registry.finish_spend(ctx)?; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "update_price", &[user_bls.sk.clone()])?; @@ -1997,12 +1997,14 @@ mod tests { ensure_conditions_met(ctx, &mut sim, secure_cond.clone(), 1)?; assert_eq!( - spent_values, - XchandlesRegisterAction::get_spent_slot_values_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1] - .solution - )? + registry + .pending_spend + .spent_slots + .iter() + .rev() + .take(2) + .collect::>(), + spent_values.iter().collect::>(), ); registry = registry.finish_spend(ctx)?; sim.pass_time(100); // registration start was at timestamp 100 @@ -2030,13 +2032,14 @@ mod tests { assert_eq!( spent_slot_value_hash, - XchandlesOracleAction::get_spent_slot_value_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1] - .solution - )? - .tree_hash() - .into() + registry + .pending_spend + .spent_slots + .iter() + .next_back() + .unwrap() + .tree_hash() + .into() ); registry = registry.finish_spend(ctx)?; @@ -2067,13 +2070,14 @@ mod tests { assert_eq!( spent_slot_value_hash, - XchandlesExtendAction::get_spent_slot_value_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1] - .solution - )? - .tree_hash() - .into() + registry + .pending_spend + .spent_slots + .iter() + .next_back() + .unwrap() + .tree_hash() + .into() ); let payment_cat_inner_spend = minter_p2.spend_with_conditions( @@ -2144,13 +2148,14 @@ mod tests { assert_eq!( update_slot_value_hash, - XchandlesUpdateAction::get_spent_slot_value_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1] - .solution - )? - .tree_hash() - .into() + registry + .pending_spend + .spent_slots + .iter() + .next_back() + .unwrap() + .tree_hash() + .into() ); registry = registry.finish_spend(ctx)?; @@ -2271,12 +2276,14 @@ mod tests { assert_eq!( spent_slot_value_hash, - XchandlesExpireAction::get_spent_slot_value_from_solution( - ctx, - registry.pending_items.actions[registry.pending_items.actions.len() - 1].solution - )? - .tree_hash() - .into() + registry + .pending_spend + .spent_slots + .iter() + .next_back() + .unwrap() + .tree_hash() + .into() ); registry = registry.finish_spend(ctx)?; diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index 166bf136..d1fcf5dd 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -126,11 +126,9 @@ impl XchandlesRefundAction { registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot = if let Some(slot) = &slot { - Some(registry.created_slot_value_to_slot(slot.info.value.clone())) - } else { - None - }; + let new_slot = slot + .as_ref() + .map(|slot| registry.created_slot_value_to_slot(slot.info.value.clone())); // if there's a slot, spend it if let Some(slot) = slot { diff --git a/src/layers/actions/xchandles/update.rs b/src/layers/actions/xchandles/update.rs index caa66ca1..44d9dde3 100644 --- a/src/layers/actions/xchandles/update.rs +++ b/src/layers/actions/xchandles/update.rs @@ -86,7 +86,7 @@ impl XchandlesUpdateAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution)); + registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; let new_slot_value = slot .info From ace100f41165c39d25f4ef34c98e28a22dbacbb3 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 14:23:27 +0300 Subject: [PATCH 16/65] ez fix --- src/drivers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers.rs b/src/drivers.rs index 95208c68..37ea3529 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -2004,7 +2004,7 @@ mod tests { .rev() .take(2) .collect::>(), - spent_values.iter().collect::>(), + spent_values.iter().rev().collect::>(), ); registry = registry.finish_spend(ctx)?; sim.pass_time(100); // registration start was at timestamp 100 From 312a68fa089ebbc95e70e1817bcccce0a28f12c3 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 18:11:23 +0300 Subject: [PATCH 17/65] RewardDistributor::pending_info_delta_from_spend --- .../actions/reward_distributor/add_entry.rs | 3 +- .../reward_distributor/commit_incentives.rs | 29 ++- .../reward_distributor/initiate_payout.rs | 38 ++-- .../actions/reward_distributor/new_epoch.rs | 35 ++- .../reward_distributor/remove_entry.rs | 20 +- .../actions/reward_distributor/stake.rs | 3 +- .../actions/reward_distributor/unstake.rs | 20 +- .../reward_distributor/withdraw_incentives.rs | 44 ++-- src/primitives/reward_distributor.rs | 208 ++++++++++++++++-- 9 files changed, 279 insertions(+), 121 deletions(-) diff --git a/src/layers/actions/reward_distributor/add_entry.rs b/src/layers/actions/reward_distributor/add_entry.rs index 73687499..b5f69a76 100644 --- a/src/layers/actions/reward_distributor/add_entry.rs +++ b/src/layers/actions/reward_distributor/add_entry.rs @@ -58,8 +58,7 @@ impl RewardDistributorAddEntryAction { .map_err(DriverError::ToClvm) } - pub fn get_slot_value_from_solution( - &self, + pub fn created_slot_value( ctx: &SpendContext, state: &RewardDistributorState, solution: NodePtr, diff --git a/src/layers/actions/reward_distributor/commit_incentives.rs b/src/layers/actions/reward_distributor/commit_incentives.rs index aac0f454..df898447 100644 --- a/src/layers/actions/reward_distributor/commit_incentives.rs +++ b/src/layers/actions/reward_distributor/commit_incentives.rs @@ -52,9 +52,7 @@ impl RewardDistributorCommitIncentivesAction { .map_err(DriverError::ToClvm) } - #[allow(clippy::type_complexity)] - pub fn get_slot_values_from_solution( - &self, + pub fn created_slot_values( ctx: &SpendContext, epoch_seconds: u64, solution: NodePtr, @@ -62,7 +60,6 @@ impl RewardDistributorCommitIncentivesAction { ( RewardDistributorCommitmentSlotValue, Vec, - (RewardDistributorSlotNonce, Bytes32), // spent slot ), DriverError, > { @@ -107,18 +104,20 @@ impl RewardDistributorCommitIncentivesAction { } } - let spent_slot = ( - RewardDistributorSlotNonce::REWARD, - RewardDistributorRewardSlotValue { - epoch_start: solution.slot_epoch_time, - next_epoch_initialized: solution.slot_next_epoch_initialized, - rewards: solution.slot_total_rewards, - } - .tree_hash() - .into(), - ); + Ok((commitment_slot_value, reward_slot_values)) + } + + pub fn spent_slot_value( + ctx: &SpendContext, + solution: NodePtr, + ) -> Result { + let solution = ctx.extract::(solution)?; - Ok((commitment_slot_value, reward_slot_values, spent_slot)) + Ok(RewardDistributorRewardSlotValue { + epoch_start: solution.slot_epoch_time, + next_epoch_initialized: solution.slot_next_epoch_initialized, + rewards: solution.slot_total_rewards, + }) } #[allow(clippy::type_complexity)] diff --git a/src/layers/actions/reward_distributor/initiate_payout.rs b/src/layers/actions/reward_distributor/initiate_payout.rs index b2a49d72..4f9ada98 100644 --- a/src/layers/actions/reward_distributor/initiate_payout.rs +++ b/src/layers/actions/reward_distributor/initiate_payout.rs @@ -52,37 +52,31 @@ impl RewardDistributorInitiatePayoutAction { .map_err(DriverError::ToClvm) } - pub fn get_slot_value_from_solution( - &self, + pub fn created_slot_value( ctx: &SpendContext, - my_state: &RewardDistributorState, + current_state: &RewardDistributorState, solution: NodePtr, - ) -> Result< - ( - RewardDistributorEntrySlotValue, - (RewardDistributorSlotNonce, Bytes32), - ), - DriverError, - > { + ) -> Result { let solution = ctx.extract::(solution)?; - let new_slot = RewardDistributorEntrySlotValue { + Ok(RewardDistributorEntrySlotValue { payout_puzzle_hash: solution.entry_payout_puzzle_hash, - initial_cumulative_payout: my_state.round_reward_info.cumulative_payout, + initial_cumulative_payout: current_state.round_reward_info.cumulative_payout, shares: solution.entry_shares, - }; - let old_slot = RewardDistributorEntrySlotValue { + }) + } + + pub fn spent_slot_value( + ctx: &SpendContext, + solution: NodePtr, + ) -> Result { + let solution = ctx.extract::(solution)?; + + Ok(RewardDistributorEntrySlotValue { payout_puzzle_hash: solution.entry_payout_puzzle_hash, initial_cumulative_payout: solution.entry_initial_cumulative_payout, shares: solution.entry_shares, - }; - Ok(( - new_slot, - ( - RewardDistributorSlotNonce::ENTRY, - old_slot.tree_hash().into(), - ), - )) + }) } pub fn spend( diff --git a/src/layers/actions/reward_distributor/new_epoch.rs b/src/layers/actions/reward_distributor/new_epoch.rs index a4aefe71..e9d23a7d 100644 --- a/src/layers/actions/reward_distributor/new_epoch.rs +++ b/src/layers/actions/reward_distributor/new_epoch.rs @@ -60,31 +60,30 @@ impl RewardDistributorNewEpochAction { .map_err(DriverError::ToClvm) } - pub fn get_slot_value_from_solution( - &self, + pub fn created_slot_value( ctx: &SpendContext, solution: NodePtr, - ) -> Result< - ( - RewardDistributorRewardSlotValue, - (RewardDistributorSlotNonce, Bytes32), - ), - DriverError, - > { + ) -> Result { let solution = ctx.extract::(solution)?; - let slot_valie = RewardDistributorRewardSlotValue { + Ok(RewardDistributorRewardSlotValue { epoch_start: solution.slot_epoch_time, next_epoch_initialized: solution.slot_next_epoch_initialized, rewards: solution.slot_total_rewards, - }; - Ok(( - slot_valie, - ( - RewardDistributorSlotNonce::REWARD, - slot_valie.tree_hash().into(), - ), - )) + }) + } + + pub fn spent_slot_value( + ctx: &SpendContext, + solution: NodePtr, + ) -> Result { + let solution = ctx.extract::(solution)?; + + Ok(RewardDistributorRewardSlotValue { + epoch_start: solution.slot_epoch_time, + next_epoch_initialized: solution.slot_next_epoch_initialized, + rewards: solution.slot_total_rewards, + }) } pub fn spend( diff --git a/src/layers/actions/reward_distributor/remove_entry.rs b/src/layers/actions/reward_distributor/remove_entry.rs index 242cf84e..0e7d8acf 100644 --- a/src/layers/actions/reward_distributor/remove_entry.rs +++ b/src/layers/actions/reward_distributor/remove_entry.rs @@ -106,23 +106,17 @@ impl RewardDistributorRemoveEntryAction { Ok((remove_entry_conditions, entry_payout_amount)) } - pub fn get_spent_slot_value_from_solution( - &self, + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, - ) -> Result<(RewardDistributorSlotNonce, Bytes32), DriverError> { + ) -> Result { let solution = ctx.extract::(solution)?; - Ok(( - RewardDistributorSlotNonce::ENTRY, - RewardDistributorEntrySlotValue { - payout_puzzle_hash: solution.entry_payout_puzzle_hash, - initial_cumulative_payout: solution.entry_initial_cumulative_payout, - shares: solution.entry_shares, - } - .tree_hash() - .into(), - )) + Ok(RewardDistributorEntrySlotValue { + payout_puzzle_hash: solution.entry_payout_puzzle_hash, + initial_cumulative_payout: solution.entry_initial_cumulative_payout, + shares: solution.entry_shares, + }) } } diff --git a/src/layers/actions/reward_distributor/stake.rs b/src/layers/actions/reward_distributor/stake.rs index 49daed79..09f807bd 100644 --- a/src/layers/actions/reward_distributor/stake.rs +++ b/src/layers/actions/reward_distributor/stake.rs @@ -64,8 +64,7 @@ impl RewardDistributorStakeAction { .map_err(DriverError::ToClvm) } - pub fn get_slot_value_from_solution( - &self, + pub fn created_slot_value( ctx: &SpendContext, state: &RewardDistributorState, solution: NodePtr, diff --git a/src/layers/actions/reward_distributor/unstake.rs b/src/layers/actions/reward_distributor/unstake.rs index 2675e9ce..cb886dc8 100644 --- a/src/layers/actions/reward_distributor/unstake.rs +++ b/src/layers/actions/reward_distributor/unstake.rs @@ -58,23 +58,17 @@ impl RewardDistributorUnstakeAction { .map_err(DriverError::ToClvm) } - pub fn get_spent_slot_value_from_solution( - &self, + pub fn spent_slot_value( ctx: &SpendContext, solution: NodePtr, - ) -> Result<(RewardDistributorSlotNonce, Bytes32), DriverError> { + ) -> Result { let solution = ctx.extract::(solution)?; - Ok(( - RewardDistributorSlotNonce::ENTRY, - RewardDistributorEntrySlotValue { - payout_puzzle_hash: solution.entry_custody_puzzle_hash, - initial_cumulative_payout: solution.entry_initial_cumulative_payout, - shares: 1, - } - .tree_hash() - .into(), - )) + Ok(RewardDistributorEntrySlotValue { + payout_puzzle_hash: solution.entry_custody_puzzle_hash, + initial_cumulative_payout: solution.entry_initial_cumulative_payout, + shares: 1, + }) } pub fn spend( diff --git a/src/layers/actions/reward_distributor/withdraw_incentives.rs b/src/layers/actions/reward_distributor/withdraw_incentives.rs index 0da587e3..57a27145 100644 --- a/src/layers/actions/reward_distributor/withdraw_incentives.rs +++ b/src/layers/actions/reward_distributor/withdraw_incentives.rs @@ -52,51 +52,49 @@ impl RewardDistributorWithdrawIncentivesAction { .map_err(DriverError::ToClvm) } - pub fn get_slot_value_from_solution( - &self, + pub fn created_slot_value( + ctx: &SpendContext, + withdrawal_share_bps: u64, + solution: NodePtr, + ) -> Result { + let solution = + ctx.extract::(solution)?; + let withdrawal_share = solution.committed_value * withdrawal_share_bps / 10000; + + let new_reward_slot_value = RewardDistributorRewardSlotValue { + epoch_start: solution.reward_slot_epoch_time, + next_epoch_initialized: solution.reward_slot_next_epoch_initialized, + rewards: solution.reward_slot_total_rewards - withdrawal_share, + }; + + Ok(new_reward_slot_value) + } + + pub fn spent_slot_values( ctx: &SpendContext, - my_constants: &RewardDistributorConstants, solution: NodePtr, ) -> Result< ( RewardDistributorRewardSlotValue, - [(RewardDistributorSlotNonce, Bytes32); 2], + RewardDistributorCommitmentSlotValue, ), DriverError, > { let solution = ctx.extract::(solution)?; - let withdrawal_share = solution.committed_value * my_constants.withdrawal_share_bps / 10000; let old_reward_slot_value = RewardDistributorRewardSlotValue { epoch_start: solution.reward_slot_epoch_time, next_epoch_initialized: solution.reward_slot_next_epoch_initialized, rewards: solution.reward_slot_total_rewards, }; - let new_reward_slot_value = RewardDistributorRewardSlotValue { - epoch_start: solution.reward_slot_epoch_time, - next_epoch_initialized: solution.reward_slot_next_epoch_initialized, - rewards: solution.reward_slot_total_rewards - withdrawal_share, - }; let commitment_slot_value = RewardDistributorCommitmentSlotValue { epoch_start: solution.reward_slot_epoch_time, clawback_ph: solution.clawback_ph, rewards: solution.committed_value, }; - Ok(( - new_reward_slot_value, - [ - ( - RewardDistributorSlotNonce::REWARD, - old_reward_slot_value.tree_hash().into(), - ), - ( - RewardDistributorSlotNonce::COMMITMENT, - commitment_slot_value.tree_hash().into(), - ), - ], - )) + Ok((old_reward_slot_value, commitment_slot_value)) } pub fn spend( diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index 982a4ded..cb2f495a 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -18,10 +18,11 @@ use clvmr::{Allocator, NodePtr}; use crate::{ Action, ActionLayer, ActionLayerSolution, RawActionLayerSolution, Registry, ReserveFinalizerSolution, RewardDistributorAddEntryAction, - RewardDistributorCommitIncentivesAction, RewardDistributorInitiatePayoutAction, - RewardDistributorNewEpochAction, RewardDistributorRemoveEntryAction, - RewardDistributorStakeAction, RewardDistributorUnstakeAction, - RewardDistributorWithdrawIncentivesAction, Slot, SlotInfo, SlotProof, + RewardDistributorAddIncentivesAction, RewardDistributorCommitIncentivesAction, + RewardDistributorInitiatePayoutAction, RewardDistributorNewEpochAction, + RewardDistributorRemoveEntryAction, RewardDistributorStakeAction, RewardDistributorSyncAction, + RewardDistributorUnstakeAction, RewardDistributorWithdrawIncentivesAction, Slot, SlotInfo, + SlotProof, }; use super::{ @@ -30,15 +31,50 @@ use super::{ RewardDistributorSlotNonce, RewardDistributorState, }; -#[derive(Debug, Clone, Default)] -pub struct RewardDistributorPendingItems { - pub pending_actions: Vec, +#[derive(Debug, Clone)] +pub struct RewardDistributorPendingSpendInfo { + pub actions: Vec, + + pub spent_reward_slots: Vec, + pub spent_commitment_slots: Vec, + pub spent_entry_slots: Vec, + + pub created_reward_slots: Vec, + pub created_commitment_slots: Vec, + pub created_entry_slots: Vec, + + pub latest_state: (NodePtr, RewardDistributorState), +} + +impl RewardDistributorPendingSpendInfo { + pub fn new(latest_state: RewardDistributorState) -> Self { + Self { + actions: vec![], + created_reward_slots: vec![], + created_commitment_slots: vec![], + created_entry_slots: vec![], + spent_reward_slots: vec![], + spent_commitment_slots: vec![], + spent_entry_slots: vec![], + latest_state: (NodePtr::NIL, latest_state), + } + } - pub pending_spent_slots: Vec<(RewardDistributorSlotNonce, Bytes32)>, // (nonce, value hash) + pub fn add_delta(&mut self, delta: RewardDistributorPendingSpendInfo) { + self.actions.extend(delta.actions); - pub pending_reward_slot_values: Vec, - pub pending_commitment_slot_values: Vec, - pub pending_entry_slot_values: Vec, + self.spent_reward_slots.extend(delta.spent_reward_slots); + self.spent_commitment_slots + .extend(delta.spent_commitment_slots); + self.spent_entry_slots.extend(delta.spent_entry_slots); + + self.created_reward_slots.extend(delta.created_reward_slots); + self.created_commitment_slots + .extend(delta.created_commitment_slots); + self.created_entry_slots.extend(delta.created_entry_slots); + + self.latest_state = delta.latest_state; + } } #[derive(Debug, Clone)] @@ -49,7 +85,7 @@ pub struct RewardDistributor { pub info: RewardDistributorInfo, pub reserve: Reserve, - pub pending_items: RewardDistributorPendingItems, + pub pending_items: RewardDistributorPendingSpendInfo, } impl RewardDistributor { @@ -59,12 +95,158 @@ impl RewardDistributor { proof, info, reserve, - pending_items: RewardDistributorPendingItems::default(), + pending_items: RewardDistributorPendingSpendInfo::new(info.state), } } } impl RewardDistributor { + #[allow(clippy::type_complexity)] + pub fn pending_info_delta_from_spend( + ctx: &mut SpendContext, + action_spend: Spend, + current_state_and_ephemeral: (NodePtr, RewardDistributorState), + constants: RewardDistributorConstants, + ) -> Result { + let mut spent_reward_slots: Vec = vec![]; + let mut spent_commitment_slots: Vec = vec![]; + let mut spent_entry_slots: Vec = vec![]; + + let mut created_reward_slots: Vec = vec![]; + let mut created_commitment_slots: Vec = vec![]; + let mut created_entry_slots: Vec = vec![]; + + let new_epoch_action = RewardDistributorNewEpochAction::from_constants(&constants); + let new_epoch_hash = new_epoch_action.tree_hash(); + + let commit_incentives_action = + RewardDistributorCommitIncentivesAction::from_constants(&constants); + let commit_incentives_hash = commit_incentives_action.tree_hash(); + + let add_entry_action = RewardDistributorAddEntryAction::from_constants(&constants); + let add_entry_hash = add_entry_action.tree_hash(); + + let remove_entry_action = RewardDistributorRemoveEntryAction::from_constants(&constants); + let remove_entry_hash = remove_entry_action.tree_hash(); + + let stake_action = RewardDistributorStakeAction::from_constants(&constants); + let stake_hash = stake_action.tree_hash(); + + let unstake_action = RewardDistributorUnstakeAction::from_constants(&constants); + let unstake_hash = unstake_action.tree_hash(); + + let withdraw_incentives_action = + RewardDistributorWithdrawIncentivesAction::from_constants(&constants); + let withdraw_incentives_hash = withdraw_incentives_action.tree_hash(); + + let initiate_payout_action = + RewardDistributorInitiatePayoutAction::from_constants(&constants); + let initiate_payout_hash = initiate_payout_action.tree_hash(); + + let add_incentives_action = + RewardDistributorAddIncentivesAction::from_constants(&constants); + let add_incentives_hash = add_incentives_action.tree_hash(); + + let sync_action = RewardDistributorSyncAction::from_constants(&constants); + let sync_hash = sync_action.tree_hash(); + + let actual_solution = ctx.alloc(&clvm_list!( + current_state_and_ephemeral, + action_spend.solution + ))?; + + let output = ctx.run(action_spend.puzzle, actual_solution)?; + let (new_state_and_ephemeral, _) = + ctx.extract::(output)?; + + let raw_action_hash = ctx.tree_hash(action_spend.puzzle); + + if raw_action_hash == new_epoch_hash { + created_reward_slots.push(RewardDistributorNewEpochAction::created_slot_value( + ctx, + action_spend.solution, + )?); + spent_reward_slots.push(RewardDistributorNewEpochAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == commit_incentives_hash { + let (comm, rews) = RewardDistributorCommitIncentivesAction::created_slot_values( + ctx, + constants.epoch_seconds, + action_spend.solution, + )?; + + created_commitment_slots.push(comm); + created_reward_slots.extend(rews); + spent_reward_slots.push(RewardDistributorCommitIncentivesAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == add_entry_hash { + created_entry_slots.push(RewardDistributorAddEntryAction::created_slot_value( + ctx, + ¤t_state_and_ephemeral.1, + action_spend.solution, + )?); + } else if raw_action_hash == stake_hash { + created_entry_slots.push(RewardDistributorStakeAction::created_slot_value( + ctx, + ¤t_state_and_ephemeral.1, + action_spend.solution, + )?); + } else if raw_action_hash == remove_entry_hash { + spent_entry_slots.push(RewardDistributorRemoveEntryAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == unstake_hash { + spent_entry_slots.push(RewardDistributorUnstakeAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash == withdraw_incentives_hash { + let (rew, cmt) = RewardDistributorWithdrawIncentivesAction::spent_slot_values( + ctx, + action_spend.solution, + )?; + + spent_reward_slots.push(rew); + spent_commitment_slots.push(cmt); + created_reward_slots.push( + RewardDistributorWithdrawIncentivesAction::created_slot_value( + ctx, + constants.withdrawal_share_bps, + action_spend.solution, + )?, + ); + } else if raw_action_hash == initiate_payout_hash { + created_entry_slots.push(RewardDistributorInitiatePayoutAction::created_slot_value( + ctx, + ¤t_state_and_ephemeral.1, + action_spend.solution, + )?); + spent_entry_slots.push(RewardDistributorInitiatePayoutAction::spent_slot_value( + ctx, + action_spend.solution, + )?); + } else if raw_action_hash != add_incentives_hash && raw_action_hash != sync_hash { + // delegated state action has no effect on slots + return Err(DriverError::InvalidMerkleProof); + } + + Ok(RewardDistributorPendingSpendInfo { + actions: vec![action_spend], + spent_reward_slots, + spent_commitment_slots, + spent_entry_slots, + created_reward_slots, + created_commitment_slots, + created_entry_slots, + latest_state: new_state_and_ephemeral, + }) + } + pub fn from_parent_spend( allocator: &mut Allocator, parent_coin: Coin, From 45319ee905af7b6fb937ed3f2de648d087f04d53 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 18:25:36 +0300 Subject: [PATCH 18/65] getting there --- src/primitives/reserve.rs | 15 +++ src/primitives/reward_distributor.rs | 159 +++++++++++++++++++-------- 2 files changed, 126 insertions(+), 48 deletions(-) diff --git a/src/primitives/reserve.rs b/src/primitives/reserve.rs index 9325dcf5..9ed3cc98 100644 --- a/src/primitives/reserve.rs +++ b/src/primitives/reserve.rs @@ -180,4 +180,19 @@ impl Reserve { )?, )) } + + pub fn child(&self, child_amount: u64) -> Self { + Self::new( + self.coin.coin_id(), + LineageProof { + parent_parent_coin_info: self.coin.parent_coin_info, + parent_inner_puzzle_hash: self.inner_puzzle_hash, + parent_amount: self.coin.amount, + }, + self.asset_id, + self.controller_singleton_struct_hash, + self.nonce, + child_amount, + ) + } } diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index cb2f495a..fa769dcd 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -85,7 +85,7 @@ pub struct RewardDistributor { pub info: RewardDistributorInfo, pub reserve: Reserve, - pub pending_items: RewardDistributorPendingSpendInfo, + pub pending_spend: RewardDistributorPendingSpendInfo, } impl RewardDistributor { @@ -95,7 +95,7 @@ impl RewardDistributor { proof, info, reserve, - pending_items: RewardDistributorPendingSpendInfo::new(info.state), + pending_spend: RewardDistributorPendingSpendInfo::new(info.state), } } } @@ -247,72 +247,135 @@ impl RewardDistributor { }) } - pub fn from_parent_spend( - allocator: &mut Allocator, - parent_coin: Coin, - parent_puzzle: Puzzle, - parent_solution: NodePtr, + pub fn pending_info_from_spend( + ctx: &mut SpendContext, + inner_solution: NodePtr, + initial_state: RewardDistributorState, constants: RewardDistributorConstants, - ) -> Result, DriverError> - where - Self: Sized, - { - let Some(parent_info) = RewardDistributorInfo::parse(allocator, parent_puzzle, constants)? - else { + ) -> Result { + let mut pending_spend_info = RewardDistributorPendingSpendInfo::new(initial_state); + + let inner_solution = + ActionLayer::::parse_solution(ctx, inner_solution)?; + + for raw_action in inner_solution.action_spends.iter() { + let delta = Self::pending_info_delta_from_spend( + ctx, + *raw_action, + pending_spend_info.latest_state, + constants, + )?; + + pending_spend_info.add_delta(delta); + } + + Ok(pending_spend_info) + } + + pub fn from_spend( + ctx: &mut SpendContext, + spend: &CoinSpend, + reserve_lineage_proof: LineageProof, + constants: RewardDistributorConstants, + ) -> Result, DriverError> { + let coin = spend.coin; + let puzzle_ptr = ctx.alloc(&spend.puzzle_reveal)?; + let puzzle = Puzzle::parse(ctx, puzzle_ptr); + let solution_ptr = ctx.alloc(&spend.solution)?; + + let Some(info) = RewardDistributorInfo::parse(ctx, puzzle, constants)? else { return Ok(None); }; - let proof = Proof::Lineage(LineageProof { - parent_parent_coin_info: parent_coin.parent_coin_info, - parent_inner_puzzle_hash: parent_info.inner_puzzle_hash().into(), - parent_amount: parent_coin.amount, - }); - - let parent_solution = SingletonSolution::::from_clvm(allocator, parent_solution)?; - let new_state = ActionLayer::::get_new_state( - allocator, - parent_info.state, - parent_solution.inner_solution, - )?; + let solution = ctx.extract::>(solution_ptr)?; + let proof = solution.lineage_proof; - let new_info = parent_info.with_state(new_state); + let pending_spend = + Self::pending_info_from_spend(ctx, solution.inner_solution, info.state, constants)?; - let new_coin = Coin::new(parent_coin.coin_id(), new_info.puzzle_hash().into(), 1); + let inner_solution = + RawActionLayerSolution::::from_clvm( + ctx, + solution.inner_solution, + )?; - let parent_inner_solution = RawActionLayerSolution::< - NodePtr, - NodePtr, - ReserveFinalizerSolution, - >::from_clvm(allocator, parent_solution.inner_solution)?; - let parent_reserve = Coin::new( - parent_inner_solution.finalizer_solution.reserve_parent_id, - constants.reserve_full_puzzle_hash, - parent_info.state.total_reserves, - ); let reserve = Reserve::new( - parent_reserve.coin_id(), - LineageProof { - parent_parent_coin_info: parent_reserve.parent_coin_info, - parent_inner_puzzle_hash: constants.reserve_inner_puzzle_hash, - parent_amount: parent_reserve.amount, - }, + inner_solution.finalizer_solution.reserve_parent_id, + reserve_lineage_proof, constants.reserve_asset_id, - SingletonStruct::new(parent_info.constants.launcher_id) + SingletonStruct::new(info.constants.launcher_id) .tree_hash() .into(), 0, - new_state.total_reserves, + info.state.total_reserves, ); Ok(Some(RewardDistributor { - coin: new_coin, + coin, proof, - info: new_info, + info, reserve, - pending_items: RewardDistributorPendingItems::default(), + pending_spend, })) } + pub fn child_lineage_proof(&self) -> LineageProof { + LineageProof { + parent_parent_coin_info: self.coin.parent_coin_info, + parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), + parent_amount: self.coin.amount, + } + } + + pub fn from_parent_spend( + ctx: &mut SpendContext, + parent_spend: &CoinSpend, + constants: RewardDistributorConstants, + ) -> Result, DriverError> + where + Self: Sized, + { + let dummy_lp = LineageProof { + parent_parent_coin_info: Bytes32::default(), + parent_inner_puzzle_hash: Bytes32::default(), + parent_amount: 0, + }; + let Some(parent_registry) = Self::from_spend(ctx, parent_spend, dummy_lp, constants)? + else { + return Ok(None); + }; + + let new_info = parent_registry + .info + .with_state(parent_registry.pending_spend.latest_state.1); + + Ok(Some(RewardDistributor { + coin: Coin::new( + parent_registry.coin.coin_id(), + new_info.puzzle_hash().into(), + 1, + ), + proof: Proof::Lineage(parent_registry.child_lineage_proof()), + info: new_info, + reserve: parent_registry.reserve.child(new_info.state.total_reserves), + pending_spend: RewardDistributorPendingSpendInfo::new(new_info.state), + })) + } + + pub fn child(&self, child_state: RewardDistributorState) -> Self { + let new_info = self.info.with_state(child_state); + let new_coin = Coin::new(self.coin.coin_id(), new_info.puzzle_hash().into(), 1); + let new_reserve = self.reserve.child(child_state.total_reserves); + + RewardDistributor { + coin: new_coin, + proof: Proof::Lineage(self.child_lineage_proof()), + info: new_info, + reserve: new_reserve, + pending_spend: RewardDistributorPendingSpendInfo::new(new_info.state), + } + } + #[allow(clippy::type_complexity)] pub fn from_launcher_solution( ctx: &mut SpendContext, From 6be1dfc7e31fdd3723b79056700e66a413c5eb14 Mon Sep 17 00:00:00 2001 From: Yak Date: Wed, 25 Jun 2025 18:31:19 +0300 Subject: [PATCH 19/65] short break time --- src/primitives/reward_distributor.rs | 224 +++------------------------ 1 file changed, 25 insertions(+), 199 deletions(-) diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index fa769dcd..404dac5c 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -10,10 +10,10 @@ use chia_puzzle_types::singleton::{LauncherSolution, SingletonArgs}; use chia_wallet_sdk::{ driver::{DriverError, Layer, Puzzle, SingletonLayer, Spend, SpendContext}, prelude::{Cat, CatSpend}, - types::{run_puzzle, Condition, Conditions}, + types::{Condition, Conditions}, }; -use clvm_traits::{clvm_list, match_tuple, FromClvm, ToClvm}; -use clvmr::{Allocator, NodePtr}; +use clvm_traits::{clvm_list, match_tuple, FromClvm}; +use clvmr::NodePtr; use crate::{ Action, ActionLayer, ActionLayerSolution, RawActionLayerSolution, Registry, @@ -522,8 +522,8 @@ impl RewardDistributor { let puzzle = layers.construct_puzzle(ctx)?; let action_puzzle_hashes = self - .pending_items - .pending_actions + .pending_spend + .actions .iter() .map(|a| ctx.tree_hash(a.puzzle).into()) .collect::>(); @@ -532,6 +532,7 @@ impl RewardDistributor { reserve_parent_id: self.reserve.coin.parent_coin_info, })?; + let child = self.child(self.pending_spend.latest_state.1); let solution = layers.construct_solution( ctx, SingletonSolution { @@ -547,7 +548,7 @@ impl RewardDistributor { .ok_or(DriverError::Custom( "Couldn't build proofs for one or more actions".to_string(), ))?, - action_spends: self.pending_items.pending_actions, + action_spends: self.pending_spend.actions, finalizer_solution, }, }, @@ -567,25 +568,7 @@ impl RewardDistributor { cat_spends.push(cat_spend); Cat::spend_all(ctx, &cat_spends)?; - let my_puzzle = Puzzle::parse(ctx, my_spend.puzzle); - let new_reward_distributor = RewardDistributor::from_parent_spend( - ctx, - self.coin, - my_puzzle, - solution, - self.info.constants, - )? - .unwrap(); - - Ok(new_reward_distributor) - } - - pub fn insert(&mut self, action_spend: Spend) { - self.pending_items.pending_actions.push(action_spend); - } - - pub fn insert_multiple(&mut self, action_spends: Vec) { - self.pending_items.pending_actions.extend(action_spends); + Ok(child) } pub fn new_action(&self) -> A @@ -595,11 +578,11 @@ impl RewardDistributor { A::from_constants(&self.info.constants) } - pub fn created_slot_values_to_slots( + pub fn created_slot_value_to_slot( &self, - slot_values: Vec, + slot_value: SlotValue, nonce: RewardDistributorSlotNonce, - ) -> Vec> + ) -> Slot where SlotValue: Copy + ToTreeHash, { @@ -608,183 +591,26 @@ impl RewardDistributor { parent_inner_puzzle_hash: self.info.inner_puzzle_hash().into(), }; - slot_values - .into_iter() - .map(|slot_value| { - Slot::new( - proof, - SlotInfo::from_value( - self.info.constants.launcher_id, - nonce.to_u64(), - slot_value, - ), - ) - }) - .collect() - } - - pub fn get_latest_pending_state( - &self, - allocator: &mut Allocator, - ) -> Result { - let mut state = (NodePtr::NIL, self.info.state); - - for action in self.pending_items.pending_actions.iter() { - let actual_solution = clvm_list!(state, action.solution).to_clvm(allocator)?; - - let output = run_puzzle(allocator, action.puzzle, actual_solution)?; - (state, _) = ::from_clvm( - allocator, output, - )?; - } - - Ok(state.1) - } - - pub fn get_latest_pending_ephemeral_state( - &self, - allocator: &mut Allocator, - ) -> Result { - let mut state = (0, self.info.state); - - for action in self.pending_items.pending_actions.iter() { - let actual_solution = clvm_list!(state, action.solution).to_clvm(allocator)?; - - let output = run_puzzle(allocator, action.puzzle, actual_solution)?; - (state, _) = ::from_clvm( - allocator, output, - )?; - } - - Ok(state.0) + Slot::new( + proof, + SlotInfo::from_value(self.info.constants.launcher_id, nonce.to_u64(), slot_value), + ) } - pub fn get_pending_items_from_spend( - &self, + pub fn insert_action_spend( + &mut self, ctx: &mut SpendContext, - solution: NodePtr, - ) -> Result { - let solution = ctx.extract::>(solution)?; - let inner_solution = ActionLayer::::parse_solution( + action_spend: Spend, + ) -> Result<(), DriverError> { + let delta = Self::pending_info_delta_from_spend( ctx, - solution.inner_solution, + action_spend, + self.pending_spend.latest_state, + self.info.constants, )?; - let mut actions: Vec = vec![]; - let mut reward_slot_values: Vec = vec![]; - let mut commitment_slot_values: Vec = vec![]; - let mut entry_slot_values: Vec = vec![]; - let mut spent_slots: Vec<(RewardDistributorSlotNonce, Bytes32)> = vec![]; + self.pending_spend.add_delta(delta); - let new_epoch_action = - RewardDistributorNewEpochAction::from_constants(&self.info.constants); - let new_epoch_hash = new_epoch_action.tree_hash(); - - let commit_incentives_action = - RewardDistributorCommitIncentivesAction::from_constants(&self.info.constants); - let commit_incentives_hash = commit_incentives_action.tree_hash(); - - let add_entry_action = - RewardDistributorAddEntryAction::from_constants(&self.info.constants); - let add_entry_hash = add_entry_action.tree_hash(); - - let remove_entry_action = - RewardDistributorRemoveEntryAction::from_constants(&self.info.constants); - let remove_entry_hash = remove_entry_action.tree_hash(); - - let stake_action = RewardDistributorStakeAction::from_constants(&self.info.constants); - let stake_hash = stake_action.tree_hash(); - - let unstake_action = RewardDistributorUnstakeAction::from_constants(&self.info.constants); - let unstake_hash = unstake_action.tree_hash(); - - let withdraw_incentives_action = - RewardDistributorWithdrawIncentivesAction::from_constants(&self.info.constants); - let withdraw_incentives_hash = withdraw_incentives_action.tree_hash(); - - let initiate_payout_action = - RewardDistributorInitiatePayoutAction::from_constants(&self.info.constants); - let initiate_payout_hash = initiate_payout_action.tree_hash(); - - let mut current_state = (NodePtr::NIL, self.info.state); - for raw_action in inner_solution.action_spends { - actions.push(Spend::new(raw_action.puzzle, raw_action.solution)); - - let actual_solution = ctx.alloc(&clvm_list!(current_state, raw_action.solution))?; - - let action_output = run_puzzle(ctx, raw_action.puzzle, actual_solution)?; - (current_state, _) = ctx - .extract::( - action_output, - )?; - - let raw_action_hash = ctx.tree_hash(raw_action.puzzle); - - if raw_action_hash == new_epoch_hash { - let (rew, spent) = - new_epoch_action.get_slot_value_from_solution(ctx, raw_action.solution)?; - - reward_slot_values.push(rew); - spent_slots.push(spent); - } else if raw_action_hash == commit_incentives_hash { - let (comm, rews, spent_slot) = commit_incentives_action - .get_slot_values_from_solution( - ctx, - self.info.constants.epoch_seconds, - raw_action.solution, - )?; - - commitment_slot_values.push(comm); - reward_slot_values.extend(rews); - spent_slots.push(spent_slot); - } else if raw_action_hash == add_entry_hash { - entry_slot_values.push(add_entry_action.get_slot_value_from_solution( - ctx, - ¤t_state.1, - raw_action.solution, - )?); - } else if raw_action_hash == stake_hash { - entry_slot_values.push(stake_action.get_slot_value_from_solution( - ctx, - ¤t_state.1, - raw_action.solution, - )?); - } else if raw_action_hash == remove_entry_hash { - spent_slots.push( - remove_entry_action - .get_spent_slot_value_from_solution(ctx, raw_action.solution)?, - ); - } else if raw_action_hash == unstake_hash { - spent_slots.push( - unstake_action.get_spent_slot_value_from_solution(ctx, raw_action.solution)?, - ); - } else if raw_action_hash == withdraw_incentives_hash { - let (rew, spnt) = withdraw_incentives_action.get_slot_value_from_solution( - ctx, - &self.info.constants, - raw_action.solution, - )?; - - reward_slot_values.push(rew); - spent_slots.extend(spnt); - } else if raw_action_hash == initiate_payout_hash { - let (mirr, spent) = initiate_payout_action.get_slot_value_from_solution( - ctx, - ¤t_state.1, - raw_action.solution, - )?; - - entry_slot_values.push(mirr); - spent_slots.push(spent); - } - } - - Ok(RewardDistributorPendingItems { - pending_actions: actions, - pending_spent_slots: spent_slots, - pending_reward_slot_values: reward_slot_values, - pending_commitment_slot_values: commitment_slot_values, - pending_entry_slot_values: entry_slot_values, - }) + Ok(()) } } From 82499086f441441c904f139695b4ab2e3edb0141 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 10:46:20 +0300 Subject: [PATCH 20/65] update distributor actions --- .../actions/reward_distributor/add_entry.rs | 10 ++-- .../reward_distributor/add_incentives.rs | 4 +- .../reward_distributor/commit_incentives.rs | 34 +++++++------ .../reward_distributor/initiate_payout.rs | 13 ++--- .../actions/reward_distributor/new_epoch.rs | 11 ++-- .../reward_distributor/remove_entry.rs | 5 +- .../actions/reward_distributor/stake.rs | 17 ++++--- src/layers/actions/reward_distributor/sync.rs | 4 +- .../actions/reward_distributor/unstake.rs | 5 +- .../reward_distributor/withdraw_incentives.rs | 16 +++--- src/primitives/reward_distributor.rs | 50 +++++++++++++++++++ 11 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/layers/actions/reward_distributor/add_entry.rs b/src/layers/actions/reward_distributor/add_entry.rs index b5f69a76..5102fd62 100644 --- a/src/layers/actions/reward_distributor/add_entry.rs +++ b/src/layers/actions/reward_distributor/add_entry.rs @@ -98,14 +98,12 @@ impl RewardDistributorAddEntryAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let my_state = distributor.get_latest_pending_state(ctx)?; - let slot_value = self.get_slot_value_from_solution(ctx, &my_state, action_solution)?; - distributor.insert(Spend::new(action_puzzle, action_solution)); + let my_state = distributor.pending_spend.latest_state.1; + let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( add_entry_message, - distributor - .created_slot_values_to_slots(vec![slot_value], RewardDistributorSlotNonce::ENTRY) - .remove(0), + distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), )) } } diff --git a/src/layers/actions/reward_distributor/add_incentives.rs b/src/layers/actions/reward_distributor/add_incentives.rs index aacfd0b7..2df08620 100644 --- a/src/layers/actions/reward_distributor/add_incentives.rs +++ b/src/layers/actions/reward_distributor/add_incentives.rs @@ -55,7 +55,7 @@ impl RewardDistributorAddIncentivesAction { distributor: &mut RewardDistributor, amount: u64, ) -> Result { - let my_state = distributor.get_latest_pending_state(ctx)?; + let my_state = distributor.pending_spend.latest_state.1; // calculate announcement needed to ensure everything's happening as expected let mut add_incentives_announcement: Vec = @@ -74,7 +74,7 @@ impl RewardDistributorAddIncentivesAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - distributor.insert(Spend::new(action_puzzle, action_solution)); + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(add_incentives_announcement) } } diff --git a/src/layers/actions/reward_distributor/commit_incentives.rs b/src/layers/actions/reward_distributor/commit_incentives.rs index df898447..53e9a091 100644 --- a/src/layers/actions/reward_distributor/commit_incentives.rs +++ b/src/layers/actions/reward_distributor/commit_incentives.rs @@ -137,6 +137,8 @@ impl RewardDistributorCommitIncentivesAction { ), DriverError, > { + let reward_slot = distributor.actual_reward_slot_value(reward_slot); + let new_commitment_slot_value = RewardDistributorCommitmentSlotValue { epoch_start, clawback_ph, @@ -162,28 +164,28 @@ impl RewardDistributorCommitIncentivesAction { // spend reward slot reward_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let (_commitment_slot_value, reward_slot_values, _spent) = self - .get_slot_values_from_solution( - ctx, - distributor.info.constants.epoch_seconds, - action_solution, - )?; - distributor.insert(Spend::new(action_puzzle, action_solution)); + let (_commitment_slot_value, reward_slot_values) = Self::created_slot_values( + ctx, + distributor.info.constants.epoch_seconds, + action_solution, + )?; + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( Conditions::new().assert_puzzle_announcement(announcement_id( distributor.coin.puzzle_hash, commit_reward_announcement, )), - distributor - .created_slot_values_to_slots( - vec![new_commitment_slot_value], - RewardDistributorSlotNonce::COMMITMENT, - ) - .remove(0), - distributor.created_slot_values_to_slots( - reward_slot_values, - RewardDistributorSlotNonce::REWARD, + distributor.created_slot_value_to_slot( + new_commitment_slot_value, + RewardDistributorSlotNonce::COMMITMENT, ), + reward_slot_values + .into_iter() + .map(|slot_value| { + distributor + .created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD) + }) + .collect(), )) } } diff --git a/src/layers/actions/reward_distributor/initiate_payout.rs b/src/layers/actions/reward_distributor/initiate_payout.rs index 4f9ada98..10f2b055 100644 --- a/src/layers/actions/reward_distributor/initiate_payout.rs +++ b/src/layers/actions/reward_distributor/initiate_payout.rs @@ -85,7 +85,8 @@ impl RewardDistributorInitiatePayoutAction { distributor: &mut RewardDistributor, entry_slot: Slot, ) -> Result<(Conditions, Slot, u64), DriverError> { - let my_state = distributor.get_latest_pending_state(ctx)?; + let my_state = distributor.pending_spend.latest_state.1; + let entry_slot = distributor.actual_entry_slot_value(entry_slot); let withdrawal_amount = entry_slot.info.value.shares * (my_state.round_reward_info.cumulative_payout @@ -111,18 +112,14 @@ impl RewardDistributorInitiatePayoutAction { // spend entry slot entry_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let slot_value = self - .get_slot_value_from_solution(ctx, &my_state, action_solution)? - .0; - distributor.insert(Spend::new(action_puzzle, action_solution)); + let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( Conditions::new().assert_puzzle_announcement(announcement_id( distributor.coin.puzzle_hash, initiate_payout_announcement, )), - distributor - .created_slot_values_to_slots(vec![slot_value], RewardDistributorSlotNonce::ENTRY) - .remove(0), + distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), withdrawal_amount, )) } diff --git a/src/layers/actions/reward_distributor/new_epoch.rs b/src/layers/actions/reward_distributor/new_epoch.rs index e9d23a7d..c1fb5615 100644 --- a/src/layers/actions/reward_distributor/new_epoch.rs +++ b/src/layers/actions/reward_distributor/new_epoch.rs @@ -93,7 +93,8 @@ impl RewardDistributorNewEpochAction { reward_slot: Slot, ) -> Result<(Conditions, Slot, u64), DriverError> { // also returns fee - let my_state = distributor.get_latest_pending_state(ctx)?; + let my_state = distributor.pending_spend.latest_state.1; + let reward_slot = distributor.actual_reward_slot_value(reward_slot); let epoch_total_rewards = if my_state.round_time_info.epoch_end == reward_slot.info.value.epoch_start { @@ -127,13 +128,11 @@ impl RewardDistributorNewEpochAction { // spend slot reward_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let slot_value = self.get_slot_value_from_solution(ctx, action_solution)?.0; - distributor.insert(Spend::new(action_puzzle, action_solution)); + let slot_value = Self::created_slot_value(ctx, action_solution)?; + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( new_epoch_conditions, - distributor - .created_slot_values_to_slots(vec![slot_value], RewardDistributorSlotNonce::REWARD) - .remove(0), + distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD), fee, )) } diff --git a/src/layers/actions/reward_distributor/remove_entry.rs b/src/layers/actions/reward_distributor/remove_entry.rs index 0e7d8acf..e5468e0c 100644 --- a/src/layers/actions/reward_distributor/remove_entry.rs +++ b/src/layers/actions/reward_distributor/remove_entry.rs @@ -66,6 +66,8 @@ impl RewardDistributorRemoveEntryAction { manager_singleton_inner_puzzle_hash: Bytes32, ) -> Result<(Conditions, u64), DriverError> { // u64 = last payment amount + let my_state = distributor.pending_spend.latest_state.1; + let entry_slot = distributor.actual_entry_slot_value(entry_slot); // compute message that the manager needs to send let remove_entry_message: Bytes32 = clvm_tuple!( @@ -86,7 +88,6 @@ impl RewardDistributorRemoveEntryAction { .assert_concurrent_puzzle(entry_slot.coin.puzzle_hash); // spend self - let my_state = distributor.get_latest_pending_state(ctx)?; let entry_payout_amount = entry_slot.info.value.shares * (my_state.round_reward_info.cumulative_payout - entry_slot.info.value.initial_cumulative_payout); @@ -102,7 +103,7 @@ impl RewardDistributorRemoveEntryAction { // spend entry slot entry_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - distributor.insert(Spend::new(action_puzzle, action_solution)); + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok((remove_entry_conditions, entry_payout_amount)) } diff --git a/src/layers/actions/reward_distributor/stake.rs b/src/layers/actions/reward_distributor/stake.rs index 09f807bd..f95bd0d9 100644 --- a/src/layers/actions/reward_distributor/stake.rs +++ b/src/layers/actions/reward_distributor/stake.rs @@ -94,7 +94,9 @@ impl RewardDistributorStakeAction { ), DriverError, > { - let ephemeral_counter = distributor.get_latest_pending_ephemeral_state(ctx)?; + let my_state = distributor.pending_spend.latest_state.1; + let ephemeral_counter = + ctx.extract::(distributor.pending_spend.latest_state.0)?; let my_id = distributor.coin.coin_id(); // calculate notarized payment @@ -110,7 +112,9 @@ impl RewardDistributorStakeAction { .tree_hash() .into(); let notarized_payment = NotarizedPayment { - nonce: clvm_tuple!(ephemeral_counter, my_id).tree_hash().into(), + nonce: clvm_tuple!(ephemeral_counter.tree_hash(), my_id) + .tree_hash() + .into(), payments: vec![Payment::with_memos( payment_puzzle_hash, 1, @@ -143,19 +147,16 @@ impl RewardDistributorStakeAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let my_state = distributor.get_latest_pending_state(ctx)?; - let slot_value = self.get_slot_value_from_solution(ctx, &my_state, action_solution)?; + let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; let msg: Bytes32 = notarized_payment.tree_hash().into(); - distributor.insert(Spend::new(action_puzzle, action_solution)); + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( Conditions::new() .assert_puzzle_announcement(announcement_id(nft.coin.puzzle_hash, msg)), notarized_payment, - distributor - .created_slot_values_to_slots(vec![slot_value], RewardDistributorSlotNonce::ENTRY) - .remove(0), + distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), nft.wrapped_child(payment_puzzle_hash, None, nft.info.metadata), )) } diff --git a/src/layers/actions/reward_distributor/sync.rs b/src/layers/actions/reward_distributor/sync.rs index f60c0ee7..5e1212f4 100644 --- a/src/layers/actions/reward_distributor/sync.rs +++ b/src/layers/actions/reward_distributor/sync.rs @@ -36,7 +36,7 @@ impl RewardDistributorSyncAction { update_time: u64, ) -> Result { // calculate announcement needed to ensure everything's happening as expected - let my_state = distributor.get_latest_pending_state(ctx)?; + let my_state = distributor.pending_spend.latest_state.1; let mut new_epoch_announcement: Vec = clvm_tuple!(update_time, my_state.round_time_info.epoch_end) .tree_hash() @@ -51,7 +51,7 @@ impl RewardDistributorSyncAction { let action_solution = ctx.alloc(&RewardDistributorSyncActionSolution { update_time })?; let action_puzzle = self.construct_puzzle(ctx)?; - distributor.insert(Spend::new(action_puzzle, action_solution)); + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(new_epoch_conditions) } } diff --git a/src/layers/actions/reward_distributor/unstake.rs b/src/layers/actions/reward_distributor/unstake.rs index cb886dc8..7abbdf51 100644 --- a/src/layers/actions/reward_distributor/unstake.rs +++ b/src/layers/actions/reward_distributor/unstake.rs @@ -79,6 +79,8 @@ impl RewardDistributorUnstakeAction { locked_nft: Nft, ) -> Result<(Conditions, u64), DriverError> { // u64 = last payment amount + let my_state = distributor.pending_spend.latest_state.1; + let entry_slot = distributor.actual_entry_slot_value(entry_slot); // compute message that the custody puzzle needs to send let unstake_message: Bytes32 = locked_nft.info.launcher_id; @@ -93,7 +95,6 @@ impl RewardDistributorUnstakeAction { .assert_concurrent_puzzle(entry_slot.coin.puzzle_hash); // spend self - let my_state = distributor.get_latest_pending_state(ctx)?; let entry_payout_amount = entry_slot.info.value.shares * (my_state.round_reward_info.cumulative_payout - entry_slot.info.value.initial_cumulative_payout); @@ -118,7 +119,7 @@ impl RewardDistributorUnstakeAction { let action_puzzle = self.construct_puzzle(ctx)?; let registry_inner_puzzle_hash = distributor.info.inner_puzzle_hash(); - distributor.insert(Spend::new(action_puzzle, action_solution)); + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; // spend NFT let my_p2 = P2DelegatedBySingletonLayer::new( diff --git a/src/layers/actions/reward_distributor/withdraw_incentives.rs b/src/layers/actions/reward_distributor/withdraw_incentives.rs index 57a27145..c9af725a 100644 --- a/src/layers/actions/reward_distributor/withdraw_incentives.rs +++ b/src/layers/actions/reward_distributor/withdraw_incentives.rs @@ -105,6 +105,8 @@ impl RewardDistributorWithdrawIncentivesAction { reward_slot: Slot, ) -> Result<(Conditions, Slot, u64), DriverError> { // last u64 = withdrawn amount + let commitment_slot = distributor.actual_commitment_slot_value(commitment_slot); + let reward_slot = distributor.actual_reward_slot_value(reward_slot); let withdrawal_share = commitment_slot.info.value.rewards * distributor.info.constants.withdrawal_share_bps / 10000; @@ -129,10 +131,12 @@ impl RewardDistributorWithdrawIncentivesAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let slot_value = self - .get_slot_value_from_solution(ctx, &distributor.info.constants, action_solution)? - .0; - distributor.insert(Spend::new(action_puzzle, action_solution)); + let slot_value = Self::created_slot_value( + ctx, + distributor.info.constants.withdrawal_share_bps, + action_solution, + )?; + distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; // spend slots let my_inner_puzzle_hash: Bytes32 = distributor.info.inner_puzzle_hash().into(); @@ -141,9 +145,7 @@ impl RewardDistributorWithdrawIncentivesAction { Ok(( withdraw_incentives_conditions, - distributor - .created_slot_values_to_slots(vec![slot_value], RewardDistributorSlotNonce::REWARD) - .remove(0), + distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD), withdrawal_share, )) } diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index 404dac5c..22c62ab2 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -613,4 +613,54 @@ impl RewardDistributor { Ok(()) } + + pub fn actual_reward_slot_value( + &self, + slot: Slot, + ) -> Slot { + let mut slot = slot; + + for slot_value in self.pending_spend.created_reward_slots.iter() { + if slot_value.epoch_start == slot.info.value.epoch_start { + slot = self + .created_slot_value_to_slot(*slot_value, RewardDistributorSlotNonce::REWARD); + } + } + + slot + } + + pub fn actual_entry_slot_value( + &self, + slot: Slot, + ) -> Slot { + let mut slot = slot; + + for slot_value in self.pending_spend.created_entry_slots.iter() { + if slot_value.payout_puzzle_hash == slot.info.value.payout_puzzle_hash { + slot = + self.created_slot_value_to_slot(*slot_value, RewardDistributorSlotNonce::ENTRY); + } + } + + slot + } + + pub fn actual_commitment_slot_value( + &self, + slot: Slot, + ) -> Slot { + let mut slot = slot; + + for slot_value in self.pending_spend.created_commitment_slots.iter() { + if slot_value.epoch_start == slot.info.value.epoch_start { + slot = self.created_slot_value_to_slot( + *slot_value, + RewardDistributorSlotNonce::COMMITMENT, + ); + } + } + + slot + } } From 02c0d8257d3f5aeb0be5e4611638ea4afb6b3a0a Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 12:45:38 +0300 Subject: [PATCH 21/65] sync; gotta do slots as well now --- src/cli/database.rs | 150 +------ .../reward_distributor/sync_distributor.rs | 387 +++++++----------- 2 files changed, 157 insertions(+), 380 deletions(-) diff --git a/src/cli/database.rs b/src/cli/database.rs index f967ccc8..10cef3bd 100644 --- a/src/cli/database.rs +++ b/src/cli/database.rs @@ -112,24 +112,9 @@ impl Db { sqlx::query( " - CREATE TABLE IF NOT EXISTS dig_indexed_slot_values_by_epoch_start ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - epoch_start INTEGER NOT NULL, - nonce INTEGER NOT NULL, - slot_value_hash BLOB NOT NULL - ) - ", - ) - .execute(&pool) - .await?; - - sqlx::query( - " - CREATE TABLE IF NOT EXISTS dig_indexed_slot_values_by_puzzle_hash ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - puzzle_hash BLOB NOT NULL, - nonce INTEGER NOT NULL, - slot_value_hash BLOB NOT NULL + CREATE TABLE IF NOT EXISTS xchandles_configurations ( + launcher_id BLOB PRIMARY KEY, + constants BLOB NOT NULL ) ", ) @@ -137,17 +122,6 @@ impl Db { .await?; } - sqlx::query( - " - CREATE TABLE IF NOT EXISTS xchandles_configurations ( - launcher_id BLOB PRIMARY KEY, - constants BLOB NOT NULL - ) - ", - ) - .execute(&pool) - .await?; - Ok(Self { pool }) } @@ -818,124 +792,6 @@ impl Db { Ok(Some(constants)) } - - pub async fn save_dig_indexed_slot_value_by_epoch_start( - &self, - epoch_start: u64, - nonce: u64, - slot_value_hash: Bytes32, - ) -> Result<(), CliError> { - sqlx::query( - " - INSERT INTO dig_indexed_slot_values_by_epoch_start (epoch_start, nonce, slot_value_hash) VALUES (?1, ?2, ?3) - ", - ) - .bind(epoch_start as i64) - .bind(nonce as i64) - .bind(slot_value_hash.to_vec()) - .execute(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - Ok(()) - } - - pub async fn save_dig_indexed_slot_value_by_puzzle_hash( - &self, - puzzle_hash: Bytes32, - nonce: u64, - slot_value_hash: Bytes32, - ) -> Result<(), CliError> { - sqlx::query( - " - INSERT INTO dig_indexed_slot_values_by_puzzle_hash (puzzle_hash, nonce, slot_value_hash) VALUES (?1, ?2, ?3) - ", - ) - .bind(puzzle_hash.to_vec()) - .bind(nonce as i64) - .bind(slot_value_hash.to_vec()) - .execute(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - Ok(()) - } - - pub async fn get_dig_indexed_slot_values_by_epoch_start( - &self, - epoch_start: u64, - nonce: u64, - ) -> Result, CliError> { - let row = sqlx::query( - " - SELECT slot_value_hash FROM dig_indexed_slot_values_by_epoch_start WHERE epoch_start = ?1 AND nonce = ?2 - ", - ) - .bind(epoch_start as i64) - .bind(nonce as i64) - .fetch_all(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - row.into_iter() - .map(|row| column_to_bytes32(row.get::<&[u8], _>("slot_value_hash"))) - .collect::, _>>() - } - - pub async fn get_dig_indexed_slot_values_by_puzzle_hash( - &self, - puzzle_hash: Bytes32, - nonce: u64, - ) -> Result, CliError> { - let row = sqlx::query( - " - SELECT slot_value_hash FROM dig_indexed_slot_values_by_puzzle_hash WHERE puzzle_hash = ?1 AND nonce = ?2 - ", - ) - .bind(puzzle_hash.to_vec()) - .bind(nonce as i64) - .fetch_all(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - row.into_iter() - .map(|row| column_to_bytes32(row.get::<&[u8], _>("slot_value_hash"))) - .collect::, _>>() - } - - pub async fn delete_dig_indexed_slot_values_by_epoch_start_using_value_hash( - &self, - value_hash: Bytes32, - ) -> Result<(), CliError> { - sqlx::query( - " - DELETE FROM dig_indexed_slot_values_by_epoch_start WHERE slot_value_hash = ?1 - ", - ) - .bind(value_hash.to_vec()) - .execute(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - Ok(()) - } - - pub async fn delete_dig_indexed_slot_values_by_puzzle_hash_using_value_hash( - &self, - value_hash: Bytes32, - ) -> Result<(), CliError> { - sqlx::query( - " - DELETE FROM dig_indexed_slot_values_by_puzzle_hash WHERE slot_value_hash = ?1 - ", - ) - .bind(value_hash.to_vec()) - .execute(&self.pool) - .await - .map_err(CliError::Sqlx)?; - - Ok(()) - } } pub fn column_to_bytes32(column_value: &[u8]) -> Result { diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index 9e34080f..791fb786 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -9,10 +9,7 @@ use chia_wallet_sdk::{ }; use clvmr::NodePtr; -use crate::{ - CliError, Db, P2DelegatedBySingletonLayerArgs, Reserve, RewardDistributor, - RewardDistributorSlotNonce, -}; +use crate::{CliError, Db, P2DelegatedBySingletonLayerArgs, Reserve, RewardDistributor}; pub async fn sync_distributor( client: &CoinsetClient, @@ -20,248 +17,128 @@ pub async fn sync_distributor( ctx: &mut SpendContext, launcher_id: Bytes32, ) -> Result { - let last_unspent_coin_info = db.get_last_unspent_singleton_coin(launcher_id).await?; - - let (last_spent_coin_id, constants, mut skip_db_save, prev_distributor) = - if let Some((_coin_id, parent_coin_id)) = last_unspent_coin_info { - let constants_from_db = db - .get_reward_distributor_configuration(ctx, launcher_id) - .await? - .ok_or(CliError::Custom( - "Reward distributor configuration not found in database".to_string(), - ))?; - - (parent_coin_id, constants_from_db, true, None) - } else { - let Some(launcher_coin_record) = client - .get_coin_record_by_name(launcher_id) - .await? - .coin_record - else { - return Err(CliError::CoinNotFound(launcher_id)); - }; - if !launcher_coin_record.spent { - return Err(CliError::CoinNotSpent(launcher_id)); - } - - let Some(launcher_coin_spend) = client - .get_puzzle_and_solution( - launcher_coin_record.coin.coin_id(), - Some(launcher_coin_record.spent_block_index), - ) - .await? - .coin_solution - else { - return Err(CliError::CoinNotSpent(launcher_id)); - }; - - let launcher_solution_ptr = ctx.alloc(&launcher_coin_spend.solution)?; - let Some((constants, initial_state, distributor_eve_coin)) = - RewardDistributor::from_launcher_solution( - ctx, - launcher_coin_spend.coin, - launcher_solution_ptr, - )? - else { - return Err(CliError::Custom( - "Could not parse launcher spend".to_string(), - )); - }; - - let Some(distributor_eve_coin_spend) = client - .get_puzzle_and_solution( - distributor_eve_coin.coin_id(), - Some(launcher_coin_record.spent_block_index), - ) - .await? - .coin_solution - else { - return Err(CliError::CoinNotSpent(distributor_eve_coin.coin_id())); - }; - - let reserve = find_reserve( - ctx, - client, - launcher_id, - constants.reserve_asset_id, - 0, - 0, - true, - ) - .await?; - - let Some((new_distributor, slot)) = RewardDistributor::from_eve_coin_spend( + let constants = if let Some(cached_constants) = db + .get_reward_distributor_configuration(ctx, launcher_id) + .await? + { + cached_constants + } else { + // configuration not in database, so we need to fetch the launcher + let launcher_coin_record = client + .get_coin_record_by_name(launcher_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(launcher_id))?; + let launcher_coin_spend = client + .get_puzzle_and_solution(launcher_id, Some(launcher_coin_record.spent_block_index)) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(launcher_id))?; + + let launcher_solution_ptr = ctx.alloc(&launcher_coin_spend.solution)?; + let Some((constants, _initial_state, _distributor_eve_coin)) = + RewardDistributor::from_launcher_solution( ctx, - constants, - initial_state, - distributor_eve_coin_spend, - reserve.coin.parent_coin_info, - reserve.proof, + launcher_coin_spend.coin, + launcher_solution_ptr, )? - else { - return Err(CliError::Custom( - "Could not parse eve coin spend".to_string(), - )); - }; - - let slot_value = slot.info.value; - db.save_slot(ctx, slot, 0).await?; - db.save_dig_indexed_slot_value_by_epoch_start( - slot_value.epoch_start, - RewardDistributorSlotNonce::REWARD.to_u64(), - slot_value.tree_hash().into(), - ) - .await?; - db.save_reward_distributor_configuration(ctx, constants.launcher_id, constants) - .await?; - - let Some(distributor_record) = client - .get_coin_record_by_name(new_distributor.coin.coin_id()) - .await? - .coin_record - else { - return Err(CliError::CoinNotFound(new_distributor.coin.coin_id())); - }; - if !distributor_record.spent { - return Ok(new_distributor); - } - - ( - new_distributor.coin.coin_id(), - new_distributor.info.constants, - false, - Some(new_distributor), - ) + else { + return Err(CliError::Custom( + "Could not parse launcher spend".to_string(), + )); }; - let mut last_coin_id = last_spent_coin_id; - let mut distributor: Option = prev_distributor; - loop { - let coin_record_response = client.get_coin_record_by_name(last_coin_id).await?; - let Some(coin_record) = coin_record_response.coin_record else { - return Err(CliError::CoinNotFound(last_coin_id)); - }; - if !coin_record.spent { - break; - } + constants + }; - if !skip_db_save { - db.save_singleton_coin(constants.launcher_id, coin_record) - .await?; + let mut records = client + .get_coin_records_by_hint(constants.launcher_id, None, None, Some(false)) + .await? + .coin_records + .ok_or(CliError::Custom( + "No unspent coin records found".to_string(), + ))?; + + while !records.is_empty() { + let coin_record = records.remove(0); + if coin_record.spent { + continue; } - let puzzle_and_solution_resp = client + let next_spend = client .get_puzzle_and_solution( - coin_record.coin.coin_id(), - Some(coin_record.spent_block_index), + coin_record.coin.parent_coin_info, + Some(coin_record.confirmed_block_index), ) - .await?; - let Some(coin_spend) = puzzle_and_solution_resp.coin_solution else { - return Err(CliError::CoinNotSpent(last_coin_id)); - }; - - let puzzle_ptr = ctx.alloc(&coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(ctx, puzzle_ptr); - let solution_ptr = ctx.alloc(&coin_spend.solution)?; - if !skip_db_save { - if let Some(ref prev_distributor) = distributor { - let pending_items = - prev_distributor.get_pending_items_from_spend(ctx, solution_ptr)?; - - for (nonce, value_hash) in pending_items.pending_spent_slots.iter() { - db.mark_slot_as_spent( - constants.launcher_id, - nonce.to_u64(), - *value_hash, - coin_record.spent_block_index, - ) - .await?; - - db.delete_dig_indexed_slot_values_by_epoch_start_using_value_hash(*value_hash) - .await?; - db.delete_dig_indexed_slot_values_by_puzzle_hash_using_value_hash(*value_hash) - .await?; - } - - for slot in prev_distributor.created_slot_values_to_slots( - pending_items.pending_commitment_slot_values, - RewardDistributorSlotNonce::COMMITMENT, - ) { - let spent_block_index = if pending_items.pending_spent_slots.contains(&( - RewardDistributorSlotNonce::from_u64(slot.info.nonce).unwrap(), - slot.info.value_hash, - )) { - coin_record.spent_block_index - } else { - 0 - }; - - if spent_block_index == 0 { - // ephemeral slot for this spend - db.save_dig_indexed_slot_value_by_puzzle_hash( - slot.info.value.clawback_ph, - RewardDistributorSlotNonce::COMMITMENT.to_u64(), - slot.info.value_hash, - ) - .await?; - db.save_dig_indexed_slot_value_by_epoch_start( - slot.info.value.epoch_start, - RewardDistributorSlotNonce::COMMITMENT.to_u64(), - slot.info.value_hash, - ) - .await?; - } - db.save_slot(ctx, slot, spent_block_index).await?; - } - - for slot in prev_distributor.created_slot_values_to_slots( - pending_items.pending_entry_slot_values, - RewardDistributorSlotNonce::ENTRY, - ) { - db.save_dig_indexed_slot_value_by_puzzle_hash( - slot.info.value.payout_puzzle_hash, - RewardDistributorSlotNonce::ENTRY.to_u64(), - slot.info.value_hash, - ) - .await?; - db.save_slot(ctx, slot, 0).await?; - } - - for slot in prev_distributor.created_slot_values_to_slots( - pending_items.pending_reward_slot_values, - RewardDistributorSlotNonce::REWARD, - ) { - db.save_dig_indexed_slot_value_by_epoch_start( - slot.info.value.epoch_start, - RewardDistributorSlotNonce::REWARD.to_u64(), - slot.info.value_hash, - ) - .await?; - db.save_slot(ctx, slot, 0).await?; - } - } + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; + + if let Ok(Some(distributor)) = + RewardDistributor::from_parent_spend(ctx, &next_spend, constants) + { + return mempool_distributor_maybe(ctx, distributor, client).await; } + } - if let Some(some_distributor) = RewardDistributor::from_parent_spend( + // Could not find distributor, so we're just after the eve spend and need to do special parsing + let launcher_coin_record = client + .get_coin_record_by_name(launcher_id) + .await? + .coin_record + .ok_or(CliError::CoinNotFound(launcher_id))?; + let launcher_coin_spend = client + .get_puzzle_and_solution(launcher_id, Some(launcher_coin_record.spent_block_index)) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(launcher_id))?; + + let launcher_solution_ptr = ctx.alloc(&launcher_coin_spend.solution)?; + let Some((constants, initial_state, distributor_eve_coin)) = + RewardDistributor::from_launcher_solution( ctx, - coin_record.coin, - parent_puzzle, - solution_ptr, - constants, - )? { - last_coin_id = some_distributor.coin.coin_id(); - distributor = Some(some_distributor); - skip_db_save = false; - } else { - break; - }; - } + launcher_coin_spend.coin, + launcher_solution_ptr, + )? + else { + return Err(CliError::Custom( + "Could not parse launcher spend".to_string(), + )); + }; - if let Some(distributor) = distributor { - Ok(distributor) - } else { - Err(CliError::CoinNotFound(last_coin_id)) - } + let distributor_eve_coin_spend = client + .get_puzzle_and_solution( + distributor_eve_coin.coin_id(), + Some(launcher_coin_record.spent_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(distributor_eve_coin.coin_id()))?; + + let reserve = find_reserve( + ctx, + client, + launcher_id, + constants.reserve_asset_id, + 0, + 0, + false, + ) + .await?; + + let (new_distributor, _slot) = RewardDistributor::from_eve_coin_spend( + ctx, + constants, + initial_state, + distributor_eve_coin_spend, + reserve.coin.parent_coin_info, + reserve.proof, + )? + .ok_or(CliError::Custom( + "Could not parse eve coin spend".to_string(), + ))?; + + Ok(new_distributor) } pub async fn find_reserve( @@ -326,3 +203,47 @@ pub async fn find_reserve( nonce, }) } + +pub async fn mempool_distributor_maybe( + ctx: &mut SpendContext, + on_chain_distributor: RewardDistributor, + client: &CoinsetClient, +) -> Result { + let Some(mut mempool_items) = client + .get_mempool_items_by_coin_name(on_chain_distributor.coin.coin_id()) + .await? + .mempool_items + else { + return Ok(on_chain_distributor); + }; + + if mempool_items.is_empty() { + return Ok(on_chain_distributor); + } + + let mempool_item = mempool_items.remove(0); + let mut distributor = on_chain_distributor; + loop { + let Some(distributor_spend) = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|c| c.coin.coin_id() == distributor.coin.coin_id()) + else { + break; + }; + + let Some(new_distributor) = RewardDistributor::from_spend( + ctx, + distributor_spend, + distributor.reserve.child(1).proof, + distributor.info.constants, + )? + else { + break; + }; + distributor = new_distributor; + } + + Ok(distributor) +} From 0bfc0722e136f1720f257a061ed8b33fc54d57ea Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 14:15:43 +0300 Subject: [PATCH 22/65] find slots command --- .../reward_distributor/sync_distributor.rs | 179 +++++++++++++++++- src/primitives/reward_distributor.rs | 16 +- 2 files changed, 183 insertions(+), 12 deletions(-) diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index 791fb786..e22b1864 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -5,11 +5,16 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{CatLayer, Layer, Puzzle, SpendContext}, + driver::{CatLayer, DriverError, Layer, Puzzle, SpendContext}, }; use clvmr::NodePtr; -use crate::{CliError, Db, P2DelegatedBySingletonLayerArgs, Reserve, RewardDistributor}; +use crate::{ + CliError, Db, P2DelegatedBySingletonLayerArgs, Reserve, RewardDistributor, + RewardDistributorCommitmentSlotValue, RewardDistributorConstants, + RewardDistributorEntrySlotValue, RewardDistributorRewardSlotValue, RewardDistributorSlotNonce, + Slot, +}; pub async fn sync_distributor( client: &CoinsetClient, @@ -236,7 +241,7 @@ pub async fn mempool_distributor_maybe( let Some(new_distributor) = RewardDistributor::from_spend( ctx, distributor_spend, - distributor.reserve.child(1).proof, + Some(distributor.reserve.child(1).proof), distributor.info.constants, )? else { @@ -247,3 +252,171 @@ pub async fn mempool_distributor_maybe( Ok(distributor) } + +pub async fn find_reward_slots( + ctx: &mut SpendContext, + client: &CoinsetClient, + constants: RewardDistributorConstants, + epoch_start: u64, +) -> Result>, CliError> { + let mut possible_records = client + .get_coin_records_by_hint(epoch_start.tree_hash().into(), None, None, Some(false)) + .await? + .coin_records + .ok_or(DriverError::MissingHint)?; + + let mut slots = Vec::new(); + + while !possible_records.is_empty() { + let coin_record = possible_records.remove(0); + let distributor_spent = client + .get_puzzle_and_solution( + coin_record.coin.parent_coin_info, + Some(coin_record.confirmed_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; + + let Some(distributor) = + RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? + else { + continue; + }; + + if let Some(slot) = distributor + .pending_spend + .created_reward_slots + .iter() + .find_map(|slot| { + if slot.epoch_start == epoch_start { + let slot = distributor + .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::REWARD); + if slot.coin == coin_record.coin { + Some(slot) + } else { + None + } + } else { + None + } + }) + { + slots.push(slot); + }; + } + + Ok(slots) +} + +pub async fn find_commitment_slots( + ctx: &mut SpendContext, + client: &CoinsetClient, + constants: RewardDistributorConstants, + clawback_ph: Bytes32, +) -> Result>, CliError> { + let mut possible_records = client + .get_coin_records_by_hint(clawback_ph, None, None, Some(false)) + .await? + .coin_records + .ok_or(DriverError::MissingHint)?; + + let mut slots = Vec::new(); + + while !possible_records.is_empty() { + let coin_record = possible_records.remove(0); + let distributor_spent = client + .get_puzzle_and_solution( + coin_record.coin.parent_coin_info, + Some(coin_record.confirmed_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; + + let Some(distributor) = + RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? + else { + continue; + }; + + if let Some(slot) = distributor + .pending_spend + .created_commitment_slots + .iter() + .find_map(|slot| { + if slot.clawback_ph == clawback_ph { + let slot = distributor + .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::COMMITMENT); + if slot.coin == coin_record.coin { + Some(slot) + } else { + None + } + } else { + None + } + }) + { + slots.push(slot); + }; + } + + Ok(slots) +} + +pub async fn find_entry_slots( + ctx: &mut SpendContext, + client: &CoinsetClient, + constants: RewardDistributorConstants, + payout_puzzle_hash: Bytes32, +) -> Result>, CliError> { + let mut possible_records = client + .get_coin_records_by_hint(payout_puzzle_hash, None, None, Some(false)) + .await? + .coin_records + .ok_or(DriverError::MissingHint)?; + + let mut slots = Vec::new(); + + while !possible_records.is_empty() { + let coin_record = possible_records.remove(0); + let distributor_spent = client + .get_puzzle_and_solution( + coin_record.coin.parent_coin_info, + Some(coin_record.confirmed_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; + + let Some(distributor) = + RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? + else { + continue; + }; + + if let Some(slot) = distributor + .pending_spend + .created_entry_slots + .iter() + .find_map(|slot| { + if slot.payout_puzzle_hash == payout_puzzle_hash { + let slot = distributor + .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::ENTRY); + if slot.coin == coin_record.coin { + Some(slot) + } else { + None + } + } else { + None + } + }) + { + slots.push(slot); + }; + } + + Ok(slots) +} diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index 22c62ab2..c67c27e8 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -275,7 +275,7 @@ impl RewardDistributor { pub fn from_spend( ctx: &mut SpendContext, spend: &CoinSpend, - reserve_lineage_proof: LineageProof, + reserve_lineage_proof: Option, constants: RewardDistributorConstants, ) -> Result, DriverError> { let coin = spend.coin; @@ -301,7 +301,11 @@ impl RewardDistributor { let reserve = Reserve::new( inner_solution.finalizer_solution.reserve_parent_id, - reserve_lineage_proof, + reserve_lineage_proof.unwrap_or(LineageProof { + parent_parent_coin_info: Bytes32::default(), + parent_inner_puzzle_hash: Bytes32::default(), + parent_amount: 0, + }), // dummy default value constants.reserve_asset_id, SingletonStruct::new(info.constants.launcher_id) .tree_hash() @@ -335,13 +339,7 @@ impl RewardDistributor { where Self: Sized, { - let dummy_lp = LineageProof { - parent_parent_coin_info: Bytes32::default(), - parent_inner_puzzle_hash: Bytes32::default(), - parent_amount: 0, - }; - let Some(parent_registry) = Self::from_spend(ctx, parent_spend, dummy_lp, constants)? - else { + let Some(parent_registry) = Self::from_spend(ctx, parent_spend, None, constants)? else { return Ok(None); }; From 81535fb8f3ad48212fe66e6dd205c194d58669a6 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 14:28:04 +0300 Subject: [PATCH 23/65] one step at a time --- src/cli/reward_distributor.rs | 2 - .../broadcast_entry_update.rs | 17 ++- .../reward_distributor/clawback_rewards.rs | 28 ++-- src/cli/reward_distributor/find_slot.rs | 129 ------------------ .../reward_distributor/sync_distributor.rs | 24 ++++ 5 files changed, 50 insertions(+), 150 deletions(-) delete mode 100644 src/cli/reward_distributor/find_slot.rs diff --git a/src/cli/reward_distributor.rs b/src/cli/reward_distributor.rs index 581dff68..889cc103 100644 --- a/src/cli/reward_distributor.rs +++ b/src/cli/reward_distributor.rs @@ -2,7 +2,6 @@ mod add_rewards; mod broadcast_entry_update; mod clawback_rewards; mod commit_rewards; -mod find_slot; mod initiate_payout; mod launch; mod new_epoch; @@ -17,7 +16,6 @@ pub use add_rewards::*; pub use broadcast_entry_update::*; pub use clawback_rewards::*; pub use commit_rewards::*; -pub use find_slot::*; pub use initiate_payout::*; pub use launch::*; pub use new_epoch::*; diff --git a/src/cli/reward_distributor/broadcast_entry_update.rs b/src/cli/reward_distributor/broadcast_entry_update.rs index bce4b7ce..949f8287 100644 --- a/src/cli/reward_distributor/broadcast_entry_update.rs +++ b/src/cli/reward_distributor/broadcast_entry_update.rs @@ -3,10 +3,10 @@ use chia::{clvm_utils::ToTreeHash, protocol::Bytes}; use clvmr::{Allocator, NodePtr}; use crate::{ - find_entry_slot_for_puzzle_hash, get_constants, get_last_onchain_timestamp, - hex_string_to_bytes32, multisig_broadcast_thing_finish, multisig_broadcast_thing_start, - sync_distributor, CliError, Db, MedievalVault, RewardDistributorAddEntryAction, - RewardDistributorRemoveEntryAction, RewardDistributorSyncAction, StateSchedulerLayerSolution, + find_entry_slots, get_constants, get_last_onchain_timestamp, hex_string_to_bytes32, + multisig_broadcast_thing_finish, multisig_broadcast_thing_start, sync_distributor, CliError, + Db, MedievalVault, RewardDistributorAddEntryAction, RewardDistributorRemoveEntryAction, + RewardDistributorSyncAction, StateSchedulerLayerSolution, }; pub async fn reward_distributor_broadcast_entry_update( @@ -104,14 +104,17 @@ pub async fn reward_distributor_broadcast_entry_update( if remove_entry { println!("Finding entry slot..."); - let entry_slot = find_entry_slot_for_puzzle_hash( + let entry_slot = find_entry_slots( &mut ctx, - &db, - launcher_id, + &client, + reward_distributor.info.constants, entry_payout_puzzle_hash, + None, Some(entry_shares), ) .await? + .into_iter() + .next() .ok_or(CliError::SlotNotFound("Mirror"))?; let (_conds, last_payment_amount) = reward_distributor diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index 081bbc37..f3bb4fad 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -8,11 +8,11 @@ use clvm_traits::clvm_quote; use clvmr::NodePtr; use crate::{ - assets_xch_only, find_commitment_slot_for_puzzle_hash, find_reward_slot_for_epoch, - get_coin_public_key, get_coinset_client, get_constants, hex_string_to_bytes32, - hex_string_to_signature, new_sk, no_assets, parse_amount, parse_one_sided_offer, - spend_security_coin, spend_to_coin_spend, sync_distributor, wait_for_coin, yes_no_prompt, - CliError, Db, RewardDistributorWithdrawIncentivesAction, SageClient, + assets_xch_only, find_commitment_slots, find_reward_slots, get_coin_public_key, + get_coinset_client, get_constants, hex_string_to_bytes32, hex_string_to_signature, new_sk, + no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, spend_to_coin_spend, + sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, + RewardDistributorWithdrawIncentivesAction, SageClient, }; pub async fn reward_distributor_clawback_rewards( @@ -37,24 +37,28 @@ pub async fn reward_distributor_clawback_rewards( println!("Fetching slots..."); let clawback_ph = Address::decode(&clawback_address)?.puzzle_hash; - let commitment_slot = find_commitment_slot_for_puzzle_hash( + + let commitment_slot = find_commitment_slots( &mut ctx, - &db, - launcher_id, + &client, + distributor.info.constants, clawback_ph, epoch_start, reward_amount, ) .await? + .into_iter() + .next() .ok_or(CliError::SlotNotFound("Commitment"))?; - let reward_slot = find_reward_slot_for_epoch( + let reward_slot = find_reward_slots( &mut ctx, - &db, - launcher_id, + &client, + distributor.info.constants, commitment_slot.info.value.epoch_start, - distributor.info.constants.epoch_seconds, ) .await? + .into_iter() + .next() .ok_or(CliError::SlotNotFound("Reward"))?; println!( diff --git a/src/cli/reward_distributor/find_slot.rs b/src/cli/reward_distributor/find_slot.rs deleted file mode 100644 index 261b9b5c..00000000 --- a/src/cli/reward_distributor/find_slot.rs +++ /dev/null @@ -1,129 +0,0 @@ -use chia::protocol::Bytes32; -use chia_wallet_sdk::driver::SpendContext; - -use crate::{ - CliError, Db, RewardDistributorCommitmentSlotValue, RewardDistributorEntrySlotValue, - RewardDistributorRewardSlotValue, RewardDistributorSlotNonce, Slot, -}; - -pub async fn find_reward_slot_for_epoch( - ctx: &mut SpendContext, - db: &Db, - launcher_id: Bytes32, - epoch_start: u64, - epoch_seconds: u64, -) -> Result>, CliError> { - let mut next_slot_epoch = epoch_start; - let mut reward_slot = None; - - let mut n = 0; - while reward_slot.is_none() && n <= 52 { - let nonce = RewardDistributorSlotNonce::REWARD.to_u64(); - let reward_slot_value_hashes = db - .get_dig_indexed_slot_values_by_epoch_start(next_slot_epoch, nonce) - .await?; - - // 0 or 1 value hashes per epoch - for reward_slot_value_hash in reward_slot_value_hashes { - if let Some(found_reward_slot) = db - .get_slot::( - ctx, - launcher_id, - nonce, - reward_slot_value_hash, - 0, - ) - .await? - { - reward_slot = Some(found_reward_slot); - break; - } - } - - next_slot_epoch -= epoch_seconds; - n += 1; - } - - Ok(reward_slot) -} - -pub async fn find_commitment_slot_for_puzzle_hash( - ctx: &mut SpendContext, - db: &Db, - launcher_id: Bytes32, - clawback_ph: Bytes32, - epoch_start: Option, - reward_amount: Option, -) -> Result>, CliError> { - let nonce = RewardDistributorSlotNonce::COMMITMENT.to_u64(); - let value_hashes = db - .get_dig_indexed_slot_values_by_puzzle_hash(clawback_ph, nonce) - .await?; - - let mut slot = None; - for value_hash in value_hashes { - let Some(commitment_slot) = db - .get_slot::( - ctx, - launcher_id, - nonce, - value_hash, - 0, - ) - .await? - else { - continue; - }; - - if let Some(reward_amount) = reward_amount { - if commitment_slot.info.value.rewards != reward_amount { - continue; - } - } - - if let Some(epoch_start) = epoch_start { - if commitment_slot.info.value.epoch_start != epoch_start { - continue; - } - } - - slot = Some(commitment_slot); - break; - } - - Ok(slot) -} - -pub async fn find_entry_slot_for_puzzle_hash( - ctx: &mut SpendContext, - db: &Db, - launcher_id: Bytes32, - entry_payout_puzzle_hash: Bytes32, - entry_shares: Option, -) -> Result>, CliError> { - let nonce = RewardDistributorSlotNonce::ENTRY.to_u64(); - let value_hashes = db - .get_dig_indexed_slot_values_by_puzzle_hash(entry_payout_puzzle_hash, nonce) - .await?; - - let mut slot = None; - for value_hash in value_hashes { - let Some(entry_slot) = db - .get_slot::(ctx, launcher_id, nonce, value_hash, 0) - .await? - else { - continue; - }; - - if let Some(entry_shares) = entry_shares { - if entry_slot.info.value.shares != entry_shares { - continue; - } - } - - slot = Some(entry_slot); - break; - } - - Ok(slot) -} diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index e22b1864..f200861b 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -314,6 +314,8 @@ pub async fn find_commitment_slots( client: &CoinsetClient, constants: RewardDistributorConstants, clawback_ph: Bytes32, + epoch_start: Option, + rewards: Option, ) -> Result>, CliError> { let mut possible_records = client .get_coin_records_by_hint(clawback_ph, None, None, Some(false)) @@ -346,6 +348,16 @@ pub async fn find_commitment_slots( .iter() .find_map(|slot| { if slot.clawback_ph == clawback_ph { + if let Some(epoch_start) = epoch_start { + if slot.epoch_start != epoch_start { + return None; + } + } + if let Some(rewards) = rewards { + if slot.rewards != rewards { + return None; + } + } let slot = distributor .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::COMMITMENT); if slot.coin == coin_record.coin { @@ -370,6 +382,8 @@ pub async fn find_entry_slots( client: &CoinsetClient, constants: RewardDistributorConstants, payout_puzzle_hash: Bytes32, + initial_cumulative_payout: Option, + shares: Option, ) -> Result>, CliError> { let mut possible_records = client .get_coin_records_by_hint(payout_puzzle_hash, None, None, Some(false)) @@ -401,6 +415,16 @@ pub async fn find_entry_slots( .created_entry_slots .iter() .find_map(|slot| { + if let Some(initial_cumulative_payout) = initial_cumulative_payout { + if initial_cumulative_payout != slot.initial_cumulative_payout { + return None; + } + } + if let Some(shares) = shares { + if shares != slot.shares { + return None; + } + } if slot.payout_puzzle_hash == payout_puzzle_hash { let slot = distributor .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::ENTRY); From 0258bff043a385d78be1c85837217988752664fe Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 14:52:37 +0300 Subject: [PATCH 24/65] no more syncing needed for the distributor :) --- src/cli/reward_distributor/commit_rewards.rs | 16 +++---- src/cli/reward_distributor/initiate_payout.rs | 18 +++++--- src/cli/reward_distributor/new_epoch.rs | 17 ++++---- src/cli/reward_distributor/unstake.rs | 43 +++++++------------ 4 files changed, 44 insertions(+), 50 deletions(-) diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index 1d19ea9c..42eae0fd 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -8,7 +8,7 @@ use chia_wallet_sdk::{ use clvmr::NodePtr; use crate::{ - assets_xch_and_cat, find_reward_slot_for_epoch, get_coinset_client, get_constants, + assets_xch_and_cat, find_reward_slots, get_coinset_client, get_constants, hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorCommitIncentivesAction, SageClient, @@ -82,15 +82,11 @@ pub async fn reward_distributor_commit_rewards( )?; offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - let reward_slot = find_reward_slot_for_epoch( - &mut ctx, - &db, - launcher_id, - epoch_start, - distributor.info.constants.epoch_seconds, - ) - .await? - .ok_or(CliError::SlotNotFound("Reward"))?; + let reward_slot = find_reward_slots(&mut ctx, &client, distributor.info.constants, epoch_start) + .await? + .into_iter() + .next() + .ok_or(CliError::SlotNotFound("Reward"))?; let (sec_conds, _slot1, _slot2) = distributor .new_action::() diff --git a/src/cli/reward_distributor/initiate_payout.rs b/src/cli/reward_distributor/initiate_payout.rs index d5c4292e..dcedd88e 100644 --- a/src/cli/reward_distributor/initiate_payout.rs +++ b/src/cli/reward_distributor/initiate_payout.rs @@ -6,7 +6,7 @@ use chia_wallet_sdk::{ }; use crate::{ - assets_xch_only, find_entry_slot_for_puzzle_hash, get_coinset_client, get_constants, + assets_xch_only, find_entry_slots, get_coinset_client, get_constants, get_last_onchain_timestamp, hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorInitiatePayoutAction, RewardDistributorSyncAction, SageClient, @@ -45,10 +45,18 @@ pub async fn reward_distributor_initiate_payout( } println!("Finding reward slot..."); - let slot = - find_entry_slot_for_puzzle_hash(&mut ctx, &db, launcher_id, payout_puzzle_hash, None) - .await? - .ok_or(CliError::SlotNotFound("Mirror reward"))?; + let slot = find_entry_slots( + &mut ctx, + &client, + distributor.info.constants, + payout_puzzle_hash, + None, + None, + ) + .await? + .into_iter() + .next() + .ok_or(CliError::SlotNotFound("Entry"))?; println!("A one-sided offer will be created. It will contain:"); println!(" 1 mojo",); diff --git a/src/cli/reward_distributor/new_epoch.rs b/src/cli/reward_distributor/new_epoch.rs index fe0c99e9..3ac47533 100644 --- a/src/cli/reward_distributor/new_epoch.rs +++ b/src/cli/reward_distributor/new_epoch.rs @@ -1,8 +1,8 @@ use crate::{ - assets_xch_only, find_reward_slot_for_epoch, get_coinset_client, get_constants, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, - spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, - RewardDistributorNewEpochAction, RewardDistributorSyncAction, SageClient, + assets_xch_only, find_reward_slots, get_coinset_client, get_constants, hex_string_to_bytes32, + new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, + wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorNewEpochAction, + RewardDistributorSyncAction, SageClient, }; use chia::protocol::SpendBundle; use chia_wallet_sdk::{ @@ -40,14 +40,15 @@ pub async fn reward_distributor_new_epoch( } println!("Finding appropriate reward slot..."); - let reward_slot = find_reward_slot_for_epoch( + let reward_slot = find_reward_slots( &mut ctx, - &db, - launcher_id, + &client, + distributor.info.constants, next_epoch_start, - distributor.info.constants.epoch_seconds, ) .await? + .into_iter() + .next() .ok_or(CliError::SlotNotFound("Reward"))?; println!("A one-sided offer will be created. It will contain:"); diff --git a/src/cli/reward_distributor/unstake.rs b/src/cli/reward_distributor/unstake.rs index 84ad2a50..9837252e 100644 --- a/src/cli/reward_distributor/unstake.rs +++ b/src/cli/reward_distributor/unstake.rs @@ -11,12 +11,12 @@ use chia_wallet_sdk::{ }; use crate::{ - assets_xch_only, get_coinset_client, get_last_onchain_timestamp, get_prefix, + assets_xch_only, find_entry_slots, get_coinset_client, get_last_onchain_timestamp, get_prefix, hex_string_to_bytes32, hex_string_to_pubkey, hex_string_to_signature, no_assets, parse_amount, parse_one_sided_offer, prompt_for_value, spend_to_coin_spend, sync_distributor, wait_for_coin, - yes_no_prompt, CliError, Db, NonceWrapperArgs, RewardDistributorEntrySlotValue, - RewardDistributorSlotNonce, RewardDistributorStakeActionArgs, RewardDistributorSyncAction, - RewardDistributorUnstakeAction, SageClient, Slot, NONCE_WRAPPER_PUZZLE_HASH, + yes_no_prompt, CliError, Db, NonceWrapperArgs, RewardDistributorStakeActionArgs, + RewardDistributorSyncAction, RewardDistributorUnstakeAction, SageClient, + NONCE_WRAPPER_PUZZLE_HASH, }; pub async fn reward_distributor_unstake( @@ -64,29 +64,18 @@ pub async fn reward_distributor_unstake( ); println!("Getting entry slot..."); - let entry_slot_value_hashes = db - .get_dig_indexed_slot_values_by_puzzle_hash( - custody_puzzle_hash, - RewardDistributorSlotNonce::ENTRY.to_u64(), - ) - .await?; - if entry_slot_value_hashes.is_empty() { - return Err(CliError::Custom( - "No entry slot found - you may be using the wrong custody address/puzzle hash" - .to_string(), - )); - } - - let entry_slot: Slot = db - .get_slot( - &mut ctx, - launcher_id, - RewardDistributorSlotNonce::ENTRY.to_u64(), - entry_slot_value_hashes[0], - 0, - ) - .await? - .unwrap(); + let entry_slot = find_entry_slots( + &mut ctx, + &client, + distributor.info.constants, + custody_puzzle_hash, + None, + None, + ) + .await? + .into_iter() + .next() + .ok_or(CliError::SlotNotFound("Entry"))?; println!("Fetching locked NFT..."); let locked_nft_hint: Bytes32 = CurriedProgram { From 4eb1fc1caa2d04635fab8716d94f8dec2e93ca7f Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 14:56:28 +0300 Subject: [PATCH 25/65] reward slot appropriate resolution --- .../reward_distributor/clawback_rewards.rs | 9 +- src/cli/reward_distributor/commit_rewards.rs | 15 ++-- src/cli/reward_distributor/new_epoch.rs | 9 +- .../reward_distributor/sync_distributor.rs | 89 ++++++++++--------- 4 files changed, 57 insertions(+), 65 deletions(-) diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index f3bb4fad..9b4c441d 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -8,7 +8,7 @@ use clvm_traits::clvm_quote; use clvmr::NodePtr; use crate::{ - assets_xch_only, find_commitment_slots, find_reward_slots, get_coin_public_key, + assets_xch_only, find_commitment_slots, find_reward_slot, get_coin_public_key, get_coinset_client, get_constants, hex_string_to_bytes32, hex_string_to_signature, new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, spend_to_coin_spend, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, @@ -50,16 +50,13 @@ pub async fn reward_distributor_clawback_rewards( .into_iter() .next() .ok_or(CliError::SlotNotFound("Commitment"))?; - let reward_slot = find_reward_slots( + let reward_slot = find_reward_slot( &mut ctx, &client, distributor.info.constants, commitment_slot.info.value.epoch_start, ) - .await? - .into_iter() - .next() - .ok_or(CliError::SlotNotFound("Reward"))?; + .await?; println!( "Will use commitment slot with rewards={} for epoch_start={}", diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index 42eae0fd..236199cd 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -8,10 +8,10 @@ use chia_wallet_sdk::{ use clvmr::NodePtr; use crate::{ - assets_xch_and_cat, find_reward_slots, get_coinset_client, get_constants, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, - spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, - RewardDistributorCommitIncentivesAction, SageClient, + assets_xch_and_cat, find_reward_slot, get_coinset_client, get_constants, hex_string_to_bytes32, + new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, + wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorCommitIncentivesAction, + SageClient, }; pub async fn reward_distributor_commit_rewards( @@ -82,11 +82,8 @@ pub async fn reward_distributor_commit_rewards( )?; offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - let reward_slot = find_reward_slots(&mut ctx, &client, distributor.info.constants, epoch_start) - .await? - .into_iter() - .next() - .ok_or(CliError::SlotNotFound("Reward"))?; + let reward_slot = + find_reward_slot(&mut ctx, &client, distributor.info.constants, epoch_start).await?; let (sec_conds, _slot1, _slot2) = distributor .new_action::() diff --git a/src/cli/reward_distributor/new_epoch.rs b/src/cli/reward_distributor/new_epoch.rs index 3ac47533..0ea76fc6 100644 --- a/src/cli/reward_distributor/new_epoch.rs +++ b/src/cli/reward_distributor/new_epoch.rs @@ -1,5 +1,5 @@ use crate::{ - assets_xch_only, find_reward_slots, get_coinset_client, get_constants, hex_string_to_bytes32, + assets_xch_only, find_reward_slot, get_coinset_client, get_constants, hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorNewEpochAction, RewardDistributorSyncAction, SageClient, @@ -40,16 +40,13 @@ pub async fn reward_distributor_new_epoch( } println!("Finding appropriate reward slot..."); - let reward_slot = find_reward_slots( + let reward_slot = find_reward_slot( &mut ctx, &client, distributor.info.constants, next_epoch_start, ) - .await? - .into_iter() - .next() - .ok_or(CliError::SlotNotFound("Reward"))?; + .await?; println!("A one-sided offer will be created. It will contain:"); println!(" 1 mojo",); diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index f200861b..2137d0ed 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -253,60 +253,61 @@ pub async fn mempool_distributor_maybe( Ok(distributor) } -pub async fn find_reward_slots( +pub async fn find_reward_slot( ctx: &mut SpendContext, client: &CoinsetClient, constants: RewardDistributorConstants, epoch_start: u64, -) -> Result>, CliError> { - let mut possible_records = client - .get_coin_records_by_hint(epoch_start.tree_hash().into(), None, None, Some(false)) - .await? - .coin_records - .ok_or(DriverError::MissingHint)?; - - let mut slots = Vec::new(); +) -> Result, CliError> { + let mut epoch_start = epoch_start; - while !possible_records.is_empty() { - let coin_record = possible_records.remove(0); - let distributor_spent = client - .get_puzzle_and_solution( - coin_record.coin.parent_coin_info, - Some(coin_record.confirmed_block_index), - ) + loop { + let mut possible_records = client + .get_coin_records_by_hint(epoch_start.tree_hash().into(), None, None, Some(false)) .await? - .coin_solution - .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; - - let Some(distributor) = - RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? - else { - continue; - }; - - if let Some(slot) = distributor - .pending_spend - .created_reward_slots - .iter() - .find_map(|slot| { - if slot.epoch_start == epoch_start { - let slot = distributor - .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::REWARD); - if slot.coin == coin_record.coin { - Some(slot) + .coin_records + .ok_or(DriverError::MissingHint)?; + + while !possible_records.is_empty() { + let coin_record = possible_records.remove(0); + let distributor_spent = client + .get_puzzle_and_solution( + coin_record.coin.parent_coin_info, + Some(coin_record.confirmed_block_index), + ) + .await? + .coin_solution + .ok_or(CliError::CoinNotSpent(coin_record.coin.parent_coin_info))?; + + let Some(distributor) = + RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? + else { + continue; + }; + + if let Some(slot) = distributor + .pending_spend + .created_reward_slots + .iter() + .find_map(|slot| { + if slot.epoch_start == epoch_start { + let slot = distributor + .created_slot_value_to_slot(*slot, RewardDistributorSlotNonce::REWARD); + if slot.coin == coin_record.coin { + Some(slot) + } else { + None + } } else { None } - } else { - None - } - }) - { - slots.push(slot); - }; + }) + { + return Ok(slot); + }; + } + epoch_start -= constants.epoch_seconds; } - - Ok(slots) } pub async fn find_commitment_slots( From 8f2941da968f0d38537af02d2d57d1a75e546452 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 15:19:46 +0300 Subject: [PATCH 26/65] do not return created slots from function calls as the pending spend contains them anyway --- src/layers/actions/catalog/register.rs | 11 ++----- .../actions/reward_distributor/add_entry.rs | 9 ++---- .../reward_distributor/commit_incentives.rs | 29 ++----------------- .../reward_distributor/initiate_payout.rs | 5 ++-- .../actions/reward_distributor/new_epoch.rs | 9 ++---- .../actions/reward_distributor/stake.rs | 14 +-------- .../reward_distributor/withdraw_incentives.rs | 13 ++------- src/layers/actions/xchandles/expire.rs | 10 ++----- src/layers/actions/xchandles/extend.rs | 7 ++--- src/layers/actions/xchandles/oracle.rs | 9 ++---- src/layers/actions/xchandles/refund.rs | 11 ++----- src/layers/actions/xchandles/register.rs | 14 ++------- src/layers/actions/xchandles/update.rs | 19 ++++-------- 13 files changed, 34 insertions(+), 126 deletions(-) diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index 4daa74b6..5aa64ee7 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -126,7 +126,7 @@ impl CatalogRegisterAction { right_slot: Slot, precommit_coin: PrecommitCoin, eve_nft_inner_spend: Spend, - ) -> Result<(Conditions, Vec>), DriverError> { + ) -> Result { // calculate announcement let register_announcement: Bytes32 = clvm_tuple!(tail_hash, precommit_coin.value.initial_inner_puzzle_hash) @@ -182,23 +182,18 @@ impl CatalogRegisterAction { let my_solution = my_solution.to_clvm(ctx)?; let my_puzzle = self.construct_puzzle(ctx)?; - let slot_values = self.created_slot_values(ctx, my_solution)?; catalog.insert_action_spend(ctx, Spend::new(my_puzzle, my_solution))?; // spend slots left_slot.spend(ctx, my_inner_puzzle_hash)?; right_slot.spend(ctx, my_inner_puzzle_hash)?; - Ok(( + Ok( Conditions::new().assert_puzzle_announcement(announcement_id( catalog.coin.puzzle_hash, register_announcement, )), - slot_values - .into_iter() - .map(|s| catalog.created_slot_value_to_slot(s)) - .collect(), - )) + ) } } diff --git a/src/layers/actions/reward_distributor/add_entry.rs b/src/layers/actions/reward_distributor/add_entry.rs index 5102fd62..bac4112d 100644 --- a/src/layers/actions/reward_distributor/add_entry.rs +++ b/src/layers/actions/reward_distributor/add_entry.rs @@ -79,7 +79,7 @@ impl RewardDistributorAddEntryAction { payout_puzzle_hash: Bytes32, shares: u64, manager_singleton_inner_puzzle_hash: Bytes32, - ) -> Result<(Conditions, Slot), DriverError> { + ) -> Result { // calculate message that the manager needs to send let add_entry_message: Bytes32 = clvm_tuple!(payout_puzzle_hash, shares).tree_hash().into(); let mut add_entry_message: Vec = add_entry_message.to_vec(); @@ -98,13 +98,8 @@ impl RewardDistributorAddEntryAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let my_state = distributor.pending_spend.latest_state.1; - let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - Ok(( - add_entry_message, - distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), - )) + Ok(add_entry_message) } } diff --git a/src/layers/actions/reward_distributor/commit_incentives.rs b/src/layers/actions/reward_distributor/commit_incentives.rs index 53e9a091..7e4f5504 100644 --- a/src/layers/actions/reward_distributor/commit_incentives.rs +++ b/src/layers/actions/reward_distributor/commit_incentives.rs @@ -129,14 +129,7 @@ impl RewardDistributorCommitIncentivesAction { epoch_start: u64, clawback_ph: Bytes32, rewards_to_add: u64, - ) -> Result< - ( - Conditions, - Slot, - Vec>, - ), - DriverError, - > { + ) -> Result { let reward_slot = distributor.actual_reward_slot_value(reward_slot); let new_commitment_slot_value = RewardDistributorCommitmentSlotValue { @@ -164,29 +157,13 @@ impl RewardDistributorCommitIncentivesAction { // spend reward slot reward_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let (_commitment_slot_value, reward_slot_values) = Self::created_slot_values( - ctx, - distributor.info.constants.epoch_seconds, - action_solution, - )?; distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - Ok(( + Ok( Conditions::new().assert_puzzle_announcement(announcement_id( distributor.coin.puzzle_hash, commit_reward_announcement, )), - distributor.created_slot_value_to_slot( - new_commitment_slot_value, - RewardDistributorSlotNonce::COMMITMENT, - ), - reward_slot_values - .into_iter() - .map(|slot_value| { - distributor - .created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD) - }) - .collect(), - )) + ) } } diff --git a/src/layers/actions/reward_distributor/initiate_payout.rs b/src/layers/actions/reward_distributor/initiate_payout.rs index 10f2b055..28f02bd6 100644 --- a/src/layers/actions/reward_distributor/initiate_payout.rs +++ b/src/layers/actions/reward_distributor/initiate_payout.rs @@ -84,7 +84,7 @@ impl RewardDistributorInitiatePayoutAction { ctx: &mut SpendContext, distributor: &mut RewardDistributor, entry_slot: Slot, - ) -> Result<(Conditions, Slot, u64), DriverError> { + ) -> Result<(Conditions, u64), DriverError> { let my_state = distributor.pending_spend.latest_state.1; let entry_slot = distributor.actual_entry_slot_value(entry_slot); @@ -112,14 +112,13 @@ impl RewardDistributorInitiatePayoutAction { // spend entry slot entry_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; + Ok(( Conditions::new().assert_puzzle_announcement(announcement_id( distributor.coin.puzzle_hash, initiate_payout_announcement, )), - distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), withdrawal_amount, )) } diff --git a/src/layers/actions/reward_distributor/new_epoch.rs b/src/layers/actions/reward_distributor/new_epoch.rs index c1fb5615..66acdc0e 100644 --- a/src/layers/actions/reward_distributor/new_epoch.rs +++ b/src/layers/actions/reward_distributor/new_epoch.rs @@ -91,7 +91,7 @@ impl RewardDistributorNewEpochAction { ctx: &mut SpendContext, distributor: &mut RewardDistributor, reward_slot: Slot, - ) -> Result<(Conditions, Slot, u64), DriverError> { + ) -> Result<(Conditions, u64), DriverError> { // also returns fee let my_state = distributor.pending_spend.latest_state.1; let reward_slot = distributor.actual_reward_slot_value(reward_slot); @@ -128,13 +128,8 @@ impl RewardDistributorNewEpochAction { // spend slot reward_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; - let slot_value = Self::created_slot_value(ctx, action_solution)?; distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - Ok(( - new_epoch_conditions, - distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD), - fee, - )) + Ok((new_epoch_conditions, fee)) } } diff --git a/src/layers/actions/reward_distributor/stake.rs b/src/layers/actions/reward_distributor/stake.rs index f95bd0d9..32e47b44 100644 --- a/src/layers/actions/reward_distributor/stake.rs +++ b/src/layers/actions/reward_distributor/stake.rs @@ -85,16 +85,7 @@ impl RewardDistributorStakeAction { current_nft: Nft, nft_launcher_proof: NftLauncherProof, entry_custody_puzzle_hash: Bytes32, - ) -> Result< - ( - Conditions, - NotarizedPayment, - Slot, - Nft, - ), - DriverError, - > { - let my_state = distributor.pending_spend.latest_state.1; + ) -> Result<(Conditions, NotarizedPayment, Nft), DriverError> { let ephemeral_counter = ctx.extract::(distributor.pending_spend.latest_state.0)?; let my_id = distributor.coin.coin_id(); @@ -147,8 +138,6 @@ impl RewardDistributorStakeAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let slot_value = Self::created_slot_value(ctx, &my_state, action_solution)?; - let msg: Bytes32 = notarized_payment.tree_hash().into(); distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; @@ -156,7 +145,6 @@ impl RewardDistributorStakeAction { Conditions::new() .assert_puzzle_announcement(announcement_id(nft.coin.puzzle_hash, msg)), notarized_payment, - distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::ENTRY), nft.wrapped_child(payment_puzzle_hash, None, nft.info.metadata), )) } diff --git a/src/layers/actions/reward_distributor/withdraw_incentives.rs b/src/layers/actions/reward_distributor/withdraw_incentives.rs index c9af725a..9157fee2 100644 --- a/src/layers/actions/reward_distributor/withdraw_incentives.rs +++ b/src/layers/actions/reward_distributor/withdraw_incentives.rs @@ -103,7 +103,7 @@ impl RewardDistributorWithdrawIncentivesAction { distributor: &mut RewardDistributor, commitment_slot: Slot, reward_slot: Slot, - ) -> Result<(Conditions, Slot, u64), DriverError> { + ) -> Result<(Conditions, u64), DriverError> { // last u64 = withdrawn amount let commitment_slot = distributor.actual_commitment_slot_value(commitment_slot); let reward_slot = distributor.actual_reward_slot_value(reward_slot); @@ -131,11 +131,6 @@ impl RewardDistributorWithdrawIncentivesAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let slot_value = Self::created_slot_value( - ctx, - distributor.info.constants.withdrawal_share_bps, - action_solution, - )?; distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; // spend slots @@ -143,11 +138,7 @@ impl RewardDistributorWithdrawIncentivesAction { reward_slot.spend(ctx, my_inner_puzzle_hash)?; commitment_slot.spend(ctx, my_inner_puzzle_hash)?; - Ok(( - withdraw_incentives_conditions, - distributor.created_slot_value_to_slot(slot_value, RewardDistributorSlotNonce::REWARD), - withdrawal_share, - )) + Ok((withdraw_incentives_conditions, withdrawal_share)) } } diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index 277946c2..c2b64368 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -128,7 +128,7 @@ impl XchandlesExpireAction { base_handle_price: u64, registration_period: u64, precommit_coin: PrecommitCoin, - ) -> Result<(Conditions, Slot), DriverError> { + ) -> Result { let my_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); // announcement is simply premcommitment coin ph @@ -179,18 +179,14 @@ impl XchandlesExpireAction { let action_puzzle = self.construct_puzzle(ctx)?; registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot_value = Self::created_slot_value(ctx, action_solution)?; // spend slot slot.spend(ctx, my_inner_puzzle_hash)?; let mut expire_ann: Vec = expire_ann.to_vec(); expire_ann.insert(0, b'x'); - Ok(( - Conditions::new() - .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, expire_ann)), - registry.created_slot_value_to_slot(new_slot_value.clone()), - )) + Ok(Conditions::new() + .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, expire_ann))) } } diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index d1aff4c3..b8fb0e65 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -112,7 +112,7 @@ impl XchandlesExtendAction { base_handle_price: u64, registration_period: u64, num_periods: u64, - ) -> Result<(NotarizedPayment, Conditions, Slot), DriverError> { + ) -> Result<(Conditions, NotarizedPayment), DriverError> { let spender_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); // spend self @@ -161,13 +161,10 @@ impl XchandlesExtendAction { let mut extend_ann: Vec = clvm_tuple!(renew_amount, handle).tree_hash().to_vec(); extend_ann.insert(0, b'e'); - let new_slot_value = Self::created_slot_value(ctx, action_solution)?; - Ok(( - notarized_payment, Conditions::new() .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, extend_ann)), - registry.created_slot_value_to_slot(new_slot_value.clone()), + notarized_payment, )) } } diff --git a/src/layers/actions/xchandles/oracle.rs b/src/layers/actions/xchandles/oracle.rs index 866b27c9..b63fb11e 100644 --- a/src/layers/actions/xchandles/oracle.rs +++ b/src/layers/actions/xchandles/oracle.rs @@ -60,7 +60,7 @@ impl XchandlesOracleAction { ctx: &mut SpendContext, registry: &mut XchandlesRegistry, slot: Slot, - ) -> Result<(Conditions, Slot), DriverError> { + ) -> Result { // spend self let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&slot.info.value)?; @@ -75,11 +75,8 @@ impl XchandlesOracleAction { let mut oracle_ann = new_slot.tree_hash().to_vec(); oracle_ann.insert(0, b'o'); - Ok(( - Conditions::new() - .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, oracle_ann)), - registry.created_slot_value_to_slot(new_slot.clone()), - )) + Ok(Conditions::new() + .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, oracle_ann))) } } diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index d1fcf5dd..164837a6 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -82,7 +82,7 @@ impl XchandlesRefundAction { precommited_pricing_puzzle_reveal: NodePtr, precommited_pricing_puzzle_solution: NodePtr, slot: Option>, - ) -> Result<(Conditions, Option>), DriverError> { + ) -> Result { // calculate announcement let mut refund_announcement: Vec = precommit_coin.coin.puzzle_hash.to_vec(); refund_announcement.insert(0, b'$'); @@ -126,22 +126,17 @@ impl XchandlesRefundAction { registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot = slot - .as_ref() - .map(|slot| registry.created_slot_value_to_slot(slot.info.value.clone())); - // if there's a slot, spend it if let Some(slot) = slot { slot.spend(ctx, my_inner_puzzle_hash)?; } - Ok(( + Ok( Conditions::new().assert_puzzle_announcement(announcement_id( registry.coin.puzzle_hash, refund_announcement, )), - new_slot, - )) + ) } } diff --git a/src/layers/actions/xchandles/register.rs b/src/layers/actions/xchandles/register.rs index 242c449b..1682de1d 100644 --- a/src/layers/actions/xchandles/register.rs +++ b/src/layers/actions/xchandles/register.rs @@ -145,7 +145,7 @@ impl XchandlesRegisterAction { precommit_coin: PrecommitCoin, base_handle_price: u64, registration_period: u64, - ) -> Result<(Conditions, [Slot; 3]), DriverError> { + ) -> Result { let handle: String = precommit_coin.value.handle.clone(); let handle_hash: Bytes32 = handle.tree_hash().into(); let (left_slot, right_slot) = registry.actual_neigbors(handle_hash, left_slot, right_slot); @@ -213,20 +213,12 @@ impl XchandlesRegisterAction { left_slot.spend(ctx, my_inner_puzzle_hash)?; right_slot.spend(ctx, my_inner_puzzle_hash)?; - let [new_left_slot, new_slot, new_right_slot] = - Self::created_slot_values(ctx, action_solution)?; - - Ok(( + Ok( Conditions::new().assert_puzzle_announcement(announcement_id( registry.coin.puzzle_hash, register_announcement, )), - [ - registry.created_slot_value_to_slot(new_left_slot), - registry.created_slot_value_to_slot(new_slot), - registry.created_slot_value_to_slot(new_right_slot), - ], - )) + ) } } diff --git a/src/layers/actions/xchandles/update.rs b/src/layers/actions/xchandles/update.rs index 44d9dde3..4d946cce 100644 --- a/src/layers/actions/xchandles/update.rs +++ b/src/layers/actions/xchandles/update.rs @@ -73,7 +73,7 @@ impl XchandlesUpdateAction { new_owner_launcher_id: Bytes32, new_resolved_data: Bytes, announcer_inner_puzzle_hash: Bytes32, - ) -> Result<(Conditions, Slot), DriverError> { + ) -> Result { // spend self let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&XchandlesUpdateActionSolution { @@ -88,12 +88,6 @@ impl XchandlesUpdateAction { registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; - let new_slot_value = slot - .info - .value - .clone() - .with_data(new_owner_launcher_id, new_resolved_data.clone()); - // spend slot let my_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); @@ -106,13 +100,10 @@ impl XchandlesUpdateAction { slot.spend(ctx, my_inner_puzzle_hash)?; - Ok(( - Conditions::new().send_message( - 18, - msg.into(), - vec![ctx.alloc(®istry.coin.puzzle_hash)?], - ), - registry.created_slot_value_to_slot(new_slot_value), + Ok(Conditions::new().send_message( + 18, + msg.into(), + vec![ctx.alloc(®istry.coin.puzzle_hash)?], )) } } From 698922bbb8d9120327cf67d0821e6cdc7f4ae5fa Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 15:32:41 +0300 Subject: [PATCH 27/65] no more errors but a lot of warnings and no idea if tests will run --- src/cli/catalog/continue_launch.rs | 2 +- src/cli/catalog/register.rs | 27 ++-- .../broadcast_entry_update.rs | 2 +- .../reward_distributor/clawback_rewards.rs | 2 +- src/cli/reward_distributor/commit_rewards.rs | 2 +- src/cli/reward_distributor/initiate_payout.rs | 2 +- src/cli/reward_distributor/new_epoch.rs | 2 +- src/cli/reward_distributor/stake.rs | 2 +- src/cli/xchandles/continue_launch.rs | 2 +- src/cli/xchandles/expire.rs | 22 ++- src/cli/xchandles/extend.rs | 21 ++- src/cli/xchandles/register.rs | 22 ++- src/cli/xchandles/update.rs | 2 +- src/drivers.rs | 141 +++++++++++++++--- 14 files changed, 168 insertions(+), 83 deletions(-) diff --git a/src/cli/catalog/continue_launch.rs b/src/cli/catalog/continue_launch.rs index ca7ed226..e1e8aa79 100644 --- a/src/cli/catalog/continue_launch.rs +++ b/src/cli/catalog/continue_launch.rs @@ -510,7 +510,7 @@ pub async fn catalog_continue_launch( let eve_nft_inner_puzzle = initial_cat_inner_puzzle_ptr(&mut ctx, &cats[i])?; - let (sec_conds, _new_slots) = catalog.new_action::().spend( + let sec_conds = catalog.new_action::().spend( &mut ctx, &mut catalog, tail_hash, diff --git a/src/cli/catalog/register.rs b/src/cli/catalog/register.rs index 0b1e18e3..c577b361 100644 --- a/src/cli/catalog/register.rs +++ b/src/cli/catalog/register.rs @@ -369,21 +369,18 @@ pub async fn catalog_register( .await? }; - catalog - .new_action::() - .spend( - &mut ctx, - &mut catalog, - registered_asset_id, - left_slot, - right_slot, - precommit_coin, - Spend { - puzzle: initial_nft_puzzle_ptr, - solution: NodePtr::NIL, - }, - )? - .0 + catalog.new_action::().spend( + &mut ctx, + &mut catalog, + registered_asset_id, + left_slot, + right_slot, + precommit_coin, + Spend { + puzzle: initial_nft_puzzle_ptr, + solution: NodePtr::NIL, + }, + )? }; let _new_catalog = catalog.finish_spend(&mut ctx)?; diff --git a/src/cli/reward_distributor/broadcast_entry_update.rs b/src/cli/reward_distributor/broadcast_entry_update.rs index 949f8287..db5f735c 100644 --- a/src/cli/reward_distributor/broadcast_entry_update.rs +++ b/src/cli/reward_distributor/broadcast_entry_update.rs @@ -130,7 +130,7 @@ pub async fn reward_distributor_broadcast_entry_update( last_payment_amount ); } else { - let (_conds, _new_slot) = reward_distributor + let _conds = reward_distributor .new_action::() .spend( &mut ctx, diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index 9b4c441d..dfd42a72 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -82,7 +82,7 @@ pub async fn reward_distributor_clawback_rewards( let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - let (send_message_conds, _slot1, returned_amount) = distributor + let (send_message_conds, returned_amount) = distributor .new_action::() .spend(&mut ctx, &mut distributor, commitment_slot, reward_slot)?; let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index 236199cd..18b0a79b 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -85,7 +85,7 @@ pub async fn reward_distributor_commit_rewards( let reward_slot = find_reward_slot(&mut ctx, &client, distributor.info.constants, epoch_start).await?; - let (sec_conds, _slot1, _slot2) = distributor + let sec_conds = distributor .new_action::() .spend( &mut ctx, diff --git a/src/cli/reward_distributor/initiate_payout.rs b/src/cli/reward_distributor/initiate_payout.rs index dcedd88e..6c9283c4 100644 --- a/src/cli/reward_distributor/initiate_payout.rs +++ b/src/cli/reward_distributor/initiate_payout.rs @@ -84,7 +84,7 @@ pub async fn reward_distributor_initiate_payout( Conditions::new() }; - let (new_conds, _new_slot, payout_amount) = distributor + let (new_conds, payout_amount) = distributor .new_action::() .spend(&mut ctx, &mut distributor, slot)?; sec_conds = sec_conds.extend(new_conds); diff --git a/src/cli/reward_distributor/new_epoch.rs b/src/cli/reward_distributor/new_epoch.rs index 0ea76fc6..4edc4b79 100644 --- a/src/cli/reward_distributor/new_epoch.rs +++ b/src/cli/reward_distributor/new_epoch.rs @@ -66,7 +66,7 @@ pub async fn reward_distributor_new_epoch( let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - let (sec_conds, _new_slot, fee) = distributor + let (sec_conds, fee) = distributor .new_action::() .spend(&mut ctx, &mut distributor, reward_slot)?; let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; diff --git a/src/cli/reward_distributor/stake.rs b/src/cli/reward_distributor/stake.rs index c4c0d64a..cb9b2784 100644 --- a/src/cli/reward_distributor/stake.rs +++ b/src/cli/reward_distributor/stake.rs @@ -191,7 +191,7 @@ pub async fn reward_distributor_stake( } // accept offer - let (conds, notarized_payment, _slot, _locked_nft) = distributor + let (conds, notarized_payment, _locked_nft) = distributor .new_action::() .spend( &mut ctx, diff --git a/src/cli/xchandles/continue_launch.rs b/src/cli/xchandles/continue_launch.rs index 6bc59b52..b11e2186 100644 --- a/src/cli/xchandles/continue_launch.rs +++ b/src/cli/xchandles/continue_launch.rs @@ -515,7 +515,7 @@ pub async fn xchandles_continue_launch( let (left_slot, right_slot) = registry.actual_neigbors(handle_hash, left_slot, right_slot); - let (sec_conds, _new_slots) = registry.new_action::().spend( + let sec_conds = registry.new_action::().spend( &mut ctx, &mut registry, left_slot, diff --git a/src/cli/xchandles/expire.rs b/src/cli/xchandles/expire.rs index d6f41b37..22de5d2f 100644 --- a/src/cli/xchandles/expire.rs +++ b/src/cli/xchandles/expire.rs @@ -337,21 +337,17 @@ pub async fn xchandles_expire( precommitted_pricing_solution, slot, )? - .0 .reserve_fee(1) } else { - registry - .new_action::() - .spend( - &mut ctx, - &mut registry, - slot, - num_periods, - payment_cat_base_price, - registration_period, - precommit_coin, - )? - .0 + registry.new_action::().spend( + &mut ctx, + &mut registry, + slot, + num_periods, + payment_cat_base_price, + registration_period, + precommit_coin, + )? }; let _new_registry = registry.finish_spend(&mut ctx)?; diff --git a/src/cli/xchandles/extend.rs b/src/cli/xchandles/extend.rs index 4d85efef..b6016d4a 100644 --- a/src/cli/xchandles/extend.rs +++ b/src/cli/xchandles/extend.rs @@ -81,17 +81,16 @@ pub async fn xchandles_extend( .await? }; - let (notarized_payment, sec_conds, _new_slot) = - registry.new_action::().spend( - &mut ctx, - &mut registry, - handle, - slot, - payment_asset_id, - payment_cat_base_price, - registration_period, - num_periods, - )?; + let (sec_conds, notarized_payment) = registry.new_action::().spend( + &mut ctx, + &mut registry, + handle, + slot, + payment_asset_id, + payment_cat_base_price, + registration_period, + num_periods, + )?; yes_no_prompt("Continue with extension?")?; diff --git a/src/cli/xchandles/register.rs b/src/cli/xchandles/register.rs index 30d142a1..59c6f515 100644 --- a/src/cli/xchandles/register.rs +++ b/src/cli/xchandles/register.rs @@ -326,7 +326,6 @@ pub async fn xchandles_register( precommitted_pricing_solution, slot, )? - .0 .reserve_fee(1) } else { let (left_slot, right_slot) = if local { @@ -339,18 +338,15 @@ pub async fn xchandles_register( .await? }; - registry - .new_action::() - .spend( - &mut ctx, - &mut registry, - left_slot, - right_slot, - precommit_coin, - payment_cat_base_price, - registration_period, - )? - .0 + registry.new_action::().spend( + &mut ctx, + &mut registry, + left_slot, + right_slot, + precommit_coin, + payment_cat_base_price, + registration_period, + )? }; let _new_registry = registry.finish_spend(&mut ctx)?; diff --git a/src/cli/xchandles/update.rs b/src/cli/xchandles/update.rs index 091c08fb..dda2ff58 100644 --- a/src/cli/xchandles/update.rs +++ b/src/cli/xchandles/update.rs @@ -147,7 +147,7 @@ pub async fn xchandles_update( let nft = offer.created_nft.unwrap(); - let (nft_inner_conds, _new_slot) = registry.new_action::().spend( + let nft_inner_conds = registry.new_action::().spend( &mut ctx, &mut registry, slot, diff --git a/src/drivers.rs b/src/drivers.rs index 37ea3529..c22d76c7 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1439,7 +1439,7 @@ mod tests { benchmark.add_spends(ctx, &mut sim, "update_price", &[user_bls.sk.clone()])?; }; - let (secure_cond, new_slots) = catalog.new_action::().spend( + let secure_cond = catalog.new_action::().spend( ctx, &mut catalog, tail_hash.into(), @@ -1475,7 +1475,7 @@ mod tests { s.info.value_hash != left_slot.info.value_hash && s.info.value_hash != right_slot.info.value_hash }); - slots.extend(new_slots); + slots.extend(created_slots.clone()); created_slots.into_iter().for_each(|s| { assert!(sim @@ -1658,7 +1658,7 @@ mod tests { let mut registry = registry; let used_slot_value_hash = slot.clone().map(|s| s.info.value_hash); - let (secure_cond, _new_slot_maybe) = registry.new_action::().spend( + let secure_cond = registry.new_action::().spend( ctx, &mut registry, precommit_coin, @@ -1984,7 +1984,7 @@ mod tests { }; let spent_values = [left_slot.info.value.clone(), right_slot.info.value.clone()]; - let (secure_cond, new_slots) = registry.new_action::().spend( + let secure_cond = registry.new_action::().spend( ctx, &mut registry, left_slot.clone(), @@ -2006,6 +2006,12 @@ mod tests { .collect::>(), spent_values.iter().rev().collect::>(), ); + let new_slots = registry + .pending_spend + .created_slots + .iter() + .map(|s| registry.created_slot_value_to_slot(s.clone())) + .collect::>(); registry = registry.finish_spend(ctx)?; sim.pass_time(100); // registration start was at timestamp 100 @@ -2022,11 +2028,13 @@ mod tests { // test on-chain oracle for current handle let spent_slot_value_hash = oracle_slot.info.value_hash; - let (oracle_conds, new_slot) = registry.new_action::().spend( + let oracle_conds = registry.new_action::().spend( ctx, &mut registry, oracle_slot.clone(), )?; + let new_slot = registry + .created_slot_value_to_slot(registry.pending_spend.created_slots[0].clone()); ensure_conditions_met(ctx, &mut sim, oracle_conds, 0)?; @@ -2056,7 +2064,7 @@ mod tests { XchandlesFactorPricingPuzzleArgs::get_price(base_price, &handle, extension_years); let spent_slot_value_hash = extension_slot.info.value_hash; - let (notarized_payment, extend_conds, new_slot) = + let (extend_conds, notarized_payment) = registry.new_action::().spend( ctx, &mut registry, @@ -2067,6 +2075,8 @@ mod tests { reg_period, extension_years, )?; + let new_slot = registry + .created_slot_value_to_slot(registry.pending_spend.created_slots[0].clone()); assert_eq!( spent_slot_value_hash, @@ -2135,7 +2145,7 @@ mod tests { let update_slot = new_slot; let update_slot_value_hash = update_slot.info.value_hash; - let (update_conds, new_slot) = registry.new_action::().spend( + let update_conds = registry.new_action::().spend( ctx, &mut registry, update_slot.clone(), @@ -2143,6 +2153,8 @@ mod tests { new_resolved_data, did.info.inner_puzzle_hash().into(), )?; + let new_slot = registry + .created_slot_value_to_slot(registry.pending_spend.created_slots[0].clone()); let _new_did = did.update(ctx, &user_p2, update_conds)?; @@ -2261,7 +2273,7 @@ mod tests { )?; let spent_slot_value_hash = initial_slot.info.value_hash; - let (expire_conds, _new_slot) = registry.new_action::().spend( + let expire_conds = registry.new_action::().spend( ctx, &mut registry, initial_slot.clone(), @@ -2732,7 +2744,7 @@ mod tests { // add the 1st entry/NFT before reward epoch ('first epoch') begins let (entry1_slot, _nft1) = if manager_type == RewardDistributorType::Manager { - let (manager_conditions, entry1_slot) = registry + let manager_conditions = registry .new_action::() .spend( ctx, @@ -2741,6 +2753,10 @@ mod tests { 1, manager_or_did_singleton_inner_puzzle_hash, )?; + let entry1_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_entry_slots[0].clone(), + RewardDistributorSlotNonce::ENTRY, + ); registry = registry.finish_spend(ctx, vec![])?; (manager_or_did_coin, manager_or_did_singleton_proof) = spend_manager_singleton( @@ -2797,9 +2813,13 @@ mod tests { }], }; - let (sec_conds, notarized_payment, entry1_slot, locked_nft) = registry + let (sec_conds, notarized_payment, locked_nft) = registry .new_action::() .spend(ctx, &mut registry, nft, nft_proof, nft_bls.puzzle_hash)?; + let entry1_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_entry_slots[0].clone(), + RewardDistributorSlotNonce::ENTRY, + ); registry = registry.finish_spend(ctx, vec![])?; ensure_conditions_met(ctx, &mut sim, sec_conds, 0)?; @@ -2835,7 +2855,7 @@ mod tests { // commit incentives for first epoch let rewards_to_add = constants.epoch_seconds; - let (secure_conditions, first_epoch_commitment_slot, mut incentive_slots) = registry + let secure_conditions = registry .new_action::() .spend( ctx, @@ -2845,6 +2865,18 @@ mod tests { cat_minter.puzzle_hash, rewards_to_add, )?; + let first_epoch_commitment_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_commitment_slots[0].clone(), + RewardDistributorSlotNonce::COMMITMENT, + ); + let mut incentive_slots = registry + .pending_spend + .created_reward_slots + .iter() + .map(|s| { + registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) + }) + .collect::>(); // spend reserve and source cat together so deltas add up let source_cat_spend = CatSpend::new( @@ -2876,7 +2908,7 @@ mod tests { // commit incentives for fifth epoch let fifth_epoch_start = first_epoch_start + constants.epoch_seconds * 4; let rewards_to_add = constants.epoch_seconds * 10; - let (secure_conditions, fifth_epoch_commitment_slot, new_incentive_slots) = registry + let secure_conditions = registry .new_action::() .spend( ctx, @@ -2886,6 +2918,18 @@ mod tests { cat_minter.puzzle_hash, rewards_to_add, )?; + let fifth_epoch_commitment_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_commitment_slots[0].clone(), + RewardDistributorSlotNonce::COMMITMENT, + ); + let new_incentive_slots = registry + .pending_spend + .created_reward_slots + .iter() + .map(|s| { + registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) + }) + .collect::>(); let new_value_keys = new_incentive_slots .iter() @@ -2924,7 +2968,7 @@ mod tests { // 2nd commit incentives for fifth epoch let rewards_to_add = constants.epoch_seconds * 2; - let (secure_conditions, fifth_epoch_commitment_slot2, new_incentive_slots) = registry + let secure_conditions = registry .new_action::() .spend( ctx, @@ -2938,6 +2982,18 @@ mod tests { cat_minter.puzzle_hash, rewards_to_add, )?; + let fifth_epoch_commitment_slot2 = registry.created_slot_value_to_slot( + registry.pending_spend.created_commitment_slots[0].clone(), + RewardDistributorSlotNonce::COMMITMENT, + ); + let new_incentive_slots = registry + .pending_spend + .created_reward_slots + .iter() + .map(|s| { + registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) + }) + .collect::>(); let new_value_keys = new_incentive_slots .iter() @@ -2980,7 +3036,7 @@ mod tests { .is_none()); // withdraw the 1st incentives for epoch 5 - let (withdraw_incentives_conditions, new_reward_slot, withdrawn_amount) = registry + let (withdraw_incentives_conditions, withdrawn_amount) = registry .new_action::() .spend( ctx, @@ -2992,6 +3048,10 @@ mod tests { .unwrap() .clone(), )?; + let new_reward_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_reward_slots[0].clone(), + RewardDistributorSlotNonce::REWARD, + ); let payout_coin_id = registry .reserve @@ -3038,7 +3098,7 @@ mod tests { .find(|s| s.info.value.epoch_start == first_epoch_start) .unwrap() .clone(); - let (new_epoch_conditions, new_reward_slot, fee) = registry + let (new_epoch_conditions, fee) = registry .new_action::() .spend( ctx, @@ -3046,6 +3106,10 @@ mod tests { first_epoch_incentives_slot.clone(), // first_epoch_incentives_slot.info.value.rewards, )?; + let new_reward_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_reward_slots[0].clone(), + RewardDistributorSlotNonce::REWARD, + ); let payout_coin_id = reserve_cat .wrapped_child(constants.fee_payout_puzzle_hash, fee) .coin @@ -3186,7 +3250,7 @@ mod tests { let nft2_bls = sim.bls(0); let nft3_bls = sim.bls(0); let (entry2_slot, other_nft2_info) = if manager_type == RewardDistributorType::Manager { - let (manager_conditions, entry2_slot) = registry + let manager_conditions = registry .new_action::() .spend( ctx, @@ -3195,6 +3259,11 @@ mod tests { 2, manager_or_did_singleton_inner_puzzle_hash, )?; + let entry2_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_entry_slots[0].clone(), + RewardDistributorSlotNonce::ENTRY, + ); + (manager_or_did_coin, manager_or_did_singleton_proof) = spend_manager_singleton( ctx, manager_or_did_coin, @@ -3272,12 +3341,20 @@ mod tests { }], }; - let (sec_conds2, notarized_payment2, entry2_slot, locked_nft2) = registry + let (sec_conds2, notarized_payment2, locked_nft2) = registry .new_action::() .spend(ctx, &mut registry, nft2, nft2_proof, nft2_bls.puzzle_hash)?; - let (sec_conds3, notarized_payment3, entry3_slot, locked_nft3) = registry + let entry2_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_entry_slots[0].clone(), + RewardDistributorSlotNonce::ENTRY, + ); + let (sec_conds3, notarized_payment3, locked_nft3) = registry .new_action::() .spend(ctx, &mut registry, nft3, nft3_proof, nft3_bls.puzzle_hash)?; + let entry3_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_entry_slots[1].clone(), + RewardDistributorSlotNonce::ENTRY, + ); registry = registry.finish_spend(ctx, vec![])?; ensure_conditions_met(ctx, &mut sim, sec_conds2.extend(sec_conds3), 0)?; @@ -3466,9 +3543,13 @@ mod tests { .unwrap() .clone(); - let (new_epoch_conditions, new_reward_slot, _manager_fee) = registry + let (new_epoch_conditions, _manager_fee) = registry .new_action::() .spend(ctx, &mut registry, reward_slot)?; + let new_reward_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_reward_slots[0].clone(), + RewardDistributorSlotNonce::REWARD, + ); incentive_slots .retain(|s| s.info.value.epoch_start != new_reward_slot.info.value.epoch_start); incentive_slots.push(new_reward_slot); @@ -3491,7 +3572,7 @@ mod tests { // commit incentives for 10th epoch let tenth_epoch_start = first_epoch_start + constants.epoch_seconds * 9; let rewards_to_add = constants.epoch_seconds * 10; - let (secure_conditions, tenth_epoch_commitment_slot, new_incentive_slots) = registry + let secure_conditions = registry .new_action::() .spend( ctx, @@ -3501,6 +3582,18 @@ mod tests { cat_minter.puzzle_hash, rewards_to_add, )?; + let tenth_epoch_commitment_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_commitment_slots[0].clone(), + RewardDistributorSlotNonce::COMMITMENT, + ); + let new_incentive_slots = registry + .pending_spend + .created_reward_slots + .iter() + .map(|s| { + registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) + }) + .collect::>(); let new_value_keys = new_incentive_slots .iter() @@ -3551,7 +3644,7 @@ mod tests { }) .unwrap() .clone(); - let (new_epoch_conditions, new_reward_slot, _manager_fee) = registry + let (new_epoch_conditions, _manager_fee) = registry .new_action::() .spend( ctx, @@ -3559,6 +3652,10 @@ mod tests { reward_slot.clone(), // reward_slot.info.value.rewards, )?; + let new_reward_slot = registry.created_slot_value_to_slot( + registry.pending_spend.created_reward_slots[0].clone(), + RewardDistributorSlotNonce::REWARD, + ); incentive_slots .retain(|s| s.info.value.epoch_start != new_reward_slot.info.value.epoch_start); incentive_slots.push(new_reward_slot); @@ -3585,7 +3682,7 @@ mod tests { // payout entry let reserve_cat = registry.reserve.to_cat(); - let (payout_conditions, _entry1_slot, withdrawal_amount) = registry + let (payout_conditions, withdrawal_amount) = registry .new_action::() .spend(ctx, &mut registry, entry1_slot)?; From 14a7ae55f3577c4ad16189936bcbf91482d0eaa2 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 15:35:04 +0300 Subject: [PATCH 28/65] tests working yay --- src/drivers.rs | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index c22d76c7..5f6c512a 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -2754,7 +2754,7 @@ mod tests { manager_or_did_singleton_inner_puzzle_hash, )?; let entry1_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_entry_slots[0].clone(), + registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); registry = registry.finish_spend(ctx, vec![])?; @@ -2817,7 +2817,7 @@ mod tests { .new_action::() .spend(ctx, &mut registry, nft, nft_proof, nft_bls.puzzle_hash)?; let entry1_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_entry_slots[0].clone(), + registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); registry = registry.finish_spend(ctx, vec![])?; @@ -2866,16 +2866,14 @@ mod tests { rewards_to_add, )?; let first_epoch_commitment_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_commitment_slots[0].clone(), + registry.pending_spend.created_commitment_slots[0], RewardDistributorSlotNonce::COMMITMENT, ); let mut incentive_slots = registry .pending_spend .created_reward_slots .iter() - .map(|s| { - registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) - }) + .map(|s| registry.created_slot_value_to_slot(*s, RewardDistributorSlotNonce::REWARD)) .collect::>(); // spend reserve and source cat together so deltas add up @@ -2919,16 +2917,14 @@ mod tests { rewards_to_add, )?; let fifth_epoch_commitment_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_commitment_slots[0].clone(), + registry.pending_spend.created_commitment_slots[0], RewardDistributorSlotNonce::COMMITMENT, ); let new_incentive_slots = registry .pending_spend .created_reward_slots .iter() - .map(|s| { - registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) - }) + .map(|s| registry.created_slot_value_to_slot(*s, RewardDistributorSlotNonce::REWARD)) .collect::>(); let new_value_keys = new_incentive_slots @@ -2983,16 +2979,14 @@ mod tests { rewards_to_add, )?; let fifth_epoch_commitment_slot2 = registry.created_slot_value_to_slot( - registry.pending_spend.created_commitment_slots[0].clone(), + registry.pending_spend.created_commitment_slots[0], RewardDistributorSlotNonce::COMMITMENT, ); let new_incentive_slots = registry .pending_spend .created_reward_slots .iter() - .map(|s| { - registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) - }) + .map(|s| registry.created_slot_value_to_slot(*s, RewardDistributorSlotNonce::REWARD)) .collect::>(); let new_value_keys = new_incentive_slots @@ -3049,7 +3043,7 @@ mod tests { .clone(), )?; let new_reward_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_reward_slots[0].clone(), + registry.pending_spend.created_reward_slots[0], RewardDistributorSlotNonce::REWARD, ); @@ -3107,7 +3101,7 @@ mod tests { // first_epoch_incentives_slot.info.value.rewards, )?; let new_reward_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_reward_slots[0].clone(), + registry.pending_spend.created_reward_slots[0], RewardDistributorSlotNonce::REWARD, ); let payout_coin_id = reserve_cat @@ -3260,7 +3254,7 @@ mod tests { manager_or_did_singleton_inner_puzzle_hash, )?; let entry2_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_entry_slots[0].clone(), + registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); @@ -3345,14 +3339,14 @@ mod tests { .new_action::() .spend(ctx, &mut registry, nft2, nft2_proof, nft2_bls.puzzle_hash)?; let entry2_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_entry_slots[0].clone(), + registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); let (sec_conds3, notarized_payment3, locked_nft3) = registry .new_action::() .spend(ctx, &mut registry, nft3, nft3_proof, nft3_bls.puzzle_hash)?; let entry3_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_entry_slots[1].clone(), + registry.pending_spend.created_entry_slots[1], RewardDistributorSlotNonce::ENTRY, ); registry = registry.finish_spend(ctx, vec![])?; @@ -3547,7 +3541,7 @@ mod tests { .new_action::() .spend(ctx, &mut registry, reward_slot)?; let new_reward_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_reward_slots[0].clone(), + registry.pending_spend.created_reward_slots[0], RewardDistributorSlotNonce::REWARD, ); incentive_slots @@ -3583,16 +3577,14 @@ mod tests { rewards_to_add, )?; let tenth_epoch_commitment_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_commitment_slots[0].clone(), + registry.pending_spend.created_commitment_slots[0], RewardDistributorSlotNonce::COMMITMENT, ); let new_incentive_slots = registry .pending_spend .created_reward_slots .iter() - .map(|s| { - registry.created_slot_value_to_slot(s.clone(), RewardDistributorSlotNonce::REWARD) - }) + .map(|s| registry.created_slot_value_to_slot(*s, RewardDistributorSlotNonce::REWARD)) .collect::>(); let new_value_keys = new_incentive_slots @@ -3653,7 +3645,7 @@ mod tests { // reward_slot.info.value.rewards, )?; let new_reward_slot = registry.created_slot_value_to_slot( - registry.pending_spend.created_reward_slots[0].clone(), + registry.pending_spend.created_reward_slots[0], RewardDistributorSlotNonce::REWARD, ); incentive_slots From 22abdb813fe56e333122573cf4583b8c3e2cf923 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 16:01:19 +0300 Subject: [PATCH 29/65] BramV comment updates --- puzzles/default_puzzles/exponential_premium.clsp | 5 ++++- puzzles/default_puzzles/factor_pricing.clsp | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/puzzles/default_puzzles/exponential_premium.clsp b/puzzles/default_puzzles/exponential_premium.clsp index 7340064f..4f2f0e09 100644 --- a/puzzles/default_puzzles/exponential_premium.clsp +++ b/puzzles/default_puzzles/exponential_premium.clsp @@ -12,7 +12,10 @@ BASE_PROGRAM ; compute base price using this program HALVING_PERIOD ; one day = 86400 = 60 * 60 * 24 seconds START_PREMIUM - END_VALUE ; premium at the very end of the expiry auction + END_VALUE ; value returned by the premium function at the end of the reverse auction + ; to make premium = 0 at the end, we subtract this small value from all + ; values returned by the function, effectively moving the graph a bit + ; down on the y-axis so f(auction_end_time) = 0 PRECISION ; 10 ** 18 BITS_LIST ; (list bit1 bit2 bit3 ...) Buy_Time ; 'time now' - assumes user is interested in passing in a value as late as possible diff --git a/puzzles/default_puzzles/factor_pricing.clsp b/puzzles/default_puzzles/factor_pricing.clsp index 97b579eb..d3702777 100644 --- a/puzzles/default_puzzles/factor_pricing.clsp +++ b/puzzles/default_puzzles/factor_pricing.clsp @@ -17,6 +17,8 @@ REGISTRATION_PERIOD ; number of seconds to register a handle for, in seconds ; most likely 31622400 = 366 days * 24 hours/day * 60 minutes/hour * 60 seconds/minute Current_Expiration ; 0 if the handle is being registered, != 0 if extension + ; this Truth is unused in this puzzle, but can be used to price renewals differently + ; in custom ones Handle . num_periods ; number of periods to register the handle for (e.g., 1 year, 2 years, and so on) ) @@ -26,7 +28,7 @@ (if (> length 4) (if (= length 5) 16 - ; else length > 6 + ; else length >= 6 (if (> length 31) (x) 2) ) ; else 2 < length < 5 @@ -55,7 +57,7 @@ ) ) - ;; this function will return 1 if the handle contains numbers and 0 otherwise + ;; this function will return the number of numbers in a handle ;; PLUS it will (x) if the handle contains invalid characters (defun count_numbers_plus_validate (handle) (if handle From 678a9a55013eb518f5b11340cd968b988791026c Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 16:57:19 +0300 Subject: [PATCH 30/65] fix mempool syncing --- src/cli/catalog/sync.rs | 6 ++++-- src/cli/reward_distributor/sync_distributor.rs | 4 +++- src/cli/xchandles/sync.rs | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index c6f57eab..71ad2f9d 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -251,7 +251,7 @@ pub async fn sync_catalog( .iter() .filter(|sv| sv == &slot_value) .count(); - if no_spent != no_created { + if no_spent >= no_created { continue; } @@ -286,12 +286,13 @@ pub async fn mempool_catalog_maybe( let mempool_item = mempool_items.remove(0); let mut catalog = on_chain_catalog; + let mut parent_id_to_look_for = catalog.coin.parent_coin_info; loop { let Some(catalog_spend) = mempool_item .spend_bundle .coin_spends .iter() - .find(|c| c.coin.coin_id() == catalog.coin.coin_id()) + .find(|c| c.coin.parent_coin_info == parent_id_to_look_for) else { break; }; @@ -302,6 +303,7 @@ pub async fn mempool_catalog_maybe( break; }; catalog = new_catalog; + parent_id_to_look_for = catalog.coin.coin_id(); } Ok(catalog) diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index 2137d0ed..125d4730 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -228,12 +228,13 @@ pub async fn mempool_distributor_maybe( let mempool_item = mempool_items.remove(0); let mut distributor = on_chain_distributor; + let mut parent_id_to_look_for = distributor.coin.parent_coin_info; loop { let Some(distributor_spend) = mempool_item .spend_bundle .coin_spends .iter() - .find(|c| c.coin.coin_id() == distributor.coin.coin_id()) + .find(|c| c.coin.parent_coin_info == parent_id_to_look_for) else { break; }; @@ -248,6 +249,7 @@ pub async fn mempool_distributor_maybe( break; }; distributor = new_distributor; + parent_id_to_look_for = distributor.coin.coin_id(); } Ok(distributor) diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index 7d12dc5b..739c9ff4 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -156,7 +156,7 @@ pub async fn sync_xchandles( .iter() .filter(|sv| sv.tree_hash() == slot_value_hash.into()) .count(); - if no_spent != no_created { + if no_spent >= no_created { continue; } @@ -199,12 +199,13 @@ pub async fn mempool_registry_maybe( let mempool_item = mempool_items.remove(0); let mut registry = on_chain_registry; + let mut parent_id_to_look_for = registry.coin.parent_coin_info; loop { let Some(registry_spend) = mempool_item .spend_bundle .coin_spends .iter() - .find(|c| c.coin.coin_id() == registry.coin.coin_id()) + .find(|c| c.coin.parent_coin_info == parent_id_to_look_for) else { break; }; @@ -215,6 +216,7 @@ pub async fn mempool_registry_maybe( break; }; registry = new_registry; + parent_id_to_look_for = registry.coin.coin_id(); } Ok(registry) From 3937a5bbf6a5b69195553e1b86a618f41fa66310 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 17:06:27 +0300 Subject: [PATCH 31/65] slightly better log (handle expiration works yay) --- src/cli/xchandles/expire.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cli/xchandles/expire.rs b/src/cli/xchandles/expire.rs index 22de5d2f..401e162f 100644 --- a/src/cli/xchandles/expire.rs +++ b/src/cli/xchandles/expire.rs @@ -145,6 +145,7 @@ pub async fn xchandles_expire( } else { slot.info.value.expiration }; + println!("Using committed expiration: {}", commited_expiration); let pricing_solution = XchandlesExponentialPremiumRenewPuzzleSolution { buy_time: expire_time, pricing_program_solution: XchandlesFactorPricingSolution { From f7f55c978e7b119ac09480409eeb5023cb9f99e3 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 17:26:16 +0300 Subject: [PATCH 32/65] xchandles seems to work --- src/cli/commands.rs | 8 ++++---- src/cli/xchandles/extend.rs | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cli/commands.rs b/src/cli/commands.rs index 55d5591d..a363e703 100644 --- a/src/cli/commands.rs +++ b/src/cli/commands.rs @@ -511,9 +511,9 @@ enum XchandlesCliAction { #[arg(long)] handle: String, - /// Number of years to extend the handle for + /// Number of periods (e.g., years) to extend the handle for #[arg(long, default_value = "1")] - years: u64, + num_periods: u64, /// Use testnet11 #[arg(long, default_value_t = false)] @@ -1331,7 +1331,7 @@ pub async fn run_cli() { XchandlesCliAction::Extend { launcher_id, handle, - years, + num_periods, testnet11, payment_asset_id, payment_cat_base_price, @@ -1342,7 +1342,7 @@ pub async fn run_cli() { xchandles_extend( launcher_id, handle, - years, + num_periods, testnet11, payment_asset_id, payment_cat_base_price, diff --git a/src/cli/xchandles/extend.rs b/src/cli/xchandles/extend.rs index b6016d4a..b3952584 100644 --- a/src/cli/xchandles/extend.rs +++ b/src/cli/xchandles/extend.rs @@ -80,6 +80,7 @@ pub async fn xchandles_extend( .get_slot_value(launcher_id, handle.tree_hash().into()) .await? }; + println!("Current expiration: {}", slot.info.value.expiration); let (sec_conds, notarized_payment) = registry.new_action::().spend( &mut ctx, From bd99eeb907fb4d9d73b694bdd0d3c4723120efc3 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 17:40:12 +0300 Subject: [PATCH 33/65] fix expire finding --- puzzles/actions/auctions/end.clsp.hex | 2 +- puzzles/actions/xchandles/expire.clsp | 2 +- puzzles/actions/xchandles/expire.clsp.hex | 2 +- src/layers/actions/xchandles/expire.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/puzzles/actions/auctions/end.clsp.hex b/puzzles/actions/auctions/end.clsp.hex index 4165f55e..15bf3597 100644 --- a/puzzles/actions/auctions/end.clsp.hex +++ b/puzzles/actions/auctions/end.clsp.hex @@ -1 +1 @@ -FAIL: can't compile ("take_comissions" "AUCTIONEER_PUZZLE_HASH" "bid_amount" (26982 (> "fee_type" 2) (- "remaining_funds" (26982 (= "fee_type" ()) (/ (* "bid_amount" "fee_arg") 10000) "fee_arg")) "remaining_funds") "remaining_fees"), unknown operator ("take_comissions" "AUCTIONEER_PUZZLE_HASH" "bid_amount" (26982 (> "fee_type" 2) (- "remaining_funds" (26982 (= "fee_type" ()) (/ (* "bid_amount" "fee_arg") 10000) "fee_arg")) "remaining_funds") "remaining_fees") +FAIL: can't compile ("sha256tree" (c 1 ("list" ("list" "CREATE_COIN" "King" "asset_amount" ("list" "King"))))), unknown operator ("sha256tree" (c 1 ("list" ("list" "CREATE_COIN" "King" "asset_amount" ("list" "King"))))) diff --git a/puzzles/actions/xchandles/expire.clsp b/puzzles/actions/xchandles/expire.clsp index 2ddcb2f0..5e50716e 100644 --- a/puzzles/actions/xchandles/expire.clsp +++ b/puzzles/actions/xchandles/expire.clsp @@ -105,7 +105,7 @@ (if (all (= (sha256tree cat_maker_puzzle_reveal) Cat_Maker_Puzzle_Hash) (= (sha256tree expired_handle_pricing_puzzle_reveal) Expired_Handle_Pricing_Puzzle_Hash) - (= (strlen new_resolved_data) 32) + (= (strlen new_owner_launcher_id) 32) (> 65 (strlen new_resolved_data)) ) (main diff --git a/puzzles/actions/xchandles/expire.clsp.hex b/puzzles/actions/xchandles/expire.clsp.hex index 1aea97bc..3c72348b 100644 --- a/puzzles/actions/xchandles/expire.clsp.hex +++ b/puzzles/actions/xchandles/expire.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff827fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index c2b64368..54305f33 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -191,11 +191,11 @@ impl XchandlesExpireAction { } pub const XCHANDLES_EXPIRE_PUZZLE: [u8; 1081] = - hex!("ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff827fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); + hex!("ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); pub const XCHANDLES_EXPIRE_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - f17bc6e5a0503ce269c6ea2c9c51d74d34531638cc61349e6b1cfa104098001d + 586fe828a78bc521b6fa358b5f10de0393d7e9ccd6096a201420527a5903978f " )); From 36403615816e04d0233789865cd5caa589936657 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 17:56:45 +0300 Subject: [PATCH 34/65] add Truths comments --- puzzles/default_puzzles/default_cat_maker.clsp | 2 ++ puzzles/default_puzzles/exponential_premium.clsp | 2 ++ puzzles/default_puzzles/factor_pricing.clsp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/puzzles/default_puzzles/default_cat_maker.clsp b/puzzles/default_puzzles/default_cat_maker.clsp index 7e232962..6256de50 100644 --- a/puzzles/default_puzzles/default_cat_maker.clsp +++ b/puzzles/default_puzzles/default_cat_maker.clsp @@ -5,6 +5,8 @@ ;; The default CAT maker assumes no intermediary layers between the CAT outer puzzle and the inner puzzle. +;; Note: Truths (Inner_Puzzle_Hash) are trusted and should be verified by the outer puzzle. + (mod ( CAT_MOD_HASH TAIL_HASH_HASH ; (sha256 1 TAIL_HASH) diff --git a/puzzles/default_puzzles/exponential_premium.clsp b/puzzles/default_puzzles/exponential_premium.clsp index 4f2f0e09..d771058d 100644 --- a/puzzles/default_puzzles/exponential_premium.clsp +++ b/puzzles/default_puzzles/exponential_premium.clsp @@ -8,6 +8,8 @@ ;; Inspired by ExponentialPremiumPirceOracle: https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/ExponentialPremiumPriceOracle.sol +;; Note: Truths (Buy_Time & Expiration) are trusted and should be verified by the outer puzzle. + (mod ( BASE_PROGRAM ; compute base price using this program HALVING_PERIOD ; one day = 86400 = 60 * 60 * 24 seconds diff --git a/puzzles/default_puzzles/factor_pricing.clsp b/puzzles/default_puzzles/factor_pricing.clsp index d3702777..823c110b 100644 --- a/puzzles/default_puzzles/factor_pricing.clsp +++ b/puzzles/default_puzzles/factor_pricing.clsp @@ -12,6 +12,8 @@ ;; - 3 characters with no numbers: 128 ;; If the handle contains a number, the price is halved. +;; Note: Truths (Handle) are trusted and should be verified by the outer puzzle. + (mod ( BASE_PRICE ; base price = price per month of a 6+ character handle with at least one number REGISTRATION_PERIOD ; number of seconds to register a handle for, in seconds From 50ef659ee7baccfb5165e93207cccb47a560e88c Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 18:04:58 +0300 Subject: [PATCH 35/65] rest --- puzzles/actions/xchandles/expire.clsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puzzles/actions/xchandles/expire.clsp b/puzzles/actions/xchandles/expire.clsp index 5e50716e..8257cf87 100644 --- a/puzzles/actions/xchandles/expire.clsp +++ b/puzzles/actions/xchandles/expire.clsp @@ -20,7 +20,7 @@ cat_maker_puzzle_reveal cat_maker_puzzle_solution expired_handle_pricing_puzzle_reveal - (@ expired_handle_pricing_puzzle_solution (buy_time current_expiration handle . rest_maybe)) + (@ expired_handle_pricing_puzzle_solution (buy_time current_expiration handle . expired_handle_pricing_puzzle_solution_rest)) refund_puzzle_hash_hash secret neighbors ; (c left right) From 7c8b55be03ab43f6426a0d0a83ed1b79f1037e71 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 18:30:58 +0300 Subject: [PATCH 36/65] start update --- puzzles/actions/auctions/end.clsp.hex | 2 +- .../default_puzzles/exponential_premium.clsp | 18 +++++++++++------- .../exponential_premium.clsp.hex | 2 +- puzzles/default_puzzles/factor_pricing.clsp | 6 +++++- .../default_puzzles/factor_pricing.clsp.hex | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/puzzles/actions/auctions/end.clsp.hex b/puzzles/actions/auctions/end.clsp.hex index 15bf3597..4165f55e 100644 --- a/puzzles/actions/auctions/end.clsp.hex +++ b/puzzles/actions/auctions/end.clsp.hex @@ -1 +1 @@ -FAIL: can't compile ("sha256tree" (c 1 ("list" ("list" "CREATE_COIN" "King" "asset_amount" ("list" "King"))))), unknown operator ("sha256tree" (c 1 ("list" ("list" "CREATE_COIN" "King" "asset_amount" ("list" "King"))))) +FAIL: can't compile ("take_comissions" "AUCTIONEER_PUZZLE_HASH" "bid_amount" (26982 (> "fee_type" 2) (- "remaining_funds" (26982 (= "fee_type" ()) (/ (* "bid_amount" "fee_arg") 10000) "fee_arg")) "remaining_funds") "remaining_fees"), unknown operator ("take_comissions" "AUCTIONEER_PUZZLE_HASH" "bid_amount" (26982 (> "fee_type" 2) (- "remaining_funds" (26982 (= "fee_type" ()) (/ (* "bid_amount" "fee_arg") 10000) "fee_arg")) "remaining_funds") "remaining_fees") diff --git a/puzzles/default_puzzles/exponential_premium.clsp b/puzzles/default_puzzles/exponential_premium.clsp index d771058d..ada3cf22 100644 --- a/puzzles/default_puzzles/exponential_premium.clsp +++ b/puzzles/default_puzzles/exponential_premium.clsp @@ -19,10 +19,14 @@ ; values returned by the function, effectively moving the graph a bit ; down on the y-axis so f(auction_end_time) = 0 PRECISION ; 10 ** 18 - BITS_LIST ; (list bit1 bit2 bit3 ...) - Buy_Time ; 'time now' - assumes user is interested in passing in a value as late as possible - Expiration . - rest_of_pricing_program_solution ; pricing_program_solution passed to BASE_PROGRAM (r expiration handle . num_years) = (handle . num_years) + BITS_LIST . ; (list bit1 bit2 bit3 ...) + (@ solution + ( + Buy_Time ; 'time now' - assumes user is interested in passing in a value as late as possible + Current_Expiration + rest_of_pricing_program_solution ; pricing_program_solution passed to BASE_PROGRAM (e.g., (Handle . num_periods)) + ) + ) ) (defun add_fractional_part (PRECISION bits_list acc fraction_part premium) (if bits_list @@ -55,8 +59,8 @@ PRECISION BITS_LIST 1 - (/ (* 65536 (% (- Buy_Time Expiration) HALVING_PERIOD)) HALVING_PERIOD) ; fractional part of n with 16 bits of precision (2 ** 16 = 65536) - (/ START_PREMIUM (lsh 1 (/ (- Buy_Time Expiration) HALVING_PERIOD))) ; premium from whole periods = START_PREMIUM / 2^p + (/ (* 65536 (% (- Buy_Time Current_Expiration) HALVING_PERIOD)) HALVING_PERIOD) ; fractional part of n with 16 bits of precision (2 ** 16 = 65536) + (/ START_PREMIUM (lsh 1 (/ (- Buy_Time Current_Expiration) HALVING_PERIOD))) ; premium from whole periods = START_PREMIUM / 2^p ) END_VALUE) ; premium ) registered_time @@ -64,6 +68,6 @@ ) (main - (a BASE_PROGRAM (c Expiration rest_of_pricing_program_solution)) + (a BASE_PROGRAM solution) ) ) \ No newline at end of file diff --git a/puzzles/default_puzzles/exponential_premium.clsp.hex b/puzzles/default_puzzles/exponential_premium.clsp.hex index f9b3273e..c1d66d62 100644 --- a/puzzles/default_puzzles/exponential_premium.clsp.hex +++ b/puzzles/default_puzzles/exponential_premium.clsp.hex @@ -1 +1 @@ -ff02ffff01ff04ffff10ffff05ffff02ff05ffff04ff8202ffff8203ff808080ffff02ff06ffff04ff02ffff04ffff02ff04ffff04ff02ffff04ff5fffff04ff81bfffff04ffff0101ffff04ffff05ffff14ffff12ffff0183010000ffff3dffff11ff82017fff8202ff80ff0b8080ff0b8080ffff04ffff05ffff14ff17ffff17ffff0101ffff05ffff14ffff11ff82017fff8202ff80ff0b8080808080ff8080808080808080ffff04ff2fff808080808080ffff06ffff02ff05ffff04ff8202ffff8203ff80808080ffff04ffff01ffff02ffff03ff0bffff01ff02ff04ffff04ff02ffff04ff05ffff04ff1bffff04ffff17ff17ffff010180ffff04ff2fffff04ffff02ffff03ffff18ff2fff1780ffff01ff05ffff14ffff12ff5fff1380ff058080ffff015f80ff0180ff8080808080808080ffff015f80ff0180ff02ffff03ffff15ff05ff0b80ffff01ff11ff05ff0b80ff8080ff0180ff018080 +ff02ffff01ff04ffff10ffff05ffff02ff05ff81ff8080ffff02ff06ffff04ff02ffff04ffff02ff04ffff04ff02ffff04ff5fffff04ff81bfffff04ffff0101ffff04ffff05ffff14ffff12ffff0183010000ffff3dffff11ff82017fff8202ff80ff0b8080ff0b8080ffff04ffff05ffff14ff17ffff17ffff0101ffff05ffff14ffff11ff82017fff8202ff80ff0b8080808080ff8080808080808080ffff04ff2fff808080808080ffff06ffff02ff05ff81ff808080ffff04ffff01ffff02ffff03ff0bffff01ff02ff04ffff04ff02ffff04ff05ffff04ff1bffff04ffff17ff17ffff010180ffff04ff2fffff04ffff02ffff03ffff18ff2fff1780ffff01ff05ffff14ffff12ff5fff1380ff058080ffff015f80ff0180ff8080808080808080ffff015f80ff0180ff02ffff03ffff15ff05ff0b80ffff01ff11ff05ff0b80ff8080ff0180ff018080 diff --git a/puzzles/default_puzzles/factor_pricing.clsp b/puzzles/default_puzzles/factor_pricing.clsp index 823c110b..581f2cbc 100644 --- a/puzzles/default_puzzles/factor_pricing.clsp +++ b/puzzles/default_puzzles/factor_pricing.clsp @@ -12,12 +12,16 @@ ;; - 3 characters with no numbers: 128 ;; If the handle contains a number, the price is halved. -;; Note: Truths (Handle) are trusted and should be verified by the outer puzzle. +;; Note: Truths (Buy_Time, Current_Expiration, Handle) are trusted and should be verified by the outer puzzle. (mod ( BASE_PRICE ; base price = price per month of a 6+ character handle with at least one number REGISTRATION_PERIOD ; number of seconds to register a handle for, in seconds ; most likely 31622400 = 366 days * 24 hours/day * 60 minutes/hour * 60 seconds/minute + Buy_Time ; 'time now' - assumes user is interested in passing in a value as late as possible + ; This Truth is unused in this puzzle, but can be used to price handles differently + ; Generally, the outer puzzle will just verify it with an ASSERT_SECONDS_ABSOLUTE + ; but with no matching ASSERT_BEFORE_SECONDS_ABSOLUTE & delay Current_Expiration ; 0 if the handle is being registered, != 0 if extension ; this Truth is unused in this puzzle, but can be used to price renewals differently ; in custom ones diff --git a/puzzles/default_puzzles/factor_pricing.clsp.hex b/puzzles/default_puzzles/factor_pricing.clsp.hex index 0db57ef0..88c5aa0b 100644 --- a/puzzles/default_puzzles/factor_pricing.clsp.hex +++ b/puzzles/default_puzzles/factor_pricing.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff15ff3fff8080ffff01ff04ffff12ff3fff05ffff02ff06ffff04ff02ffff04ffff0dff2f80ffff04ffff02ff04ffff04ff02ffff04ff2fff80808080ff808080808080ffff12ff3fff0b8080ffff01ff088080ff0180ffff04ffff01ffff02ffff03ff05ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff016080ffff15ffff017bffff0cff05ff80ffff0101808080ffff01ff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff80808080ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff012f80ffff15ffff013affff0cff05ff80ffff0101808080ffff01ff10ffff0101ffff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff8080808080ffff01ff088080ff018080ff0180ff8080ff0180ff05ffff14ffff02ffff03ffff15ff05ffff010280ffff01ff02ffff03ffff15ff05ffff010480ffff01ff02ffff03ffff09ff05ffff010580ffff01ff0110ffff01ff02ffff03ffff15ff05ffff011f80ffff01ff0880ffff01ff010280ff018080ff0180ffff01ff02ffff03ffff09ff05ffff010380ffff01ff01820080ffff01ff014080ff018080ff0180ffff01ff088080ff0180ffff03ff0bffff0102ffff0101808080ff018080 +ff02ffff01ff02ffff03ffff15ff7fff8080ffff01ff04ffff12ff7fff05ffff02ff06ffff04ff02ffff04ffff0dff5f80ffff04ffff02ff04ffff04ff02ffff04ff5fff80808080ff808080808080ffff12ff7fff0b8080ffff01ff088080ff0180ffff04ffff01ffff02ffff03ff05ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff016080ffff15ffff017bffff0cff05ff80ffff0101808080ffff01ff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff80808080ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff012f80ffff15ffff013affff0cff05ff80ffff0101808080ffff01ff10ffff0101ffff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff8080808080ffff01ff088080ff018080ff0180ff8080ff0180ff05ffff14ffff02ffff03ffff15ff05ffff010280ffff01ff02ffff03ffff15ff05ffff010480ffff01ff02ffff03ffff09ff05ffff010580ffff01ff0110ffff01ff02ffff03ffff15ff05ffff011f80ffff01ff0880ffff01ff010280ff018080ff0180ffff01ff02ffff03ffff09ff05ffff010380ffff01ff01820080ffff01ff014080ff018080ff0180ffff01ff088080ff0180ffff03ff0bffff0102ffff0101808080ff018080 From 80615cdb143c0218b565baf7f3736767fa055f11 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 19:11:03 +0300 Subject: [PATCH 37/65] ImpossibleSecondsAbsoluteConstraints ood --- include/slots.clib | 4 +- include/xchandles.clib | 3 +- puzzles/actions/xchandles/expire.clsp | 1 - puzzles/actions/xchandles/expire.clsp.hex | 2 +- puzzles/actions/xchandles/extend.clsp | 5 +- puzzles/actions/xchandles/extend.clsp.hex | 2 +- puzzles/actions/xchandles/refund.clsp | 2 - puzzles/actions/xchandles/refund.clsp.hex | 2 +- puzzles/actions/xchandles/register.clsp | 4 +- puzzles/actions/xchandles/register.clsp.hex | 2 +- src/benchmarker.rs | 1 + src/cli/xchandles/continue_launch.rs | 7 +- src/cli/xchandles/expire.rs | 17 ++--- src/cli/xchandles/extend.rs | 13 ++-- src/cli/xchandles/register.rs | 7 +- src/drivers.rs | 74 +++++++-------------- src/layers/actions/xchandles/expire.rs | 74 ++++++++------------- src/layers/actions/xchandles/extend.rs | 18 ++--- src/layers/actions/xchandles/refund.rs | 8 +-- src/layers/actions/xchandles/register.rs | 34 ++++++---- src/layers/precommit_layer.rs | 12 +--- 21 files changed, 122 insertions(+), 170 deletions(-) diff --git a/include/slots.clib b/include/slots.clib index c1f1d0ae..122142a8 100644 --- a/include/slots.clib +++ b/include/slots.clib @@ -21,7 +21,7 @@ ) ) - (defun create_slot (SLOT_1ST_CURRY_HASH slot_value_hash hint) + (defun create_slot (SLOT_1ST_CURRY_HASH slot_value_hash) (list CREATE_COIN (curry_hashes SLOT_1ST_CURRY_HASH @@ -54,7 +54,7 @@ ) ) - (defun create_slot_inline (SLOT_1ST_CURRY_HASH slot_value_hash hint) + (defun create_slot_inline (SLOT_1ST_CURRY_HASH slot_value_hash) (list CREATE_COIN (curry_hashes_inline SLOT_1ST_CURRY_HASH diff --git a/include/xchandles.clib b/include/xchandles.clib index 353a7146..0b5cbe20 100644 --- a/include/xchandles.clib +++ b/include/xchandles.clib @@ -13,7 +13,6 @@ pricing_puzzle_solution handle secret - start_time owner_launcher_id resolved_data ) @@ -25,7 +24,7 @@ ) (c (c handle secret) - (c start_time (c owner_launcher_id resolved_data)) + (c owner_launcher_id resolved_data) ) ) ) diff --git a/puzzles/actions/xchandles/expire.clsp b/puzzles/actions/xchandles/expire.clsp index 8257cf87..09094fc3 100644 --- a/puzzles/actions/xchandles/expire.clsp +++ b/puzzles/actions/xchandles/expire.clsp @@ -73,7 +73,6 @@ expired_handle_pricing_puzzle_solution handle secret - buy_time new_owner_launcher_id new_resolved_data )) diff --git a/puzzles/actions/xchandles/expire.clsp.hex b/puzzles/actions/xchandles/expire.clsp.hex index 3c72348b..6281e1b9 100644 --- a/puzzles/actions/xchandles/expire.clsp.hex +++ b/puzzles/actions/xchandles/expire.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff825fefff827fef808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 diff --git a/puzzles/actions/xchandles/extend.clsp b/puzzles/actions/xchandles/extend.clsp index ed3aaf48..7e6d636b 100644 --- a/puzzles/actions/xchandles/extend.clsp +++ b/puzzles/actions/xchandles/extend.clsp @@ -19,7 +19,7 @@ ) ( pricing_puzzle_reveal - (@ pricing_solution (expiration handle . rest)) + (@ pricing_solution (buy_time expiration handle . rest)) cat_maker_puzzle_reveal cat_maker_solution neighbors . @@ -47,6 +47,9 @@ ; can't extend if expired (list ASSERT_BEFORE_SECONDS_ABSOLUTE expiration) + ; assert buy time + (list ASSERT_SECONDS_ABSOLUTE buy_time) + ; create new slot (create_slot_inline SLOT_1ST_CURRY_HASH (get_xchandles_slot_value_hash diff --git a/puzzles/actions/xchandles/extend.clsp.hex b/puzzles/actions/xchandles/extend.clsp.hex index 9cdb70a0..7b7ab7e2 100644 --- a/puzzles/actions/xchandles/extend.clsp.hex +++ b/puzzles/actions/xchandles/extend.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff8202dfff8080808080ffff09ff82016fffff02ff2effff04ff02ffff04ff819fff808080808080ffff01ff04ff2fffff04ffff02ff3effff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff82055f80ff820bdf80ffff04ff82025fff820fdf8080ff80808080ff8080808080ffff04ffff04ff2cffff04ffff0effff0165ffff02ff2effff04ff02ffff04ffff04ffff05ffff02ff819fff82015f8080ff82055f80ff8080808080ff808080ffff04ffff04ff10ffff04ff82025fff808080ffff04ffff02ff16ffff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff82055f80ff820bdf80ffff04ffff10ff82025fffff06ffff02ff819fff82015f808080ff820fdf8080ff80808080ff8080808080ffff04ffff04ff18ffff04ffff0bffff02ff8202dfffff04ff05ff8205df8080ffff02ff2effff04ff02ffff04ffff04ffff02ff2effff04ff02ffff04ffff04ff82055fff82025f80ff80808080ffff04ffff04ff0bffff04ffff05ffff02ff819fff82015f8080ffff04ffff04ff0bff8080ff80808080ff808080ff8080808080ff808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff553fff33ff3e42ffff02ffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff04ff14ffff04ffff0bff5affff0bff12ffff0bff12ff6aff0580ffff0bff12ffff0bff7affff0bff12ffff0bff12ff6affff0bffff0101ff0b8080ffff0bff12ff6aff4a808080ff4a808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff3cffff04ffff0112ffff04ff80ffff04ffff0bff5affff0bff12ffff0bff12ff6aff0580ffff0bff12ffff0bff7affff0bff12ffff0bff12ff6affff0bffff0101ff0b8080ffff0bff12ff6aff4a808080ff4a808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff8202dfff8080808080ffff09ff82016fffff02ff2effff04ff02ffff04ff819fff808080808080ffff01ff04ff2fffff04ffff02ff3effff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff820b5f80ff820bdf80ffff04ff82055fff820fdf8080ff80808080ff8080808080ffff04ffff04ff3cffff04ffff0effff0165ffff02ff2effff04ff02ffff04ffff04ffff05ffff02ff819fff82015f8080ff820b5f80ff8080808080ff808080ffff04ffff04ff10ffff04ff82055fff808080ffff04ffff04ff14ffff04ff82025fff808080ffff04ffff02ff16ffff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff820b5f80ff820bdf80ffff04ffff10ff82055fffff06ffff02ff819fff82015f808080ff820fdf8080ff80808080ff8080808080ffff04ffff04ff18ffff04ffff0bffff02ff8202dfffff04ff05ff8205df8080ffff02ff2effff04ff02ffff04ffff04ffff02ff2effff04ff02ffff04ffff04ff820b5fff82055f80ff80808080ffff04ffff04ff0bffff04ffff05ffff02ff819fff82015f8080ffff04ffff04ff0bff8080ff80808080ff808080ff8080808080ff808080ff8080808080808080ffff01ff088080ff0180ffff04ffff01ffffff553fff51ff333effff42ff02ffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff04ff2cffff04ffff0bff81baffff0bff2affff0bff2aff81daff0580ffff0bff2affff0bff81faffff0bff2affff0bff2aff81daffff0bffff0101ff0b8080ffff0bff2aff81daff819a808080ff819a808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff12ffff04ffff0112ffff04ff80ffff04ffff0bff81baffff0bff2affff0bff2aff81daff0580ffff0bff2affff0bff81faffff0bff2affff0bff2aff81daffff0bffff0101ff0b8080ffff0bff2aff81daff819a808080ff819a808080ff8080808080ff018080 diff --git a/puzzles/actions/xchandles/refund.clsp b/puzzles/actions/xchandles/refund.clsp index 0adaf32c..05ac17e9 100644 --- a/puzzles/actions/xchandles/refund.clsp +++ b/puzzles/actions/xchandles/refund.clsp @@ -28,7 +28,6 @@ precommited_pricing_puzzle_solution handle secret - precommited_start_time precommited_owner_launcher_id precommited_resolved_data refund_puzzle_hash_hash @@ -114,7 +113,6 @@ precommited_pricing_puzzle_solution handle secret - precommited_start_time precommited_owner_launcher_id precommited_resolved_data )) ; hash of precommit value, which is itself a hash :) diff --git a/puzzles/actions/xchandles/refund.clsp.hex b/puzzles/actions/xchandles/refund.clsp.hex index b30748cf..c348c030 100644 --- a/puzzles/actions/xchandles/refund.clsp.hex +++ b/puzzles/actions/xchandles/refund.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8307ffefffff01ff09ff8313ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8307ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8305ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff8302ffef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefffff04ff82bfefff83017fef80808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8305ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080 diff --git a/puzzles/actions/xchandles/register.clsp b/puzzles/actions/xchandles/register.clsp index b71c777e..3a49159d 100644 --- a/puzzles/actions/xchandles/register.clsp +++ b/puzzles/actions/xchandles/register.clsp @@ -30,7 +30,7 @@ ( handle_hash pricing_puzzle_reveal - (@ pricing_solution (this_is_zero handle . solution_rest)) + (@ pricing_solution (start_time this_is_zero handle . solution_rest)) cat_maker_puzzle_reveal cat_maker_solution ; start neighbor slots info @@ -42,7 +42,6 @@ right_expiration right_data ; end neighbor slots info - start_time (@ data (owner_launcher_id . resolved_data)) ; info needed to compute precommit coin puzzle hash refund_puzzle_hash_hash @@ -94,7 +93,6 @@ pricing_solution handle secret - start_time owner_launcher_id resolved_data )) diff --git a/puzzles/actions/xchandles/register.clsp.hex b/puzzles/actions/xchandles/register.clsp.hex index 9c826934..c5600429 100644 --- a/puzzles/actions/xchandles/register.clsp.hex +++ b/puzzles/actions/xchandles/register.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ff4fffff0bffff0101ff82056f8080ffff20ff82026f80ffff0aff4fff8213ef80ffff0aff821befff4f80ffff09ff57ffff02ff2effff04ff02ffff04ff8202efff8080808080ffff09ff81b7ffff02ff2effff04ff02ffff04ff81afff8080808080ffff09ffff0dff8313ffef80ffff012080ffff15ffff0141ffff0dff831bffef808080ffff01ff04ff17ffff02ff1affff04ff02ffff04ffff02ff8202efffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8317ffef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff57ff8205ef80ffff04ff81b7ff82016f8080ffff04ffff04ff82056fff832fffef80ffff04ff8305ffefffff04ff8313ffefff831bffef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff8205ef8080ffff04ffff05ffff02ff81afff82016f8080ffff04ffff04ffff04ff10ffff04ff8305ffefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff821bef8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff8213efff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff4fff820bef80ffff04ffff10ff8305ffefffff06ffff02ff81afff82016f808080ff830bffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff4f8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff4fff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ff80808080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0172ff0580ff808080ff178080ffff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ff4fffff0bffff0101ff820b6f8080ffff20ff82056f80ffff0aff4fff8213ef80ffff0aff821befff4f80ffff09ff57ffff02ff2effff04ff02ffff04ff8202efff8080808080ffff09ff81b7ffff02ff2effff04ff02ffff04ff81afff8080808080ffff09ffff0dff8309ffef80ffff012080ffff15ffff0141ffff0dff830dffef808080ffff01ff04ff17ffff02ff1affff04ff02ffff04ffff02ff8202efffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff830bffef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff57ff8205ef80ffff04ff81b7ff82016f8080ffff04ffff04ff820b6fff8317ffef80ffff04ff8309ffefff830dffef808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff8205ef8080ffff04ffff05ffff02ff81afff82016f8080ffff04ffff04ffff04ff10ffff04ff82026fff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff821bef8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff8213efff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff4fff820bef80ffff04ffff10ff82026fffff06ffff02ff81afff82016f808080ff8305ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff4f8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff4fff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ff80808080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0172ff0580ff808080ff178080ffff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080 diff --git a/src/benchmarker.rs b/src/benchmarker.rs index 40a913c3..dd79e721 100644 --- a/src/benchmarker.rs +++ b/src/benchmarker.rs @@ -33,6 +33,7 @@ pub mod tests { key: &str, keys: &[SecretKey], ) -> anyhow::Result<()> { + println!("Adding spend for {}", key); // todo: debug let sb = SpendBundle::new(ctx.take(), Signature::default()); let sb_conds = get_conditions_from_spendbundle( ctx, diff --git a/src/cli/xchandles/continue_launch.rs b/src/cli/xchandles/continue_launch.rs index b11e2186..7807b7e5 100644 --- a/src/cli/xchandles/continue_launch.rs +++ b/src/cli/xchandles/continue_launch.rs @@ -20,7 +20,7 @@ use crate::{ load_xchandles_premine_csv, new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CatalogPrecommitValue, CliError, Db, PrecommitCoin, PrecommitLayer, SageClient, XchandlesFactorPricingPuzzleArgs, - XchandlesFactorPricingSolution, XchandlesPrecommitValue, XchandlesPremineRecord, + XchandlesPrecommitValue, XchandlesPremineRecord, XchandlesPricingSolution, XchandlesRegisterAction, }; @@ -35,7 +35,8 @@ fn precommit_value_for_handle( Ok(XchandlesPrecommitValue::for_normal_registration( payment_asset_id.tree_hash(), XchandlesFactorPricingPuzzleArgs::curry_tree_hash(1, registration_period), - XchandlesFactorPricingSolution { + XchandlesPricingSolution { + buy_time: start_time, current_expiration: 0, handle: handle.handle.clone(), num_periods: 1, @@ -43,7 +44,6 @@ fn precommit_value_for_handle( .tree_hash(), handle.handle.clone(), Bytes32::default(), - start_time, owner_nft_launcher_id, owner_nft_launcher_id.into(), )) @@ -523,6 +523,7 @@ pub async fn xchandles_continue_launch( precommit_coin, 1, registration_period, + start_time, )?; security_coin_conditions = security_coin_conditions.extend(sec_conds); diff --git a/src/cli/xchandles/expire.rs b/src/cli/xchandles/expire.rs index 401e162f..259bf66f 100644 --- a/src/cli/xchandles/expire.rs +++ b/src/cli/xchandles/expire.rs @@ -16,9 +16,8 @@ use crate::{ quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, PrecommitCoin, PrecommitLayer, SageClient, Slot, XchandlesApiClient, XchandlesExpireAction, XchandlesExponentialPremiumRenewPuzzleArgs, - XchandlesExponentialPremiumRenewPuzzleSolution, XchandlesFactorPricingPuzzleArgs, - XchandlesFactorPricingSolution, XchandlesPrecommitValue, XchandlesRefundAction, - XchandlesSlotValue, + XchandlesFactorPricingPuzzleArgs, XchandlesPrecommitValue, XchandlesPricingSolution, + XchandlesRefundAction, XchandlesSlotValue, }; #[allow(clippy::too_many_arguments)] @@ -146,13 +145,11 @@ pub async fn xchandles_expire( slot.info.value.expiration }; println!("Using committed expiration: {}", commited_expiration); - let pricing_solution = XchandlesExponentialPremiumRenewPuzzleSolution { + let pricing_solution = XchandlesPricingSolution { buy_time: expire_time, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: commited_expiration, - handle: handle.clone(), - num_periods, - }, + current_expiration: commited_expiration, + handle: handle.clone(), + num_periods, }; let precommit_coin_value = XchandlesPrecommitValue::for_normal_registration( payment_asset_id.tree_hash(), @@ -164,7 +161,6 @@ pub async fn xchandles_expire( pricing_solution.tree_hash(), handle.clone(), secret, - expire_time, nft_launcher_id, nft_launcher_id.into(), ); @@ -348,6 +344,7 @@ pub async fn xchandles_expire( payment_cat_base_price, registration_period, precommit_coin, + expire_time, )? }; diff --git a/src/cli/xchandles/extend.rs b/src/cli/xchandles/extend.rs index b3952584..a28f69a4 100644 --- a/src/cli/xchandles/extend.rs +++ b/src/cli/xchandles/extend.rs @@ -5,10 +5,11 @@ use chia_wallet_sdk::{ }; use crate::{ - assets_xch_and_cat, get_coinset_client, get_constants, hex_string_to_bytes32, new_sk, - no_assets, parse_amount, parse_one_sided_offer, quick_sync_xchandles, spend_security_coin, - sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, SageClient, - XchandlesApiClient, XchandlesExtendAction, XchandlesFactorPricingPuzzleArgs, + assets_xch_and_cat, get_coinset_client, get_constants, get_last_onchain_timestamp, + hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, + CliError, Db, DefaultCatMakerArgs, SageClient, XchandlesApiClient, XchandlesExtendAction, + XchandlesFactorPricingPuzzleArgs, }; #[allow(clippy::too_many_arguments)] @@ -82,6 +83,9 @@ pub async fn xchandles_extend( }; println!("Current expiration: {}", slot.info.value.expiration); + let start_time = get_last_onchain_timestamp(&cli).await? - 1; + println!("Extension time: {}", start_time); + let (sec_conds, notarized_payment) = registry.new_action::().spend( &mut ctx, &mut registry, @@ -91,6 +95,7 @@ pub async fn xchandles_extend( payment_cat_base_price, registration_period, num_periods, + start_time, )?; yes_no_prompt("Continue with extension?")?; diff --git a/src/cli/xchandles/register.rs b/src/cli/xchandles/register.rs index 59c6f515..d5edfff7 100644 --- a/src/cli/xchandles/register.rs +++ b/src/cli/xchandles/register.rs @@ -16,7 +16,7 @@ use crate::{ print_spend_bundle_to_file, quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, PrecommitCoin, PrecommitLayer, SageClient, Slot, XchandlesApiClient, XchandlesExponentialPremiumRenewPuzzleArgs, - XchandlesFactorPricingPuzzleArgs, XchandlesFactorPricingSolution, XchandlesPrecommitValue, + XchandlesFactorPricingPuzzleArgs, XchandlesPrecommitValue, XchandlesPricingSolution, XchandlesRefundAction, XchandlesRegisterAction, XchandlesSlotValue, }; @@ -114,7 +114,8 @@ pub async fn xchandles_register( payment_cat_base_price, registration_period, )?; - let pricing_solution = XchandlesFactorPricingSolution { + let pricing_solution = XchandlesPricingSolution { + buy_time: start_time, current_expiration: 0, handle: handle.clone(), num_periods, @@ -139,7 +140,6 @@ pub async fn xchandles_register( pricing_solution.tree_hash(), handle.clone(), secret, - start_time, nft_launcher_id, nft_launcher_id.into(), ); @@ -346,6 +346,7 @@ pub async fn xchandles_register( precommit_coin, payment_cat_base_price, registration_period, + start_time, )? }; diff --git a/src/drivers.rs b/src/drivers.rs index 5f6c512a..06a4c77a 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -950,10 +950,9 @@ mod tests { RewardDistributorStakeAction, RewardDistributorSyncAction, RewardDistributorType, RewardDistributorUnstakeAction, RewardDistributorWithdrawIncentivesAction, Slot, SpendContextExt, XchandlesExpireAction, XchandlesExponentialPremiumRenewPuzzleArgs, - XchandlesExponentialPremiumRenewPuzzleSolution, XchandlesExtendAction, - XchandlesFactorPricingPuzzleArgs, XchandlesFactorPricingSolution, XchandlesOracleAction, - XchandlesPrecommitValue, XchandlesRefundAction, XchandlesRegisterAction, - XchandlesUpdateAction, ANY_METADATA_UPDATER_HASH, + XchandlesExtendAction, XchandlesFactorPricingPuzzleArgs, XchandlesOracleAction, + XchandlesPrecommitValue, XchandlesPricingSolution, XchandlesRefundAction, + XchandlesRegisterAction, XchandlesUpdateAction, ANY_METADATA_UPDATER_HASH, }; use super::*; @@ -1598,11 +1597,6 @@ mod tests { pricing_solution_hash, handle_to_refund.clone(), Bytes32::default(), - if let Some(existing_slot) = &slot { - existing_slot.info.value.expiration + 28 * 24 * 60 * 60 + 1 - } else { - 0 - }, Bytes32::default(), Bytes::default(), ); @@ -1840,7 +1834,8 @@ mod tests { let value = XchandlesPrecommitValue::for_normal_registration( payment_cat.asset_id.tree_hash(), XchandlesFactorPricingPuzzleArgs::curry_tree_hash(base_price, reg_period), - XchandlesFactorPricingSolution { + XchandlesPricingSolution { + buy_time: 100, current_expiration: 0, handle: handle.clone(), num_periods: 1, @@ -1848,7 +1843,6 @@ mod tests { .tree_hash(), handle.clone(), secret, - 100, handle_owner_launcher_id, handle_resolved_data, ); @@ -1992,6 +1986,7 @@ mod tests { precommit_coin, base_price, reg_period, + 100, )?; ensure_conditions_met(ctx, &mut sim, secure_cond.clone(), 1)?; @@ -2074,6 +2069,7 @@ mod tests { base_price, reg_period, extension_years, + 0, )?; let new_slot = registry .created_slot_value_to_slot(registry.pending_spend.created_slots[0].clone()); @@ -2203,18 +2199,15 @@ mod tests { XchandlesExponentialPremiumRenewPuzzleArgs::curry_tree_hash( base_price, reg_period, 1000, ), - XchandlesExponentialPremiumRenewPuzzleSolution { + XchandlesPricingSolution { buy_time, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: expiration, - handle: handle_to_expire.clone(), - num_periods: 1, - }, + current_expiration: expiration, + handle: handle_to_expire.clone(), + num_periods: 1, } .tree_hash(), handle_to_expire.clone(), Bytes32::default(), - buy_time, Bytes32::from([42; 32]), Bytes32::from([69; 32]).into(), ); @@ -2281,6 +2274,7 @@ mod tests { base_price, reg_period, precommit_coin, + buy_time, )?; // assert expire conds @@ -2314,22 +2308,12 @@ mod tests { )? .get_puzzle(ctx)? }; - let pricing_solution = if use_factor_pricing { - ctx.alloc(&XchandlesFactorPricingSolution { - current_expiration: 0, - handle: unregistered_handle.clone(), - num_periods: 1, - })? - } else { - ctx.alloc(&XchandlesExponentialPremiumRenewPuzzleSolution { - buy_time: 28 * 24 * 60 * 60 + 1, // premium should be 0 - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: 0, - handle: unregistered_handle.clone(), - num_periods: 1, - }, - })? - }; + let pricing_solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: 28 * 24 * 60 * 60 + 1, // premium should be 0 + current_expiration: 0, + handle: unregistered_handle.clone(), + num_periods: 1, + })?; let expected_price = XchandlesFactorPricingPuzzleArgs::get_price(base_price, &unregistered_handle, 1); @@ -2361,22 +2345,12 @@ mod tests { .find(|s| s.info.value.handle_hash == existing_handle.tree_hash().into()) .unwrap() .clone(); - let existing_handle_pricing_solution = if use_factor_pricing { - ctx.alloc(&XchandlesFactorPricingSolution { - current_expiration: existing_slot.info.value.expiration, - handle: existing_handle.clone(), - num_periods: 1, - })? - } else { - ctx.alloc(&XchandlesExponentialPremiumRenewPuzzleSolution { - buy_time: existing_slot.info.value.expiration + 28 * 24 * 60 * 60 + 1, // premium should be 0 - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: existing_slot.info.value.expiration, - handle: existing_handle.clone(), - num_periods: 1, - }, - })? - }; + let existing_handle_pricing_solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: existing_slot.info.value.expiration + 28 * 24 * 60 * 60 + 1, // premium should be 0 + current_expiration: existing_slot.info.value.expiration, + handle: existing_handle.clone(), + num_periods: 1, + })?; let existing_handle_expected_price = XchandlesFactorPricingPuzzleArgs::get_price(base_price, &existing_handle, 1); diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index 54305f33..a1b6709c 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -17,7 +17,7 @@ use crate::{ XchandlesRegistry, XchandlesSlotValue, }; -use super::{XchandlesFactorPricingPuzzleArgs, XchandlesFactorPricingSolution}; +use super::{XchandlesFactorPricingPuzzleArgs, XchandlesPricingSolution}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XchandlesExpireAction { @@ -128,6 +128,7 @@ impl XchandlesExpireAction { base_handle_price: u64, registration_period: u64, precommit_coin: PrecommitCoin, + start_time: u64, ) -> Result { let my_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); @@ -157,15 +158,12 @@ impl XchandlesExpireAction { 1000, )? .get_puzzle(ctx)?, - expired_handle_pricing_puzzle_solution: - XchandlesExponentialPremiumRenewPuzzleSolution:: { - buy_time: precommit_coin.value.start_time, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: slot.info.value.expiration, - handle: precommit_coin.value.handle.clone(), - num_periods, - }, - }, + expired_handle_pricing_puzzle_solution: XchandlesPricingSolution { + buy_time: start_time, + current_expiration: slot.info.value.expiration, + handle: precommit_coin.value.handle.clone(), + num_periods, + }, refund_puzzle_hash_hash: precommit_coin.refund_puzzle_hash.tree_hash().into(), secret: precommit_coin.value.secret, neighbors: slot.info.value.neighbors, @@ -190,12 +188,12 @@ impl XchandlesExpireAction { } } -pub const XCHANDLES_EXPIRE_PUZZLE: [u8; 1081] = - hex!("ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff8204efffff04ff825fefff827fef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); +pub const XCHANDLES_EXPIRE_PUZZLE: [u8; 1073] = + hex!("ff02ffff01ff02ffff03ffff22ffff09ffff02ff16ffff04ff02ffff04ff4fff80808080ff5780ffff09ffff02ff16ffff04ff02ffff04ff82016fff80808080ff81f780ffff09ffff0dff825fef80ffff012080ffff15ffff0141ffff0dff827fef808080ffff01ff04ff17ffff02ff2effff04ff02ffff04ffff02ff4fffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8205ef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff16ffff04ff02ffff04ffff04ffff04ffff04ff57ff81af80ffff04ff81f7ff8202ef8080ffff04ffff04ff8216efff820bef80ffff04ff825fefff827fef808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff81af8080ffff04ffff05ffff02ff82016fff8202ef8080ffff04ffff04ffff04ff10ffff04ff8204efff808080ffff04ffff04ff10ffff04ff820aefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ff820aefff822fef8080ff80808080ff8080808080ffff04ffff02ff1affff04ff02ffff04ff0bffff04ffff02ff16ffff04ff02ffff04ffff04ffff04ffff0bffff0101ff8216ef80ff8217ef80ffff04ffff10ffff06ffff02ff82016fff8202ef8080ff8204ef80ff823fef8080ff80808080ff8080808080ff8080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff16ffff04ff02ffff04ff09ff80808080ffff02ff16ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0178ff0580ff808080ff178080ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); pub const XCHANDLES_EXPIRE_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - 586fe828a78bc521b6fa358b5f10de0393d7e9ccd6096a201420527a5903978f + 514d248262b0b1607f305a26bf315f6ecb7d7705bfcf5856f12a9a22344af728 " )); @@ -257,12 +255,12 @@ pub struct XchandlesExpireActionSolution { pub new_rest: XchandlesDataValue, } -pub const XCHANDLES_EXPONENTIAL_PREMIUM_RENEW_PUZZLE: [u8; 351] = - hex!("ff02ffff01ff04ffff10ffff05ffff02ff05ffff04ff8202ffff8203ff808080ffff02ff06ffff04ff02ffff04ffff02ff04ffff04ff02ffff04ff5fffff04ff81bfffff04ffff0101ffff04ffff05ffff14ffff12ffff0183010000ffff3dffff11ff82017fff8202ff80ff0b8080ff0b8080ffff04ffff05ffff14ff17ffff17ffff0101ffff05ffff14ffff11ff82017fff8202ff80ff0b8080808080ff8080808080808080ffff04ff2fff808080808080ffff06ffff02ff05ffff04ff8202ffff8203ff80808080ffff04ffff01ffff02ffff03ff0bffff01ff02ff04ffff04ff02ffff04ff05ffff04ff1bffff04ffff17ff17ffff010180ffff04ff2fffff04ffff02ffff03ffff18ff2fff1780ffff01ff05ffff14ffff12ff5fff1380ff058080ffff015f80ff0180ff8080808080808080ffff015f80ff0180ff02ffff03ffff15ff05ff0b80ffff01ff11ff05ff0b80ff8080ff0180ff018080"); +pub const XCHANDLES_EXPONENTIAL_PREMIUM_RENEW_PUZZLE: [u8; 333] = + hex!("ff02ffff01ff04ffff10ffff05ffff02ff05ff81ff8080ffff02ff06ffff04ff02ffff04ffff02ff04ffff04ff02ffff04ff5fffff04ff81bfffff04ffff0101ffff04ffff05ffff14ffff12ffff0183010000ffff3dffff11ff82017fff8202ff80ff0b8080ff0b8080ffff04ffff05ffff14ff17ffff17ffff0101ffff05ffff14ffff11ff82017fff8202ff80ff0b8080808080ff8080808080808080ffff04ff2fff808080808080ffff06ffff02ff05ff81ff808080ffff04ffff01ffff02ffff03ff0bffff01ff02ff04ffff04ff02ffff04ff05ffff04ff1bffff04ffff17ff17ffff010180ffff04ff2fffff04ffff02ffff03ffff18ff2fff1780ffff01ff05ffff14ffff12ff5fff1380ff058080ffff015f80ff0180ff8080808080808080ffff015f80ff0180ff02ffff03ffff15ff05ff0b80ffff01ff11ff05ff0b80ff8080ff0180ff018080"); pub const XCHANDLES_EXPONENTIAL_PREMIUM_RENEW_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - 1e690af48fe029e072638c4952929d3d17795592d59b6cc8c18ddf5921f50285 + b54c0f4b73e63e78470366bd4006ca629d94f36c8ea58abacf8cc1cbb7724907 " )); @@ -371,15 +369,11 @@ impl XchandlesExponentialPremiumRenewPuzzleArgs { num_periods: u64, ) -> Result { let puzzle = self.get_puzzle(ctx)?; - let solution = ctx.alloc(&XchandlesExponentialPremiumRenewPuzzleSolution::< - XchandlesFactorPricingSolution, - > { + let solution = ctx.alloc(&XchandlesPricingSolution { buy_time, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: expiration, - handle, - num_periods, - }, + current_expiration: expiration, + handle, + num_periods, })?; let output = ctx.run(puzzle, solution)?; @@ -387,14 +381,6 @@ impl XchandlesExponentialPremiumRenewPuzzleArgs { } } -#[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] -pub struct XchandlesExponentialPremiumRenewPuzzleSolution { - pub buy_time: u64, - #[clvm(rest)] - pub pricing_program_solution: S, -} - #[cfg(test)] mod tests { use super::*; @@ -424,15 +410,11 @@ mod tests { for day in 0..28 { for hour in 0..24 { let buy_time = day * 24 * 60 * 60 + hour * 60 * 60; - let solution = ctx.alloc(&XchandlesExponentialPremiumRenewPuzzleSolution::< - XchandlesFactorPricingSolution, - > { + let solution = ctx.alloc(&XchandlesPricingSolution { buy_time, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: 0, - handle: "yakuhito".to_string(), - num_periods: 1, - }, + current_expiration: 0, + handle: "yakuhito".to_string(), + num_periods: 1, })?; let output = ctx.run(puzzle, solution)?; @@ -472,15 +454,11 @@ mod tests { } // check premium after auction is 0 - let solution = ctx.alloc(&XchandlesExponentialPremiumRenewPuzzleSolution::< - XchandlesFactorPricingSolution, - > { + let solution = ctx.alloc(&XchandlesPricingSolution { buy_time: 28 * 24 * 60 * 60, - pricing_program_solution: XchandlesFactorPricingSolution { - current_expiration: 0, - handle: "yakuhito".to_string(), - num_periods: 1, - }, + current_expiration: 0, + handle: "yakuhito".to_string(), + num_periods: 1, })?; let output = ctx.run(puzzle, solution)?; diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index b8fb0e65..b93c1e15 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -17,7 +17,7 @@ use crate::{ XchandlesDataValue, XchandlesRegistry, XchandlesSlotValue, }; -use super::{XchandlesFactorPricingPuzzleArgs, XchandlesFactorPricingSolution}; +use super::{XchandlesFactorPricingPuzzleArgs, XchandlesPricingSolution}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XchandlesExtendAction { @@ -55,16 +55,16 @@ impl XchandlesExtendAction { ) -> Result { let solution = ctx.extract::>(solution)?; - // current expiration is the first truth given to a pricing puzzle - let current_expiration = solution.pricing_solution.0; + // current expiration is the second truth given to a pricing puzzle + let current_expiration = solution.pricing_solution.1 .0; Ok(XchandlesSlotValue::new( - solution.pricing_solution.1 .0.tree_hash().into(), + solution.pricing_solution.1 .1 .0.tree_hash().into(), solution.neighbors.left_value, solution.neighbors.right_value, current_expiration, @@ -85,8 +85,8 @@ impl XchandlesExtendAction { let pricing_output = ctx.run(solution.pricing_puzzle_reveal, solution.pricing_solution)?; let registration_time_delta = <(NodePtr, u64)>::from_clvm(ctx, pricing_output)?.1; - let (_, (handle, _)) = - ctx.extract::<(NodePtr, (String, NodePtr))>(solution.pricing_solution)?; + let (_, (_, (handle, _))) = + ctx.extract::<(NodePtr, (NodePtr, (String, NodePtr)))>(solution.pricing_solution)?; // current expiration is the first truth given to a pricing puzzle let current_expiration = ctx.extract::<(u64, NodePtr)>(solution.pricing_solution)?.0; @@ -112,6 +112,7 @@ impl XchandlesExtendAction { base_handle_price: u64, registration_period: u64, num_periods: u64, + buy_time: u64, ) -> Result<(Conditions, NotarizedPayment), DriverError> { let spender_inner_puzzle_hash: Bytes32 = registry.info.inner_puzzle_hash().into(); @@ -127,7 +128,8 @@ impl XchandlesExtendAction { let slot = registry.actual_slot(slot); let action_solution = ctx.alloc(&XchandlesExtendActionSolution { pricing_puzzle_reveal, - pricing_solution: XchandlesFactorPricingSolution { + pricing_solution: XchandlesPricingSolution { + buy_time, current_expiration: slot.info.value.expiration, handle: handle.clone(), num_periods, diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index 164837a6..3aef0b4f 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -114,7 +114,6 @@ impl XchandlesRefundAction { precommited_pricing_puzzle_solution, handle: precommit_coin.value.handle.clone(), secret: precommit_coin.value.secret, - precommited_start_time: precommit_coin.value.start_time, precommited_owner_launcher_id: precommit_coin.value.owner_launcher_id, precommited_resolved_data: precommit_coin.value.resolved_data.clone(), refund_puzzle_hash_hash: precommit_coin.refund_puzzle_hash.tree_hash().into(), @@ -140,12 +139,12 @@ impl XchandlesRefundAction { } } -pub const XCHANDLES_REFUND_PUZZLE: [u8; 1081] = - hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8307ffefffff01ff09ff8313ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8307ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8305ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff8302ffef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefffff04ff82bfefff83017fef80808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8305ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080"); +pub const XCHANDLES_REFUND_PUZZLE: [u8; 1072] = + hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080"); pub const XCHANDLES_REFUND_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - e1ea8aede5151fb27f29ab643f1078ec608e586fb446f4d39464dd803d40343a + f2c327896bb802ad837d8248292a94dbbd04c758bcfae89519305571164bfb68 " )); @@ -203,7 +202,6 @@ pub struct XchandlesRefundActionSolution { pub precommited_pricing_puzzle_solution: PS, pub handle: String, pub secret: S, - pub precommited_start_time: u64, pub precommited_owner_launcher_id: Bytes32, pub precommited_resolved_data: Bytes, pub refund_puzzle_hash_hash: Bytes32, diff --git a/src/layers/actions/xchandles/register.rs b/src/layers/actions/xchandles/register.rs index 1682de1d..6795eabd 100644 --- a/src/layers/actions/xchandles/register.rs +++ b/src/layers/actions/xchandles/register.rs @@ -107,6 +107,8 @@ impl XchandlesRegisterAction { )?; let registration_time_delta = <(NodePtr, u64)>::from_clvm(ctx, pricing_output)?.1; + let (start_time, _) = ctx.extract::<(u64, NodePtr)>(solution.pricing_puzzle_solution)?; + Ok([ XchandlesSlotValue::new( solution.neighbors.left_value, @@ -120,7 +122,7 @@ impl XchandlesRegisterAction { solution.handle_hash, solution.neighbors.left_value, solution.neighbors.right_value, - solution.start_time + registration_time_delta, + start_time + registration_time_delta, solution.data.owner_launcher_id, solution.data.resolved_data, ), @@ -145,13 +147,13 @@ impl XchandlesRegisterAction { precommit_coin: PrecommitCoin, base_handle_price: u64, registration_period: u64, + start_time: u64, ) -> Result { let handle: String = precommit_coin.value.handle.clone(); let handle_hash: Bytes32 = handle.tree_hash().into(); let (left_slot, right_slot) = registry.actual_neigbors(handle_hash, left_slot, right_slot); let secret = precommit_coin.value.secret; - let start_time = precommit_coin.value.start_time; let num_periods = precommit_coin.coin.amount / XchandlesFactorPricingPuzzleArgs::get_price(base_handle_price, &handle, 1); @@ -176,7 +178,8 @@ impl XchandlesRegisterAction { base_handle_price, registration_period, )?, - pricing_puzzle_solution: XchandlesFactorPricingSolution { + pricing_puzzle_solution: XchandlesPricingSolution { + buy_time: start_time, current_expiration: 0, handle: handle.clone(), num_periods, @@ -196,7 +199,6 @@ impl XchandlesRegisterAction { right_right_value: right_slot.info.value.neighbors.right_value, right_expiration: right_slot.info.value.expiration, right_data: right_slot.info.value.rest_data(), - start_time, data: XchandlesDataValue { owner_launcher_id: precommit_coin.value.owner_launcher_id, resolved_data: precommit_coin.value.resolved_data, @@ -222,11 +224,11 @@ impl XchandlesRegisterAction { } } -pub const XCHANDLES_REGISTER_PUZZLE: [u8; 1356] = hex!("ff02ffff01ff02ffff03ffff22ffff09ff4fffff0bffff0101ff82056f8080ffff20ff82026f80ffff0aff4fff8213ef80ffff0aff821befff4f80ffff09ff57ffff02ff2effff04ff02ffff04ff8202efff8080808080ffff09ff81b7ffff02ff2effff04ff02ffff04ff81afff8080808080ffff09ffff0dff8313ffef80ffff012080ffff15ffff0141ffff0dff831bffef808080ffff01ff04ff17ffff02ff1affff04ff02ffff04ffff02ff8202efffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff8317ffef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff57ff8205ef80ffff04ff81b7ff82016f8080ffff04ffff04ff82056fff832fffef80ffff04ff8305ffefffff04ff8313ffefff831bffef80808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff8205ef8080ffff04ffff05ffff02ff81afff82016f8080ffff04ffff04ffff04ff10ffff04ff8305ffefff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff821bef8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff8213efff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff4fff820bef80ffff04ffff10ff8305ffefffff06ffff02ff81afff82016f808080ff830bffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff4f8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff4fff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ff80808080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0172ff0580ff808080ff178080ffff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); +pub const XCHANDLES_REGISTER_PUZZLE: [u8; 1345] = hex!("ff02ffff01ff02ffff03ffff22ffff09ff4fffff0bffff0101ff820b6f8080ffff20ff82056f80ffff0aff4fff8213ef80ffff0aff821befff4f80ffff09ff57ffff02ff2effff04ff02ffff04ff8202efff8080808080ffff09ff81b7ffff02ff2effff04ff02ffff04ff81afff8080808080ffff09ffff0dff8309ffef80ffff012080ffff15ffff0141ffff0dff830dffef808080ffff01ff04ff17ffff02ff1affff04ff02ffff04ffff02ff8202efffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ff830bffef80ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff57ff8205ef80ffff04ff81b7ff82016f8080ffff04ffff04ff820b6fff8317ffef80ffff04ff8309ffefff830dffef808080ff808080808080ffff0bff3cff62ff42808080ff42808080ff42808080ff8205ef8080ffff04ffff05ffff02ff81afff82016f8080ffff04ffff04ffff04ff10ffff04ff82026fff808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff821bef8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff3effff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff8213efff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff4fff820bef80ffff04ffff10ff82026fffff06ffff02ff81afff82016f808080ff8305ffef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff8213efffff04ff8217efff4f8080ffff04ff822fefff825fef8080ff80808080ff8080808080ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ffff04ffff04ff821befffff04ff4fff82bfef8080ffff04ff83017fefff8302ffef8080ff80808080ff8080808080ff80808080808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff5133ff3eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ffff04ff2cffff04ffff0113ffff04ffff0101ffff04ff05ffff04ff0bff808080808080ffff04ffff04ff14ffff04ffff0effff0172ff0580ff808080ff178080ffff04ff18ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff2cffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff3cffff0bff3cff62ff0580ffff0bff3cffff0bff72ffff0bff3cffff0bff3cff62ffff0bffff0101ff0b8080ffff0bff3cff62ff42808080ff42808080ff8080808080ff018080"); pub const XCHANDLES_REGISTER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - 277d7b7171f56365d124c68beb3933aecda41dd09a2112f4dd56ebde542f54e5 + 07848cf0db85d13490c15331a065364add5f5b52d8059c410f1ff7aa87e66722 " )); @@ -288,17 +290,16 @@ pub struct XchandlesRegisterActionSolution { pub right_right_value: Bytes32, pub right_expiration: u64, pub right_data: XchandlesDataValue, - pub start_time: u64, pub data: XchandlesDataValue, pub refund_puzzle_hash_hash: Bytes32, pub secret: S, } -pub const XCHANDLES_FACTOR_PRICING_PUZZLE: [u8; 475] = hex!("ff02ffff01ff02ffff03ffff15ff3fff8080ffff01ff04ffff12ff3fff05ffff02ff06ffff04ff02ffff04ffff0dff2f80ffff04ffff02ff04ffff04ff02ffff04ff2fff80808080ff808080808080ffff12ff3fff0b8080ffff01ff088080ff0180ffff04ffff01ffff02ffff03ff05ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff016080ffff15ffff017bffff0cff05ff80ffff0101808080ffff01ff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff80808080ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff012f80ffff15ffff013affff0cff05ff80ffff0101808080ffff01ff10ffff0101ffff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff8080808080ffff01ff088080ff018080ff0180ff8080ff0180ff05ffff14ffff02ffff03ffff15ff05ffff010280ffff01ff02ffff03ffff15ff05ffff010480ffff01ff02ffff03ffff09ff05ffff010580ffff01ff0110ffff01ff02ffff03ffff15ff05ffff011f80ffff01ff0880ffff01ff010280ff018080ff0180ffff01ff02ffff03ffff09ff05ffff010380ffff01ff01820080ffff01ff014080ff018080ff0180ffff01ff088080ff0180ffff03ff0bffff0102ffff0101808080ff018080"); +pub const XCHANDLES_FACTOR_PRICING_PUZZLE: [u8; 475] = hex!("ff02ffff01ff02ffff03ffff15ff7fff8080ffff01ff04ffff12ff7fff05ffff02ff06ffff04ff02ffff04ffff0dff5f80ffff04ffff02ff04ffff04ff02ffff04ff5fff80808080ff808080808080ffff12ff7fff0b8080ffff01ff088080ff0180ffff04ffff01ffff02ffff03ff05ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff016080ffff15ffff017bffff0cff05ff80ffff0101808080ffff01ff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff80808080ffff01ff02ffff03ffff22ffff15ffff0cff05ff80ffff010180ffff012f80ffff15ffff013affff0cff05ff80ffff0101808080ffff01ff10ffff0101ffff02ff04ffff04ff02ffff04ffff0cff05ffff010180ff8080808080ffff01ff088080ff018080ff0180ff8080ff0180ff05ffff14ffff02ffff03ffff15ff05ffff010280ffff01ff02ffff03ffff15ff05ffff010480ffff01ff02ffff03ffff09ff05ffff010580ffff01ff0110ffff01ff02ffff03ffff15ff05ffff011f80ffff01ff0880ffff01ff010280ff018080ff0180ffff01ff02ffff03ffff09ff05ffff010380ffff01ff01820080ffff01ff014080ff018080ff0180ffff01ff088080ff0180ffff03ff0bffff0102ffff0101808080ff018080"); pub const XCHANDLES_FACTOR_PRICING_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - 3795a26d84d34e964f4f53ca7431d925d2b3399f9fdf2570de4d50313a3e9e4b + a7edc890e6c256e4e729e826e7b45ad0616ec8d431e4e051ee68ddf4cae868bb " )); @@ -359,7 +360,8 @@ impl XchandlesFactorPricingPuzzleArgs { #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] #[clvm(solution)] -pub struct XchandlesFactorPricingSolution { +pub struct XchandlesPricingSolution { + pub buy_time: u64, pub current_expiration: u64, pub handle: String, #[clvm(rest)] @@ -401,7 +403,8 @@ mod tests { "a".repeat(handle_length) }; - let solution = ctx.alloc(&XchandlesFactorPricingSolution { + let solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: 0, current_expiration: (handle_length - 3) as u64, // shouldn't matter handle, num_periods, @@ -432,7 +435,8 @@ mod tests { // make sure the puzzle won't let us register a handle of length 2 - let solution = ctx.alloc(&XchandlesFactorPricingSolution { + let solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: 0, current_expiration: 0, handle: "aa".to_string(), num_periods: 1, @@ -445,7 +449,8 @@ mod tests { // make sure the puzzle won't let us register a handle of length 32 - let solution = ctx.alloc(&XchandlesFactorPricingSolution { + let solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: 0, current_expiration: 0, handle: "a".repeat(32), num_periods: 1, @@ -458,7 +463,8 @@ mod tests { // make sure the puzzle won't let us register a handle with invalid characters - let solution = ctx.alloc(&XchandlesFactorPricingSolution { + let solution = ctx.alloc(&XchandlesPricingSolution { + buy_time: 0, current_expiration: 0, handle: "yak@test".to_string(), num_periods: 1, diff --git a/src/layers/precommit_layer.rs b/src/layers/precommit_layer.rs index 9542e9a6..7be05de2 100644 --- a/src/layers/precommit_layer.rs +++ b/src/layers/precommit_layer.rs @@ -269,7 +269,7 @@ where // value is: // (c // (c (c cat_maker_reveal cat_maker_solution) (c pricing_puzzle_reveal pricing_solution)) -// (c (c secret handle) (c start_time (c owner_launcher_id resolved_data)))) +// (c (c secret handle) (c owner_launcher_id resolved_data))) // ) #[derive(Debug, Clone, PartialEq, Eq)] pub struct XchandlesPrecommitValue @@ -284,7 +284,6 @@ where pub pricing_solution: PS, pub handle: String, pub secret: S, - pub start_time: u64, pub owner_launcher_id: Bytes32, pub resolved_data: Bytes, } @@ -303,7 +302,6 @@ where pricing_solution: PS, handle: String, secret: S, - start_time: u64, owner_launcher_id: Bytes32, resolved_data: Bytes, ) -> Self { @@ -314,7 +312,6 @@ where pricing_solution, handle, secret, - start_time, owner_launcher_id, resolved_data, } @@ -329,7 +326,6 @@ impl XchandlesPrecommitValue<(), TreeHash, Bytes32> { pricing_puzzle_solution: PS, handle: String, secret: Bytes32, - start_time: u64, owner_launcher_id: Bytes32, resolved_data: Bytes, ) -> Self @@ -343,7 +339,6 @@ impl XchandlesPrecommitValue<(), TreeHash, Bytes32> { pricing_puzzle_solution.tree_hash(), handle, secret, - start_time, owner_launcher_id, resolved_data, ) @@ -365,10 +360,7 @@ where ), clvm_tuple!( clvm_tuple!(self.handle.tree_hash(), self.secret.tree_hash()), - clvm_tuple!( - self.start_time, - clvm_tuple!(self.owner_launcher_id, self.resolved_data.tree_hash()) - ) + clvm_tuple!(self.owner_launcher_id, self.resolved_data.tree_hash()) ) ) .tree_hash() From 37dc54d8dc7be99d3b8872c2bc65be237a1fca56 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 19:28:19 +0300 Subject: [PATCH 38/65] thank god for tests --- .../reward_distributor/nft/stake.clsp.hex | 1 - puzzles/actions/xchandles/refund.clsp | 16 ++++++---------- puzzles/actions/xchandles/refund.clsp.hex | 2 +- src/benchmarker.rs | 1 - src/drivers.rs | 2 +- src/layers/actions/xchandles/extend.rs | 11 +++++++---- src/layers/actions/xchandles/refund.rs | 6 +++--- 7 files changed, 18 insertions(+), 21 deletions(-) diff --git a/puzzles/actions/reward_distributor/nft/stake.clsp.hex b/puzzles/actions/reward_distributor/nft/stake.clsp.hex index 01ababce..e69de29b 100644 --- a/puzzles/actions/reward_distributor/nft/stake.clsp.hex +++ b/puzzles/actions/reward_distributor/nft/stake.clsp.hex @@ -1 +0,0 @@ -ff02ffff01ff04ffff04ffff10ff8209ffffff010180ffff04ff8215ffffff04ffff10ff822dffffff010180ffff04ff825dffffff04ff82bdffff808080808080ffff02ff3cffff04ff02ffff04ffff0bffff02ff3affff04ff02ffff04ff09ffff04ffff02ff3effff04ff02ffff04ffff04ff09ffff04ffff02ff36ffff04ff02ffff04ffff30ff83047bffffff02ff3affff04ff02ffff04ff09ffff04ffff02ff3effff04ff02ffff04ff05ff80808080ffff04ff830a7bffff808080808080ff83167bff80ffff04ff83037bffff8080808080ff1d8080ff80808080ffff04ffff02ff3affff04ff02ffff04ff0bffff04ffff0bffff0101ff0b80ffff04ff822bffffff04ff825bffffff04ffff02ff3affff04ff02ffff04ff17ffff04ffff0bffff0101ff1780ffff04ff8192ffff04ff82bbffffff04ff2fff8080808080808080ff8080808080808080ff808080808080ffff02ff3effff04ff02ffff04ffff04ffff02ff3effff04ff02ffff04ffff04ff8209ffff8213ff80ff80808080ffff04ffff02ff2effff04ff02ffff04ffff02ff3affff04ff02ffff04ff5fffff04ffff0bffff0101ff8301fbff80ffff04ff81bfff808080808080ff80808080ff808080ff8080808080ffff04ffff04ffff04ff28ffff04ff8213ffff808080ffff04ffff02ff2affff04ff02ffff04ff82017fffff04ffff02ff3effff04ff02ffff04ffff04ff8301fbffffff04ff829dffffff01018080ff80808080ffff04ff8301fbffff808080808080ffff04ffff04ff10ffff04ffff10ff83013dffff8202ff80ff808080ff80808080ff808080808080ffff04ffff01ffffff55ff463fffff333eff02ff04ffff04ff38ffff04ff05ff808080ffff04ffff04ff34ffff04ff05ff808080ff0b8080ffffffff02ffff03ff05ffff01ff0bff81f2ffff02ff26ffff04ff02ffff04ff09ffff04ffff02ff22ffff04ff02ffff04ff0dff80808080ff808080808080ffff0181d280ff0180ffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff04ff24ffff04ffff02ff3affff04ff02ffff04ff05ffff04ffff0bffff0101ff0b80ff8080808080ffff04ff80ffff04ffff04ff17ff8080ff8080808080ff0bff81b2ffff02ff26ffff04ff02ffff04ff05ffff04ffff02ff22ffff04ff02ffff04ff07ff80808080ff808080808080ffffff0bff2cffff0bff2cff81d2ff0580ffff0bff2cff0bff81928080ff02ffff03ff0bffff01ff30ffff02ff36ffff04ff02ffff04ff05ffff04ff1bff8080808080ff23ff3380ffff010580ff0180ffff04ff05ffff04ffff0101ffff04ffff04ff05ff8080ff80808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 diff --git a/puzzles/actions/xchandles/refund.clsp b/puzzles/actions/xchandles/refund.clsp index 05ac17e9..6210687c 100644 --- a/puzzles/actions/xchandles/refund.clsp +++ b/puzzles/actions/xchandles/refund.clsp @@ -88,17 +88,13 @@ (all ; not (a) (= precommited_cat_maker_reveal_hash Cat_Maker_Puzzle_Hash) - ; not (b) - (if (= precommited_pricing_puzzle_reveal_hash Pricing_Puzzle_Hash) - (= handle (f (r precommited_pricing_puzzle_solution))) - ; else - (if (= precommited_pricing_puzzle_reveal_hash Expired_Handle_Pricing_Puzzle_Hash) - (= handle (f (r (r precommited_pricing_puzzle_solution)))) - ; else - () - ) - ) ; not (c) + (= handle (f (r (r precommited_pricing_puzzle_solution)))) + (any + (= precommited_pricing_puzzle_reveal_hash Pricing_Puzzle_Hash) + (= precommited_pricing_puzzle_reveal_hash Expired_Handle_Pricing_Puzzle_Hash) + ) + ; not (b) (= precommit_amount (f (a precommited_pricing_puzzle_reveal precommited_pricing_puzzle_solution))) ) ; slot spend needed if (a), (b), and (c) are not met - we need (d) (a diff --git a/puzzles/actions/xchandles/refund.clsp.hex b/puzzles/actions/xchandles/refund.clsp.hex index c348c030..a3e6b779 100644 --- a/puzzles/actions/xchandles/refund.clsp.hex +++ b/puzzles/actions/xchandles/refund.clsp.hex @@ -1 +1 @@ -ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080 +ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff09ff8217efff825bef80ffff21ffff09ff8205efff81b780ffff09ff8205efff81f78080ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080 diff --git a/src/benchmarker.rs b/src/benchmarker.rs index dd79e721..40a913c3 100644 --- a/src/benchmarker.rs +++ b/src/benchmarker.rs @@ -33,7 +33,6 @@ pub mod tests { key: &str, keys: &[SecretKey], ) -> anyhow::Result<()> { - println!("Adding spend for {}", key); // todo: debug let sb = SpendBundle::new(ctx.take(), Signature::default()); let sb_conds = get_conditions_from_spendbundle( ctx, diff --git a/src/drivers.rs b/src/drivers.rs index 06a4c77a..7c66c126 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -2124,7 +2124,7 @@ mod tests { registry = registry.finish_spend(ctx)?; - // sim.spend_coins(ctx.take(), &[user_bls.sk.clone(), minter_bls.sk.clone()])?; + // sim.spend_coins(spends, &[user_bls.sk.clone(), minter_bls.sk.clone()])?; benchmark.add_spends( ctx, &mut sim, diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index b93c1e15..0ffd256e 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -88,8 +88,11 @@ impl XchandlesExtendAction { let (_, (_, (handle, _))) = ctx.extract::<(NodePtr, (NodePtr, (String, NodePtr)))>(solution.pricing_solution)?; - // current expiration is the first truth given to a pricing puzzle - let current_expiration = ctx.extract::<(u64, NodePtr)>(solution.pricing_solution)?.0; + // current expiration is the second truth given to a pricing puzzle + let current_expiration = ctx + .extract::<(NodePtr, (u64, NodePtr))>(solution.pricing_solution)? + .1 + .0; Ok(XchandlesSlotValue::new( handle.tree_hash().into(), @@ -171,11 +174,11 @@ impl XchandlesExtendAction { } } -pub const XCHANDLES_EXTEND_PUZZLE: [u8; 928] = hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff8202dfff8080808080ffff09ff82016fffff02ff2effff04ff02ffff04ff819fff808080808080ffff01ff04ff2fffff04ffff02ff3effff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff82055f80ff820bdf80ffff04ff82025fff820fdf8080ff80808080ff8080808080ffff04ffff04ff2cffff04ffff0effff0165ffff02ff2effff04ff02ffff04ffff04ffff05ffff02ff819fff82015f8080ff82055f80ff8080808080ff808080ffff04ffff04ff10ffff04ff82025fff808080ffff04ffff02ff16ffff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff82055f80ff820bdf80ffff04ffff10ff82025fffff06ffff02ff819fff82015f808080ff820fdf8080ff80808080ff8080808080ffff04ffff04ff18ffff04ffff0bffff02ff8202dfffff04ff05ff8205df8080ffff02ff2effff04ff02ffff04ffff04ffff02ff2effff04ff02ffff04ffff04ff82055fff82025f80ff80808080ffff04ffff04ff0bffff04ffff05ffff02ff819fff82015f8080ffff04ffff04ff0bff8080ff80808080ff808080ff8080808080ff808080ff80808080808080ffff01ff088080ff0180ffff04ffff01ffffff553fff33ff3e42ffff02ffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff04ff14ffff04ffff0bff5affff0bff12ffff0bff12ff6aff0580ffff0bff12ffff0bff7affff0bff12ffff0bff12ff6affff0bffff0101ff0b8080ffff0bff12ff6aff4a808080ff4a808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff3cffff04ffff0112ffff04ff80ffff04ffff0bff5affff0bff12ffff0bff12ff6aff0580ffff0bff12ffff0bff7affff0bff12ffff0bff12ff6affff0bffff0101ff0b8080ffff0bff12ff6aff4a808080ff4a808080ff8080808080ff018080"); +pub const XCHANDLES_EXTEND_PUZZLE: [u8; 964] = hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff8202dfff8080808080ffff09ff82016fffff02ff2effff04ff02ffff04ff819fff808080808080ffff01ff04ff2fffff04ffff02ff3effff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff820b5f80ff820bdf80ffff04ff82055fff820fdf8080ff80808080ff8080808080ffff04ffff04ff3cffff04ffff0effff0165ffff02ff2effff04ff02ffff04ffff04ffff05ffff02ff819fff82015f8080ff820b5f80ff8080808080ff808080ffff04ffff04ff10ffff04ff82055fff808080ffff04ffff04ff14ffff04ff82025fff808080ffff04ffff02ff16ffff04ff02ffff04ff17ffff04ffff02ff2effff04ff02ffff04ffff04ffff04ffff0bffff0101ff820b5f80ff820bdf80ffff04ffff10ff82055fffff06ffff02ff819fff82015f808080ff820fdf8080ff80808080ff8080808080ffff04ffff04ff18ffff04ffff0bffff02ff8202dfffff04ff05ff8205df8080ffff02ff2effff04ff02ffff04ffff04ffff02ff2effff04ff02ffff04ffff04ff820b5fff82055f80ff80808080ffff04ffff04ff0bffff04ffff05ffff02ff819fff82015f8080ffff04ffff04ff0bff8080ff80808080ff808080ff8080808080ff808080ff8080808080808080ffff01ff088080ff0180ffff04ffff01ffffff553fff51ff333effff42ff02ffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff04ff2cffff04ffff0bff81baffff0bff2affff0bff2aff81daff0580ffff0bff2affff0bff81faffff0bff2affff0bff2aff81daffff0bffff0101ff0b8080ffff0bff2aff81daff819a808080ff819a808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff12ffff04ffff0112ffff04ff80ffff04ffff0bff81baffff0bff2affff0bff2aff81daff0580ffff0bff2affff0bff81faffff0bff2affff0bff2aff81daffff0bffff0101ff0b8080ffff0bff2aff81daff819a808080ff819a808080ff8080808080ff018080"); pub const XCHANDLES_EXTEND_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - 16682d7841b1e3d77a6202b70ed75c5bc9d923aa6ac045d71aa489f0d7886584 + caa665c939f3de5d90dd22b00d092ba7c794300bf994b9ddcea536fa77843e08 " )); diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index 3aef0b4f..e91be3c2 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -139,12 +139,12 @@ impl XchandlesRefundAction { } } -pub const XCHANDLES_REFUND_PUZZLE: [u8; 1072] = - hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff02ffff03ffff09ff8205efff81b780ffff01ff09ff8217efff822bef80ffff01ff02ffff03ffff09ff8205efff81f780ffff01ff09ff8217efff825bef80ff8080ff018080ff0180ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080"); +pub const XCHANDLES_REFUND_PUZZLE: [u8; 1036] = + hex!("ff02ffff01ff02ffff03ffff22ffff09ff81afffff02ff2effff04ff02ffff04ff4fff8080808080ffff09ff8205efffff02ff2effff04ff02ffff04ff8202efff8080808080ffff02ffff03ff8303ffefffff01ff09ff8309ffefffff0bffff0101ff8217ef8080ffff01ff010180ff018080ffff01ff04ff17ffff02ff16ffff04ff02ffff04ff0bffff04ffff02ff2effff04ff02ffff04ff8303ffefff80808080ffff04ffff22ffff09ff81afff5780ffff09ff8217efff825bef80ffff21ffff09ff8205efff81b780ffff09ff8205efff81f78080ffff09ff8302ffefffff05ffff02ff8202efff820bef80808080ffff04ffff02ff4fffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ff83017fef80ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ffff02ff2effff04ff02ffff04ffff04ffff04ffff04ff81afff82016f80ffff04ff8205efff820bef8080ffff04ffff04ff8217efff822fef80ffff04ff825fefff82bfef808080ff808080808080ffff0bff1cff62ff42808080ff42808080ff42808080ff82016f8080ffff04ff8302ffefff808080808080808080ffff01ff088080ff0180ffff04ffff01ffffff333eff4202ffffffffa04bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ff04ff10ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ffff04ff80ffff04ffff04ff05ff8080ff8080808080ffff04ffff04ff14ffff04ffff0113ffff04ff80ffff04ff2fffff04ff5fff808080808080ffff04ffff04ff18ffff04ffff0effff0124ff2f80ff808080ffff02ffff03ff17ffff01ff04ffff02ff3effff04ff02ffff04ff05ffff04ff0bff8080808080ffff04ffff02ff1affff04ff02ffff04ff05ffff04ff0bff8080808080ff808080ff8080ff01808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff04ff14ffff04ffff0112ffff04ff80ffff04ffff0bff52ffff0bff1cffff0bff1cff62ff0580ffff0bff1cffff0bff72ffff0bff1cffff0bff1cff62ffff0bffff0101ff0b8080ffff0bff1cff62ff42808080ff42808080ff8080808080ff018080"); pub const XCHANDLES_REFUND_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( " - f2c327896bb802ad837d8248292a94dbbd04c758bcfae89519305571164bfb68 + 4083fcef97c4ed9aa0a07884e4280ec6a00b77fb5ff5300ca0c7cdddacdfeae8 " )); From ceec5ecb800136146e0d98e72582700aa0782cc3 Mon Sep 17 00:00:00 2001 From: Yak Date: Thu, 26 Jun 2025 20:03:13 +0300 Subject: [PATCH 39/65] new CATalog deployment --- src/primitives/catalog_registry_info.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/primitives/catalog_registry_info.rs b/src/primitives/catalog_registry_info.rs index fafb3993..709977eb 100644 --- a/src/primitives/catalog_registry_info.rs +++ b/src/primitives/catalog_registry_info.rs @@ -45,7 +45,7 @@ impl CatalogRegistryConstants { if testnet11 { return CatalogRegistryConstants { launcher_id: Bytes32::from(hex!( - "05183ec35a4ee07049ba629c76f49f2d52b2056a1c4c63d780113244a7307a2f" + "0b705afb0d848794311970de0cb98722468fad6c8f687337735ab9e5286d7704" )), royalty_address: Bytes32::from(hex!( "b3aea098428b2b5e6d57cf3bff6ee82e3950dec338b17df6d8ee20944787def5" @@ -54,9 +54,9 @@ impl CatalogRegistryConstants { precommit_payout_puzzle_hash: Bytes32::from(hex!( "b3aea098428b2b5e6d57cf3bff6ee82e3950dec338b17df6d8ee20944787def5" )), - relative_block_height: 8, + relative_block_height: 4, price_singleton_launcher_id: Bytes32::from(hex!( - "283caf3922c2ac7f7e3265bad97ae59d8395bcdae61cd7fdc98553e77873d35e" + "45dff01375d9bd681d36a3a186ab3d0c86eb809d7f85fff950f0b37f068ec664" )), }; } From 0621802847d377835f5bb379546703a19cd53f5f Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 09:15:38 +0300 Subject: [PATCH 40/65] comment --- puzzles/actions/xchandles/register.clsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puzzles/actions/xchandles/register.clsp b/puzzles/actions/xchandles/register.clsp index 3a49159d..5f11d0ed 100644 --- a/puzzles/actions/xchandles/register.clsp +++ b/puzzles/actions/xchandles/register.clsp @@ -26,7 +26,7 @@ ) ) ) - ; pricing_solution's first element MUST be handle_reveal + ; pricing_solution has 3 Truths: Start_Time, Current_Expiration, and Handle_Reveal ( handle_hash pricing_puzzle_reveal From ac14ec3963704b9ed00ce3750c7358aa77c67dd8 Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 18:19:29 +0300 Subject: [PATCH 41/65] so many errors --- Cargo.lock | 1162 +++++++++++++++++++++++++++++++++++++++------------- Cargo.toml | 18 +- 2 files changed, 886 insertions(+), 294 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c60e127c..8e7a4bef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,9 +122,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "asn1-rs" @@ -477,9 +483,9 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "bigdecimal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f31f3af01c5c65a07985c804d3366560e6fa7883d640a122819b14ec327482c" +checksum = "1a22f228ab7a1b23027ccc6c350b72868017af7ea8356fbdf19f8d991c690013" dependencies = [ "autocfg", "libm", @@ -488,6 +494,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + [[package]] name = "bindgen" version = "0.69.5" @@ -513,9 +525,9 @@ dependencies = [ [[package]] name = "bip39" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" +checksum = "43d193de1f7487df1914d3a568b772458861d33f9c54249612cc2893d6915054" dependencies = [ "bitcoin_hashes", "serde", @@ -565,6 +577,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -589,9 +610,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" dependencies = [ "cc", "glob", @@ -656,18 +677,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be75455e34f2a0e221f0e10bae7a4a066bdeee18b63fb92047d5d075eaf1044c" dependencies = [ "chia-bls 0.20.0", - "chia-client", - "chia-consensus", - "chia-protocol", - "chia-puzzle-types", - "chia-secp", - "chia-serde", + "chia-client 0.20.0", + "chia-consensus 0.20.0", + "chia-protocol 0.20.0", + "chia-puzzle-types 0.20.0", + "chia-secp 0.20.0", + "chia-serde 0.20.0", "chia-sha2 0.20.0", - "chia-ssl", + "chia-ssl 0.20.0", "chia-traits 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", +] + +[[package]] +name = "chia" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e23293631a6453f729ac18ecd1caf5aad3c8686de79daaaeead77d09957f68" +dependencies = [ + "chia-bls 0.25.0", + "chia-client 0.25.0", + "chia-consensus 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzle-types 0.25.0", + "chia-secp 0.25.0", + "chia-serde 0.25.0", + "chia-sha2 0.25.0", + "chia-ssl 0.25.0", + "chia-traits 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", ] [[package]] @@ -682,7 +724,7 @@ dependencies = [ "hex", "hkdf", "lru", - "sha2", + "sha2 0.10.9", "thiserror 1.0.69", ] @@ -693,14 +735,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d94b11e12208aa2bb8a76a05fc57f6e616efabf695e3fc2e6041a9d6df563ccb" dependencies = [ "blst", - "chia-serde", + "chia-serde 0.20.0", "chia-sha2 0.20.0", "chia-traits 0.20.0", "hex", "hkdf", "linked-hash-map", "serde", - "sha2", + "sha2 0.10.9", + "thiserror 1.0.69", +] + +[[package]] +name = "chia-bls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86eaaa00a83a7511e8eb74ccb1ebe4358d927f43e06d45da5350e19ef2df1ca" +dependencies = [ + "blst", + "chia-sha2 0.22.0", + "chia-traits 0.22.0", + "hex", + "hkdf", + "linked-hash-map", + "sha2 0.10.9", + "thiserror 1.0.69", +] + +[[package]] +name = "chia-bls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c16b9296d434304de07601f24f520dd8dcd127ab217f6c3de2f08b9215e2665" +dependencies = [ + "blst", + "chia-serde 0.25.0", + "chia-sha2 0.25.0", + "chia-traits 0.25.0", + "hex", + "hkdf", + "linked-hash-map", + "serde", + "sha2 0.10.9", "thiserror 1.0.69", ] @@ -710,7 +786,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c318dc78d656cf8617a672e06af2da200b003603f0597e80363dc869502dc1ec" dependencies = [ - "chia-protocol", + "chia-protocol 0.20.0", "chia-traits 0.20.0", "futures-util", "thiserror 1.0.69", @@ -719,6 +795,21 @@ dependencies = [ "tungstenite 0.24.0", ] +[[package]] +name = "chia-client" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320a354175bea6a8b8d13e2c803217179f6b818e647304a294755c4ac9e1ec90" +dependencies = [ + "chia-protocol 0.25.0", + "chia-traits 0.25.0", + "futures-util", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite 0.24.0", + "tungstenite 0.24.0", +] + [[package]] name = "chia-consensus" version = "0.20.0" @@ -726,17 +817,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc7acfdaf6819c19bd61de9e6004312aa257a8df0e36caec81675e06112658b9" dependencies = [ "chia-bls 0.20.0", - "chia-protocol", - "chia-puzzle-types", + "chia-protocol 0.20.0", + "chia-puzzle-types 0.20.0", "chia-puzzles", "chia-sha2 0.20.0", "chia-traits 0.20.0", "chia_streamable_macro 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", + "hex", + "hex-literal", + "thiserror 1.0.69", +] + +[[package]] +name = "chia-consensus" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "716e9c3b8c4418049cac10c8e859246e64f6581ccf433fe65a569b8c43b1b361" +dependencies = [ + "chia-bls 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzle-types 0.25.0", + "chia-puzzles", + "chia-sha2 0.25.0", + "chia-traits 0.25.0", + "chia_streamable_macro 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", "hex", - "hex-literal 0.4.1", + "hex-literal", "thiserror 1.0.69", ] @@ -747,13 +859,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3cced8dfdc4541d1e2b617e50c41028d2f318310df8060d0bf718a957ad5dcb" dependencies = [ "chia-bls 0.20.0", - "chia-serde", + "chia-serde 0.20.0", "chia-sha2 0.20.0", "chia-traits 0.20.0", "chia_streamable_macro 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", + "hex", + "serde", +] + +[[package]] +name = "chia-protocol" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d09bfaf24a4a3e9ec7f89d0b95fadf093617aa87cec089aa651a905e81d1af1" +dependencies = [ + "chia-bls 0.25.0", + "chia-serde 0.25.0", + "chia-sha2 0.25.0", + "chia-traits 0.25.0", + "chia_streamable_macro 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", "hex", "serde", ] @@ -765,13 +895,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a6a5a6ab34939140c4211a8dbca3d816a30177e4ef62fda53c3142eaba2fe0a" dependencies = [ "chia-bls 0.20.0", - "chia-protocol", + "chia-protocol 0.20.0", "chia-puzzles", "chia-sha2 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", - "hex-literal 0.4.1", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", + "hex-literal", + "num-bigint", +] + +[[package]] +name = "chia-puzzle-types" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378afbe1412a2862f7afdb7b6b536957955a28c48bc282223dd70fd0b94a1cf1" +dependencies = [ + "chia-bls 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzles", + "chia-sha2 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", + "hex-literal", "num-bigint", ] @@ -782,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7108a1597c78873f6c116b434db0bc7bfaf16f30828c35ce648a6ca49710c8" dependencies = [ "hex", - "hex-literal 0.4.1", + "hex-literal", ] [[package]] @@ -792,9 +939,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e79752f8c692ef3f74f94a902e91000cc8668a19c5e27c4142c44213a7a7b1" dependencies = [ "aws-lc-rs", - "chia-protocol", - "chia-sdk-types", - "chia-ssl", + "chia-protocol 0.20.0", + "chia-sdk-types 0.23.0", + "chia-ssl 0.20.0", "chia-traits 0.20.0", "futures-util", "once_cell", @@ -807,15 +954,48 @@ dependencies = [ "tungstenite 0.24.0", ] +[[package]] +name = "chia-sdk-client" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc7c12f1e2345af54ce39484d54d2e03260fd805659cd63ad364ab2264a55077" +dependencies = [ + "chia-protocol 0.25.0", + "chia-sdk-types 0.25.0", + "chia-ssl 0.25.0", + "chia-traits 0.25.0", + "futures-util", + "once_cell", + "thiserror 2.0.12", + "tokio", + "tokio-tungstenite 0.24.0", + "tracing", + "tungstenite 0.24.0", +] + [[package]] name = "chia-sdk-coinset" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df6e3ed139b6112cdbaf817c95c5cee9319f37f6df40e4547adb29687b33c96" dependencies = [ - "chia-protocol", + "chia-protocol 0.20.0", + "hex", + "hex-literal", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "chia-sdk-coinset" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b19d96cf8169f5338e3fea6e9ec415bb6397738fcaff91907cb077e1e7854d4" +dependencies = [ + "chia-protocol 0.25.0", "hex", - "hex-literal 0.4.1", + "hex-literal", "reqwest", "serde", "serde_json", @@ -832,6 +1012,17 @@ dependencies = [ "syn", ] +[[package]] +name = "chia-sdk-derive" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5029013b79a6b9b0b1fcc5e7ea9dbb01d72a399256338c6bdc68044be36538af" +dependencies = [ + "convert_case", + "quote", + "syn", +] + [[package]] name = "chia-sdk-driver" version = "0.23.0" @@ -841,22 +1032,52 @@ dependencies = [ "bech32", "bigdecimal", "chia-bls 0.20.0", - "chia-consensus", - "chia-protocol", - "chia-puzzle-types", + "chia-consensus 0.20.0", + "chia-protocol 0.20.0", + "chia-puzzle-types 0.20.0", "chia-puzzles", - "chia-sdk-types", - "chia-secp", + "chia-sdk-types 0.23.0", + "chia-secp 0.20.0", "chia-sha2 0.20.0", "chia-traits 0.20.0", "chia_streamable_macro 0.21.2", - "clvm-traits", - "clvm-utils", - "clvmr", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", + "flate2", + "hex", + "hex-literal", + "indexmap 2.10.0", + "num-bigint", + "once_cell", + "thiserror 2.0.12", +] + +[[package]] +name = "chia-sdk-driver" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4903943baff2462b9c86716525e90639a4536e5728a18abcbb32298d4b963e" +dependencies = [ + "bech32", + "bigdecimal", + "chia-bls 0.25.0", + "chia-consensus 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzle-types 0.25.0", + "chia-puzzles", + "chia-sdk-types 0.25.0", + "chia-secp 0.25.0", + "chia-sha2 0.25.0", + "chia-traits 0.25.0", + "chia_streamable_macro 0.26.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", "flate2", "hex", - "hex-literal 0.4.1", - "indexmap 2.8.0", + "hex-literal", + "indexmap 2.10.0", "num-bigint", "once_cell", "thiserror 2.0.12", @@ -869,13 +1090,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80a7262ffc41549aeade067a278924114740fb01fefb76f66fba2a2efbc38883" dependencies = [ "chia-bls 0.20.0", - "chia-consensus", - "chia-protocol", - "chia-sdk-types", - "chia-secp", + "chia-consensus 0.20.0", + "chia-protocol 0.20.0", + "chia-sdk-types 0.23.0", + "chia-secp 0.20.0", "chia-sha2 0.20.0", - "clvm-traits", - "clvmr", + "clvm-traits 0.20.0", + "clvmr 0.12.1", + "k256", + "thiserror 2.0.12", +] + +[[package]] +name = "chia-sdk-signer" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2649f232c44298ccbe965bea021e42fbfb4de541436cea11ae064491ffa33dc" +dependencies = [ + "chia-bls 0.25.0", + "chia-consensus 0.25.0", + "chia-protocol 0.25.0", + "chia-sdk-types 0.25.0", + "chia-secp 0.25.0", + "chia-sha2 0.25.0", + "clvm-traits 0.25.0", + "clvmr 0.14.0", "k256", "thiserror 2.0.12", ] @@ -889,21 +1128,21 @@ dependencies = [ "anyhow", "bip39", "chia-bls 0.20.0", - "chia-consensus", - "chia-protocol", - "chia-puzzle-types", - "chia-sdk-client", - "chia-sdk-signer", - "chia-sdk-types", - "chia-secp", + "chia-consensus 0.20.0", + "chia-protocol 0.20.0", + "chia-puzzle-types 0.20.0", + "chia-sdk-client 0.23.0", + "chia-sdk-signer 0.23.0", + "chia-sdk-types 0.23.0", + "chia-secp 0.20.0", "chia-traits 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", "futures-channel", "futures-util", "hex", - "indexmap 2.8.0", + "indexmap 2.10.0", "itertools 0.13.0", "rand 0.8.5", "rand_chacha 0.3.1", @@ -914,6 +1153,32 @@ dependencies = [ "tracing", ] +[[package]] +name = "chia-sdk-test" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df246e7716f98d11943ea6663d87a4b68cb0b2f51729f18c637d973b457c4a6" +dependencies = [ + "anyhow", + "bip39", + "chia-bls 0.25.0", + "chia-consensus 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzle-types 0.25.0", + "chia-sdk-signer 0.25.0", + "chia-sdk-types 0.25.0", + "chia-secp 0.25.0", + "chia-traits 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", + "hex", + "indexmap 2.10.0", + "rand 0.8.5", + "rand_chacha 0.3.1", + "thiserror 2.0.12", +] + [[package]] name = "chia-sdk-types" version = "0.23.0" @@ -921,18 +1186,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "896773b58dd6f8c509ea0956462371d7a03c2e13d2d8646136c6376667864606" dependencies = [ "chia-bls 0.20.0", - "chia-consensus", - "chia-protocol", - "chia-puzzle-types", + "chia-consensus 0.20.0", + "chia-protocol 0.20.0", + "chia-puzzle-types 0.20.0", "chia-puzzles", - "chia-sdk-derive", - "chia-secp", + "chia-sdk-derive 0.23.0", + "chia-secp 0.20.0", "chia-sha2 0.20.0", - "clvm-traits", - "clvm-utils", - "clvmr", - "hex-literal 0.4.1", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", + "hex-literal", + "once_cell", +] + +[[package]] +name = "chia-sdk-types" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55c70758cd449677f2e6749e0b21445db98cccfe8f15f484c2078dcbd4239706" +dependencies = [ + "chia-bls 0.25.0", + "chia-consensus 0.25.0", + "chia-protocol 0.25.0", + "chia-puzzle-types 0.25.0", + "chia-puzzles", + "chia-sdk-derive 0.25.0", + "chia-secp 0.25.0", + "chia-sha2 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvm_tools_rs", + "clvmr 0.14.0", + "hex-literal", "once_cell", + "thiserror 2.0.12", ] [[package]] @@ -942,8 +1230,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "659f1d4a9b91d9164b1953b0497baec080243830d4f573ea7388d7cd33fae459" dependencies = [ "bech32", - "chia-protocol", - "indexmap 2.8.0", + "chia-protocol 0.20.0", + "indexmap 2.10.0", + "rand 0.8.5", + "rand_chacha 0.3.1", + "thiserror 2.0.12", +] + +[[package]] +name = "chia-sdk-utils" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b2cd12291bcf071751945ff9524f81b1dde7c4b0fbbe81bf76a39b6f7e16d4d" +dependencies = [ + "bech32", + "chia-protocol 0.25.0", + "indexmap 2.10.0", "rand 0.8.5", "rand_chacha 0.3.1", "thiserror 2.0.12", @@ -961,6 +1263,18 @@ dependencies = [ "p256", ] +[[package]] +name = "chia-secp" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727ab0317d4dc3e74152e0db4a60c86e4e2d5f69c879baf112ca6500866d5d60" +dependencies = [ + "chia-sha2 0.25.0", + "hex", + "k256", + "p256", +] + [[package]] name = "chia-serde" version = "0.20.0" @@ -971,13 +1285,23 @@ dependencies = [ "serde", ] +[[package]] +name = "chia-serde" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cffa2ea6267199feaa1bb0836095cd57d79c664277d8be28d370a44f36e47df1" +dependencies = [ + "hex", + "serde", +] + [[package]] name = "chia-sha2" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7020f53eeae8b4c24c5666165738173a167c6478e0c0a9e1c428a491a2e1383d" dependencies = [ - "sha2", + "sha2 0.10.9", ] [[package]] @@ -986,7 +1310,25 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320474241a5e4b4eb7c7935ddac6e893cc4237d5fab58f1855c1aa48a97b1474" dependencies = [ - "sha2", + "sha2 0.10.9", +] + +[[package]] +name = "chia-sha2" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7b37c5362dfb1c9449902139e94a91bbd8d3773c13939972fd88e4f14c4f9d" +dependencies = [ + "sha2 0.10.9", +] + +[[package]] +name = "chia-sha2" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0074799301bb192744727aa91f88a3ee75d2504bfb8a843b02d2e303a58dd87" +dependencies = [ + "sha2 0.10.9", ] [[package]] @@ -1003,6 +1345,19 @@ dependencies = [ "time", ] +[[package]] +name = "chia-ssl" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb268d7d4d08e83bda869a2b931dbe519ea4d60426515079c4dbd22f7731a2f4" +dependencies = [ + "rand 0.8.5", + "rcgen", + "rsa", + "thiserror 1.0.69", + "time", +] + [[package]] name = "chia-traits" version = "0.15.0" @@ -1025,6 +1380,28 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "chia-traits" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340ad823ef953d2ab9f937deae99b04bab73c0bf1a6aea1353331a5f875192e0" +dependencies = [ + "chia-sha2 0.22.0", + "chia_streamable_macro 0.22.0", + "thiserror 1.0.69", +] + +[[package]] +name = "chia-traits" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b67043daeab938c9b4d205b70e018d3352288fdd62709e87f6e2b331db5baca" +dependencies = [ + "chia-sha2 0.25.0", + "chia_streamable_macro 0.25.0", + "thiserror 1.0.69", +] + [[package]] name = "chia-wallet-sdk" version = "0.23.0" @@ -1032,17 +1409,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb4e8041651d5dc6630307406b8e9e145a9325b293050edfab8006cccdb46d6b" dependencies = [ "chia-bls 0.20.0", - "chia-protocol", - "chia-sdk-client", - "chia-sdk-coinset", - "chia-sdk-driver", - "chia-sdk-signer", - "chia-sdk-test", - "chia-sdk-types", - "chia-sdk-utils", - "clvm-traits", - "clvm-utils", - "clvmr", + "chia-protocol 0.20.0", + "chia-sdk-client 0.23.0", + "chia-sdk-coinset 0.23.0", + "chia-sdk-driver 0.23.0", + "chia-sdk-signer 0.23.0", + "chia-sdk-test 0.23.0", + "chia-sdk-types 0.23.0", + "chia-sdk-utils 0.23.0", + "clvm-traits 0.20.0", + "clvm-utils 0.20.0", + "clvmr 0.12.1", +] + +[[package]] +name = "chia-wallet-sdk" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e924ad4aa74bd00451a30de243855350a2e4afd22a3c504d5735e8330ab547e5" +dependencies = [ + "chia-bls 0.25.0", + "chia-protocol 0.25.0", + "chia-sdk-client 0.25.0", + "chia-sdk-coinset 0.25.0", + "chia-sdk-driver 0.25.0", + "chia-sdk-signer 0.25.0", + "chia-sdk-test 0.25.0", + "chia-sdk-types 0.25.0", + "chia-sdk-utils 0.25.0", + "clvm-traits 0.25.0", + "clvm-utils 0.25.0", + "clvmr 0.14.0", ] [[package]] @@ -1081,6 +1478,42 @@ dependencies = [ "syn", ] +[[package]] +name = "chia_streamable_macro" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed16ee21f14ed878cfc23b0354c8c6703190a5565d03625ea44324a3f21717f1" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "chia_streamable_macro" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc5c6400d47fc7b0bef1e08791e96fc391d678012090c4b95411cfa516c894c" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "chia_streamable_macro" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068278c78a0c53786012f6330a088f3f6ffe83bd39cb8f21d308eeec2f43a3dc" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "chrono" version = "0.4.40" @@ -1147,9 +1580,20 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clvm-derive" -version = "0.20.0" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36c308af8c7380c8c4b02bb48826f7a6398c38edc632c522d2ba7e92cb7fe50" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clvm-derive" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36c308af8c7380c8c4b02bb48826f7a6398c38edc632c522d2ba7e92cb7fe50" +checksum = "e184e2f4aa7473bf377bd0f03e61406668124eb0d16ccdd4591ec5b6cb8ea533" dependencies = [ "proc-macro2", "quote", @@ -1163,9 +1607,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71cd5dd7977b36416ea1f0b5917cbc9fd0e0a00539dc75f9edec4744b3be69a" dependencies = [ "chia-bls 0.20.0", - "chia-secp", - "clvm-derive", - "clvmr", + "chia-secp 0.20.0", + "clvm-derive 0.20.0", + "clvmr 0.12.1", + "num-bigint", + "thiserror 1.0.69", +] + +[[package]] +name = "clvm-traits" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a93051ecabce23522df9d597c915b5df1be00a8b6d28f852a306304d9fe94d" +dependencies = [ + "chia-bls 0.25.0", + "chia-secp 0.25.0", + "clvm-derive 0.25.0", + "clvmr 0.14.0", "num-bigint", "thiserror 1.0.69", ] @@ -1177,9 +1635,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8504b2255e7bd3eaf4c05abb88c4a1519235522b04b4bcbc7289cdda5380f7b" dependencies = [ "chia-sha2 0.20.0", - "clvm-traits", - "clvmr", + "clvm-traits 0.20.0", + "clvmr 0.12.1", + "hex", +] + +[[package]] +name = "clvm-utils" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3cfd58c573d44d4ecf9b17af614861a53e7e9170523decd212df162162b190" +dependencies = [ + "chia-sha2 0.25.0", + "clvm-traits 0.25.0", + "clvmr 0.14.0", + "hex", +] + +[[package]] +name = "clvm_tools_rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00394d353154d726b10ca4f76056f4fac3ad37a3218c83ba3008b041e1398c3" +dependencies = [ + "binascii", + "chia-bls 0.22.0", + "clvmr 0.14.0", + "do-notation", + "getrandom 0.2.15", + "hashlink", "hex", + "indoc", + "js-sys", + "lazy_static", + "num", + "num-bigint", + "num-traits", + "pyo3-build-config", + "regex", + "serde", + "serde_json", + "sha2 0.9.9", + "tempfile", + "unicode-segmentation", + "wasm-bindgen", + "yaml-rust2", ] [[package]] @@ -1193,7 +1693,30 @@ dependencies = [ "chia-bls 0.15.0", "chia-sha2 0.15.0", "hex", - "hex-literal 0.4.1", + "hex-literal", + "k256", + "lazy_static", + "num-bigint", + "num-integer", + "num-traits", + "p256", + "rand 0.8.5", + "sha1", + "sha3", +] + +[[package]] +name = "clvmr" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6b7142674607f3a213addaf261bd70b07537297e460a9cc6a389068a62934f" +dependencies = [ + "bitvec", + "bumpalo", + "chia-bls 0.22.0", + "chia-sha2 0.22.0", + "hex", + "hex-literal", "k256", "lazy_static", "num-bigint", @@ -1429,21 +1952,30 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -1502,6 +2034,12 @@ dependencies = [ "syn", ] +[[package]] +name = "do-notation" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e16a80c1dda2cf52fa07106427d3d798b6331dca8155fcb8c39f7fc78f6dd2" + [[package]] name = "dotenvy" version = "0.15.7" @@ -1521,7 +2059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", @@ -1545,7 +2083,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -1580,12 +2118,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1653,9 +2191,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "libz-sys", @@ -1940,7 +2478,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.8.0", + "indexmap 2.10.0", "slab", "tokio", "tokio-util", @@ -2025,12 +2563,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hex-literal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" - [[package]] name = "hkdf" version = "0.12.4" @@ -2046,7 +2578,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -2140,7 +2672,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 0.26.8", ] [[package]] @@ -2161,21 +2693,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" dependencies = [ + "base64", "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", "hyper", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.10", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2360,15 +2899,21 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown 0.15.2", "serde", ] +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + [[package]] name = "instant" version = "0.1.13" @@ -2395,6 +2940,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.16" @@ -2465,7 +3020,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2", + "sha2 0.10.9", "signature", ] @@ -2504,9 +3059,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" @@ -2515,7 +3070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2576,6 +3131,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "litemap" version = "0.7.5" @@ -2623,7 +3184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] @@ -2701,6 +3262,20 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -2709,6 +3284,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "serde", ] [[package]] @@ -2728,6 +3304,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -2754,6 +3339,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2798,6 +3394,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.66" @@ -2867,7 +3469,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -3080,13 +3682,23 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] +[[package]] +name = "pyo3-build-config" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999" +dependencies = [ + "once_cell", + "target-lexicon", +] + [[package]] name = "quinn" version = "0.11.7" @@ -3100,7 +3712,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.5.7", + "socket2 0.5.10", "thiserror 2.0.12", "tokio", "tracing", @@ -3136,7 +3748,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.7", + "socket2 0.5.10", "tracing", "windows-sys 0.59.0", ] @@ -3269,9 +3881,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -3281,9 +3893,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -3292,9 +3904,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relative-path" @@ -3304,15 +3916,14 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", - "futures-util", "h2", "http", "http-body", @@ -3321,34 +3932,30 @@ dependencies = [ "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", - "windows-registry", + "webpki-roots 1.0.1", ] [[package]] @@ -3383,7 +3990,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", - "digest", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -3489,6 +4096,19 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", +] + [[package]] name = "rustls" version = "0.23.27" @@ -3565,7 +4185,7 @@ name = "sage-api" version = "0.10.3" source = "git+https://github.com/xch-dev/sage.git#206ea6db50e4a36dcb0258f4e4554f0547efa011" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.10.0", "once_cell", "sage-config", "serde", @@ -3576,10 +4196,10 @@ name = "sage-config" version = "0.10.3" source = "git+https://github.com/xch-dev/sage.git#206ea6db50e4a36dcb0258f4e4554f0547efa011" dependencies = [ - "chia", - "chia-wallet-sdk", + "chia 0.20.0", + "chia-wallet-sdk 0.23.0", "hex", - "indexmap 2.8.0", + "indexmap 2.10.0", "once_cell", "serde", "serde_with", @@ -3721,7 +4341,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.8.0", + "indexmap 2.10.0", "serde", "serde_derive", "serde_json", @@ -3749,18 +4369,31 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] name = "sha2" -version = "0.10.8" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -3769,7 +4402,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] @@ -3794,7 +4427,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -3815,20 +4448,20 @@ dependencies = [ "axum", "bech32", "bip39", - "chia", - "chia-puzzle-types", + "chia 0.25.0", + "chia-puzzle-types 0.25.0", "chia-puzzles", - "chia-wallet-sdk", + "chia-wallet-sdk 0.25.0", "clap", - "clvm-traits", - "clvmr", + "clvm-traits 0.25.0", + "clvmr 0.14.0", "csv", "dirs", "futures", "futures-util", "getrandom 0.3.2", "hex", - "hex-literal 1.0.0", + "hex-literal", "openssl", "openssl-sys", "prettytable-rs", @@ -3866,9 +4499,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3880,7 +4513,7 @@ version = "2.0.0-rc.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab7f01e9310a820edd31c80fde3cae445295adde21a3f9416517d7d65015b971" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.10.0", "specta-macros", "thiserror 1.0.69", ] @@ -3948,7 +4581,7 @@ dependencies = [ "futures-util", "hashbrown 0.15.2", "hashlink", - "indexmap 2.8.0", + "indexmap 2.10.0", "log", "memchr", "native-tls", @@ -3956,7 +4589,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror 2.0.12", "tracing", @@ -3992,7 +4625,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", @@ -4014,7 +4647,7 @@ dependencies = [ "byteorder", "bytes", "crc", - "digest", + "digest 0.10.7", "dotenvy", "either", "futures-channel", @@ -4035,7 +4668,7 @@ dependencies = [ "rsa", "serde", "sha1", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -4072,7 +4705,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -4135,9 +4768,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -4191,16 +4824,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" + [[package]] name = "tempfile" -version = "3.13.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", "fastrand 2.1.1", + "getrandom 0.3.2", "once_cell", - "rustix 0.38.37", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -4266,9 +4905,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -4281,15 +4920,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -4322,9 +4961,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", @@ -4333,7 +4972,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.10", "tokio-macros", "windows-sys 0.52.0", ] @@ -4382,7 +5021,7 @@ dependencies = [ "tokio", "tokio-rustls", "tungstenite 0.24.0", - "webpki-roots", + "webpki-roots 0.26.8", ] [[package]] @@ -4426,7 +5065,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.10.0", "toml_datetime", "winnow 0.5.40", ] @@ -4437,7 +5076,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.10.0", "toml_datetime", "winnow 0.6.18", ] @@ -4460,14 +5099,18 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.6.0", "bytes", + "futures-util", "http", + "http-body", + "iri-string", "pin-project-lite", + "tower", "tower-layer", "tower-service", ] @@ -4596,9 +5239,9 @@ checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" @@ -4716,6 +5359,8 @@ dependencies = [ "cfg-if", "once_cell", "rustversion", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -4806,6 +5451,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" @@ -4860,7 +5514,7 @@ dependencies = [ "windows-interface", "windows-link", "windows-result", - "windows-strings 0.4.0", + "windows-strings", ] [[package]] @@ -4887,44 +5541,35 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ + "windows-link", "windows-result", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-strings", ] [[package]] name = "windows-result" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -4980,29 +5625,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5015,12 +5644,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5033,12 +5656,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5051,24 +5668,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5081,12 +5686,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5099,12 +5698,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5117,12 +5710,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5135,12 +5722,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.5.40" @@ -5207,6 +5788,17 @@ dependencies = [ "time", ] +[[package]] +name = "yaml-rust2" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + [[package]] name = "yasna" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index 84049b10..0ea3cbff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,11 @@ homepage = "https://github.com/Yakuhito/slot-machine" repository = "https://github.com/Yakuhito/slot-machine" [dependencies] -clvmr = "0.12.1" -chia = "0.20.0" -clvm-traits = "0.20.0" -hex-literal = "1.0.0" -bip39 = "2.1.0" +clvmr = "0.14.0" +chia = "0.25.0" +clvm-traits = "0.25.0" +hex-literal = "0.4.1" +bip39 = "2.2.0" getrandom = "0.3.2" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" @@ -23,7 +23,7 @@ thiserror = "2.0.12" tokio = { version = "1.44.1", features = ["full"] } sqlx = { version = "0.8.3", features = ["sqlite", "runtime-async-std-native-tls"] } bech32 = "0.9.1" -reqwest = { version = "0.12.15", features = ["json", "rustls-tls"] } +reqwest = { version = "0.12.20", features = ["json", "rustls-tls"] } dirs = "6.0.0" rustls = { version = "0.23", features = ["ring","logging","tls12"], default-features = false } tokio-tungstenite ={ version = "0.26.2", features = ["rustls-tls-native-roots"] } @@ -31,13 +31,13 @@ futures-util = "0.3.31" axum = { version = "0.8.3", features = ["macros"]} tower-http = { version = "0.6.2", features = ["cors"] } futures = "0.3.31" -chia-wallet-sdk = { version="0.23.0", features=["offers"] } +chia-wallet-sdk = { version="0.25.0", features=["offers"] } sage-api = { version = "0.10.3", git = "https://github.com/xch-dev/sage.git" } chia-puzzles = "0.20.1" -chia-puzzle-types = "0.20.0" +chia-puzzle-types = "0.25.0" [dev-dependencies] -anyhow = "1.0.86" +anyhow = "1.0.98" rstest = "0.22.0" prettytable-rs = "0.10.0" From 7052789f8dfd777a06a07fddf2217544ca6653cb Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 19:24:28 +0300 Subject: [PATCH 42/65] tried to migrate to new chia wallet sdk but now all I get is UnknownUnspent --- src/cli/catalog/continue_launch.rs | 17 +- src/cli/catalog/initiate_launch.rs | 16 +- src/cli/catalog/sync.rs | 8 +- src/cli/catalog/verify_deployment.rs | 13 +- src/cli/reward_distributor/add_rewards.rs | 6 +- .../reward_distributor/clawback_rewards.rs | 3 +- src/cli/reward_distributor/commit_rewards.rs | 6 +- src/cli/verifications/broadcast_launch.rs | 19 +- src/cli/verifications/create_offer.rs | 12 +- src/cli/verifications/sign_launch.rs | 2 +- src/cli/xchandles/continue_launch.rs | 10 +- src/cli/xchandles/initiate_launch.rs | 9 +- src/cli/xchandles/update.rs | 16 +- src/drivers.rs | 287 ++++++++++-------- src/layers/action_layer.rs | 4 +- src/layers/actions/catalog/refund.rs | 2 +- src/layers/actions/catalog/register.rs | 6 +- src/layers/actions/delegated_state.rs | 2 +- .../actions/reward_distributor/add_entry.rs | 2 +- .../reward_distributor/add_incentives.rs | 2 +- .../reward_distributor/commit_incentives.rs | 2 +- .../reward_distributor/initiate_payout.rs | 2 +- .../actions/reward_distributor/new_epoch.rs | 2 +- .../reward_distributor/remove_entry.rs | 2 +- .../actions/reward_distributor/stake.rs | 15 +- src/layers/actions/reward_distributor/sync.rs | 2 +- .../actions/reward_distributor/unstake.rs | 9 +- .../reward_distributor/withdraw_incentives.rs | 2 +- src/layers/actions/xchandles/expire.rs | 2 +- src/layers/actions/xchandles/extend.rs | 6 +- src/layers/actions/xchandles/refund.rs | 2 +- src/layers/actions/xchandles/register.rs | 4 +- src/layers/actions/xchandles/update.rs | 2 +- src/layers/m_of_n_layer.rs | 2 +- src/layers/p2_delegated_by_singleton_layer.rs | 2 +- src/layers/precommit_layer.rs | 4 +- src/layers/state_scheduler_layer.rs | 5 +- src/layers/verification_layer.rs | 2 +- src/primitives/catalog_registry_info.rs | 4 +- src/primitives/medieval_vault.rs | 22 +- src/primitives/medieval_vault_info.rs | 2 +- src/primitives/reserve.rs | 9 +- src/primitives/slot.rs | 2 +- src/primitives/state_scheduler.rs | 3 +- src/primitives/state_scheduler_info.rs | 3 +- src/primitives/verification.rs | 3 +- src/primitives/verification_asserter.rs | 4 +- 47 files changed, 294 insertions(+), 267 deletions(-) diff --git a/src/cli/catalog/continue_launch.rs b/src/cli/catalog/continue_launch.rs index e1e8aa79..374691a4 100644 --- a/src/cli/catalog/continue_launch.rs +++ b/src/cli/catalog/continue_launch.rs @@ -219,11 +219,8 @@ pub async fn catalog_continue_launch( let mut cat_creator_conds = Conditions::new(); for inner_ph in precommitment_inner_puzzle_hashes_to_launch { - cat_creator_conds = cat_creator_conds.create_coin( - inner_ph.into(), - 1, - Some(ctx.hint(inner_ph.into())?), - ); + cat_creator_conds = + cat_creator_conds.create_coin(inner_ph.into(), 1, ctx.hint(inner_ph.into())?); } let cat_destination_puzzle_ptr = ctx.alloc(&clvm_quote!(cat_creator_conds))?; let cat_destination_puzzle_hash: Bytes32 = @@ -233,17 +230,14 @@ pub async fn catalog_continue_launch( let security_coin_sk = new_sk()?; // Parse one-sided offer + let hint = ctx.hint(cat_destination_puzzle_hash)?; let one_sided_offer = parse_one_sided_offer( &mut ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: constants.launcher_id, - payments: vec![Payment::with_memos( - cat_destination_puzzle_hash, - cat_amount, - vec![cat_destination_puzzle_hash.into()], - )], + payments: vec![Payment::new(cat_destination_puzzle_hash, cat_amount, hint)], }), None, )?; @@ -281,13 +275,14 @@ pub async fn catalog_continue_launch( SingleCatSpend { next_coin_proof: CoinProof { parent_coin_info: created_cat.coin.parent_coin_info, - inner_puzzle_hash: created_cat.p2_puzzle_hash, + inner_puzzle_hash: created_cat.info.p2_puzzle_hash, amount: created_cat.coin.amount, }, prev_coin_id: created_cat.coin.coin_id(), prev_subtotal: 0, extra_delta: 0, inner_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), + revoke: false, }, )?; diff --git a/src/cli/catalog/initiate_launch.rs b/src/cli/catalog/initiate_launch.rs index ec5cd452..db9115a0 100644 --- a/src/cli/catalog/initiate_launch.rs +++ b/src/cli/catalog/initiate_launch.rs @@ -19,7 +19,6 @@ use chia::{ use chia_wallet_sdk::{ coinset::ChiaRpcClient, driver::{Cat, DriverError, Launcher, Offer, SpendContext}, - prelude::Memos, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::Address, }; @@ -72,18 +71,18 @@ fn get_additional_info_for_launch( )?; conditions = conditions.extend(price_singleton_launch_conds); - let cat_memos = Memos::some(ctx.alloc(&vec![cat_destination_puzzle_hash])?); - let (cat_creation_conds, eve_cat) = Cat::single_issuance_eve( + let hint = ctx.hint(cat_destination_puzzle_hash)?; + let (cat_creation_conds, eve_cat) = Cat::issue_with_coin( ctx, security_coin.coin_id(), cat_amount, - Conditions::new().create_coin(cat_destination_puzzle_hash, cat_amount, cat_memos), + Conditions::new().create_coin(cat_destination_puzzle_hash, cat_amount, hint), )?; conditions = conditions.extend(cat_creation_conds); println!( "Premine payment asset id: {}", - hex::encode(eve_cat.asset_id) + hex::encode(eve_cat[0].info.asset_id) ); println!( "Price singleton id (SAVE THIS): {}", @@ -95,7 +94,7 @@ fn get_additional_info_for_launch( catalog_constants .with_price_singleton(price_singleton_launcher_id) .with_launcher_id(catalog_launcher_id), - eve_cat.asset_id, + eve_cat[0].info.asset_id, )) } @@ -188,10 +187,7 @@ pub async fn catalog_initiate_launch( println!("Default constants will be used:"); println!(" royalty address: {}", royalty_address); - println!( - " royalty ten thousandths: {}", - constants.royalty_ten_thousandths - ); + println!(" royalty basis points: {}", constants.royalty_basis_points); println!(" precommit payout address: {}", precommit_payout_address); println!( " relative block height: {}", diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index 71ad2f9d..2e7806cb 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -5,6 +5,7 @@ use chia::{ protocol::{Bytes32, Coin}, puzzles::{singleton::LauncherSolution, LineageProof, Proof}, }; +use chia_puzzle_types::Memos; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, driver::{DriverError, Layer, Puzzle, SingletonLayer, SpendContext}, @@ -106,10 +107,11 @@ pub async fn sync_catalog( )); }; + let Memos::Some(memos) = odd_create_coin.memos else { + return Err(CliError::Driver(DriverError::MissingHint)); + }; let (decoded_launcher_id, (_decoded_asset_id, (initial_state, ()))) = - ctx.extract::<(Bytes32, (Bytes32, (CatalogRegistryState, ())))>( - odd_create_coin.memos.unwrap().value, - )?; + ctx.extract::<(Bytes32, (Bytes32, (CatalogRegistryState, ())))>(memos)?; if decoded_launcher_id != constants.launcher_id { return Err(CliError::Custom("CATalog launcher ID mismatch".to_string())); } diff --git a/src/cli/catalog/verify_deployment.rs b/src/cli/catalog/verify_deployment.rs index cccc57f5..6ca02854 100644 --- a/src/cli/catalog/verify_deployment.rs +++ b/src/cli/catalog/verify_deployment.rs @@ -3,7 +3,9 @@ use chia::protocol::{Bytes32, Coin}; use chia::puzzles::nft::{NftOwnershipLayerArgs, NftRoyaltyTransferPuzzleArgs, NftStateLayerArgs}; use chia::puzzles::singleton::SingletonArgs; use chia::puzzles::{LineageProof, Proof}; +use chia_puzzle_types::Memos; use chia_puzzles::{NFT_STATE_LAYER_HASH, SINGLETON_LAUNCHER_HASH}; +use chia_wallet_sdk::driver::DriverError; use chia_wallet_sdk::{ coinset::ChiaRpcClient, driver::{Layer, Puzzle, SingletonLayer, SpendContext}, @@ -143,10 +145,11 @@ pub async fn catalog_verify_deployment(testnet11: bool) -> Result<(), CliError> )); } - let (hinted_launcher_id, (initial_registration_asset_id, (initial_state, ()))) = ctx - .extract::<(Bytes32, (Bytes32, (CatalogRegistryState, ())))>( - catalog_cc.memos.unwrap().value, - )?; + let Memos::Some(memos) = catalog_cc.memos else { + return Err(CliError::Driver(DriverError::MissingHint)); + }; + let (hinted_launcher_id, (initial_registration_asset_id, (initial_state, ()))) = + ctx.extract::<(Bytes32, (Bytes32, (CatalogRegistryState, ())))>(memos)?; let catalog_info = CatalogRegistryInfo::new(initial_state, catalog_constants); let catalog_full_ph = SingletonArgs::curry_tree_hash( @@ -244,7 +247,7 @@ pub async fn catalog_verify_deployment(testnet11: bool) -> Result<(), CliError> NftRoyaltyTransferPuzzleArgs::curry_tree_hash( cat_nft_launcher_id, catalog_constants.royalty_address, - catalog_constants.royalty_ten_thousandths, + catalog_constants.royalty_basis_points, ), eve_nft_inner_puzzle_hash, ), diff --git a/src/cli/reward_distributor/add_rewards.rs b/src/cli/reward_distributor/add_rewards.rs index e248391e..62633cce 100644 --- a/src/cli/reward_distributor/add_rewards.rs +++ b/src/cli/reward_distributor/add_rewards.rs @@ -77,16 +77,17 @@ pub async fn reward_distributor_add_rewards( let cat_destination_inner_puzzle = ctx.alloc(&(1, ()))?; let cat_destination_inner_puzzle_hash: Bytes32 = ctx.tree_hash(cat_destination_inner_puzzle).into(); + let hint = ctx.hint(cat_destination_inner_puzzle_hash)?; let offer = parse_one_sided_offer( &mut ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: launcher_id, - payments: vec![Payment::with_memos( + payments: vec![Payment::new( cat_destination_inner_puzzle_hash, reward_amount, - vec![cat_destination_inner_puzzle_hash.into()], + hint, )], }), None, @@ -112,6 +113,7 @@ pub async fn reward_distributor_add_rewards( cat: offer.created_cat.unwrap(), inner_spend: Spend::new(cat_destination_inner_puzzle, NodePtr::NIL), extra_delta: 0, + revoke: false, }], )?; diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index dfd42a72..b85b7aef 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -1,4 +1,5 @@ use chia::protocol::{Coin, SpendBundle}; +use chia_puzzle_types::Memos; use chia_wallet_sdk::{ coinset::ChiaRpcClient, driver::{Offer, Spend, SpendContext, StandardLayer}, @@ -94,7 +95,7 @@ pub async fn reward_distributor_clawback_rewards( offer.security_coin, offer .security_base_conditions - .create_coin(clawback_ph, 0, None), + .create_coin(clawback_ph, 0, Memos::None), &security_coin_sk, get_constants(testnet11), )?; diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index 18b0a79b..0f43eac9 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -66,16 +66,17 @@ pub async fn reward_distributor_commit_rewards( let cat_destination_inner_puzzle = ctx.alloc(&(1, ()))?; let cat_destination_inner_puzzle_hash: Bytes32 = ctx.tree_hash(cat_destination_inner_puzzle).into(); + let hint = ctx.hint(cat_destination_inner_puzzle_hash)?; let offer = parse_one_sided_offer( &mut ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: launcher_id, - payments: vec![Payment::with_memos( + payments: vec![Payment::new( cat_destination_inner_puzzle_hash, reward_amount, - vec![cat_destination_inner_puzzle_hash.into()], + hint, )], }), None, @@ -101,6 +102,7 @@ pub async fn reward_distributor_commit_rewards( cat: offer.created_cat.unwrap(), inner_spend: Spend::new(cat_destination_inner_puzzle, NodePtr::NIL), extra_delta: 0, + revoke: false, }], )?; diff --git a/src/cli/verifications/broadcast_launch.rs b/src/cli/verifications/broadcast_launch.rs index 61f60ad7..ea21afa7 100644 --- a/src/cli/verifications/broadcast_launch.rs +++ b/src/cli/verifications/broadcast_launch.rs @@ -11,7 +11,7 @@ use chia_puzzle_types::{ }; use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH}; use chia_wallet_sdk::{ - driver::{decompress_offer_bytes, Cat, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, + driver::{decompress_offer_bytes, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, utils::Address, }; @@ -80,7 +80,7 @@ pub async fn verifications_broadcast_launch( let launch_conds_with_recreate = launch_conds.create_coin( medieval_vault.info.inner_puzzle_hash().into(), medieval_vault.coin.amount, - Some(ctx.hint(medieval_vault.info.launcher_id)?), + ctx.hint(medieval_vault.info.launcher_id)?, ); let delegated_puzzle = ctx.alloc(&clvm_quote!(MedievalVault::delegated_conditions( launch_conds_with_recreate, @@ -168,12 +168,13 @@ pub async fn verifications_broadcast_launch( _ => None, }) { yes_no_prompt(format!("{} CAT mojos (asset id: {}) will be transferred to the specified recipient. Continue?", cc.amount, hex::encode(payment_cat_asset_id)).as_str())?; + let hint = ctx.hint(recipient_puzzle_hash)?; let notarized_payment = NotarizedPayment { nonce: coin_spend.coin.coin_id(), - payments: vec![Payment::with_memos( + payments: vec![Payment::new( recipient_puzzle_hash, cc.amount, - vec![recipient_puzzle_hash.into()], + hint, )], }; @@ -187,8 +188,11 @@ pub async fn verifications_broadcast_launch( .into(), parent_amount: coin_spend.coin.amount, }), - payment_cat_asset_id, - SETTLEMENT_PAYMENT_HASH.into(), + CatInfo::new( + payment_cat_asset_id, + None, + SETTLEMENT_PAYMENT_HASH.into(), + ), ); let offer_cat_inner_solution = @@ -207,7 +211,8 @@ pub async fn verifications_broadcast_launch( Cat::spend_all(&mut ctx, &[offer_cat_spend])?; payment_sent = true; - let msg: Bytes32 = notarized_payment.tree_hash().into(); + let notarized_payment_ptr = ctx.alloc(¬arized_payment)?; + let msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); conds = conds.assert_puzzle_announcement(announcement_id( offer_puzzle_hash, msg, diff --git a/src/cli/verifications/create_offer.rs b/src/cli/verifications/create_offer.rs index 5c7560a0..4ac67716 100644 --- a/src/cli/verifications/create_offer.rs +++ b/src/cli/verifications/create_offer.rs @@ -4,7 +4,10 @@ use chia::{ protocol::{Bytes32, SpendBundle}, traits::Streamable, }; -use chia_puzzle_types::offer::{NotarizedPayment, Payment}; +use chia_puzzle_types::{ + offer::{NotarizedPayment, Payment}, + Memos, +}; use chia_puzzles::SETTLEMENT_PAYMENT_HASH; use chia_wallet_sdk::{ driver::{compress_offer_bytes, Offer, SpendContext}, @@ -77,16 +80,17 @@ pub async fn verifications_create_offer( let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; let security_coin_sk = new_sk()?; + let hint = ctx.hint(SETTLEMENT_PAYMENT_HASH.into())?; let offer = parse_one_sided_offer( &mut ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: Bytes32::default(), - payments: vec![Payment::with_memos( + payments: vec![Payment::new( SETTLEMENT_PAYMENT_HASH.into(), payment_amount, - vec![SETTLEMENT_PAYMENT_HASH.to_vec().into()], + hint, )], }), None, @@ -97,7 +101,7 @@ pub async fn verifications_create_offer( .security_base_conditions .reserve_fee(1) .assert_concurrent_spend(offer.created_cat.unwrap().coin.coin_id()) - .create_coin(verification_asserter_puzzle_hash, 0, None) + .create_coin(verification_asserter_puzzle_hash, 0, Memos::None) .assert_concurrent_puzzle(verification_asserter_puzzle_hash); let security_coin_sig = spend_security_coin( diff --git a/src/cli/verifications/sign_launch.rs b/src/cli/verifications/sign_launch.rs index 87bd1815..bb4d3987 100644 --- a/src/cli/verifications/sign_launch.rs +++ b/src/cli/verifications/sign_launch.rs @@ -58,7 +58,7 @@ pub async fn verifications_sign_launch( let launch_conds_with_recreate = launch_conds.create_coin( medieval_vault.info.inner_puzzle_hash().into(), medieval_vault.coin.amount, - Some(ctx.hint(medieval_vault.info.launcher_id)?), + ctx.hint(medieval_vault.info.launcher_id)?, ); let delegated_puzzle = ctx.alloc(&clvm_quote!(MedievalVault::delegated_conditions( launch_conds_with_recreate, diff --git a/src/cli/xchandles/continue_launch.rs b/src/cli/xchandles/continue_launch.rs index 7807b7e5..5fb281a6 100644 --- a/src/cli/xchandles/continue_launch.rs +++ b/src/cli/xchandles/continue_launch.rs @@ -226,7 +226,7 @@ pub async fn xchandles_continue_launch( cat_creator_conds = cat_creator_conds.create_coin( inner_ph.into(), amount, - Some(ctx.hint(inner_ph.into())?), + ctx.hint(inner_ph.into())?, ); } let cat_destination_puzzle_ptr = ctx.alloc(&clvm_quote!(cat_creator_conds))?; @@ -237,16 +237,17 @@ pub async fn xchandles_continue_launch( let security_coin_sk = new_sk()?; // Parse one-sided offer + let hint = ctx.hint(cat_destination_puzzle_hash)?; let one_sided_offer = parse_one_sided_offer( &mut ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: launcher_id, - payments: vec![Payment::with_memos( + payments: vec![Payment::new( cat_destination_puzzle_hash, handles_payment_total, - vec![cat_destination_puzzle_hash.into()], + hint, )], }), None, @@ -285,13 +286,14 @@ pub async fn xchandles_continue_launch( SingleCatSpend { next_coin_proof: CoinProof { parent_coin_info: created_cat.coin.parent_coin_info, - inner_puzzle_hash: created_cat.p2_puzzle_hash, + inner_puzzle_hash: created_cat.info.p2_puzzle_hash, amount: created_cat.coin.amount, }, prev_coin_id: created_cat.coin.coin_id(), prev_subtotal: 0, extra_delta: 0, inner_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), + revoke: false, }, )?; diff --git a/src/cli/xchandles/initiate_launch.rs b/src/cli/xchandles/initiate_launch.rs index 94e130e9..cb5ca47b 100644 --- a/src/cli/xchandles/initiate_launch.rs +++ b/src/cli/xchandles/initiate_launch.rs @@ -18,7 +18,6 @@ use chia::{ use chia_wallet_sdk::{ coinset::ChiaRpcClient, driver::{Cat, DriverError, Launcher, Offer, SpendContext}, - prelude::Memos, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::Address, }; @@ -71,8 +70,8 @@ fn get_additional_info_for_launch( )?; conditions = conditions.extend(price_singleton_launch_conds); - let cat_memos = Memos::some(ctx.alloc(&vec![cat_destination_puzzle_hash])?); - let (cat_creation_conds, eve_cat) = Cat::single_issuance_eve( + let cat_memos = ctx.hint(cat_destination_puzzle_hash)?; + let (cat_creation_conds, eve_cat) = Cat::issue_with_coin( ctx, security_coin.coin_id(), cat_amount, @@ -82,7 +81,7 @@ fn get_additional_info_for_launch( println!( "Premine payment asset id: {}", - hex::encode(eve_cat.asset_id) + hex::encode(eve_cat[0].info.asset_id) ); println!( "Price singleton id (SAVE THIS): {}", @@ -94,7 +93,7 @@ fn get_additional_info_for_launch( xchandles_constants .with_price_singleton(price_singleton_launcher_id) .with_launcher_id(xchandles_launcher_id), - eve_cat.asset_id, + eve_cat[0].info.asset_id, )) } diff --git a/src/cli/xchandles/update.rs b/src/cli/xchandles/update.rs index dda2ff58..387a9190 100644 --- a/src/cli/xchandles/update.rs +++ b/src/cli/xchandles/update.rs @@ -8,8 +8,7 @@ use chia_puzzle_types::{ }; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{DriverError, Offer, Spend, SpendContext, StandardLayer}, - prelude::Memos, + driver::{Offer, Spend, SpendContext, StandardLayer}, utils::Address, }; use clvm_traits::clvm_quote; @@ -128,6 +127,7 @@ pub async fn xchandles_update( let security_coin_sk = new_sk()?; let pk = security_coin_sk.public_key(); let nft_inner_ph: Bytes32 = StandardArgs::curry_tree_hash(pk).into(); + let hint = ctx.hint(nft_inner_ph)?; let offer = parse_one_sided_offer( &mut ctx, offer, @@ -135,11 +135,7 @@ pub async fn xchandles_update( None, Some(NotarizedPayment { nonce: registry.coin.coin_id(), - payments: vec![Payment::with_memos( - nft_inner_ph, - 1, - vec![nft_inner_ph.into()], - )], + payments: vec![Payment::new(nft_inner_ph, 1, hint)], }), )?; @@ -157,11 +153,7 @@ pub async fn xchandles_update( )?; let nft_return_ph: Bytes32 = Address::decode(&return_address)?.puzzle_hash; - let nft_inner_spend = nft_inner_conds.create_coin( - nft_return_ph, - 1, - Some(Memos::hint(&mut ctx, nft_return_ph).map_err(DriverError::from)?), - ); + let nft_inner_spend = nft_inner_conds.create_coin(nft_return_ph, 1, ctx.hint(nft_return_ph)?); let nft_inner_spend = ctx.alloc(&clvm_quote!(nft_inner_spend))?; let nft_inner_spend = StandardLayer::new(pk) .delegated_inner_spend(&mut ctx, Spend::new(nft_inner_spend, NodePtr::NIL))?; diff --git a/src/drivers.rs b/src/drivers.rs index 7c66c126..ecb3f2dd 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -12,11 +12,12 @@ use chia::{ CoinProof, EveProof, LineageProof, Proof, }, }; +use chia_puzzle_types::Memos; use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH, SINGLETON_TOP_LAYER_V1_1_HASH}; use chia_wallet_sdk::{ driver::{ - Cat, CatSpend, CurriedPuzzle, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, Puzzle, - SingleCatSpend, Spend, SpendContext, StandardLayer, + Cat, CatInfo, CatSpend, CurriedPuzzle, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, + Puzzle, SingleCatSpend, Spend, SpendContext, StandardLayer, }, prelude::{AggSig, AggSigKind}, signer::{AggSigConstants, RequiredBlsSignature}, @@ -141,33 +142,29 @@ pub fn parse_one_sided_offer( parent_inner_puzzle_hash: refund_puzzle_hash, parent_amount: coin_spend.coin.amount, }), - cat_args.asset_id, - SETTLEMENT_PAYMENT_HASH.into(), + CatInfo::new(cat_args.asset_id, None, SETTLEMENT_PAYMENT_HASH.into()), ); // offers don't allow amount 0 coins, so we create an 1-amount coin, // which creates a 0-amount coin and spend all the CATs together if cat_notarized_payment.payments[0].amount == 0 { - let memos = Some(chia_wallet_sdk::prelude::Memos::new( - ctx.alloc(&cat_notarized_payment.payments[0].memos)?, - )); let interim_inner_puzzle = ctx.alloc(&clvm_quote!(Conditions::new() .create_coin( cat_notarized_payment.payments[0].puzzle_hash, 0, - memos, + cat_notarized_payment.payments[0].memos, )))?; let interim_inner_ph: Bytes32 = ctx.tree_hash(interim_inner_puzzle).into(); let notarized_payment = NotarizedPayment { nonce: offer_coin_cat.coin_id(), payments: vec![ - Payment::with_memos( + Payment::new( refund_puzzle_hash, cc.amount, - vec![refund_puzzle_hash.into()], + ctx.hint(refund_puzzle_hash)?, ), - Payment::new(interim_inner_ph, 1), + Payment::new(interim_inner_ph, 1, Memos::None), ], }; let offer_cat_inner_solution = ctx.alloc(&SettlementPaymentsSolution { @@ -182,7 +179,7 @@ pub fn parse_one_sided_offer( ), ); - let interim_cat = offer_cat.wrapped_child(interim_inner_ph, 1); + let interim_cat = offer_cat.child(interim_inner_ph, 1); let interim_cat_spend = CatSpend::new( interim_cat, Spend::new(interim_inner_puzzle, NodePtr::NIL), @@ -198,10 +195,10 @@ pub fn parse_one_sided_offer( } created_cat = Some( - interim_cat - .wrapped_child(cat_notarized_payment.payments[0].puzzle_hash, 0), + interim_cat.child(cat_notarized_payment.payments[0].puzzle_hash, 0), ); - let announcement_msg: Bytes32 = notarized_payment.tree_hash().into(); + let notarized_payment_ptr = ctx.alloc(¬arized_payment)?; + let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); base_conditions = base_conditions.assert_puzzle_announcement( announcement_id(offer_cat.coin.puzzle_hash, announcement_msg), ); @@ -217,7 +214,7 @@ pub fn parse_one_sided_offer( prev_coin_id: offer_cat.coin.coin_id(), next_coin_proof: CoinProof { parent_coin_info: offer_cat.coin.parent_coin_info, - inner_puzzle_hash: offer_cat.p2_puzzle_hash, + inner_puzzle_hash: offer_cat.info.p2_puzzle_hash, amount: cc.amount, }, prev_subtotal: 0, @@ -226,14 +223,16 @@ pub fn parse_one_sided_offer( offer_cat_inner_puzzle, offer_cat_inner_solution, ), + revoke: false, }, )?; - created_cat = Some(offer_cat.wrapped_child( - cat_notarized_payment.payments[0].puzzle_hash, - cc.amount, - )); - let announcement_msg: Bytes32 = cat_notarized_payment.tree_hash().into(); + created_cat = Some( + offer_cat + .child(cat_notarized_payment.payments[0].puzzle_hash, cc.amount), + ); + let notarized_payment_ptr = ctx.alloc(&cat_notarized_payment)?; + let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); base_conditions = base_conditions.assert_puzzle_announcement( announcement_id(offer_cat.coin.puzzle_hash, announcement_msg), ); @@ -264,12 +263,13 @@ pub fn parse_one_sided_offer( nft.spend(ctx, Spend::new(inner_puzzle, inner_solution))?; - created_nft = Some(nft.wrapped_child::( + created_nft = Some(nft.child::( nft_notatized_payment.payments[0].puzzle_hash, nft.info.current_owner, nft.info.metadata, )); - let announcement_msg: Bytes32 = nft_notatized_payment.tree_hash().into(); + let notarized_payment_ptr = ctx.alloc(&nft_notatized_payment)?; + let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); base_conditions = base_conditions.assert_puzzle_announcement(announcement_id( nft.coin.puzzle_hash, announcement_msg, @@ -311,6 +311,7 @@ pub fn parse_one_sided_offer( payments: vec![Payment::new( security_coin_puzzle_hash, security_coin_amount, + Memos::None, )], }], }; @@ -438,9 +439,9 @@ where let launcher_memos = ctx.memos(&clvm_tuple!(launcher_id_ptr, memos_after_hint))?; clvm_quote!(Conditions::new() - .create_coin(left_slot_puzzle_hash.into(), 0, Some(slot_memos)) - .create_coin(right_slot_puzzle_hash.into(), 0, Some(slot_memos)) - .create_coin(target_inner_puzzle_hash, 1, Some(launcher_memos))) + .create_coin(left_slot_puzzle_hash.into(), 0, slot_memos) + .create_coin(right_slot_puzzle_hash.into(), 0, slot_memos) + .create_coin(target_inner_puzzle_hash, 1, launcher_memos)) .to_clvm(ctx) .map_err(DriverError::ToClvm) } @@ -765,23 +766,19 @@ pub fn launch_dig_reward_distributor( // use a 'trick' to find the launcher id so we can determine reserve id, then call the function again // with the right CAT destination ph let security_coin_sk = new_sk()?; + let hint = ctx.hint(cat_refund_puzzle_hash)?; let mock_offer = parse_one_sided_offer( ctx, offer.clone(), security_coin_sk.public_key(), Some(NotarizedPayment { nonce: constants.launcher_id, - payments: vec![Payment::with_memos( - cat_refund_puzzle_hash, - 0, - vec![cat_refund_puzzle_hash.into()], - )], + payments: vec![Payment::new(cat_refund_puzzle_hash, 0, hint)], }), None, )?; let reward_distributor_hint: Bytes32 = "Reward Distributor v1".tree_hash().into(); - let launcher_memos = - chia_wallet_sdk::prelude::Memos::new(ctx.alloc(&(reward_distributor_hint, (comment, ())))?); + let launcher_memos = ctx.memos(&(reward_distributor_hint, (comment, ())))?; let launcher = Launcher::with_memos(mock_offer.security_coin.coin_id(), 1, launcher_memos); let launcher_coin = launcher.coin(); let launcher_id = launcher_coin.coin_id(); @@ -792,17 +789,14 @@ pub fn launch_dig_reward_distributor( P2DelegatedBySingletonLayerArgs::curry_tree_hash(controller_singleton_struct_hash, 0) .into(); + let hint = ctx.hint(reserve_inner_ph)?; let offer = parse_one_sided_offer( ctx, offer, security_coin_sk.public_key(), Some(NotarizedPayment { nonce: constants.launcher_id, - payments: vec![Payment::with_memos( - reserve_inner_ph, - 0, - vec![reserve_inner_ph.into()], - )], + payments: vec![Payment::new(reserve_inner_ph, 0, hint)], }), None, )?; @@ -836,8 +830,8 @@ pub fn launch_dig_reward_distributor( let slot_memos = ctx.hint(slot_hint)?; let launcher_memos = ctx.hint(launcher_id)?; let eve_singleton_inner_puzzle = clvm_quote!(Conditions::new() - .create_coin(slot_puzzle_hash.into(), 0, Some(slot_memos)) - .create_coin(target_inner_puzzle_hash.into(), 1, Some(launcher_memos))) + .create_coin(slot_puzzle_hash.into(), 0, slot_memos) + .create_coin(target_inner_puzzle_hash.into(), 1, launcher_memos)) .to_clvm(ctx)?; let eve_singleton_inner_puzzle_hash = ctx.tree_hash(eve_singleton_inner_puzzle); @@ -895,7 +889,7 @@ pub fn launch_dig_reward_distributor( let reserve = Reserve::new( reserve_cat.coin.parent_coin_info, reserve_cat.lineage_proof.unwrap(), - reserve_cat.asset_id, + reserve_cat.info.asset_id, controller_singleton_struct_hash, 0, reserve_cat.coin.amount, @@ -1042,7 +1036,7 @@ mod tests { let message: Bytes32 = new_state.tree_hash().into(); let price_singleton_inner_solution = Conditions::new() .send_message(18, message.into(), vec![ctx.alloc(&receiver_puzzle_hash)?]) - .create_coin(price_singleton_inner_puzzle_hash.into(), 1, None); + .create_coin(price_singleton_inner_puzzle_hash.into(), 1, Memos::None); let price_singleton_inner_solution = price_singleton_inner_solution.to_clvm(ctx)?; let price_singleton_solution = SingletonSolution { @@ -1107,7 +1101,7 @@ mod tests { let eve_nft_inner_puzzle_hash = tail_hash; let value = CatalogPrecommitValue::with_default_cat_maker( - payment_cat.asset_id.tree_hash(), + payment_cat.info.asset_id.tree_hash(), eve_nft_inner_puzzle_hash.into(), tail, ); @@ -1118,7 +1112,7 @@ mod tests { ctx, payment_cat.coin.coin_id(), payment_cat.child_lineage_proof(), - payment_cat.asset_id, + payment_cat.info.asset_id, SingletonStruct::new(catalog.info.constants.launcher_id) .tree_hash() .into(), @@ -1132,11 +1126,11 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, Conditions::new() - .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, None) + .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, Memos::None) .create_coin( minter_puzzle_hash, payment_cat.coin.amount - reg_amount, - None, + Memos::None, ), )?; Cat::spend_all( @@ -1145,11 +1139,12 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }], )?; let new_payment_cat = - payment_cat.wrapped_child(minter_puzzle_hash, payment_cat.coin.amount - reg_amount); + payment_cat.child(minter_puzzle_hash, payment_cat.coin.amount - reg_amount); // sim.spend_coins(ctx.take(), sks)?; benchmark.add_spends(ctx, sim, "create_precommit", sks)?; @@ -1206,7 +1201,7 @@ mod tests { let catalog_constants = CatalogRegistryConstants { launcher_id: Bytes32::from([1; 32]), royalty_address: Bytes32::from([7; 32]), - royalty_ten_thousandths: 100, + royalty_basis_points: 100, precommit_payout_puzzle_hash: Bytes32::from([8; 32]), relative_block_height: 1, price_singleton_launcher_id: Bytes32::from(hex!( @@ -1223,7 +1218,11 @@ mod tests { let offer_src_coin = launcher_bls.coin; let offer_spend = StandardLayer::new(launcher_bls.pk).spend_with_conditions( ctx, - Conditions::new().create_coin(SETTLEMENT_PAYMENT_HASH.into(), offer_amount, None), + Conditions::new().create_coin( + SETTLEMENT_PAYMENT_HASH.into(), + offer_amount, + Memos::None, + ), )?; let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; @@ -1253,15 +1252,16 @@ mod tests { let minter_bls = sim.bls(payment_cat_amount); let minter_p2 = StandardLayer::new(minter_bls.pk); - let (issue_cat, mut payment_cat) = Cat::single_issuance_eve( + let (issue_cat, payment_cat) = Cat::issue_with_coin( ctx, minter_bls.coin.coin_id(), payment_cat_amount, - Conditions::new().create_coin(minter_bls.puzzle_hash, payment_cat_amount, None), + Conditions::new().create_coin(minter_bls.puzzle_hash, payment_cat_amount, Memos::None), )?; + let mut payment_cat = payment_cat[0]; minter_p2.spend(ctx, minter_bls.coin, issue_cat)?; - payment_cat = payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); sim.spend_coins(ctx.take(), &[minter_bls.sk.clone()])?; // Launch catalog @@ -1279,7 +1279,7 @@ mod tests { &TESTNET11_CONSTANTS, ( catalog_constants.with_price_singleton(price_singleton_launcher_id), - payment_cat.asset_id, + payment_cat.info.asset_id, ), )?; @@ -1305,13 +1305,13 @@ mod tests { let eve_nft_inner_puzzle = clvm_quote!(Conditions::new().create_coin( Bytes32::new([4 + i as u8; 32]), 1, - None + Memos::None, )) .to_clvm(ctx)?; let eve_nft_inner_puzzle_hash = ctx.tree_hash(eve_nft_inner_puzzle); let value = CatalogPrecommitValue::with_default_cat_maker( - payment_cat.asset_id.tree_hash(), + payment_cat.info.asset_id.tree_hash(), eve_nft_inner_puzzle_hash.into(), tail, ); @@ -1322,7 +1322,7 @@ mod tests { ctx, payment_cat.coin.coin_id(), payment_cat.child_lineage_proof(), - payment_cat.asset_id, + payment_cat.info.asset_id, SingletonStruct::new(catalog.info.constants.launcher_id) .tree_hash() .into(), @@ -1336,11 +1336,11 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, Conditions::new() - .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, None) + .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, Memos::None) .create_coin( minter_bls.puzzle_hash, payment_cat_amount - reg_amount, - None, + Memos::None, ), )?; Cat::spend_all( @@ -1349,11 +1349,12 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }], )?; payment_cat_amount -= reg_amount; - payment_cat = payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); // sim.spend_coins(ctx.take(), &[user_bls.sk.clone(), minter_bls.sk.clone()])?; benchmark.add_spends( @@ -1403,7 +1404,7 @@ mod tests { let new_state = CatalogRegistryState { cat_maker_puzzle_hash: DefaultCatMakerArgs::curry_tree_hash( - payment_cat.asset_id.tree_hash().into(), + payment_cat.info.asset_id.tree_hash().into(), ) .into(), registration_price: new_price, @@ -1515,20 +1516,21 @@ mod tests { let minter2_bls = sim.bls(alternative_payment_cat_amount); let minter_p2_2 = StandardLayer::new(minter2_bls.pk); - let (issue_cat, mut alternative_payment_cat) = Cat::single_issuance_eve( + let (issue_cat, alternative_payment_cat) = Cat::issue_with_coin( ctx, minter2_bls.coin.coin_id(), alternative_payment_cat_amount, Conditions::new().create_coin( minter2_bls.puzzle_hash, alternative_payment_cat_amount, - None, + Memos::None, ), )?; minter_p2_2.spend(ctx, minter2_bls.coin, issue_cat)?; + let mut alternative_payment_cat = alternative_payment_cat[0]; - alternative_payment_cat = alternative_payment_cat - .wrapped_child(minter2_bls.puzzle_hash, alternative_payment_cat_amount); + alternative_payment_cat = + alternative_payment_cat.child(minter2_bls.puzzle_hash, alternative_payment_cat_amount); sim.spend_coins(ctx.take(), &[minter2_bls.sk.clone()])?; let (catalog, _alternative_payment_cat) = test_refund_for_catalog( @@ -1592,7 +1594,7 @@ mod tests { let pricing_solution_hash = ctx.tree_hash(pricing_solution); let value = XchandlesPrecommitValue::for_normal_registration( - payment_cat.asset_id.tree_hash(), + payment_cat.info.asset_id.tree_hash(), pricing_puzzle_hash, pricing_solution_hash, handle_to_refund.clone(), @@ -1607,7 +1609,7 @@ mod tests { ctx, payment_cat.coin.coin_id(), payment_cat.child_lineage_proof(), - payment_cat.asset_id, + payment_cat.info.asset_id, SingletonStruct::new(registry.info.constants.launcher_id) .tree_hash() .into(), @@ -1621,11 +1623,15 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, Conditions::new() - .create_coin(precommit_coin.inner_puzzle_hash, payment_cat_amount, None) + .create_coin( + precommit_coin.inner_puzzle_hash, + payment_cat_amount, + Memos::None, + ) .create_coin( minter_puzzle_hash, payment_cat.coin.amount - payment_cat_amount, - None, + Memos::None, ), )?; Cat::spend_all( @@ -1634,10 +1640,11 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }], )?; - let new_payment_cat = payment_cat.wrapped_child( + let new_payment_cat = payment_cat.child( minter_puzzle_hash, payment_cat.coin.amount - payment_cat_amount, ); @@ -1705,7 +1712,11 @@ mod tests { let launcher_bls = sim.bls(offer_amount); let offer_spend = StandardLayer::new(launcher_bls.pk).spend_with_conditions( ctx, - Conditions::new().create_coin(SETTLEMENT_PAYMENT_HASH.into(), offer_amount, None), + Conditions::new().create_coin( + SETTLEMENT_PAYMENT_HASH.into(), + offer_amount, + Memos::None, + ), )?; let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; @@ -1726,15 +1737,16 @@ mod tests { let minter_bls = sim.bls(payment_cat_amount); let minter_p2 = StandardLayer::new(minter_bls.pk); - let (issue_cat, mut payment_cat) = Cat::single_issuance_eve( + let (issue_cat, payment_cat) = Cat::issue_with_coin( ctx, minter_bls.coin.coin_id(), payment_cat_amount, - Conditions::new().create_coin(minter_bls.puzzle_hash, payment_cat_amount, None), + Conditions::new().create_coin(minter_bls.puzzle_hash, payment_cat_amount, Memos::None), )?; + let mut payment_cat = payment_cat[0]; minter_p2.spend(ctx, minter_bls.coin, issue_cat)?; - payment_cat = payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); sim.spend_coins(ctx.take(), &[minter_bls.sk.clone()])?; @@ -1762,7 +1774,7 @@ mod tests { &TESTNET11_CONSTANTS, ( xchandles_constants.with_price_singleton(price_singleton_launcher_id), - payment_cat.asset_id, + payment_cat.info.asset_id, ), )?; @@ -1777,7 +1789,7 @@ mod tests { XchandlesRegistry::from_launcher_solution(ctx, spend.coin, launcher_solution)? { initial_slots = Some(slots); - assert_eq!(initial_registration_asset_id, payment_cat.asset_id); + assert_eq!(initial_registration_asset_id, payment_cat.info.asset_id); assert_eq!( registry.info.constants, xchandles_constants @@ -1832,7 +1844,7 @@ mod tests { let secret = Bytes32::default(); let value = XchandlesPrecommitValue::for_normal_registration( - payment_cat.asset_id.tree_hash(), + payment_cat.info.asset_id.tree_hash(), XchandlesFactorPricingPuzzleArgs::curry_tree_hash(base_price, reg_period), XchandlesPricingSolution { buy_time: 100, @@ -1853,7 +1865,7 @@ mod tests { ctx, payment_cat.coin.coin_id(), payment_cat.child_lineage_proof(), - payment_cat.asset_id, + payment_cat.info.asset_id, SingletonStruct::new(registry.info.constants.launcher_id) .tree_hash() .into(), @@ -1867,11 +1879,11 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, Conditions::new() - .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, None) + .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, Memos::None) .create_coin( minter_bls.puzzle_hash, payment_cat_amount - reg_amount, - None, + Memos::None, ), )?; Cat::spend_all( @@ -1880,11 +1892,12 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }], )?; payment_cat_amount -= reg_amount; - payment_cat = payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); // sim.spend_coins(ctx.take(), &[user_bls.sk.clone(), minter_bls.sk.clone()])?; benchmark.add_spends( @@ -1954,7 +1967,7 @@ mod tests { price_singleton_proof, price_singleton_puzzle, XchandlesRegistryState::from( - payment_cat.asset_id.tree_hash().into(), + payment_cat.info.asset_id.tree_hash().into(), new_price, reg_period, ), @@ -2065,7 +2078,7 @@ mod tests { &mut registry, handle, extension_slot.clone(), - payment_cat.asset_id, + payment_cat.info.asset_id, base_price, reg_period, extension_years, @@ -2089,11 +2102,15 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, extend_conds - .create_coin(SETTLEMENT_PAYMENT_HASH.into(), pay_for_extension, None) + .create_coin( + SETTLEMENT_PAYMENT_HASH.into(), + pay_for_extension, + Memos::None, + ) .create_coin( minter_bls.puzzle_hash, payment_cat_amount - pay_for_extension, - None, + Memos::None, ), )?; @@ -2109,18 +2126,19 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }, CatSpend { - cat: payment_cat - .wrapped_child(SETTLEMENT_PAYMENT_HASH.into(), pay_for_extension), + cat: payment_cat.child(SETTLEMENT_PAYMENT_HASH.into(), pay_for_extension), inner_spend: cat_offer_inner_spend, extra_delta: 0, + revoke: false, }, ], )?; payment_cat_amount -= pay_for_extension; - payment_cat = payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); registry = registry.finish_spend(ctx)?; @@ -2195,7 +2213,7 @@ mod tests { let expiration = initial_slot.info.value.expiration; let buy_time = expiration + 27 * 24 * 60 * 60; // last day of auction; 0 < premium < 1 CAT let value = XchandlesPrecommitValue::for_normal_registration( - payment_cat.asset_id.tree_hash(), + payment_cat.info.asset_id.tree_hash(), XchandlesExponentialPremiumRenewPuzzleArgs::curry_tree_hash( base_price, reg_period, 1000, ), @@ -2222,7 +2240,7 @@ mod tests { ctx, payment_cat.coin.coin_id(), payment_cat.child_lineage_proof(), - payment_cat.asset_id, + payment_cat.info.asset_id, SingletonStruct::new(registry.info.constants.launcher_id) .tree_hash() .into(), @@ -2237,11 +2255,11 @@ mod tests { let payment_cat_inner_spend = minter_p2.spend_with_conditions( ctx, Conditions::new() - .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, None) + .create_coin(precommit_coin.inner_puzzle_hash, reg_amount, Memos::None) .create_coin( minter_bls.puzzle_hash, payment_cat_amount - reg_amount, - None, + Memos::None, ), )?; Cat::spend_all( @@ -2250,11 +2268,12 @@ mod tests { cat: payment_cat, inner_spend: payment_cat_inner_spend, extra_delta: 0, + revoke: false, }], )?; payment_cat = - payment_cat.wrapped_child(minter_bls.puzzle_hash, payment_cat.coin.amount - reg_amount); + payment_cat.child(minter_bls.puzzle_hash, payment_cat.coin.amount - reg_amount); sim.set_next_timestamp(buy_time)?; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone(), minter_bls.sk.clone()])?; @@ -2359,20 +2378,21 @@ mod tests { let minter2 = sim.bls(alternative_payment_cat_amount); let minter_p2_2 = StandardLayer::new(minter2.pk); - let (issue_cat, mut alternative_payment_cat) = Cat::single_issuance_eve( + let (issue_cat, alternative_payment_cat) = Cat::issue_with_coin( ctx, minter2.coin.coin_id(), alternative_payment_cat_amount, Conditions::new().create_coin( minter2.puzzle_hash, alternative_payment_cat_amount, - None, + Memos::None, ), )?; minter_p2_2.spend(ctx, minter2.coin, issue_cat)?; - alternative_payment_cat = alternative_payment_cat - .wrapped_child(minter2.puzzle_hash, alternative_payment_cat_amount); + let mut alternative_payment_cat = alternative_payment_cat[0]; + alternative_payment_cat = + alternative_payment_cat.child(minter2.puzzle_hash, alternative_payment_cat_amount); sim.spend_coins(ctx.take(), &[minter2.sk.clone()])?; registry = test_refund_for_xchandles( @@ -2474,7 +2494,7 @@ mod tests { metadata: cat_nft_metadata_for_testing(), metadata_updater_puzzle_hash: ANY_METADATA_UPDATER_HASH.into(), royalty_puzzle_hash, - royalty_ten_thousandths: 100, + royalty_basis_points: 100, p2_puzzle_hash: bls.puzzle_hash, owner: None, }, @@ -2525,7 +2545,7 @@ mod tests { let test_singleton_inner_puzzle_hash = ctx.tree_hash(test_singleton_inner_puzzle); let test_singleton_inner_solution = test_singleton_output_conditions - .create_coin(test_singleton_inner_puzzle_hash.into(), 1, None) + .create_coin(test_singleton_inner_puzzle_hash.into(), 1, Memos::None) .to_clvm(ctx)?; let test_singleton_solution = ctx.alloc(&SingletonSolution { lineage_proof: test_singleton_proof, @@ -2577,15 +2597,16 @@ mod tests { let cat_minter = sim.bls(cat_amount); let cat_minter_p2 = StandardLayer::new(cat_minter.pk); - let (issue_cat, mut source_cat) = Cat::single_issuance_eve( + let (issue_cat, source_cat) = Cat::issue_with_coin( ctx, cat_minter.coin.coin_id(), cat_amount, - Conditions::new().create_coin(cat_minter.puzzle_hash, cat_amount, None), + Conditions::new().create_coin(cat_minter.puzzle_hash, cat_amount, Memos::None), )?; cat_minter_p2.spend(ctx, cat_minter.coin, issue_cat)?; - source_cat = source_cat.wrapped_child(cat_minter.puzzle_hash, cat_amount); + let mut source_cat = source_cat[0]; + source_cat = source_cat.child(cat_minter.puzzle_hash, cat_amount); sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; // Launch manager singleton @@ -2608,7 +2629,7 @@ mod tests { 42, 420, // 4.2% fee 9000, // 90% of the amount deposited will be returned - source_cat.asset_id, + source_cat.info.asset_id, ); // Create source offer @@ -2619,7 +2640,11 @@ mod tests { let launcher_bls = sim.bls(offer_amount); let offer_spend = StandardLayer::new(launcher_bls.pk).spend_with_conditions( ctx, - Conditions::new().create_coin(SETTLEMENT_PAYMENT_HASH.into(), offer_amount, None), + Conditions::new().create_coin( + SETTLEMENT_PAYMENT_HASH.into(), + offer_amount, + Memos::None, + ), )?; let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; @@ -2628,7 +2653,7 @@ mod tests { let cat_minter_inner_puzzle = clvm_quote!(Conditions::new().create_coin( SETTLEMENT_PAYMENT_HASH.into(), source_cat.coin.amount, - None + Memos::None )) .to_clvm(ctx)?; let source_cat_inner_spend = cat_minter_p2.delegated_inner_spend( @@ -2650,6 +2675,7 @@ mod tests { prev_subtotal: 0, extra_delta: 0, inner_spend: source_cat_inner_spend, + revoke: false, }, )?; let spends = ctx.take(); @@ -2710,8 +2736,8 @@ mod tests { )?; source_cat = source_cat - .wrapped_child(SETTLEMENT_PAYMENT_HASH.into(), source_cat.coin.amount) - .wrapped_child(cat_minter.puzzle_hash, source_cat.coin.amount); + .child(SETTLEMENT_PAYMENT_HASH.into(), source_cat.coin.amount) + .child(cat_minter.puzzle_hash, source_cat.coin.amount); assert!(sim.coin_state(source_cat.coin.coin_id()).is_some()); let nft_bls = sim.bls(1); @@ -2798,14 +2824,13 @@ mod tests { ensure_conditions_met(ctx, &mut sim, sec_conds, 0)?; - let offer_nft = - nft.wrapped_child(SETTLEMENT_PAYMENT_HASH.into(), None, nft.info.metadata); + let offer_nft = nft.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft.info.metadata); let nft_inner_spend = Spend::new( ctx.alloc(&clvm_quote!(Conditions::new().create_coin( SETTLEMENT_PAYMENT_HASH.into(), 1, - None + Memos::None )))?, NodePtr::NIL, ); @@ -2858,7 +2883,7 @@ mod tests { secure_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, - None, + Memos::None, ), )?, ); @@ -2866,7 +2891,7 @@ mod tests { registry = registry.finish_spend(ctx, vec![source_cat_spend])?; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; - source_cat = source_cat.wrapped_child( + source_cat = source_cat.child( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, ); @@ -2916,7 +2941,7 @@ mod tests { secure_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, - None, + Memos::None, ), )?, ); @@ -2925,7 +2950,7 @@ mod tests { // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; - source_cat = source_cat.wrapped_child( + source_cat = source_cat.child( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, ); @@ -2978,7 +3003,7 @@ mod tests { secure_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, - None, + Memos::None, ), )?, ); @@ -2987,7 +3012,7 @@ mod tests { // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; - source_cat = source_cat.wrapped_child( + source_cat = source_cat.child( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, ); @@ -3024,7 +3049,7 @@ mod tests { let payout_coin_id = registry .reserve .to_cat() - .wrapped_child( + .child( cat_minter.puzzle_hash, // fifth_epoch_commitment_slot.info.value.unwrap().clawback_ph, withdrawn_amount, ) @@ -3079,7 +3104,7 @@ mod tests { RewardDistributorSlotNonce::REWARD, ); let payout_coin_id = reserve_cat - .wrapped_child(constants.fee_payout_puzzle_hash, fee) + .child(constants.fee_payout_puzzle_hash, fee) .coin .coin_id(); @@ -3187,7 +3212,7 @@ mod tests { add_incentives_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - incentives_amount, - None, + Memos::None, ), )?, ); @@ -3209,7 +3234,7 @@ mod tests { registry_info.state.round_reward_info.remaining_rewards + (incentives_amount - incentives_amount * constants.fee_bps / 10000) ); - source_cat = source_cat.wrapped_child( + source_cat = source_cat.child( cat_minter.puzzle_hash, source_cat.coin.amount - incentives_amount, ); @@ -3327,16 +3352,14 @@ mod tests { ensure_conditions_met(ctx, &mut sim, sec_conds2.extend(sec_conds3), 0)?; - let offer2_nft = - nft2.wrapped_child(SETTLEMENT_PAYMENT_HASH.into(), None, nft2.info.metadata); - let offer3_nft = - nft3.wrapped_child(SETTLEMENT_PAYMENT_HASH.into(), None, nft3.info.metadata); + let offer2_nft = nft2.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft2.info.metadata); + let offer3_nft = nft3.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft3.info.metadata); let nfts_inner_spend = Spend::new( ctx.alloc(&clvm_quote!(Conditions::new().create_coin( SETTLEMENT_PAYMENT_HASH.into(), 1, - None + Memos::None )))?, NodePtr::NIL, ); @@ -3404,11 +3427,11 @@ mod tests { let reserve_cat = registry.reserve.to_cat(); if let Some((entry3_slot, locked_nft2, locked_nft3)) = other_nft2_info { let nft2_return_coin_id = locked_nft2 - .wrapped_child(nft2_bls.puzzle_hash, None, locked_nft2.info.metadata) + .child(nft2_bls.puzzle_hash, None, locked_nft2.info.metadata) .coin .coin_id(); let nft3_return_coin_id = locked_nft3 - .wrapped_child(nft3_bls.puzzle_hash, None, locked_nft3.info.metadata) + .child(nft3_bls.puzzle_hash, None, locked_nft3.info.metadata) .coin .coin_id(); @@ -3433,11 +3456,11 @@ mod tests { )?; let payout_coin_id2 = reserve_cat - .wrapped_child(nft2_bls.puzzle_hash, payout2_amount) + .child(nft2_bls.puzzle_hash, payout2_amount) .coin .coin_id(); let payout_coin_id3 = reserve_cat - .wrapped_child(nft3_bls.puzzle_hash, payout3_amount) + .child(nft3_bls.puzzle_hash, payout3_amount) .coin .coin_id(); @@ -3472,7 +3495,7 @@ mod tests { // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "remove_entry", &[])?; let payout_coin_id = reserve_cat - .wrapped_child(entry2_bls.puzzle_hash, entry2_payout_amount) + .child(entry2_bls.puzzle_hash, entry2_payout_amount) .coin .coin_id(); @@ -3576,7 +3599,7 @@ mod tests { secure_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, - None, + Memos::None, ), )?, ); @@ -3584,7 +3607,7 @@ mod tests { registry = registry.finish_spend(ctx, vec![source_cat_spend])?; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; - let _source_cat = source_cat.wrapped_child( + let _source_cat = source_cat.child( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, ); @@ -3660,7 +3683,7 @@ mod tests { benchmark.add_spends(ctx, &mut sim, "initiate_payout", &[])?; let payout_coin_id = reserve_cat - .wrapped_child( + .child( match manager_type { RewardDistributorType::Manager => entry1_bls.puzzle_hash, RewardDistributorType::Nft => nft_bls.puzzle_hash, diff --git a/src/layers/action_layer.rs b/src/layers/action_layer.rs index 026b5707..fcc99612 100644 --- a/src/layers/action_layer.rs +++ b/src/layers/action_layer.rs @@ -566,7 +566,7 @@ impl ReserveFinalizer2ndCurryArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, Copy, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct ReserveFinalizerSolution { pub reserve_parent_id: Bytes32, } @@ -611,7 +611,7 @@ impl ActionLayerArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RawActionLayerSolution { pub puzzles: Vec

, pub selectors_and_proofs: Vec<(u32, Option)>, diff --git a/src/layers/actions/catalog/refund.rs b/src/layers/actions/catalog/refund.rs index 08d5ed1b..9b3e8e52 100644 --- a/src/layers/actions/catalog/refund.rs +++ b/src/layers/actions/catalog/refund.rs @@ -192,7 +192,7 @@ impl CatalogRefundActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct CatalogRefundActionSolution { pub precommited_cat_maker_hash: Bytes32, pub precommited_cat_maker_reveal: P, diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index 5aa64ee7..d7c370c8 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -47,7 +47,7 @@ impl Action for CatalogRegisterAction { Self { launcher_id: constants.launcher_id, royalty_puzzle_hash_hash: constants.royalty_address.tree_hash().into(), - trade_price_percentage: constants.royalty_ten_thousandths, + trade_price_percentage: constants.royalty_basis_points, relative_block_height: constants.relative_block_height, payout_puzzle_hash: constants.precommit_payout_puzzle_hash, } @@ -156,7 +156,7 @@ impl CatalogRegisterAction { (), ANY_METADATA_UPDATER_HASH.into(), catalog.info.constants.royalty_address, - catalog.info.constants.royalty_ten_thousandths, + catalog.info.constants.royalty_basis_points, )?; // spend nft launcher @@ -299,7 +299,7 @@ impl CatalogRegisterActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct CatalogRegisterActionSolution { pub cat_maker_reveal: P, pub cat_maker_solution: S, diff --git a/src/layers/actions/delegated_state.rs b/src/layers/actions/delegated_state.rs index 3f1b2eb6..383676ec 100644 --- a/src/layers/actions/delegated_state.rs +++ b/src/layers/actions/delegated_state.rs @@ -119,7 +119,7 @@ impl DelegatedStateActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct DelegatedStateActionSolution { pub new_state: S, #[clvm(rest)] diff --git a/src/layers/actions/reward_distributor/add_entry.rs b/src/layers/actions/reward_distributor/add_entry.rs index bac4112d..c6d010cf 100644 --- a/src/layers/actions/reward_distributor/add_entry.rs +++ b/src/layers/actions/reward_distributor/add_entry.rs @@ -156,7 +156,7 @@ impl RewardDistributorAddEntryActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorAddEntryActionSolution { pub manager_singleton_inner_puzzle_hash: Bytes32, pub entry_payout_puzzle_hash: Bytes32, diff --git a/src/layers/actions/reward_distributor/add_incentives.rs b/src/layers/actions/reward_distributor/add_incentives.rs index 2df08620..29f33463 100644 --- a/src/layers/actions/reward_distributor/add_incentives.rs +++ b/src/layers/actions/reward_distributor/add_incentives.rs @@ -108,7 +108,7 @@ impl RewardDistributorAddIncentivesActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorAddIncentivesActionSolution { pub amount: u64, #[clvm(rest)] diff --git a/src/layers/actions/reward_distributor/commit_incentives.rs b/src/layers/actions/reward_distributor/commit_incentives.rs index 7e4f5504..608c48c8 100644 --- a/src/layers/actions/reward_distributor/commit_incentives.rs +++ b/src/layers/actions/reward_distributor/commit_incentives.rs @@ -212,7 +212,7 @@ impl RewardDistributorCommitIncentivesActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorCommitIncentivesActionSolution { pub slot_epoch_time: u64, pub slot_next_epoch_initialized: bool, diff --git a/src/layers/actions/reward_distributor/initiate_payout.rs b/src/layers/actions/reward_distributor/initiate_payout.rs index 28f02bd6..d7af0ca7 100644 --- a/src/layers/actions/reward_distributor/initiate_payout.rs +++ b/src/layers/actions/reward_distributor/initiate_payout.rs @@ -173,7 +173,7 @@ impl RewardDistributorInitiatePayoutActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorInitiatePayoutActionSolution { pub entry_payout_amount: u64, pub entry_payout_puzzle_hash: Bytes32, diff --git a/src/layers/actions/reward_distributor/new_epoch.rs b/src/layers/actions/reward_distributor/new_epoch.rs index 66acdc0e..da16cc85 100644 --- a/src/layers/actions/reward_distributor/new_epoch.rs +++ b/src/layers/actions/reward_distributor/new_epoch.rs @@ -191,7 +191,7 @@ impl RewardDistributorNewEpochActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorNewEpochActionSolution { pub slot_epoch_time: u64, pub slot_next_epoch_initialized: bool, diff --git a/src/layers/actions/reward_distributor/remove_entry.rs b/src/layers/actions/reward_distributor/remove_entry.rs index e5468e0c..9ca84c72 100644 --- a/src/layers/actions/reward_distributor/remove_entry.rs +++ b/src/layers/actions/reward_distributor/remove_entry.rs @@ -178,7 +178,7 @@ impl RewardDistributorRemoveEntryActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorRemoveEntryActionSolution { pub manager_singleton_inner_puzzle_hash: Bytes32, pub entry_payout_amount: u64, diff --git a/src/layers/actions/reward_distributor/stake.rs b/src/layers/actions/reward_distributor/stake.rs index 32e47b44..697e8a6c 100644 --- a/src/layers/actions/reward_distributor/stake.rs +++ b/src/layers/actions/reward_distributor/stake.rs @@ -106,15 +106,15 @@ impl RewardDistributorStakeAction { nonce: clvm_tuple!(ephemeral_counter.tree_hash(), my_id) .tree_hash() .into(), - payments: vec![Payment::with_memos( + payments: vec![Payment::new( payment_puzzle_hash, 1, - vec![payment_puzzle_hash.into()], + ctx.hint(payment_puzzle_hash)?, )], }; // spend self - let nft = current_nft.wrapped_child( + let nft = current_nft.child( SETTLEMENT_PAYMENT_HASH.into(), None, current_nft.info.metadata, @@ -130,7 +130,7 @@ impl RewardDistributorStakeAction { nft_transfer_porgram_hash: NftRoyaltyTransferPuzzleArgs::curry_tree_hash( nft.info.launcher_id, nft.info.royalty_puzzle_hash, - nft.info.royalty_ten_thousandths, + nft.info.royalty_basis_points, ) .into(), nft_launcher_proof, @@ -138,14 +138,15 @@ impl RewardDistributorStakeAction { })?; let action_puzzle = self.construct_puzzle(ctx)?; - let msg: Bytes32 = notarized_payment.tree_hash().into(); + let notarized_payment_ptr = ctx.alloc(¬arized_payment)?; + let msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); distributor.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?; Ok(( Conditions::new() .assert_puzzle_announcement(announcement_id(nft.coin.puzzle_hash, msg)), notarized_payment, - nft.wrapped_child(payment_puzzle_hash, None, nft.info.metadata), + nft.child(payment_puzzle_hash, None, nft.info.metadata), )) } } @@ -246,7 +247,7 @@ pub struct NftLauncherProof { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorStakeActionSolution { pub my_id: Bytes32, pub nft_metadata_hash: Bytes32, diff --git a/src/layers/actions/reward_distributor/sync.rs b/src/layers/actions/reward_distributor/sync.rs index 5e1212f4..29d65543 100644 --- a/src/layers/actions/reward_distributor/sync.rs +++ b/src/layers/actions/reward_distributor/sync.rs @@ -72,7 +72,7 @@ impl RewardDistributorSyncActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorSyncActionSolution { pub update_time: u64, } diff --git a/src/layers/actions/reward_distributor/unstake.rs b/src/layers/actions/reward_distributor/unstake.rs index 7abbdf51..c063d697 100644 --- a/src/layers/actions/reward_distributor/unstake.rs +++ b/src/layers/actions/reward_distributor/unstake.rs @@ -10,7 +10,6 @@ use chia_puzzles::{ }; use chia_wallet_sdk::{ driver::{DriverError, HashedPtr, Layer, Nft, Spend, SpendContext}, - prelude::Memos, types::Conditions, }; use clvm_traits::{clvm_quote, FromClvm, ToClvm}; @@ -110,7 +109,7 @@ impl RewardDistributorUnstakeAction { nft_transfer_porgram_hash: NftRoyaltyTransferPuzzleArgs::curry_tree_hash( locked_nft.info.launcher_id, locked_nft.info.royalty_puzzle_hash, - locked_nft.info.royalty_ten_thousandths, + locked_nft.info.royalty_basis_points, ) .into(), entry_initial_cumulative_payout: entry_slot.info.value.initial_cumulative_payout, @@ -138,11 +137,11 @@ impl RewardDistributorUnstakeAction { .to_clvm(ctx) .map_err(DriverError::ToClvm)?; - let hint = Memos::hint(ctx, entry_slot.info.value.payout_puzzle_hash)?; + let hint = ctx.hint(entry_slot.info.value.payout_puzzle_hash)?; let delegated_puzzle = ctx.alloc(&clvm_quote!(Conditions::new().create_coin( entry_slot.info.value.payout_puzzle_hash, 1, - Some(hint), + hint, )))?; let nft_inner_solution = my_p2.construct_solution( ctx, @@ -221,7 +220,7 @@ impl RewardDistributorUnstakeActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorUnstakeActionSolution { pub nft_launcher_id: Bytes32, pub nft_parent_id: Bytes32, diff --git a/src/layers/actions/reward_distributor/withdraw_incentives.rs b/src/layers/actions/reward_distributor/withdraw_incentives.rs index 9157fee2..349a85c6 100644 --- a/src/layers/actions/reward_distributor/withdraw_incentives.rs +++ b/src/layers/actions/reward_distributor/withdraw_incentives.rs @@ -190,7 +190,7 @@ impl RewardDistributorWithdrawIncentivesActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct RewardDistributorWithdrawIncentivesActionSolution { pub reward_slot_epoch_time: u64, pub reward_slot_next_epoch_initialized: bool, diff --git a/src/layers/actions/xchandles/expire.rs b/src/layers/actions/xchandles/expire.rs index a1b6709c..69c1572b 100644 --- a/src/layers/actions/xchandles/expire.rs +++ b/src/layers/actions/xchandles/expire.rs @@ -241,7 +241,7 @@ impl XchandlesExpireActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesExpireActionSolution { pub cat_maker_puzzle_reveal: CMP, pub cat_maker_puzzle_solution: CMS, diff --git a/src/layers/actions/xchandles/extend.rs b/src/layers/actions/xchandles/extend.rs index 0ffd256e..6d13683c 100644 --- a/src/layers/actions/xchandles/extend.rs +++ b/src/layers/actions/xchandles/extend.rs @@ -153,10 +153,10 @@ impl XchandlesExtendAction { nonce: clvm_tuple!(handle.clone(), slot.info.value.expiration) .tree_hash() .into(), - payments: vec![Payment::with_memos( + payments: vec![Payment::new( registry.info.constants.precommit_payout_puzzle_hash, renew_amount, - vec![registry.info.constants.precommit_payout_puzzle_hash.into()], + ctx.hint(registry.info.constants.precommit_payout_puzzle_hash)?, )], }; @@ -211,7 +211,7 @@ impl XchandlesExtendActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesExtendActionSolution { pub pricing_puzzle_reveal: PP, pub pricing_solution: PS, diff --git a/src/layers/actions/xchandles/refund.rs b/src/layers/actions/xchandles/refund.rs index e91be3c2..00e34a7e 100644 --- a/src/layers/actions/xchandles/refund.rs +++ b/src/layers/actions/xchandles/refund.rs @@ -192,7 +192,7 @@ impl XchandlesRefundActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesRefundActionSolution { pub precommited_cat_maker_reveal: CMP, pub precommited_cat_maker_hash: Bytes32, diff --git a/src/layers/actions/xchandles/register.rs b/src/layers/actions/xchandles/register.rs index 6795eabd..c9fc6e7f 100644 --- a/src/layers/actions/xchandles/register.rs +++ b/src/layers/actions/xchandles/register.rs @@ -276,7 +276,7 @@ impl XchandlesRegisterActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesRegisterActionSolution { pub handle_hash: Bytes32, pub pricing_puzzle_reveal: PP, @@ -359,7 +359,7 @@ impl XchandlesFactorPricingPuzzleArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesPricingSolution { pub buy_time: u64, pub current_expiration: u64, diff --git a/src/layers/actions/xchandles/update.rs b/src/layers/actions/xchandles/update.rs index 4d946cce..20de56d6 100644 --- a/src/layers/actions/xchandles/update.rs +++ b/src/layers/actions/xchandles/update.rs @@ -145,7 +145,7 @@ impl XchandlesUpdateActionArgs { } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct XchandlesUpdateActionSolution { pub current_slot_value: XchandlesSlotValue, pub new_data: XchandlesDataValue, diff --git a/src/layers/m_of_n_layer.rs b/src/layers/m_of_n_layer.rs index 03ba60db..6e34024a 100644 --- a/src/layers/m_of_n_layer.rs +++ b/src/layers/m_of_n_layer.rs @@ -173,7 +173,7 @@ impl P2MOfNDelegateDirectArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct P2MOfNDelegateDirectSolution { pub selectors: Vec, pub delegated_puzzle: P, diff --git a/src/layers/p2_delegated_by_singleton_layer.rs b/src/layers/p2_delegated_by_singleton_layer.rs index 59dafc5e..007d2fa6 100644 --- a/src/layers/p2_delegated_by_singleton_layer.rs +++ b/src/layers/p2_delegated_by_singleton_layer.rs @@ -127,7 +127,7 @@ impl P2DelegatedBySingletonLayerArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, Copy, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct P2DelegatedBySingletonLayerSolution { pub singleton_inner_puzzle_hash: Bytes32, pub delegated_puzzle: P, diff --git a/src/layers/precommit_layer.rs b/src/layers/precommit_layer.rs index 7be05de2..21486c9e 100644 --- a/src/layers/precommit_layer.rs +++ b/src/layers/precommit_layer.rs @@ -195,7 +195,7 @@ pub struct PrecommitLayer2ndCurryArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, Copy, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct PrecommitLayerSolution { pub mode: u8, pub my_amount: u64, @@ -238,7 +238,7 @@ impl CatalogPrecommitValue { let mut conds = Conditions::new().create_coin( owner_inner_puzzle_hash, 1, - Some(ctx.hint(owner_inner_puzzle_hash)?), + ctx.hint(owner_inner_puzzle_hash)?, ); let updater_solution = ctx.alloc(&initial_metadata)?; conds = conds.update_nft_metadata(ctx.any_metadata_updater()?, updater_solution); diff --git a/src/layers/state_scheduler_layer.rs b/src/layers/state_scheduler_layer.rs index 9ab38575..f050f340 100644 --- a/src/layers/state_scheduler_layer.rs +++ b/src/layers/state_scheduler_layer.rs @@ -2,6 +2,7 @@ use chia::{ clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}, protocol::Bytes32, }; +use chia_puzzle_types::Memos; use chia_puzzles::SINGLETON_TOP_LAYER_V1_1_HASH; use chia_wallet_sdk::{ driver::{DriverError, Layer, Puzzle, SpendContext}, @@ -94,7 +95,7 @@ impl Layer for StateSchedulerLayer { fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result { let base_conditions = Conditions::new() - .create_coin(self.new_puzzle_hash, 1, None) + .create_coin(self.new_puzzle_hash, 1, Memos::None) .assert_height_absolute(self.required_block_height); let inner_puzzle = ctx.alloc(&clvm_quote!(base_conditions))?; @@ -162,7 +163,7 @@ where } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct StateSchedulerLayerSolution { pub other_singleton_inner_puzzle_hash: Bytes32, #[clvm(rest)] diff --git a/src/layers/verification_layer.rs b/src/layers/verification_layer.rs index a00c75b9..edad44fd 100644 --- a/src/layers/verification_layer.rs +++ b/src/layers/verification_layer.rs @@ -180,7 +180,7 @@ where } #[derive(FromClvm, ToClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct VerificationLayerSolution { pub revocation_singleton_inner_puzzle_hash: Option, } diff --git a/src/primitives/catalog_registry_info.rs b/src/primitives/catalog_registry_info.rs index 709977eb..1be8939e 100644 --- a/src/primitives/catalog_registry_info.rs +++ b/src/primitives/catalog_registry_info.rs @@ -34,7 +34,7 @@ pub struct CatalogRegistryState { pub struct CatalogRegistryConstants { pub launcher_id: Bytes32, pub royalty_address: Bytes32, - pub royalty_ten_thousandths: u16, + pub royalty_basis_points: u16, pub precommit_payout_puzzle_hash: Bytes32, pub relative_block_height: u32, pub price_singleton_launcher_id: Bytes32, @@ -50,7 +50,7 @@ impl CatalogRegistryConstants { royalty_address: Bytes32::from(hex!( "b3aea098428b2b5e6d57cf3bff6ee82e3950dec338b17df6d8ee20944787def5" )), - royalty_ten_thousandths: 100, + royalty_basis_points: 100, precommit_payout_puzzle_hash: Bytes32::from(hex!( "b3aea098428b2b5e6d57cf3bff6ee82e3950dec338b17df6d8ee20944787def5" )), diff --git a/src/primitives/medieval_vault.rs b/src/primitives/medieval_vault.rs index 1197995e..bfd70e27 100644 --- a/src/primitives/medieval_vault.rs +++ b/src/primitives/medieval_vault.rs @@ -122,14 +122,8 @@ impl MedievalVault { return Ok(None); }; - let (new_m, new_pubkeys) = if recreate_condition.memos.is_none() { - ( - parent_layers.inner_puzzle.m, - parent_layers.inner_puzzle.public_key_list.clone(), - ) - } else { - let memos = recreate_condition.memos.unwrap(); - if let Ok(memos) = ctx.extract::(memos.value) { + let (new_m, new_pubkeys) = if let Memos::Some(memos) = recreate_condition.memos { + if let Ok(memos) = ctx.extract::(memos) { (memos.m, memos.public_key_list) } else { ( @@ -137,6 +131,11 @@ impl MedievalVault { parent_layers.inner_puzzle.public_key_list.clone(), ) } + } else { + ( + parent_layers.inner_puzzle.m, + parent_layers.inner_puzzle.public_key_list.clone(), + ) }; let parent_info = MedievalVaultInfo::new( @@ -238,7 +237,7 @@ impl MedievalVault { Ok(Conditions::new().create_coin( new_info.inner_puzzle_hash().into(), 1, - Some(Memos::new(memos)), + Memos::Some(memos), )) } @@ -271,11 +270,10 @@ impl MedievalVault { where M: ToClvm, { - let hint = ctx.hint(my_info.launcher_id)?; let conditions = Conditions::new().create_coin( my_info.inner_puzzle_hash().into(), my_coin.amount, - Some(hint), + ctx.hint(my_info.launcher_id)?, ); let genesis_challenge = ctx.alloc(&genesis_challenge)?; @@ -374,7 +372,7 @@ mod tests { let recreate_condition = Conditions::::new().create_coin( current_vault_info.inner_puzzle_hash().into(), 1, - Memos::some(recreate_memos), + Memos::Some(recreate_memos), ); let mut used_keys = 0; diff --git a/src/primitives/medieval_vault_info.rs b/src/primitives/medieval_vault_info.rs index fdbfcf30..c19ce357 100644 --- a/src/primitives/medieval_vault_info.rs +++ b/src/primitives/medieval_vault_info.rs @@ -52,7 +52,7 @@ impl MedievalVaultInfo { } #[derive(ToClvm, FromClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct MedievalVaultHint { pub my_launcher_id: Bytes32, pub m: usize, diff --git a/src/primitives/reserve.rs b/src/primitives/reserve.rs index 9ed3cc98..96b589b7 100644 --- a/src/primitives/reserve.rs +++ b/src/primitives/reserve.rs @@ -4,8 +4,8 @@ use chia::{ puzzles::{cat::CatArgs, singleton::SingletonSolution, LineageProof}, }; use chia_wallet_sdk::{ - driver::{Cat, CatSpend, DriverError, Layer, Spend, SpendContext}, - prelude::{CreateCoin, Memos}, + driver::{Cat, CatInfo, CatSpend, DriverError, Layer, Spend, SpendContext}, + prelude::CreateCoin, types::run_puzzle, }; use clvm_traits::{clvm_list, clvm_quote, match_tuple, FromClvm, ToClvm}; @@ -85,8 +85,7 @@ impl Reserve { Cat::new( self.coin, Some(self.proof), - self.asset_id, - self.inner_puzzle_hash, + CatInfo::new(self.asset_id, None, self.inner_puzzle_hash), ) } @@ -145,7 +144,7 @@ impl Reserve { let cc = CreateCoin::new( self.inner_puzzle_hash, new_reserve_amount, - Some(Memos::new(vec![self.inner_puzzle_hash])), + ctx.hint(self.inner_puzzle_hash)?, ); reserve_conditions.insert(0, ctx.alloc(&cc)?); diff --git a/src/primitives/slot.rs b/src/primitives/slot.rs index 19bfa7f2..602711fa 100644 --- a/src/primitives/slot.rs +++ b/src/primitives/slot.rs @@ -131,7 +131,7 @@ pub struct Slot2ndCurryArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, Copy, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct SlotSolution { pub parent_parent_info: Bytes32, pub parent_inner_puzzle_hash: Bytes32, diff --git a/src/primitives/state_scheduler.rs b/src/primitives/state_scheduler.rs index d695b4fb..04d50077 100644 --- a/src/primitives/state_scheduler.rs +++ b/src/primitives/state_scheduler.rs @@ -123,6 +123,7 @@ where #[cfg(test)] mod tests { + use chia_puzzle_types::Memos; use chia_wallet_sdk::{ driver::{Launcher, SingletonLayer}, test::Simulator, @@ -239,7 +240,7 @@ mod tests { new_state.tree_hash().to_vec().into(), vec![state_scheduler_puzzle_hash_ptr], ) - .create_coin(other_singleton_inner_puzzle_hash.into(), 1, None), + .create_coin(other_singleton_inner_puzzle_hash.into(), 1, Memos::None), )?; let other_singleton_spend = other_singleton.construct_spend( ctx, diff --git a/src/primitives/state_scheduler_info.rs b/src/primitives/state_scheduler_info.rs index c2d4e441..ece6985f 100644 --- a/src/primitives/state_scheduler_info.rs +++ b/src/primitives/state_scheduler_info.rs @@ -3,6 +3,7 @@ use chia::{ protocol::Bytes32, puzzles::singleton::{LauncherSolution, SingletonArgs, SingletonStruct}, }; +use chia_puzzle_types::Memos; use chia_wallet_sdk::{ driver::{DriverError, SingletonLayer}, types::Condition, @@ -63,7 +64,7 @@ where .into(), message, clvm_quote!(vec![ - Condition::<()>::create_coin(next_puzzle_hash, 1, None), + Condition::<()>::create_coin(next_puzzle_hash, 1, Memos::None), Condition::assert_height_absolute(required_block_height), ]), ) diff --git a/src/primitives/verification.rs b/src/primitives/verification.rs index 197207ec..347eeb70 100644 --- a/src/primitives/verification.rs +++ b/src/primitives/verification.rs @@ -178,6 +178,7 @@ pub struct VerificationLauncherKVList { mod tests { use anyhow::Ok; use chia::protocol::Bytes; + use chia_puzzle_types::Memos; use chia_puzzles::SINGLETON_LAUNCHER_HASH; use chia_wallet_sdk::{ driver::{Launcher, StandardLayer}, @@ -204,7 +205,7 @@ mod tests { let did = did.update( ctx, &p2, - Conditions::new().create_coin(SINGLETON_LAUNCHER_HASH.into(), 0, None), + Conditions::new().create_coin(SINGLETON_LAUNCHER_HASH.into(), 0, Memos::None), )?; let verification_launcher = Launcher::new(did.coin.parent_coin_info, 0); // we don't need an extra mojo for the verification coin since it's melted in the same tx diff --git a/src/primitives/verification_asserter.rs b/src/primitives/verification_asserter.rs index 21877aa7..e52bd4a5 100644 --- a/src/primitives/verification_asserter.rs +++ b/src/primitives/verification_asserter.rs @@ -167,7 +167,7 @@ impl

VerificationAsserterArgs

{ } #[derive(ToClvm, FromClvm, Debug, Clone, Copy, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct VerificationAsserterSolution { pub verifier_proof: LineageProof, pub verification_inner_puzzle_maker_solution: S, @@ -201,7 +201,7 @@ impl CatalogVerificationInnerPuzzleMakerArgs { } #[derive(ToClvm, FromClvm, Debug, Clone, PartialEq, Eq)] -#[clvm(solution)] +#[clvm(list)] pub struct CatalogVerificationInnerPuzzleMakerSolution { pub comment: String, } From e98b9e125eb4be13b115f09b37c72fe440c02380 Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 19:36:45 +0300 Subject: [PATCH 43/65] all tests passing after migration --- src/drivers.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index ecb3f2dd..28561cc2 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1261,7 +1261,6 @@ mod tests { let mut payment_cat = payment_cat[0]; minter_p2.spend(ctx, minter_bls.coin, issue_cat)?; - payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); sim.spend_coins(ctx.take(), &[minter_bls.sk.clone()])?; // Launch catalog @@ -1343,7 +1342,7 @@ mod tests { Memos::None, ), )?; - Cat::spend_all( + let new_cats = Cat::spend_all( ctx, &[CatSpend { cat: payment_cat, @@ -1354,7 +1353,7 @@ mod tests { )?; payment_cat_amount -= reg_amount; - payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); + payment_cat = new_cats[1]; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone(), minter_bls.sk.clone()])?; benchmark.add_spends( @@ -1527,10 +1526,8 @@ mod tests { ), )?; minter_p2_2.spend(ctx, minter2_bls.coin, issue_cat)?; - let mut alternative_payment_cat = alternative_payment_cat[0]; + let alternative_payment_cat = alternative_payment_cat[0]; - alternative_payment_cat = - alternative_payment_cat.child(minter2_bls.puzzle_hash, alternative_payment_cat_amount); sim.spend_coins(ctx.take(), &[minter2_bls.sk.clone()])?; let (catalog, _alternative_payment_cat) = test_refund_for_catalog( @@ -1746,8 +1743,6 @@ mod tests { let mut payment_cat = payment_cat[0]; minter_p2.spend(ctx, minter_bls.coin, issue_cat)?; - payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); - sim.spend_coins(ctx.take(), &[minter_bls.sk.clone()])?; // Launch price singleton @@ -2390,9 +2385,7 @@ mod tests { )?; minter_p2_2.spend(ctx, minter2.coin, issue_cat)?; - let mut alternative_payment_cat = alternative_payment_cat[0]; - alternative_payment_cat = - alternative_payment_cat.child(minter2.puzzle_hash, alternative_payment_cat_amount); + let alternative_payment_cat = alternative_payment_cat[0]; sim.spend_coins(ctx.take(), &[minter2.sk.clone()])?; registry = test_refund_for_xchandles( @@ -2606,7 +2599,6 @@ mod tests { cat_minter_p2.spend(ctx, cat_minter.coin, issue_cat)?; let mut source_cat = source_cat[0]; - source_cat = source_cat.child(cat_minter.puzzle_hash, cat_amount); sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; // Launch manager singleton From 49f38e7051c98a1e55b2c007b46d6ac634bdfb0a Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 19:41:50 +0300 Subject: [PATCH 44/65] correctly launch eve DIG slot --- src/drivers.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index 28561cc2..bd06d606 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -824,9 +824,7 @@ pub fn launch_dig_reward_distributor( ); let slot_puzzle_hash = Slot::::puzzle_hash(&slot_info); - let slot_hint: Bytes32 = - Slot::<()>::first_curry_hash(launcher_id, RewardDistributorSlotNonce::REWARD.to_u64()) - .into(); + let slot_hint: Bytes32 = first_epoch_start.tree_hash().into(); let slot_memos = ctx.hint(slot_hint)?; let launcher_memos = ctx.hint(launcher_id)?; let eve_singleton_inner_puzzle = clvm_quote!(Conditions::new() From 3977d2da162b3c0d24a1911a84b198001df6b061 Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 21:19:16 +0300 Subject: [PATCH 45/65] syncing is complicated --- src/cli/catalog/sync.rs | 2 +- src/cli/xchandles/sync.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index 2e7806cb..0e2dfd5c 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -253,7 +253,7 @@ pub async fn sync_catalog( .iter() .filter(|sv| sv == &slot_value) .count(); - if no_spent >= no_created { + if no_spent > no_created { continue; } diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index 739c9ff4..d65fb86b 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -156,7 +156,7 @@ pub async fn sync_xchandles( .iter() .filter(|sv| sv.tree_hash() == slot_value_hash.into()) .count(); - if no_spent >= no_created { + if no_spent > no_created { continue; } From 8760e63b121e16a910f8c23c24e0ec846ffdd66c Mon Sep 17 00:00:00 2001 From: Yak Date: Fri, 27 Jun 2025 21:40:08 +0300 Subject: [PATCH 46/65] fix actual sync issue --- src/cli/catalog/sync.rs | 4 ++-- src/cli/xchandles/sync.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index 0e2dfd5c..89c1c39c 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -233,7 +233,7 @@ pub async fn sync_catalog( } let mut processed_values = HashSet::::new(); - for slot_value in catalog.pending_spend.spent_slots.iter() { + for slot_value in catalog.pending_spend.created_slots.iter() { let slot_value_hash: Bytes32 = slot_value.tree_hash().into(); if processed_values.contains(&slot_value_hash) { continue; @@ -253,7 +253,7 @@ pub async fn sync_catalog( .iter() .filter(|sv| sv == &slot_value) .count(); - if no_spent > no_created { + if no_spent >= no_created { continue; } diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index d65fb86b..739c9ff4 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -156,7 +156,7 @@ pub async fn sync_xchandles( .iter() .filter(|sv| sv.tree_hash() == slot_value_hash.into()) .count(); - if no_spent > no_created { + if no_spent >= no_created { continue; } From 42902edd60c007bacc5da26904580dfcd981c437 Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 17:06:34 +0300 Subject: [PATCH 47/65] second version upgrade this week... --- Cargo.lock | 317 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 8 +- 2 files changed, 157 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e7a4bef..a2fd3269 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -693,22 +693,22 @@ dependencies = [ [[package]] name = "chia" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e23293631a6453f729ac18ecd1caf5aad3c8686de79daaaeead77d09957f68" -dependencies = [ - "chia-bls 0.25.0", - "chia-client 0.25.0", - "chia-consensus 0.25.0", - "chia-protocol 0.25.0", - "chia-puzzle-types 0.25.0", - "chia-secp 0.25.0", - "chia-serde 0.25.0", - "chia-sha2 0.25.0", - "chia-ssl 0.25.0", - "chia-traits 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b27699b864f74bfe17216295e445db63f1aedbe3be9560833009a5890ce5d46d" +dependencies = [ + "chia-bls 0.26.0", + "chia-client 0.26.0", + "chia-consensus 0.26.0", + "chia-protocol 0.26.0", + "chia-puzzle-types 0.26.0", + "chia-secp 0.26.0", + "chia-serde 0.26.0", + "chia-sha2 0.26.0", + "chia-ssl 0.26.0", + "chia-traits 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", ] @@ -764,14 +764,14 @@ dependencies = [ [[package]] name = "chia-bls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c16b9296d434304de07601f24f520dd8dcd127ab217f6c3de2f08b9215e2665" +checksum = "fc9ac7e90ae816e814dc26fb332615a5449d1d26e965eb7ad068ae530f9c3c7b" dependencies = [ "blst", - "chia-serde 0.25.0", - "chia-sha2 0.25.0", - "chia-traits 0.25.0", + "chia-serde 0.26.0", + "chia-sha2 0.26.0", + "chia-traits 0.26.0", "hex", "hkdf", "linked-hash-map", @@ -797,12 +797,12 @@ dependencies = [ [[package]] name = "chia-client" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320a354175bea6a8b8d13e2c803217179f6b818e647304a294755c4ac9e1ec90" +checksum = "3874f2e4c87f246457a42890d4f8e0cae9d019131b54f80f66c561c8d05cd444" dependencies = [ - "chia-protocol 0.25.0", - "chia-traits 0.25.0", + "chia-protocol 0.26.0", + "chia-traits 0.26.0", "futures-util", "thiserror 1.0.69", "tokio", @@ -833,19 +833,19 @@ dependencies = [ [[package]] name = "chia-consensus" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716e9c3b8c4418049cac10c8e859246e64f6581ccf433fe65a569b8c43b1b361" +checksum = "481208db317ed106dc249a5669a6916c565374633850584480a40b639409a940" dependencies = [ - "chia-bls 0.25.0", - "chia-protocol 0.25.0", - "chia-puzzle-types 0.25.0", + "chia-bls 0.26.0", + "chia-protocol 0.26.0", + "chia-puzzle-types 0.26.0", "chia-puzzles", - "chia-sha2 0.25.0", - "chia-traits 0.25.0", - "chia_streamable_macro 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "chia-sha2 0.26.0", + "chia-traits 0.26.0", + "chia_streamable_macro 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", "hex", "hex-literal", @@ -872,17 +872,17 @@ dependencies = [ [[package]] name = "chia-protocol" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d09bfaf24a4a3e9ec7f89d0b95fadf093617aa87cec089aa651a905e81d1af1" +checksum = "a9256179e4c912313532d7a47a50f67f6128313ee86a3798e54050afb73d6042" dependencies = [ - "chia-bls 0.25.0", - "chia-serde 0.25.0", - "chia-sha2 0.25.0", - "chia-traits 0.25.0", - "chia_streamable_macro 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "chia-bls 0.26.0", + "chia-serde 0.26.0", + "chia-sha2 0.26.0", + "chia-traits 0.26.0", + "chia_streamable_macro 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", "hex", "serde", @@ -907,16 +907,16 @@ dependencies = [ [[package]] name = "chia-puzzle-types" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "378afbe1412a2862f7afdb7b6b536957955a28c48bc282223dd70fd0b94a1cf1" +checksum = "239406b55be27d99a6903057e6785e0279fe9fdc48270faf7ef9270dcfa05c8d" dependencies = [ - "chia-bls 0.25.0", - "chia-protocol 0.25.0", + "chia-bls 0.26.0", + "chia-protocol 0.26.0", "chia-puzzles", - "chia-sha2 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "chia-sha2 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", "hex-literal", "num-bigint", @@ -956,14 +956,14 @@ dependencies = [ [[package]] name = "chia-sdk-client" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc7c12f1e2345af54ce39484d54d2e03260fd805659cd63ad364ab2264a55077" +checksum = "0d25008d098783a160e6377b91de2badf10dc5d150082e6b82b00b9ea7438f7b" dependencies = [ - "chia-protocol 0.25.0", - "chia-sdk-types 0.25.0", - "chia-ssl 0.25.0", - "chia-traits 0.25.0", + "chia-protocol 0.26.0", + "chia-sdk-types 0.27.0", + "chia-ssl 0.26.0", + "chia-traits 0.26.0", "futures-util", "once_cell", "thiserror 2.0.12", @@ -989,11 +989,11 @@ dependencies = [ [[package]] name = "chia-sdk-coinset" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b19d96cf8169f5338e3fea6e9ec415bb6397738fcaff91907cb077e1e7854d4" +checksum = "7d3b8d9098ad904ffa99da65f07cce7815cc26fea2af9a0676c4f35f1b556d08" dependencies = [ - "chia-protocol 0.25.0", + "chia-protocol 0.26.0", "hex", "hex-literal", "reqwest", @@ -1014,9 +1014,9 @@ dependencies = [ [[package]] name = "chia-sdk-derive" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5029013b79a6b9b0b1fcc5e7ea9dbb01d72a399256338c6bdc68044be36538af" +checksum = "d236375a71503031ddfe2865e06a4f7a5322e8b69d02a328e6d40bd207e89ae5" dependencies = [ "convert_case", "quote", @@ -1055,24 +1055,25 @@ dependencies = [ [[package]] name = "chia-sdk-driver" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4903943baff2462b9c86716525e90639a4536e5728a18abcbb32298d4b963e" +checksum = "e9313e2cc8eac6137a82bc9077bf0ccadee0c757fcbe6ffbbd32f4f496939f96" dependencies = [ "bech32", "bigdecimal", - "chia-bls 0.25.0", - "chia-consensus 0.25.0", - "chia-protocol 0.25.0", - "chia-puzzle-types 0.25.0", + "chia-bls 0.26.0", + "chia-consensus 0.26.0", + "chia-protocol 0.26.0", + "chia-puzzle-types 0.26.0", "chia-puzzles", - "chia-sdk-types 0.25.0", - "chia-secp 0.25.0", - "chia-sha2 0.25.0", - "chia-traits 0.25.0", + "chia-sdk-signer 0.27.0", + "chia-sdk-types 0.27.0", + "chia-secp 0.26.0", + "chia-sha2 0.26.0", + "chia-traits 0.26.0", "chia_streamable_macro 0.26.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", "flate2", "hex", @@ -1103,17 +1104,17 @@ dependencies = [ [[package]] name = "chia-sdk-signer" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2649f232c44298ccbe965bea021e42fbfb4de541436cea11ae064491ffa33dc" +checksum = "e61dfbd5b426741ef2df174f2db25e5204e9ef9b92d363892bf3f8c03cc8d23b" dependencies = [ - "chia-bls 0.25.0", - "chia-consensus 0.25.0", - "chia-protocol 0.25.0", - "chia-sdk-types 0.25.0", - "chia-secp 0.25.0", - "chia-sha2 0.25.0", - "clvm-traits 0.25.0", + "chia-bls 0.26.0", + "chia-consensus 0.26.0", + "chia-protocol 0.26.0", + "chia-sdk-types 0.27.0", + "chia-secp 0.26.0", + "chia-sha2 0.26.0", + "clvm-traits 0.26.0", "clvmr 0.14.0", "k256", "thiserror 2.0.12", @@ -1155,22 +1156,22 @@ dependencies = [ [[package]] name = "chia-sdk-test" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df246e7716f98d11943ea6663d87a4b68cb0b2f51729f18c637d973b457c4a6" +checksum = "a5ce29dee62c3223efe89619578b2b849d3ea661328e36a098c1d673da6b06f1" dependencies = [ "anyhow", "bip39", - "chia-bls 0.25.0", - "chia-consensus 0.25.0", - "chia-protocol 0.25.0", - "chia-puzzle-types 0.25.0", - "chia-sdk-signer 0.25.0", - "chia-sdk-types 0.25.0", - "chia-secp 0.25.0", - "chia-traits 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "chia-bls 0.26.0", + "chia-consensus 0.26.0", + "chia-protocol 0.26.0", + "chia-puzzle-types 0.26.0", + "chia-sdk-signer 0.27.0", + "chia-sdk-types 0.27.0", + "chia-secp 0.26.0", + "chia-traits 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", "hex", "indexmap 2.10.0", @@ -1202,20 +1203,20 @@ dependencies = [ [[package]] name = "chia-sdk-types" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c70758cd449677f2e6749e0b21445db98cccfe8f15f484c2078dcbd4239706" +checksum = "1b3145393e2d0854a8fb3e3de2167e5eaf1b110ac05c6276331ca18c50e814f1" dependencies = [ - "chia-bls 0.25.0", - "chia-consensus 0.25.0", - "chia-protocol 0.25.0", - "chia-puzzle-types 0.25.0", + "chia-bls 0.26.0", + "chia-consensus 0.26.0", + "chia-protocol 0.26.0", + "chia-puzzle-types 0.26.0", "chia-puzzles", - "chia-sdk-derive 0.25.0", - "chia-secp 0.25.0", - "chia-sha2 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", + "chia-sdk-derive 0.27.0", + "chia-secp 0.26.0", + "chia-sha2 0.26.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvm_tools_rs", "clvmr 0.14.0", "hex-literal", @@ -1239,12 +1240,12 @@ dependencies = [ [[package]] name = "chia-sdk-utils" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b2cd12291bcf071751945ff9524f81b1dde7c4b0fbbe81bf76a39b6f7e16d4d" +checksum = "4f1e8d1c895e2bac75c22a3aadd2c5787efaec1db6992a66351f16141298adad" dependencies = [ "bech32", - "chia-protocol 0.25.0", + "chia-protocol 0.26.0", "indexmap 2.10.0", "rand 0.8.5", "rand_chacha 0.3.1", @@ -1265,11 +1266,11 @@ dependencies = [ [[package]] name = "chia-secp" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727ab0317d4dc3e74152e0db4a60c86e4e2d5f69c879baf112ca6500866d5d60" +checksum = "8ae00dfc70f7a3b20c5074ea3684b25f7b64225ad44ca3ea766b4e908f86c2d5" dependencies = [ - "chia-sha2 0.25.0", + "chia-sha2 0.26.0", "hex", "k256", "p256", @@ -1287,9 +1288,9 @@ dependencies = [ [[package]] name = "chia-serde" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cffa2ea6267199feaa1bb0836095cd57d79c664277d8be28d370a44f36e47df1" +checksum = "2b013e263888739bfecf7456552eb4a9f2260f920db8b46b0723fb553ab1e030" dependencies = [ "hex", "serde", @@ -1324,9 +1325,9 @@ dependencies = [ [[package]] name = "chia-sha2" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0074799301bb192744727aa91f88a3ee75d2504bfb8a843b02d2e303a58dd87" +checksum = "3f3ab374b1f248d87516c34e4c128a91d2086e76a46bb44e386c96a71ea39129" dependencies = [ "sha2 0.10.9", ] @@ -1347,9 +1348,9 @@ dependencies = [ [[package]] name = "chia-ssl" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb268d7d4d08e83bda869a2b931dbe519ea4d60426515079c4dbd22f7731a2f4" +checksum = "51af8606c8376d730d6607cb69fe5edd87f5d0d106e5620065f58a31e7f348a4" dependencies = [ "rand 0.8.5", "rcgen", @@ -1393,12 +1394,12 @@ dependencies = [ [[package]] name = "chia-traits" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b67043daeab938c9b4d205b70e018d3352288fdd62709e87f6e2b331db5baca" +checksum = "440a88dfa8f685a87c4bae5f0b12c7bec1466ca1ff44dfc6b09acc605f7848fe" dependencies = [ - "chia-sha2 0.25.0", - "chia_streamable_macro 0.25.0", + "chia-sha2 0.26.0", + "chia_streamable_macro 0.26.0", "thiserror 1.0.69", ] @@ -1424,21 +1425,21 @@ dependencies = [ [[package]] name = "chia-wallet-sdk" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e924ad4aa74bd00451a30de243855350a2e4afd22a3c504d5735e8330ab547e5" -dependencies = [ - "chia-bls 0.25.0", - "chia-protocol 0.25.0", - "chia-sdk-client 0.25.0", - "chia-sdk-coinset 0.25.0", - "chia-sdk-driver 0.25.0", - "chia-sdk-signer 0.25.0", - "chia-sdk-test 0.25.0", - "chia-sdk-types 0.25.0", - "chia-sdk-utils 0.25.0", - "clvm-traits 0.25.0", - "clvm-utils 0.25.0", +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b0d2fda6bc51251d53408fa67c32a959a7eff9e812006ccc769e94e04e67a8" +dependencies = [ + "chia-bls 0.26.0", + "chia-protocol 0.26.0", + "chia-sdk-client 0.27.0", + "chia-sdk-coinset 0.27.0", + "chia-sdk-driver 0.27.0", + "chia-sdk-signer 0.27.0", + "chia-sdk-test 0.27.0", + "chia-sdk-types 0.27.0", + "chia-sdk-utils 0.27.0", + "clvm-traits 0.26.0", + "clvm-utils 0.26.0", "clvmr 0.14.0", ] @@ -1490,18 +1491,6 @@ dependencies = [ "syn", ] -[[package]] -name = "chia_streamable_macro" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc5c6400d47fc7b0bef1e08791e96fc391d678012090c4b95411cfa516c894c" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "chia_streamable_macro" version = "0.26.0" @@ -1591,9 +1580,9 @@ dependencies = [ [[package]] name = "clvm-derive" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e184e2f4aa7473bf377bd0f03e61406668124eb0d16ccdd4591ec5b6cb8ea533" +checksum = "68ded863cb5482335498872e91989487283f012adb7ca4ddf54ad7c6995058db" dependencies = [ "proc-macro2", "quote", @@ -1616,13 +1605,13 @@ dependencies = [ [[package]] name = "clvm-traits" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a93051ecabce23522df9d597c915b5df1be00a8b6d28f852a306304d9fe94d" +checksum = "469c44226c83de37509415482c89c00763f58de198844c34d2d62161b087d0ce" dependencies = [ - "chia-bls 0.25.0", - "chia-secp 0.25.0", - "clvm-derive 0.25.0", + "chia-bls 0.26.0", + "chia-secp 0.26.0", + "clvm-derive 0.26.0", "clvmr 0.14.0", "num-bigint", "thiserror 1.0.69", @@ -1642,12 +1631,12 @@ dependencies = [ [[package]] name = "clvm-utils" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3cfd58c573d44d4ecf9b17af614861a53e7e9170523decd212df162162b190" +checksum = "5646cd8d02f9c55c76ef6ff7598df54e6c8361f27fe8c9122e3ae9ef55935fcd" dependencies = [ - "chia-sha2 0.25.0", - "clvm-traits 0.25.0", + "chia-sha2 0.26.0", + "clvm-traits 0.26.0", "clvmr 0.14.0", "hex", ] @@ -4448,12 +4437,12 @@ dependencies = [ "axum", "bech32", "bip39", - "chia 0.25.0", - "chia-puzzle-types 0.25.0", + "chia 0.26.0", + "chia-puzzle-types 0.26.0", "chia-puzzles", - "chia-wallet-sdk 0.25.0", + "chia-wallet-sdk 0.27.0", "clap", - "clvm-traits 0.25.0", + "clvm-traits 0.26.0", "clvmr 0.14.0", "csv", "dirs", diff --git a/Cargo.toml b/Cargo.toml index 0ea3cbff..1c2bc149 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,9 @@ repository = "https://github.com/Yakuhito/slot-machine" [dependencies] clvmr = "0.14.0" -chia = "0.25.0" -clvm-traits = "0.25.0" +chia = "0.26.0" +clvm-traits = "0.26.0" +chia-puzzle-types = "0.26.0" hex-literal = "0.4.1" bip39 = "2.2.0" getrandom = "0.3.2" @@ -31,10 +32,9 @@ futures-util = "0.3.31" axum = { version = "0.8.3", features = ["macros"]} tower-http = { version = "0.6.2", features = ["cors"] } futures = "0.3.31" -chia-wallet-sdk = { version="0.25.0", features=["offers"] } +chia-wallet-sdk = { version="0.27.0", features=["offer-compression"] } sage-api = { version = "0.10.3", git = "https://github.com/xch-dev/sage.git" } chia-puzzles = "0.20.1" -chia-puzzle-types = "0.25.0" [dev-dependencies] anyhow = "1.0.98" From 193ac003e0c9d0c9e3765a502050d05b42722b2e Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 17:27:20 +0300 Subject: [PATCH 48/65] base --- src/drivers.rs | 373 ++++++++----------------------------------------- 1 file changed, 55 insertions(+), 318 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index bd06d606..a06121a3 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1,27 +1,25 @@ use bip39::Mnemonic; use chia::{ - bls::{sign, PublicKey, SecretKey, Signature}, + bls::{sign, SecretKey, Signature}, clvm_utils::ToTreeHash, consensus::consensus_constants::ConsensusConstants, protocol::{Bytes32, Coin, CoinSpend}, puzzles::{ - cat::{CatArgs, CatSolution}, - offer::{NotarizedPayment, Payment, SettlementPaymentsSolution}, + offer::{NotarizedPayment, Payment}, singleton::{SingletonArgs, SingletonSolution, SingletonStruct}, - standard::{StandardArgs, StandardSolution}, - CoinProof, EveProof, LineageProof, Proof, + standard::StandardSolution, + EveProof, LineageProof, Proof, }, }; -use chia_puzzle_types::Memos; -use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH, SINGLETON_TOP_LAYER_V1_1_HASH}; +use chia_puzzle_types::{offer::SettlementPaymentsSolution, standard::StandardArgs, Memos}; use chia_wallet_sdk::{ driver::{ - Cat, CatInfo, CatSpend, CurriedPuzzle, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, - Puzzle, SingleCatSpend, Spend, SpendContext, StandardLayer, + Cat, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, Spend, SpendContext, + StandardLayer, }, prelude::{AggSig, AggSigKind}, signer::{AggSigConstants, RequiredBlsSignature}, - types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, + types::{puzzles::SettlementPayment, Condition, Conditions}, }; use clvm_traits::{clvm_list, clvm_quote, clvm_tuple, FromClvm, ToClvm}; use clvmr::{Allocator, NodePtr}; @@ -61,299 +59,6 @@ pub fn new_sk() -> Result { Ok(sk) } -pub fn parse_one_sided_offer( - ctx: &mut SpendContext, - offer: Offer, - security_public_key: PublicKey, - cat_notarized_payment: Option, - nft_notatized_payment: Option, -) -> Result { - let offer = offer.parse(ctx).map_err(custom_err)?; - - if !offer.requested_payments.is_empty() { - return Err(DriverError::Custom( - "Launch offer should not have any requested payments".to_string(), - )); - } - - let security_coin_puzzle_hash: Bytes32 = - StandardArgs::curry_tree_hash(security_public_key).into(); - - // returned spends will also spend the offer coin (creating the security coin) - let mut coin_spends = Vec::with_capacity(offer.coin_spends.len() + 1); - let mut security_coin_parent_id: Option = None; - let mut security_coin_amount = 0; - - let mut base_conditions = Conditions::new(); - let mut created_cat: Option = None; - let mut created_nft: Option> = None; - - for coin_spend in offer.coin_spends { - let puzzle_ptr = coin_spend.puzzle_reveal.to_clvm(ctx)?; - let solution_ptr = coin_spend.solution.to_clvm(ctx)?; - - let curried_puzzle = CurriedPuzzle::parse(ctx, puzzle_ptr); - - if let Some(curried_puzzle) = curried_puzzle { - if curried_puzzle.mod_hash == CAT_PUZZLE_HASH.into() { - let cat_args = CatArgs::::from_clvm(ctx, curried_puzzle.args)?; - let cat_solution = CatSolution::::from_clvm(ctx, solution_ptr)?; - - let inner_output = - ctx.run(cat_args.inner_puzzle, cat_solution.inner_puzzle_solution)?; - let inner_output = Vec::>::from_clvm(ctx, inner_output)?; - - if let Some(cc) = inner_output - .into_iter() - .filter_map(|cond| { - let Condition::CreateCoin(cc) = cond else { - return None; - }; - - Some(cc) - }) - .find(|cc| cc.puzzle_hash == SETTLEMENT_PAYMENT_HASH.into()) - { - let Some(cat_notarized_payment) = cat_notarized_payment.clone() else { - return Err(DriverError::Custom( - "CAT payment not requested but offered CAT found".to_string(), - )); - }; - - // we found a CAT creating an offered CAT - spend it to create - // the offer CAT, which then creates a 0-amount coin with - // puzzle hash = cat_destination_puzzle_hash; also return the cat - // by returning it to its original puzzle hash - - // and assert the announcement to make sure it's not going - // somewhere else - let offer_cat_full_puzzle_hash = - CatArgs::curry_tree_hash(cat_args.asset_id, SETTLEMENT_PAYMENT_HASH.into()); - let offer_coin_cat = Coin::new( - coin_spend.coin.coin_id(), - offer_cat_full_puzzle_hash.into(), - cc.amount, - ); - let refund_puzzle_hash = ctx.tree_hash(cat_args.inner_puzzle).into(); // funds will be returned to refund_puzzle_hash (inner puzzle hash) - let offer_cat = Cat::new( - offer_coin_cat, - Some(LineageProof { - parent_parent_coin_info: coin_spend.coin.parent_coin_info, - parent_inner_puzzle_hash: refund_puzzle_hash, - parent_amount: coin_spend.coin.amount, - }), - CatInfo::new(cat_args.asset_id, None, SETTLEMENT_PAYMENT_HASH.into()), - ); - - // offers don't allow amount 0 coins, so we create an 1-amount coin, - // which creates a 0-amount coin and spend all the CATs together - if cat_notarized_payment.payments[0].amount == 0 { - let interim_inner_puzzle = ctx.alloc(&clvm_quote!(Conditions::new() - .create_coin( - cat_notarized_payment.payments[0].puzzle_hash, - 0, - cat_notarized_payment.payments[0].memos, - )))?; - let interim_inner_ph: Bytes32 = ctx.tree_hash(interim_inner_puzzle).into(); - - let notarized_payment = NotarizedPayment { - nonce: offer_coin_cat.coin_id(), - payments: vec![ - Payment::new( - refund_puzzle_hash, - cc.amount, - ctx.hint(refund_puzzle_hash)?, - ), - Payment::new(interim_inner_ph, 1, Memos::None), - ], - }; - let offer_cat_inner_solution = ctx.alloc(&SettlementPaymentsSolution { - notarized_payments: vec![notarized_payment.clone()], - })?; - - let offer_cat_spend = CatSpend::new( - offer_cat, - Spend::new( - ctx.alloc_mod::()?, - offer_cat_inner_solution, - ), - ); - - let interim_cat = offer_cat.child(interim_inner_ph, 1); - let interim_cat_spend = CatSpend::new( - interim_cat, - Spend::new(interim_inner_puzzle, NodePtr::NIL), - ); - - let orig_spends = ctx.take(); - - Cat::spend_all(ctx, &[offer_cat_spend, interim_cat_spend])?; - coin_spends.extend(ctx.take()); - - for og_spend in orig_spends { - ctx.insert(og_spend); - } - - created_cat = Some( - interim_cat.child(cat_notarized_payment.payments[0].puzzle_hash, 0), - ); - let notarized_payment_ptr = ctx.alloc(¬arized_payment)?; - let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); - base_conditions = base_conditions.assert_puzzle_announcement( - announcement_id(offer_cat.coin.puzzle_hash, announcement_msg), - ); - } else { - let offer_cat_inner_solution = ctx.alloc(&SettlementPaymentsSolution { - notarized_payments: vec![cat_notarized_payment.clone()], - })?; - - let offer_cat_inner_puzzle = ctx.alloc_mod::()?; - offer_cat.spend( - ctx, - SingleCatSpend { - prev_coin_id: offer_cat.coin.coin_id(), - next_coin_proof: CoinProof { - parent_coin_info: offer_cat.coin.parent_coin_info, - inner_puzzle_hash: offer_cat.info.p2_puzzle_hash, - amount: cc.amount, - }, - prev_subtotal: 0, - extra_delta: 0, - inner_spend: Spend::new( - offer_cat_inner_puzzle, - offer_cat_inner_solution, - ), - revoke: false, - }, - )?; - - created_cat = Some( - offer_cat - .child(cat_notarized_payment.payments[0].puzzle_hash, cc.amount), - ); - let notarized_payment_ptr = ctx.alloc(&cat_notarized_payment)?; - let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); - base_conditions = base_conditions.assert_puzzle_announcement( - announcement_id(offer_cat.coin.puzzle_hash, announcement_msg), - ); - } - } - } else if curried_puzzle.mod_hash == SINGLETON_TOP_LAYER_V1_1_HASH.into() { - let Some(nft_notatized_payment) = nft_notatized_payment.clone() else { - return Err(DriverError::Custom( - "NFT payment not requested but offered NFT found".to_string(), - )); - }; - - let parent_puzzle = Puzzle::from_clvm(ctx, puzzle_ptr)?; - let Some(nft) = Nft::::parse_child( - ctx, - coin_spend.coin, - parent_puzzle, - solution_ptr, - )? - else { - return Err(DriverError::Custom("Could not parse child NFT".to_string())); - }; - - let inner_puzzle = ctx.alloc_mod::()?; - let inner_solution = ctx.alloc(&SettlementPaymentsSolution { - notarized_payments: vec![nft_notatized_payment.clone()], - })?; - - nft.spend(ctx, Spend::new(inner_puzzle, inner_solution))?; - - created_nft = Some(nft.child::( - nft_notatized_payment.payments[0].puzzle_hash, - nft.info.current_owner, - nft.info.metadata, - )); - let notarized_payment_ptr = ctx.alloc(&nft_notatized_payment)?; - let announcement_msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); - base_conditions = base_conditions.assert_puzzle_announcement(announcement_id( - nft.coin.puzzle_hash, - announcement_msg, - )); - } - } - - if security_coin_parent_id.is_none() { - let res = ctx.run(puzzle_ptr, solution_ptr)?; - let res = Vec::>::from_clvm(ctx, res)?; - - if let Some(cc) = res - .into_iter() - .filter_map(|cond| { - let Condition::CreateCoin(cc) = cond else { - return None; - }; - - Some(cc) - }) - .find(|cc| cc.puzzle_hash == SETTLEMENT_PAYMENT_HASH.into()) - { - let offer_coin = Coin::new( - coin_spend.coin.coin_id(), - SETTLEMENT_PAYMENT_HASH.into(), - cc.amount, - ); - let offer_coin_id = offer_coin.coin_id(); - - security_coin_parent_id = Some(offer_coin_id); - security_coin_amount = cc.amount; - - let settlement_payments_puzzle = ctx.alloc_mod::()?; - let offer_coin_puzzle = ctx.serialize(&settlement_payments_puzzle)?; - - let offer_coin_solution = SettlementPaymentsSolution { - notarized_payments: vec![NotarizedPayment { - nonce: offer_coin_id, - payments: vec![Payment::new( - security_coin_puzzle_hash, - security_coin_amount, - Memos::None, - )], - }], - }; - let offer_coin_solution = ctx.serialize(&offer_coin_solution)?; - - let offer_coin_spend = - CoinSpend::new(offer_coin, offer_coin_puzzle, offer_coin_solution); - coin_spends.push(offer_coin_spend); - } - } - - coin_spends.push(coin_spend); - } - - let Some(security_coin_parent_id) = security_coin_parent_id else { - return Err(DriverError::Custom( - "Launch offer should offer XCH".to_string(), - )); - }; - - let security_coin = Coin::new( - security_coin_parent_id, - security_coin_puzzle_hash, - security_coin_amount, - ); - - if cat_notarized_payment.is_some() && created_cat.is_none() { - return Err(DriverError::Custom( - "Could not find CAT offered in one-sided offer".to_string(), - )); - } - - Ok(SecuredOneSidedOffer { - coin_spends, - aggregated_signature: offer.aggregated_signature, - security_coin, - security_base_conditions: base_conditions, - created_cat, - created_nft, - }) -} - pub fn spend_security_coin( ctx: &mut SpendContext, security_coin: Coin, @@ -533,6 +238,40 @@ where )) } +pub fn create_security_coin( + ctx: &mut SpendContext, + xch_settlement_coin: Coin, +) -> Result<(SecretKey, Coin), DriverError> { + let security_coin_sk = new_sk()?; + let security_coin_puzzle_hash: Bytes32 = + StandardArgs::curry_tree_hash(security_coin_sk.public_key()).into(); + + let notarized_payment = NotarizedPayment { + nonce: xch_settlement_coin.coin_id(), + payments: vec![Payment::new( + security_coin_puzzle_hash, + xch_settlement_coin.amount, + Memos::None, + )], + }; + let settlement_puzzle = ctx.alloc_mod::()?; + let settlement_solution = ctx.alloc(&SettlementPaymentsSolution { + notarized_payments: vec![notarized_payment], + })?; + ctx.spend( + xch_settlement_coin, + Spend::new(settlement_puzzle, settlement_solution), + )?; + + let security_coin = Coin::new( + xch_settlement_coin.coin_id(), + security_coin_puzzle_hash, + xch_settlement_coin.amount, + ); + + Ok((security_coin_sk, security_coin)) +} + #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] pub fn launch_catalog_registry( @@ -561,13 +300,16 @@ pub fn launch_catalog_registry( ), DriverError, > { - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let security_coin_id = offer.security_coin.coin_id(); + let (security_coin_sk, security_coin) = + create_security_coin(ctx, offer.offered_coins().xch[0])?; + offer.spend_bundle().coin_spends.iter().for_each(|cs| { + if cs.coin.parent_coin_info != Bytes32::default() { + ctx.insert(cs.clone()); + } + }); - let mut security_coin_conditions = offer.security_base_conditions; + let security_coin_id = security_coin.coin_id(); + let mut security_coin_conditions = Conditions::new(); // Create CATalog registry launcher let registry_launcher = Launcher::new(security_coin_id, 1); @@ -575,12 +317,7 @@ pub fn launch_catalog_registry( let registry_launcher_id = registry_launcher_coin.coin_id(); let (additional_security_coin_conditions, catalog_constants, initial_registration_asset_id) = - get_additional_info( - ctx, - registry_launcher_id, - offer.security_coin, - additional_args, - )?; + get_additional_info(ctx, registry_launcher_id, security_coin, additional_args)?; let initial_state = CatalogRegistryState { registration_price: initial_registration_price, @@ -623,7 +360,7 @@ pub fn launch_catalog_registry( // Spend security coin let security_coin_sig = spend_security_coin( ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, consensus_constants, @@ -631,11 +368,11 @@ pub fn launch_catalog_registry( // Finally, return the data Ok(( - offer.aggregated_signature + &security_coin_sig, + security_coin_sig + &offer.spend_bundle().aggregated_signature, security_coin_sk, catalog_registry, slots, - offer.security_coin, + security_coin, )) } From a5dd97045f0d71de4a7940c7cbe0bd0361595d15 Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 18:47:00 +0300 Subject: [PATCH 49/65] fix driver errors --- src/drivers.rs | 284 +++++++++++++++++++++++++++++-------------------- 1 file changed, 166 insertions(+), 118 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index a06121a3..26fe2a52 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -14,12 +14,12 @@ use chia::{ use chia_puzzle_types::{offer::SettlementPaymentsSolution, standard::StandardArgs, Memos}; use chia_wallet_sdk::{ driver::{ - Cat, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, Spend, SpendContext, + Cat, CatSpend, DriverError, HashedPtr, Launcher, Layer, Nft, Offer, Spend, SpendContext, StandardLayer, }, prelude::{AggSig, AggSigKind}, signer::{AggSigConstants, RequiredBlsSignature}, - types::{puzzles::SettlementPayment, Condition, Conditions}, + types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, }; use clvm_traits::{clvm_list, clvm_quote, clvm_tuple, FromClvm, ToClvm}; use clvmr::{Allocator, NodePtr}; @@ -302,11 +302,11 @@ pub fn launch_catalog_registry( > { let (security_coin_sk, security_coin) = create_security_coin(ctx, offer.offered_coins().xch[0])?; - offer.spend_bundle().coin_spends.iter().for_each(|cs| { - if cs.coin.parent_coin_info != Bytes32::default() { - ctx.insert(cs.clone()); - } - }); + offer + .spend_bundle() + .coin_spends + .iter() + .for_each(|cs| ctx.insert(cs.clone())); let security_coin_id = security_coin.coin_id(); let mut security_coin_conditions = Conditions::new(); @@ -405,13 +405,17 @@ pub fn launch_xchandles_registry( ), DriverError, > { - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let (security_coin_sk, security_coin) = + create_security_coin(ctx, offer.offered_coins().xch[0])?; + offer + .spend_bundle() + .coin_spends + .iter() + .for_each(|cs| ctx.insert(cs.clone())); - let security_coin_id = offer.security_coin.coin_id(); + let security_coin_id = security_coin.coin_id(); - let mut security_coin_conditions = offer.security_base_conditions; + let mut security_coin_conditions = Conditions::new(); // Create registry coin launcher let registry_launcher = Launcher::new(security_coin_id, 1); @@ -419,12 +423,7 @@ pub fn launch_xchandles_registry( let registry_launcher_id = registry_launcher_coin.coin_id(); let (additional_security_coin_conditions, xchandles_constants, initial_registration_asset_id) = - get_additional_info( - ctx, - registry_launcher_id, - offer.security_coin, - additional_args, - )?; + get_additional_info(ctx, registry_launcher_id, security_coin, additional_args)?; // Spend intermediary coin and create registry let initial_state = XchandlesRegistryState::from( @@ -466,7 +465,7 @@ pub fn launch_xchandles_registry( // Spend security coin let security_coin_sig = spend_security_coin( ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, consensus_constants, @@ -474,14 +473,76 @@ pub fn launch_xchandles_registry( // Finally, return the data Ok(( - offer.aggregated_signature + &security_coin_sig, + security_coin_sig + &offer.spend_bundle().aggregated_signature, security_coin_sk, xchandles_registry, slots, - offer.security_coin, + security_coin, )) } +pub fn spend_settlement_cats( + ctx: &mut SpendContext, + offer: &Offer, + asset_id: Bytes32, + nonce: Bytes32, + payments: Vec<(Bytes32, u64)>, +) -> Result<(Vec, Conditions), DriverError> { + let settlement_cats = offer + .offered_coins() + .cats + .get(&asset_id) + .ok_or(DriverError::Custom( + "Could not find required CAT in offer".to_string(), + ))?; + + let mut pmnts = Vec::with_capacity(payments.len()); + for (puzzle_hash, amount) in payments.iter() { + pmnts.push(Payment::new(*puzzle_hash, *amount, ctx.hint(*puzzle_hash)?)); + } + let notarized_payment = NotarizedPayment { + nonce, + payments: pmnts, + }; + + let offer_ann_message = ctx.alloc(¬arized_payment)?; + let offer_ann_message: Bytes32 = ctx.tree_hash(offer_ann_message).into(); + + let first_settlement_inner_solution = ctx.alloc(&SettlementPaymentsSolution { + notarized_payments: vec![notarized_payment], + })?; + let settlement_inner_puzzle = ctx.alloc_mod::()?; + + let security_coin_conditions = Conditions::new().assert_puzzle_announcement(announcement_id( + settlement_cats[0].coin.puzzle_hash, + offer_ann_message, + )); + + let created_cats = payments + .iter() + .map(|(puzzle_hash, amount)| settlement_cats[0].child(*puzzle_hash, *amount)) + .collect(); + + let mut cat_spends = Vec::with_capacity(settlement_cats.len()); + for (i, cat) in settlement_cats.into_iter().enumerate() { + cat_spends.push(CatSpend { + cat: cat.clone(), + spend: Spend::new( + settlement_inner_puzzle, + if i == 0 { + first_settlement_inner_solution + } else { + NodePtr::NIL + }, + ), + hidden: false, + }); + } + Cat::spend_all(ctx, &cat_spends)?; + + Ok((created_cats, security_coin_conditions)) +} + #[allow(clippy::type_complexity)] pub fn launch_dig_reward_distributor( ctx: &mut SpendContext, @@ -500,23 +561,17 @@ pub fn launch_dig_reward_distributor( ), DriverError, > { - // use a 'trick' to find the launcher id so we can determine reserve id, then call the function again - // with the right CAT destination ph - let security_coin_sk = new_sk()?; - let hint = ctx.hint(cat_refund_puzzle_hash)?; - let mock_offer = parse_one_sided_offer( - ctx, - offer.clone(), - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: constants.launcher_id, - payments: vec![Payment::new(cat_refund_puzzle_hash, 0, hint)], - }), - None, - )?; + let (security_coin_sk, security_coin) = + create_security_coin(ctx, offer.offered_coins().xch[0])?; + offer + .spend_bundle() + .coin_spends + .iter() + .for_each(|cs| ctx.insert(cs.clone())); + let reward_distributor_hint: Bytes32 = "Reward Distributor v1".tree_hash().into(); let launcher_memos = ctx.memos(&(reward_distributor_hint, (comment, ())))?; - let launcher = Launcher::with_memos(mock_offer.security_coin.coin_id(), 1, launcher_memos); + let launcher = Launcher::with_memos(security_coin.coin_id(), 1, launcher_memos); let launcher_coin = launcher.coin(); let launcher_id = launcher_coin.coin_id(); @@ -526,20 +581,13 @@ pub fn launch_dig_reward_distributor( P2DelegatedBySingletonLayerArgs::curry_tree_hash(controller_singleton_struct_hash, 0) .into(); - let hint = ctx.hint(reserve_inner_ph)?; - let offer = parse_one_sided_offer( + let (created_cats, mut security_coin_conditions) = spend_settlement_cats( ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: constants.launcher_id, - payments: vec![Payment::new(reserve_inner_ph, 0, hint)], - }), - None, + &offer, + constants.reserve_asset_id, + constants.launcher_id, + vec![(reserve_inner_ph, 0), (cat_refund_puzzle_hash, 1)], )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let mut security_coin_conditions = offer.security_base_conditions; // Spend intermediary coin and create registry let target_info = RewardDistributorInfo::new( @@ -616,11 +664,7 @@ pub fn launch_dig_reward_distributor( security_coin_conditions.assert_concurrent_spend(eve_coin.coin_id()); // create reserve and registry - let Some(reserve_cat) = offer.created_cat else { - return Err(DriverError::Custom( - "Offer does not contain reserve".to_string(), - )); - }; + let reserve_cat = created_cats[0]; let reserve = Reserve::new( reserve_cat.coin.parent_coin_info, reserve_cat.lineage_proof.unwrap(), @@ -634,7 +678,7 @@ pub fn launch_dig_reward_distributor( // Spend security coin let security_coin_sig = spend_security_coin( ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, consensus_constants, @@ -642,7 +686,7 @@ pub fn launch_dig_reward_distributor( // Finally, return the data Ok(( - offer.aggregated_signature + &security_coin_sig, + security_coin_sig + &offer.spend_bundle().aggregated_signature, security_coin_sk, registry, slot, @@ -659,9 +703,9 @@ mod tests { CoinProof, }, }; - use chia_puzzles::SINGLETON_LAUNCHER_HASH; + use chia_puzzles::{SETTLEMENT_PAYMENT_HASH, SINGLETON_LAUNCHER_HASH}; use chia_wallet_sdk::{ - driver::{Nft, NftMint, SpendWithConditions}, + driver::{Nft, NftMint, SingleCatSpend, SpendWithConditions}, test::Simulator, types::TESTNET11_CONSTANTS, }; @@ -872,9 +916,8 @@ mod tests { ctx, &[CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }], )?; @@ -962,16 +1005,19 @@ mod tests { let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; - let offer = Offer::new(SpendBundle { - coin_spends: vec![CoinSpend::new(offer_src_coin, puzzle_reveal, solution)], - aggregated_signature: sign_standard_transaction( - ctx, - offer_src_coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, - }); + let offer = Offer::from_spend_bundle( + ctx, + &SpendBundle { + coin_spends: vec![CoinSpend::new(offer_src_coin, puzzle_reveal, solution)], + aggregated_signature: sign_standard_transaction( + ctx, + offer_src_coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?, + }, + )?; let ( price_singleton_launcher_id, @@ -1081,9 +1127,8 @@ mod tests { ctx, &[CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }], )?; @@ -1370,9 +1415,8 @@ mod tests { ctx, &[CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }], )?; @@ -1453,16 +1497,19 @@ mod tests { let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; - let offer = Offer::new(SpendBundle { - coin_spends: vec![CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution)], - aggregated_signature: sign_standard_transaction( - ctx, - launcher_bls.coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, - }); + let offer = Offer::from_spend_bundle( + ctx, + &SpendBundle { + coin_spends: vec![CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution)], + aggregated_signature: sign_standard_transaction( + ctx, + launcher_bls.coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?, + }, + )?; // Launch CAT let mut payment_cat_amount = 10_000_000; @@ -1620,9 +1667,8 @@ mod tests { ctx, &[CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }], )?; @@ -1854,15 +1900,13 @@ mod tests { &[ CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }, CatSpend { cat: payment_cat.child(SETTLEMENT_PAYMENT_HASH.into(), pay_for_extension), - inner_spend: cat_offer_inner_spend, - extra_delta: 0, - revoke: false, + spend: cat_offer_inner_spend, + hidden: false, }, ], )?; @@ -1996,9 +2040,8 @@ mod tests { ctx, &[CatSpend { cat: payment_cat, - inner_spend: payment_cat_inner_spend, - extra_delta: 0, - revoke: false, + spend: payment_cat_inner_spend, + hidden: false, }], )?; @@ -2224,7 +2267,7 @@ mod tests { royalty_puzzle_hash, royalty_basis_points: 100, p2_puzzle_hash: bls.puzzle_hash, - owner: None, + transfer_condition: None, }, )?; p2.spend(ctx, bls.coin, create_nft)?; @@ -2401,7 +2444,7 @@ mod tests { }, prev_subtotal: 0, extra_delta: 0, - inner_spend: source_cat_inner_spend, + p2_spend: source_cat_inner_spend, revoke: false, }, )?; @@ -2417,19 +2460,22 @@ mod tests { } } - let offer = Offer::new(SpendBundle { - coin_spends: vec![ - CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution), - cat_offer_spend, - ], - aggregated_signature: sign_standard_transaction( - ctx, - launcher_bls.coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, - }); + let offer = Offer::from_spend_bundle( + ctx, + &SpendBundle { + coin_spends: vec![ + CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution), + cat_offer_spend, + ], + aggregated_signature: sign_standard_transaction( + ctx, + launcher_bls.coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?, + }, + )?; // Launch the reward distributor let first_epoch_start = 1234; @@ -2551,7 +2597,7 @@ mod tests { ensure_conditions_met(ctx, &mut sim, sec_conds, 0)?; - let offer_nft = nft.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft.info.metadata); + let offer_nft = nft.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft.info.metadata, 1); let nft_inner_spend = Spend::new( ctx.alloc(&clvm_quote!(Conditions::new().create_coin( @@ -3079,8 +3125,10 @@ mod tests { ensure_conditions_met(ctx, &mut sim, sec_conds2.extend(sec_conds3), 0)?; - let offer2_nft = nft2.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft2.info.metadata); - let offer3_nft = nft3.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft3.info.metadata); + let offer2_nft = + nft2.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft2.info.metadata, 1); + let offer3_nft = + nft3.child(SETTLEMENT_PAYMENT_HASH.into(), None, nft3.info.metadata, 1); let nfts_inner_spend = Spend::new( ctx.alloc(&clvm_quote!(Conditions::new().create_coin( @@ -3154,11 +3202,11 @@ mod tests { let reserve_cat = registry.reserve.to_cat(); if let Some((entry3_slot, locked_nft2, locked_nft3)) = other_nft2_info { let nft2_return_coin_id = locked_nft2 - .child(nft2_bls.puzzle_hash, None, locked_nft2.info.metadata) + .child(nft2_bls.puzzle_hash, None, locked_nft2.info.metadata, 1) .coin .coin_id(); let nft3_return_coin_id = locked_nft3 - .child(nft3_bls.puzzle_hash, None, locked_nft3.info.metadata) + .child(nft3_bls.puzzle_hash, None, locked_nft3.info.metadata, 1) .coin .coin_id(); From 1d3ac226db56821fc1ec9019aedbbba8a357e995 Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 19:41:07 +0300 Subject: [PATCH 50/65] making progress --- src/cli/utils.rs | 5 +- src/cli/xchandles/continue_launch.rs | 78 +++++--------- src/cli/xchandles/expire.rs | 22 ++-- src/cli/xchandles/extend.rs | 42 ++++---- src/cli/xchandles/initiate_launch.rs | 5 +- src/cli/xchandles/register.rs | 22 ++-- src/cli/xchandles/unroll_state_scheduler.rs | 25 ++--- src/cli/xchandles/update.rs | 50 ++++----- src/drivers.rs | 102 +++++++++++++----- .../actions/reward_distributor/stake.rs | 5 +- 10 files changed, 180 insertions(+), 176 deletions(-) diff --git a/src/cli/utils.rs b/src/cli/utils.rs index a6215d48..50e8d5a0 100644 --- a/src/cli/utils.rs +++ b/src/cli/utils.rs @@ -6,7 +6,7 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{DriverError, OfferError, Spend, SpendContext}, + driver::{DriverError, Spend, SpendContext}, types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::AddressError, }; @@ -67,9 +67,6 @@ pub enum CliError { #[error("Data directory could not be found")] DataDirNotFound, - #[error("offer: {0}")] - Offer(#[from] OfferError), - #[error("could not parse db column")] DbColumnParse(), diff --git a/src/cli/xchandles/continue_launch.rs b/src/cli/xchandles/continue_launch.rs index 5fb281a6..ea46925c 100644 --- a/src/cli/xchandles/continue_launch.rs +++ b/src/cli/xchandles/continue_launch.rs @@ -5,10 +5,9 @@ use chia::{ protocol::{Bytes32, SpendBundle}, puzzles::{cat::CatArgs, singleton::SingletonStruct, CoinProof, LineageProof}, }; -use chia_puzzle_types::offer::{NotarizedPayment, Payment}; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{CatLayer, Layer, Offer, Puzzle, SingleCatSpend, Spend, SpendContext}, + driver::{decode_offer, CatLayer, Layer, Offer, Puzzle, SingleCatSpend, Spend, SpendContext}, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::Address, }; @@ -16,12 +15,12 @@ use clvm_traits::clvm_quote; use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ - assets_xch_and_cat, assets_xch_only, get_last_onchain_timestamp, hex_string_to_bytes32, - load_xchandles_premine_csv, new_sk, no_assets, parse_amount, parse_one_sided_offer, - spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CatalogPrecommitValue, - CliError, Db, PrecommitCoin, PrecommitLayer, SageClient, XchandlesFactorPricingPuzzleArgs, - XchandlesPrecommitValue, XchandlesPremineRecord, XchandlesPricingSolution, - XchandlesRegisterAction, + assets_xch_and_cat, assets_xch_only, create_security_coin, get_last_onchain_timestamp, + hex_string_to_bytes32, load_xchandles_premine_csv, no_assets, parse_amount, + spend_security_coin, spend_settlement_cats, sync_xchandles, wait_for_coin, yes_no_prompt, + CatalogPrecommitValue, CliError, Db, PrecommitCoin, PrecommitLayer, SageClient, + XchandlesFactorPricingPuzzleArgs, XchandlesPrecommitValue, XchandlesPremineRecord, + XchandlesPricingSolution, XchandlesRegisterAction, }; fn precommit_value_for_handle( @@ -233,44 +232,27 @@ pub async fn xchandles_continue_launch( let cat_destination_puzzle_hash: Bytes32 = ctx.tree_hash(cat_destination_puzzle_ptr).into(); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - // Parse one-sided offer - let hint = ctx.hint(cat_destination_puzzle_hash)?; - let one_sided_offer = parse_one_sided_offer( + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; + let (created_cats, cat_assert) = spend_settlement_cats( &mut ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: launcher_id, - payments: vec![Payment::new( - cat_destination_puzzle_hash, - handles_payment_total, - hint, - )], - }), - None, + &offer, + payment_asset_id, + launcher_id, + vec![(cat_destination_puzzle_hash, handles_payment_total)], )?; - let Some(created_cat) = one_sided_offer.created_cat else { - eprintln!("No CAT was created in one-sided offer - aborting..."); - return Ok(()); - }; - one_sided_offer - .coin_spends - .into_iter() - .for_each(|cs| ctx.insert(cs)); - - let security_coin_conditions = one_sided_offer - .security_base_conditions + let created_cat = created_cats[0]; + let security_coin_conditions = cat_assert .assert_concurrent_spend(created_cat.coin.coin_id()) .reserve_fee(1); // Spend security coin let security_coin_sig = spend_security_coin( &mut ctx, - one_sided_offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -292,23 +274,20 @@ pub async fn xchandles_continue_launch( prev_coin_id: created_cat.coin.coin_id(), prev_subtotal: 0, extra_delta: 0, - inner_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), + p2_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), revoke: false, }, )?; // Build spend bundle - let sb = SpendBundle::new( - ctx.take(), - one_sided_offer.aggregated_signature + &security_coin_sig, - ); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, one_sided_offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); return Ok(()); @@ -476,12 +455,11 @@ pub async fn xchandles_continue_launch( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let mut security_coin_conditions = offer.security_base_conditions.reserve_fee(1); + let mut security_coin_conditions = Conditions::new().reserve_fee(1); for (i, precommit_value) in precommit_values.iter().enumerate() { let precommit_ph = precommit_puzzle_hashes[i]; @@ -535,7 +513,7 @@ pub async fn xchandles_continue_launch( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -545,13 +523,13 @@ pub async fn xchandles_continue_launch( }, )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/xchandles/expire.rs b/src/cli/xchandles/expire.rs index 259bf66f..4ac132a0 100644 --- a/src/cli/xchandles/expire.rs +++ b/src/cli/xchandles/expire.rs @@ -5,14 +5,14 @@ use chia::{ use chia_puzzle_types::{cat::CatArgs, singleton::SingletonStruct, LineageProof}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{CatLayer, DriverError, Layer, Offer, Puzzle, SpendContext}, + driver::{decode_offer, CatLayer, DriverError, Layer, Offer, Puzzle, SpendContext}, utils::Address, }; use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ - assets_xch_only, get_coinset_client, get_constants, get_last_onchain_timestamp, get_prefix, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_only, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, get_prefix, hex_string_to_bytes32, no_assets, parse_amount, quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, PrecommitCoin, PrecommitLayer, SageClient, Slot, XchandlesApiClient, XchandlesExpireAction, XchandlesExponentialPremiumRenewPuzzleArgs, @@ -293,11 +293,9 @@ pub async fn xchandles_expire( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = - parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let sec_conds = if refund { let slot: Option> = @@ -352,19 +350,19 @@ pub async fn xchandles_expire( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); return Ok(()); diff --git a/src/cli/xchandles/extend.rs b/src/cli/xchandles/extend.rs index a28f69a4..f85fe339 100644 --- a/src/cli/xchandles/extend.rs +++ b/src/cli/xchandles/extend.rs @@ -1,15 +1,15 @@ use chia::{clvm_utils::ToTreeHash, protocol::SpendBundle}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, }; use crate::{ - assets_xch_and_cat, get_coinset_client, get_constants, get_last_onchain_timestamp, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, - quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, - CliError, Db, DefaultCatMakerArgs, SageClient, XchandlesApiClient, XchandlesExtendAction, - XchandlesFactorPricingPuzzleArgs, + assets_xch_and_cat, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, hex_string_to_bytes32, no_assets, parse_amount, + quick_sync_xchandles, spend_security_coin, spend_settlement_cats, sync_xchandles, + wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, SageClient, + XchandlesApiClient, XchandlesExtendAction, XchandlesFactorPricingPuzzleArgs, }; #[allow(clippy::too_many_arguments)] @@ -113,35 +113,37 @@ pub async fn xchandles_extend( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer( + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; + + let (_cats, payment_assertion) = spend_settlement_cats( &mut ctx, - offer, - security_coin_sk.public_key(), - Some(notarized_payment), - None, + &offer, + payment_asset_id, + notarized_payment.nonce, + vec![( + notarized_payment.payments[0].puzzle_hash, + notarized_payment.payments[0].amount, + )], )?; - - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - let _new_registry = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds.extend(payment_assertion), &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/xchandles/initiate_launch.rs b/src/cli/xchandles/initiate_launch.rs index cb5ca47b..133b43bb 100644 --- a/src/cli/xchandles/initiate_launch.rs +++ b/src/cli/xchandles/initiate_launch.rs @@ -17,7 +17,7 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Cat, DriverError, Launcher, Offer, SpendContext}, + driver::{decode_offer, Cat, DriverError, Launcher, Offer, SpendContext}, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::Address, }; @@ -242,9 +242,10 @@ pub async fn xchandles_initiate_launch( let mut ctx = SpendContext::new(); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; let (sig, _, registry, slots, security_coin) = launch_xchandles_registry( &mut ctx, - Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?, + &offer, 1, registration_period, get_additional_info_for_launch, diff --git a/src/cli/xchandles/register.rs b/src/cli/xchandles/register.rs index d5edfff7..dbde8672 100644 --- a/src/cli/xchandles/register.rs +++ b/src/cli/xchandles/register.rs @@ -5,14 +5,14 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{CatLayer, DriverError, Layer, Offer, Puzzle, SpendContext}, + driver::{decode_offer, CatLayer, DriverError, Layer, Offer, Puzzle, SpendContext}, utils::Address, }; use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ - assets_xch_only, get_coinset_client, get_constants, get_last_onchain_timestamp, get_prefix, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_only, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, get_prefix, hex_string_to_bytes32, no_assets, parse_amount, print_spend_bundle_to_file, quick_sync_xchandles, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, PrecommitCoin, PrecommitLayer, SageClient, Slot, XchandlesApiClient, XchandlesExponentialPremiumRenewPuzzleArgs, @@ -254,11 +254,9 @@ pub async fn xchandles_register( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = - parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let sec_conds = if refund { let slot: Option> = if DefaultCatMakerArgs::curry_tree_hash( @@ -354,13 +352,13 @@ pub async fn xchandles_register( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); if log { @@ -373,7 +371,7 @@ pub async fn xchandles_register( let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); return Ok(()); diff --git a/src/cli/xchandles/unroll_state_scheduler.rs b/src/cli/xchandles/unroll_state_scheduler.rs index f34364c6..7f515b2b 100644 --- a/src/cli/xchandles/unroll_state_scheduler.rs +++ b/src/cli/xchandles/unroll_state_scheduler.rs @@ -1,13 +1,13 @@ use chia::{clvm_utils::ToTreeHash, protocol::SpendBundle}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, - types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, + driver::{decode_offer, Offer, SpendContext}, + types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; use crate::{ - assets_xch_only, get_coinset_client, hex_string_to_bytes32, load_xchandles_state_schedule_csv, - new_sk, no_assets, parse_amount, parse_one_sided_offer, quick_sync_xchandles, + assets_xch_only, create_security_coin, get_coinset_client, hex_string_to_bytes32, + load_xchandles_state_schedule_csv, no_assets, parse_amount, quick_sync_xchandles, spend_security_coin, sync_multisig_singleton, sync_xchandles, wait_for_coin, yes_no_prompt, CliError, Db, DefaultCatMakerArgs, DelegatedStateAction, MultisigSingleton, SageClient, XchandlesExponentialPremiumRenewPuzzleArgs, XchandlesFactorPricingPuzzleArgs, @@ -134,20 +134,17 @@ pub async fn xchandles_unroll_state_scheduler( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let security_coin_conditions = offer - .security_base_conditions + let security_coin_conditions = Conditions::new() .assert_concurrent_spend(state_scheduler.coin.coin_id()) .reserve_fee(1); let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -159,14 +156,14 @@ pub async fn xchandles_unroll_state_scheduler( state_scheduler.spend(&mut ctx, registry_inner_ph.into())?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/xchandles/update.rs b/src/cli/xchandles/update.rs index 387a9190..96f85580 100644 --- a/src/cli/xchandles/update.rs +++ b/src/cli/xchandles/update.rs @@ -2,23 +2,21 @@ use chia::{ clvm_utils::ToTreeHash, protocol::{Bytes32, SpendBundle}, }; -use chia_puzzle_types::{ - offer::{NotarizedPayment, Payment}, - standard::StandardArgs, -}; +use chia_puzzle_types::standard::StandardArgs; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, Spend, SpendContext, StandardLayer}, + driver::{decode_offer, Offer, Spend, SpendContext, StandardLayer}, utils::Address, }; use clvm_traits::clvm_quote; use clvmr::NodePtr; use crate::{ - assets_xch_and_nft, get_coinset_client, get_constants, hex_string_to_bytes32, new_sk, - no_assets, parse_amount, parse_one_sided_offer, quick_sync_xchandles, - sign_standard_transaction, spend_security_coin, sync_xchandles, wait_for_coin, yes_no_prompt, - CliError, Db, SageClient, XchandlesApiClient, XchandlesSlotValue, XchandlesUpdateAction, + assets_xch_and_nft, create_security_coin, get_coinset_client, get_constants, + hex_string_to_bytes32, no_assets, parse_amount, quick_sync_xchandles, + sign_standard_transaction, spend_security_coin, spend_settlement_nft, sync_xchandles, + wait_for_coin, yes_no_prompt, CliError, Db, SageClient, XchandlesApiClient, XchandlesSlotValue, + XchandlesUpdateAction, }; fn encode_nft(nft_launcher_id: Bytes32) -> Result { @@ -123,26 +121,19 @@ pub async fn xchandles_update( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let pk = security_coin_sk.public_key(); let nft_inner_ph: Bytes32 = StandardArgs::curry_tree_hash(pk).into(); - let hint = ctx.hint(nft_inner_ph)?; - let offer = parse_one_sided_offer( + let (nft, security_conds) = spend_settlement_nft( &mut ctx, - offer, - security_coin_sk.public_key(), - None, - Some(NotarizedPayment { - nonce: registry.coin.coin_id(), - payments: vec![Payment::new(nft_inner_ph, 1, hint)], - }), + &offer, + slot.info.value.owner_launcher_id, + registry.coin.coin_id(), + nft_inner_ph, )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let nft = offer.created_nft.unwrap(); - let nft_inner_conds = registry.new_action::().spend( &mut ctx, &mut registry, @@ -171,22 +162,19 @@ pub async fn xchandles_update( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions, + security_coin, + security_conds, &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new( - ctx.take(), - offer.aggregated_signature + &security_coin_sig + &nft_sig, - ); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig + &nft_sig)); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/drivers.rs b/src/drivers.rs index 26fe2a52..04556dda 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -380,7 +380,7 @@ pub fn launch_catalog_registry( #[allow(clippy::type_complexity)] pub fn launch_xchandles_registry( ctx: &mut SpendContext, - offer: Offer, + offer: &Offer, initial_base_registration_price: u64, initial_registration_period: u64, // (registry launcher id, security coin, additional_args) -> (additional conditions, registry constants, initial_registration_asset_id) @@ -518,11 +518,6 @@ pub fn spend_settlement_cats( offer_ann_message, )); - let created_cats = payments - .iter() - .map(|(puzzle_hash, amount)| settlement_cats[0].child(*puzzle_hash, *amount)) - .collect(); - let mut cat_spends = Vec::with_capacity(settlement_cats.len()); for (i, cat) in settlement_cats.into_iter().enumerate() { cat_spends.push(CatSpend { @@ -538,11 +533,57 @@ pub fn spend_settlement_cats( hidden: false, }); } - Cat::spend_all(ctx, &cat_spends)?; + let created_cats = Cat::spend_all(ctx, &cat_spends)?; Ok((created_cats, security_coin_conditions)) } +pub fn spend_settlement_nft( + ctx: &mut SpendContext, + offer: &Offer, + nft_launcher_id: Bytes32, + nonce: Bytes32, + destination_puzzle_hash: Bytes32, +) -> Result<(Nft, Conditions), DriverError> { + let settlement_nft = + offer + .offered_coins() + .nfts + .get(&nft_launcher_id) + .ok_or(DriverError::Custom( + "Could not find required NFT in offer".to_string(), + ))?; + + let notarized_payment = NotarizedPayment { + nonce, + payments: vec![Payment::new( + destination_puzzle_hash, + 1, + ctx.hint(destination_puzzle_hash)?, + )], + }; + + let offer_ann_message = ctx.alloc(¬arized_payment)?; + let offer_ann_message: Bytes32 = ctx.tree_hash(offer_ann_message).into(); + + let settlement_inner_solution = ctx.alloc(&SettlementPaymentsSolution { + notarized_payments: vec![notarized_payment], + })?; + let settlement_inner_puzzle = ctx.alloc_mod::()?; + + let security_coin_conditions = Conditions::new().assert_puzzle_announcement(announcement_id( + settlement_nft.coin.puzzle_hash, + offer_ann_message, + )); + + let created_nft = settlement_nft.spend( + ctx, + Spend::new(settlement_inner_puzzle, settlement_inner_solution), + )?; + + Ok((created_nft, security_coin_conditions)) +} + #[allow(clippy::type_complexity)] pub fn launch_dig_reward_distributor( ctx: &mut SpendContext, @@ -1005,17 +1046,18 @@ mod tests { let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; + let agg_sig = sign_standard_transaction( + ctx, + offer_src_coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?; let offer = Offer::from_spend_bundle( ctx, &SpendBundle { coin_spends: vec![CoinSpend::new(offer_src_coin, puzzle_reveal, solution)], - aggregated_signature: sign_standard_transaction( - ctx, - offer_src_coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, + aggregated_signature: agg_sig, }, )?; @@ -1497,17 +1539,18 @@ mod tests { let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; + let agg_sig = sign_standard_transaction( + ctx, + launcher_bls.coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?; let offer = Offer::from_spend_bundle( ctx, &SpendBundle { coin_spends: vec![CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution)], - aggregated_signature: sign_standard_transaction( - ctx, - launcher_bls.coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, + aggregated_signature: agg_sig, }, )?; @@ -1542,7 +1585,7 @@ mod tests { let (_, security_sk, mut registry, slots_returned_by_launch, _security_coin) = launch_xchandles_registry( ctx, - offer, + &offer, initial_registration_price, reg_period, |_ctx, _launcher_id, _coin, (xchandles_constants, payment_cat_asset_id)| { @@ -2460,6 +2503,13 @@ mod tests { } } + let agg_sig = sign_standard_transaction( + ctx, + launcher_bls.coin, + offer_spend, + &launcher_bls.sk, + &TESTNET11_CONSTANTS, + )?; let offer = Offer::from_spend_bundle( ctx, &SpendBundle { @@ -2467,13 +2517,7 @@ mod tests { CoinSpend::new(launcher_bls.coin, puzzle_reveal, solution), cat_offer_spend, ], - aggregated_signature: sign_standard_transaction( - ctx, - launcher_bls.coin, - offer_spend, - &launcher_bls.sk, - &TESTNET11_CONSTANTS, - )?, + aggregated_signature: agg_sig, }, )?; diff --git a/src/layers/actions/reward_distributor/stake.rs b/src/layers/actions/reward_distributor/stake.rs index 697e8a6c..dc0c2cff 100644 --- a/src/layers/actions/reward_distributor/stake.rs +++ b/src/layers/actions/reward_distributor/stake.rs @@ -10,7 +10,7 @@ use chia_puzzle_types::{ }; use chia_puzzles::{NFT_OWNERSHIP_LAYER_HASH, NFT_STATE_LAYER_HASH, SETTLEMENT_PAYMENT_HASH}; use chia_wallet_sdk::{ - driver::{DriverError, HashedPtr, Nft, Spend, SpendContext}, + driver::{Asset, DriverError, HashedPtr, Nft, Spend, SpendContext}, types::{announcement_id, Conditions}, }; use clvm_traits::{clvm_tuple, FromClvm, ToClvm}; @@ -118,6 +118,7 @@ impl RewardDistributorStakeAction { SETTLEMENT_PAYMENT_HASH.into(), None, current_nft.info.metadata, + current_nft.amount(), ); let action_solution = ctx.alloc(&RewardDistributorStakeActionSolution { my_id, @@ -146,7 +147,7 @@ impl RewardDistributorStakeAction { Conditions::new() .assert_puzzle_announcement(announcement_id(nft.coin.puzzle_hash, msg)), notarized_payment, - nft.child(payment_puzzle_hash, None, nft.info.metadata), + nft.child(payment_puzzle_hash, None, nft.info.metadata, nft.amount()), )) } } From 594a2625cda6b3927e51a9e7801128e499c9671d Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 19:54:23 +0300 Subject: [PATCH 51/65] update CATalog --- src/cli/catalog/continue_launch.rs | 75 +++++++++-------------- src/cli/catalog/initiate_launch.rs | 5 +- src/cli/catalog/register.rs | 22 +++---- src/cli/catalog/unroll_state_scheduler.rs | 23 +++---- src/drivers.rs | 4 +- 5 files changed, 55 insertions(+), 74 deletions(-) diff --git a/src/cli/catalog/continue_launch.rs b/src/cli/catalog/continue_launch.rs index 374691a4..92ddde72 100644 --- a/src/cli/catalog/continue_launch.rs +++ b/src/cli/catalog/continue_launch.rs @@ -5,21 +5,23 @@ use chia::{ protocol::{Bytes32, SpendBundle}, puzzles::{cat::CatArgs, singleton::SingletonStruct, CoinProof, LineageProof}, }; -use chia_puzzle_types::offer::{NotarizedPayment, Payment}; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{CatLayer, DriverError, Layer, Offer, Puzzle, SingleCatSpend, Spend, SpendContext}, + driver::{ + decode_offer, CatLayer, DriverError, Layer, Offer, Puzzle, SingleCatSpend, Spend, + SpendContext, + }, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; use clvm_traits::clvm_quote; use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ - assets_xch_and_cat, assets_xch_only, hex_string_to_bytes32, load_catalog_premine_csv, new_sk, - no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_catalog, - wait_for_coin, yes_no_prompt, CatNftMetadata, CatalogPrecommitValue, CatalogPremineRecord, - CatalogRegisterAction, CatalogRegistryConstants, CliError, Db, PrecommitCoin, PrecommitLayer, - SageClient, + assets_xch_and_cat, assets_xch_only, create_security_coin, hex_string_to_bytes32, + load_catalog_premine_csv, no_assets, parse_amount, spend_security_coin, spend_settlement_cats, + sync_catalog, wait_for_coin, yes_no_prompt, CatNftMetadata, CatalogPrecommitValue, + CatalogPremineRecord, CatalogRegisterAction, CatalogRegistryConstants, CliError, Db, + PrecommitCoin, PrecommitLayer, SageClient, }; pub fn initial_cat_inner_puzzle_ptr( @@ -226,40 +228,27 @@ pub async fn catalog_continue_launch( let cat_destination_puzzle_hash: Bytes32 = ctx.tree_hash(cat_destination_puzzle_ptr).into(); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - // Parse one-sided offer - let hint = ctx.hint(cat_destination_puzzle_hash)?; - let one_sided_offer = parse_one_sided_offer( + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; + let (created_cats, cat_assert) = spend_settlement_cats( &mut ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: constants.launcher_id, - payments: vec![Payment::new(cat_destination_puzzle_hash, cat_amount, hint)], - }), - None, + &offer, + payment_asset_id, + constants.launcher_id, + vec![(cat_destination_puzzle_hash, cat_amount)], )?; - let Some(created_cat) = one_sided_offer.created_cat else { - eprintln!("No CAT was created in one-sided offer - aborting..."); - return Ok(()); - }; - one_sided_offer - .coin_spends - .into_iter() - .for_each(|cs| ctx.insert(cs)); - - let security_coin_conditions = one_sided_offer - .security_base_conditions + let created_cat = created_cats[0]; + let security_coin_conditions = cat_assert .assert_concurrent_spend(created_cat.coin.coin_id()) .reserve_fee(1); // Spend security coin let security_coin_sig = spend_security_coin( &mut ctx, - one_sided_offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -281,23 +270,20 @@ pub async fn catalog_continue_launch( prev_coin_id: created_cat.coin.coin_id(), prev_subtotal: 0, extra_delta: 0, - inner_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), + p2_spend: Spend::new(cat_destination_puzzle_ptr, NodePtr::NIL), revoke: false, }, )?; // Build spend bundle - let sb = SpendBundle::new( - ctx.take(), - one_sided_offer.aggregated_signature + &security_coin_sig, - ); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, one_sided_offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); return Ok(()); @@ -462,12 +448,11 @@ pub async fn catalog_continue_launch( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let mut security_coin_conditions = offer.security_base_conditions; + let mut security_coin_conditions = Conditions::new(); for (i, precommit_value) in precommit_values.iter().enumerate() { let precommit_ph = precommit_puzzle_hashes[i]; @@ -525,7 +510,7 @@ pub async fn catalog_continue_launch( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -535,13 +520,13 @@ pub async fn catalog_continue_launch( }, )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/catalog/initiate_launch.rs b/src/cli/catalog/initiate_launch.rs index db9115a0..4fe50e4b 100644 --- a/src/cli/catalog/initiate_launch.rs +++ b/src/cli/catalog/initiate_launch.rs @@ -18,7 +18,7 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Cat, DriverError, Launcher, Offer, SpendContext}, + driver::{decode_offer, Cat, DriverError, Launcher, Offer, SpendContext}, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, utils::Address, }; @@ -232,9 +232,10 @@ pub async fn catalog_initiate_launch( let mut ctx = SpendContext::new(); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; let (sig, _, _registry, slots, security_coin) = launch_catalog_registry( &mut ctx, - Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?, + &offer, 1, get_additional_info_for_launch, if testnet11 { diff --git a/src/cli/catalog/register.rs b/src/cli/catalog/register.rs index c577b361..9a52d753 100644 --- a/src/cli/catalog/register.rs +++ b/src/cli/catalog/register.rs @@ -5,14 +5,14 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{CatLayer, Layer, Offer, Puzzle, Spend, SpendContext}, + driver::{decode_offer, CatLayer, Layer, Offer, Puzzle, Spend, SpendContext}, utils::Address, }; use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ - assets_xch_only, get_coinset_client, get_constants, get_prefix, hex_string_to_bytes, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_only, create_security_coin, get_coinset_client, get_constants, get_prefix, + hex_string_to_bytes, hex_string_to_bytes32, no_assets, parse_amount, print_spend_bundle_to_file, quick_sync_catalog, spend_security_coin, sync_catalog, wait_for_coin, yes_no_prompt, CatNftMetadata, CatalogApiClient, CatalogPrecommitValue, CatalogRefundAction, CatalogRegisterAction, CatalogRegistryConstants, CatalogSlotValue, @@ -278,11 +278,9 @@ pub async fn catalog_register( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = - parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let sec_conds = if refund { let slot: Option> = if DefaultCatMakerArgs::curry_tree_hash( @@ -387,13 +385,13 @@ pub async fn catalog_register( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); if log { @@ -406,7 +404,7 @@ pub async fn catalog_register( let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); return Ok(()); diff --git a/src/cli/catalog/unroll_state_scheduler.rs b/src/cli/catalog/unroll_state_scheduler.rs index 5534149a..0059cd4a 100644 --- a/src/cli/catalog/unroll_state_scheduler.rs +++ b/src/cli/catalog/unroll_state_scheduler.rs @@ -1,12 +1,12 @@ use chia::protocol::{Bytes32, SpendBundle}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, - types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, + driver::{decode_offer, Offer, SpendContext}, + types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; use crate::{ - assets_xch_only, get_coinset_client, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_only, create_security_coin, get_coinset_client, no_assets, parse_amount, spend_security_coin, sync_multisig_singleton, wait_for_coin, yes_no_prompt, CatalogRegistryConstants, CatalogRegistryState, CliError, Db, DelegatedStateAction, MultisigSingleton, SageClient, @@ -99,20 +99,17 @@ pub async fn catalog_unroll_state_scheduler( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let security_coin_conditions = offer - .security_base_conditions + let security_coin_conditions = Conditions::new() .assert_concurrent_spend(state_scheduler.coin.coin_id()) .reserve_fee(1); let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -124,14 +121,14 @@ pub async fn catalog_unroll_state_scheduler( state_scheduler.spend(&mut ctx, catalog_inner_ph.into())?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&cli, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&cli, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/drivers.rs b/src/drivers.rs index 04556dda..67bdb096 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -276,7 +276,7 @@ pub fn create_security_coin( #[allow(clippy::type_complexity)] pub fn launch_catalog_registry( ctx: &mut SpendContext, - offer: Offer, + offer: &Offer, initial_registration_price: u64, // (registry launcher id, security coin, additional_args) -> (additional conditions, registry constants, initial_registration_asset_id) get_additional_info: fn( @@ -1089,7 +1089,7 @@ mod tests { // Launch catalog let (_, security_sk, mut catalog, slots, _security_coin) = launch_catalog_registry( ctx, - offer, + &offer, initial_registration_price, |_ctx, _launcher_id, _coin, (catalog_constants, initial_registration_asset_id)| { Ok(( From dbe226ef32f15baa375421a85e1ecb29ed6e48fe Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 20:07:31 +0300 Subject: [PATCH 52/65] checkpoint - I like that the intermediary CATs can be removed --- src/cli/multisig/broadcast_thing.rs | 27 ++++---- src/cli/multisig/launch.rs | 23 ++++--- src/cli/reward_distributor/add_rewards.rs | 61 ++++++++----------- .../reward_distributor/clawback_rewards.rs | 32 +++++----- src/cli/reward_distributor/commit_rewards.rs | 58 +++++++----------- 5 files changed, 86 insertions(+), 115 deletions(-) diff --git a/src/cli/multisig/broadcast_thing.rs b/src/cli/multisig/broadcast_thing.rs index 86f869ae..e2e07fe0 100644 --- a/src/cli/multisig/broadcast_thing.rs +++ b/src/cli/multisig/broadcast_thing.rs @@ -4,13 +4,13 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; use crate::{ - assets_xch_only, get_coinset_client, hex_string_to_bytes32, hex_string_to_signature, new_sk, - no_assets, parse_amount, parse_one_sided_offer, print_medieval_vault_configuration, + assets_xch_only, create_security_coin, get_coinset_client, hex_string_to_bytes32, + hex_string_to_signature, no_assets, parse_amount, print_medieval_vault_configuration, spend_security_coin, sync_multisig_singleton, wait_for_coin, yes_no_prompt, CliError, MedievalVault, MultisigSingleton, SageClient, StateSchedulerHintedState, }; @@ -101,21 +101,18 @@ pub async fn multisig_broadcast_thing_finish( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(ctx, offer.offered_coins().xch[0])?; - let mut conditions = offer - .security_base_conditions - .assert_concurrent_spend(medieval_vault_coin_id); + let mut conditions = Conditions::new().assert_concurrent_spend(medieval_vault_coin_id); if let Some(additional_security_conditions) = additional_security_conditions { conditions = conditions.extend(additional_security_conditions); } let security_coin_sig = spend_security_coin( ctx, - offer.security_coin, + security_coin, conditions, &security_coin_sk, if testnet11 { @@ -125,16 +122,16 @@ pub async fn multisig_broadcast_thing_finish( }, )?; - let sb = SpendBundle::new( + let sb = offer.take(SpendBundle::new( ctx.take(), - offer.aggregated_signature + &security_coin_sig + &signature_from_signers, - ); + security_coin_sig + &signature_from_signers, + )); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/multisig/launch.rs b/src/cli/multisig/launch.rs index bce4a1a1..4cc9ce70 100644 --- a/src/cli/multisig/launch.rs +++ b/src/cli/multisig/launch.rs @@ -1,12 +1,12 @@ use chia::{bls::PublicKey, protocol::SpendBundle}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Launcher, Offer, SpendContext}, + driver::{decode_offer, Launcher, Offer, SpendContext}, }; use crate::{ - assets_xch_only, get_coinset_client, get_constants, new_sk, no_assets, parse_amount, - parse_one_sided_offer, print_medieval_vault_configuration, spend_security_coin, wait_for_coin, + assets_xch_only, create_security_coin, get_coinset_client, get_constants, no_assets, + parse_amount, print_medieval_vault_configuration, spend_security_coin, wait_for_coin, yes_no_prompt, CliError, MedievalVaultHint, P2MOfNDelegateDirectArgs, SageClient, }; @@ -46,12 +46,11 @@ pub async fn multisig_launch( println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let launcher = Launcher::new(offer.security_coin.coin_id(), 1); + let launcher = Launcher::new(security_coin.coin_id(), 1); let launcher_coin = launcher.coin(); let launch_hints = MedievalVaultHint { my_launcher_id: launcher_coin.coin_id(), @@ -71,13 +70,13 @@ pub async fn multisig_launch( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(create_conditions), + security_coin, + create_conditions, &security_coin_sk, get_constants(testnet11), )?; - let sb = SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -85,7 +84,7 @@ pub async fn multisig_launch( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/add_rewards.rs b/src/cli/reward_distributor/add_rewards.rs index 62633cce..54da62b7 100644 --- a/src/cli/reward_distributor/add_rewards.rs +++ b/src/cli/reward_distributor/add_rewards.rs @@ -1,15 +1,14 @@ -use chia::protocol::{Bytes32, SpendBundle}; -use chia_puzzle_types::offer::{NotarizedPayment, Payment}; +use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{CatSpend, Offer, Spend, SpendContext}, - types::Conditions, + driver::{decode_offer, CatSpend, Offer, Spend, SpendContext}, + types::{puzzles::SettlementPayment, Conditions}, }; use clvmr::NodePtr; use crate::{ - assets_xch_and_cat, get_coinset_client, get_constants, get_last_onchain_timestamp, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_and_cat, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, hex_string_to_bytes32, no_assets, parse_amount, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorAddIncentivesAction, RewardDistributorSyncAction, SageClient, }; @@ -72,27 +71,9 @@ pub async fn reward_distributor_add_rewards( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let cat_destination_inner_puzzle = ctx.alloc(&(1, ()))?; - let cat_destination_inner_puzzle_hash: Bytes32 = - ctx.tree_hash(cat_destination_inner_puzzle).into(); - let hint = ctx.hint(cat_destination_inner_puzzle_hash)?; - let offer = parse_one_sided_offer( - &mut ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: launcher_id, - payments: vec![Payment::new( - cat_destination_inner_puzzle_hash, - reward_amount, - hint, - )], - }), - None, - )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let mut sec_conds = if also_sync { distributor @@ -107,26 +88,34 @@ pub async fn reward_distributor_add_rewards( .new_action::() .spend(&mut ctx, &mut distributor, reward_amount)?, ); + + let settlement_cat = offer + .offered_coins() + .cats + .get(&distributor.info.constants.reserve_asset_id) + .ok_or(CliError::Custom( + "Reward CAT not found in offer".to_string(), + ))?[0]; + let offer_puzzle = ctx.alloc_mod::()?; + let _new_distributor = distributor.finish_spend( &mut ctx, vec![CatSpend { - cat: offer.created_cat.unwrap(), - inner_spend: Spend::new(cat_destination_inner_puzzle, NodePtr::NIL), - extra_delta: 0, - revoke: false, + cat: settlement_cat, + spend: Spend::new(offer_puzzle, NodePtr::NIL), + hidden: false, }], )?; let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -134,7 +123,7 @@ pub async fn reward_distributor_add_rewards( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index b85b7aef..ae496846 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -2,16 +2,17 @@ use chia::protocol::{Coin, SpendBundle}; use chia_puzzle_types::Memos; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, Spend, SpendContext, StandardLayer}, + driver::{decode_offer, Offer, Spend, SpendContext, StandardLayer}, + types::Conditions, utils::Address, }; use clvm_traits::clvm_quote; use clvmr::NodePtr; use crate::{ - assets_xch_only, find_commitment_slots, find_reward_slot, get_coin_public_key, - get_coinset_client, get_constants, hex_string_to_bytes32, hex_string_to_signature, new_sk, - no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, spend_to_coin_spend, + assets_xch_only, create_security_coin, find_commitment_slots, find_reward_slot, + get_coin_public_key, get_coinset_client, get_constants, hex_string_to_bytes32, + hex_string_to_signature, no_assets, parse_amount, spend_security_coin, spend_to_coin_spend, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorWithdrawIncentivesAction, SageClient, }; @@ -78,10 +79,9 @@ pub async fn reward_distributor_clawback_rewards( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let (send_message_conds, returned_amount) = distributor .new_action::() @@ -92,17 +92,15 @@ pub async fn reward_distributor_clawback_rewards( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer - .security_base_conditions - .create_coin(clawback_ph, 0, Memos::None), + security_coin, + Conditions::new().create_coin(clawback_ph, 0, Memos::None), &security_coin_sk, get_constants(testnet11), )?; println!("Fetching clawback public key..."); let wallet_pk = get_coin_public_key(&sage, &clawback_address, 10000).await?; - let message_coin = Coin::new(offer.security_coin.coin_id(), clawback_ph, 0); + let message_coin = Coin::new(security_coin.coin_id(), clawback_ph, 0); let p2 = StandardLayer::new(wallet_pk); let inner_spend = Spend::new(ctx.alloc(&clvm_quote!(send_message_conds))?, NodePtr::NIL); let spend = p2.delegated_inner_spend(&mut ctx, inner_spend)?; @@ -125,10 +123,10 @@ pub async fn reward_distributor_clawback_rewards( let message_sig = hex_string_to_signature(&resp.spend_bundle.aggregated_signature)?; - let spend_bundle = SpendBundle::new( + let spend_bundle = offer.take(SpendBundle::new( ctx.take(), - offer.aggregated_signature + &security_coin_sig + &message_sig, - ); + security_coin_sig + &message_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -136,7 +134,7 @@ pub async fn reward_distributor_clawback_rewards( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index 0f43eac9..c8e04d9c 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -1,15 +1,15 @@ -use chia::protocol::{Bytes32, SpendBundle}; -use chia_puzzle_types::offer::{NotarizedPayment, Payment}; +use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{CatSpend, Offer, Spend, SpendContext}, + driver::{decode_offer, CatSpend, Offer, Spend, SpendContext}, + types::puzzles::SettlementPayment, utils::Address, }; use clvmr::NodePtr; use crate::{ - assets_xch_and_cat, find_reward_slot, get_coinset_client, get_constants, hex_string_to_bytes32, - new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, + assets_xch_and_cat, create_security_coin, find_reward_slot, get_coinset_client, get_constants, + hex_string_to_bytes32, no_assets, parse_amount, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorCommitIncentivesAction, SageClient, }; @@ -61,27 +61,9 @@ pub async fn reward_distributor_commit_rewards( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let cat_destination_inner_puzzle = ctx.alloc(&(1, ()))?; - let cat_destination_inner_puzzle_hash: Bytes32 = - ctx.tree_hash(cat_destination_inner_puzzle).into(); - let hint = ctx.hint(cat_destination_inner_puzzle_hash)?; - let offer = parse_one_sided_offer( - &mut ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: launcher_id, - payments: vec![Payment::new( - cat_destination_inner_puzzle_hash, - reward_amount, - hint, - )], - }), - None, - )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let reward_slot = find_reward_slot(&mut ctx, &client, distributor.info.constants, epoch_start).await?; @@ -96,26 +78,32 @@ pub async fn reward_distributor_commit_rewards( clawback_ph, reward_amount, )?; + let settlement_cat = offer + .offered_coins() + .cats + .get(&distributor.info.constants.reserve_asset_id) + .ok_or(CliError::Custom( + "Reward CAT not found in offer".to_string(), + ))?[0]; + let offer_puzzle = ctx.alloc_mod::()?; let _new_distributor = distributor.finish_spend( &mut ctx, vec![CatSpend { - cat: offer.created_cat.unwrap(), - inner_spend: Spend::new(cat_destination_inner_puzzle, NodePtr::NIL), - extra_delta: 0, - revoke: false, + cat: settlement_cat, + spend: Spend::new(offer_puzzle, NodePtr::NIL), + hidden: false, }], )?; let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -123,7 +111,7 @@ pub async fn reward_distributor_commit_rewards( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) From d5b2604fb9c3d530e6e38542a116b42cec8f53e9 Mon Sep 17 00:00:00 2001 From: Yak Date: Sun, 29 Jun 2025 20:20:45 +0300 Subject: [PATCH 53/65] enough for today --- src/cli/reward_distributor/initiate_payout.rs | 26 +++--- src/cli/reward_distributor/launch.rs | 5 +- src/cli/reward_distributor/new_epoch.rs | 22 +++-- src/cli/reward_distributor/stake.rs | 83 ++++++------------- src/cli/reward_distributor/sync.rs | 22 +++-- src/cli/reward_distributor/unstake.rs | 64 ++++++++++---- src/cli/verifications/broadcast_launch.rs | 2 +- src/drivers.rs | 4 +- 8 files changed, 108 insertions(+), 120 deletions(-) diff --git a/src/cli/reward_distributor/initiate_payout.rs b/src/cli/reward_distributor/initiate_payout.rs index 6c9283c4..cee3ae21 100644 --- a/src/cli/reward_distributor/initiate_payout.rs +++ b/src/cli/reward_distributor/initiate_payout.rs @@ -1,15 +1,15 @@ use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, types::Conditions, }; use crate::{ - assets_xch_only, find_entry_slots, get_coinset_client, get_constants, - get_last_onchain_timestamp, hex_string_to_bytes32, new_sk, no_assets, parse_amount, - parse_one_sided_offer, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, - CliError, Db, RewardDistributorInitiatePayoutAction, RewardDistributorSyncAction, SageClient, + assets_xch_only, create_security_coin, find_entry_slots, get_coinset_client, get_constants, + get_last_onchain_timestamp, hex_string_to_bytes32, no_assets, parse_amount, + spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, + RewardDistributorInitiatePayoutAction, RewardDistributorSyncAction, SageClient, }; pub async fn reward_distributor_initiate_payout( @@ -71,10 +71,9 @@ pub async fn reward_distributor_initiate_payout( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let mut sec_conds = if also_sync { distributor @@ -94,14 +93,13 @@ pub async fn reward_distributor_initiate_payout( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -109,7 +107,7 @@ pub async fn reward_distributor_initiate_payout( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/launch.rs b/src/cli/reward_distributor/launch.rs index 4f94421d..2e6f2ac5 100644 --- a/src/cli/reward_distributor/launch.rs +++ b/src/cli/reward_distributor/launch.rs @@ -1,7 +1,7 @@ use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, utils::Address, }; @@ -82,9 +82,10 @@ pub async fn reward_distributor_launch( let mut ctx = SpendContext::new(); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; let (sig, _sk, reward_distributor, _slot) = launch_dig_reward_distributor( &mut ctx, - Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?, + &offer, first_epoch_start_timestamp, user_puzzle_hash, RewardDistributorConstants::without_launcher_id( diff --git a/src/cli/reward_distributor/new_epoch.rs b/src/cli/reward_distributor/new_epoch.rs index 4edc4b79..9cd2cb2e 100644 --- a/src/cli/reward_distributor/new_epoch.rs +++ b/src/cli/reward_distributor/new_epoch.rs @@ -1,13 +1,13 @@ use crate::{ - assets_xch_only, find_reward_slot, get_coinset_client, get_constants, hex_string_to_bytes32, - new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, sync_distributor, + assets_xch_only, create_security_coin, find_reward_slot, get_coinset_client, get_constants, + hex_string_to_bytes32, no_assets, parse_amount, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorNewEpochAction, RewardDistributorSyncAction, SageClient, }; use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, }; pub async fn reward_distributor_new_epoch( @@ -61,10 +61,9 @@ pub async fn reward_distributor_new_epoch( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let (sec_conds, fee) = distributor .new_action::() @@ -75,14 +74,13 @@ pub async fn reward_distributor_new_epoch( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -90,7 +88,7 @@ pub async fn reward_distributor_new_epoch( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/stake.rs b/src/cli/reward_distributor/stake.rs index cb9b2784..22b07212 100644 --- a/src/cli/reward_distributor/stake.rs +++ b/src/cli/reward_distributor/stake.rs @@ -2,18 +2,17 @@ use chia::protocol::SpendBundle; use chia_puzzle_types::{standard::StandardArgs, LineageProof}; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{HashedPtr, Layer, Nft, Offer, Puzzle, SingletonLayer, SpendContext}, + driver::{decode_offer, HashedPtr, Layer, Offer, Puzzle, SingletonLayer, SpendContext}, types::Conditions, utils::Address, }; -use clvmr::NodePtr; use crate::{ - assets_xch_and_nft, get_coinset_client, get_constants, get_last_onchain_timestamp, get_prefix, - hex_string_to_bytes32, hex_string_to_pubkey, new_sk, no_assets, parse_amount, - parse_one_sided_offer, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, - CliError, Db, IntermediaryCoinProof, NftLauncherProof, RewardDistributorStakeAction, - RewardDistributorSyncAction, SageClient, + assets_xch_and_nft, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, get_prefix, hex_string_to_bytes32, hex_string_to_pubkey, no_assets, + parse_amount, spend_security_coin, spend_settlement_nft, sync_distributor, wait_for_coin, + yes_no_prompt, CliError, Db, IntermediaryCoinProof, NftLauncherProof, + RewardDistributorStakeAction, RewardDistributorSyncAction, SageClient, }; pub async fn reward_distributor_stake( @@ -142,8 +141,9 @@ pub async fn reward_distributor_stake( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let sec_conds = if also_sync { distributor @@ -154,41 +154,11 @@ pub async fn reward_distributor_stake( }; // find NFT - let mut current_nft = None; - for coin_spend in offer.clone().parse(&mut ctx)?.coin_spends { - let puzzle_ptr = ctx.alloc(&coin_spend.puzzle_reveal)?; - let puzzle = Puzzle::parse(&ctx, puzzle_ptr); - if let Ok(Some(layer)) = SingletonLayer::::parse_puzzle(&ctx, puzzle) { - if layer.launcher_id != nft_launcher_id { - continue; - } - - let parent_record = client - .get_coin_record_by_name(coin_spend.coin.parent_coin_info) - .await? - .coin_record - .ok_or(CliError::CoinNotFound(coin_spend.coin.parent_coin_info))?; - let parent_coin_spend = client - .get_puzzle_and_solution( - coin_spend.coin.parent_coin_info, - Some(parent_record.spent_block_index), - ) - .await? - .coin_solution - .ok_or(CliError::CoinNotSpent(coin_spend.coin.parent_coin_info))?; - - let parent_puzzle = ctx.alloc(&parent_coin_spend.puzzle_reveal)?; - let parent_puzzle = Puzzle::parse(&ctx, parent_puzzle); - let parent_solution = ctx.alloc(&parent_coin_spend.solution)?; - current_nft = Nft::parse_child( - &mut ctx, - parent_coin_spend.coin, - parent_puzzle, - parent_solution, - )?; - break; - } - } + let current_nft = offer + .offered_coins() + .nfts + .get(&nft_launcher_id) + .ok_or(CliError::Custom("NFT not found in offer".to_string()))?; // accept offer let (conds, notarized_payment, _locked_nft) = distributor @@ -196,33 +166,28 @@ pub async fn reward_distributor_stake( .spend( &mut ctx, &mut distributor, - current_nft.unwrap(), + current_nft.clone(), nft_launcher_proof, custody_puzzle_hash, )?; - let offer = parse_one_sided_offer( + let (_new_nft, nft_assert) = spend_settlement_nft( &mut ctx, - offer, - security_coin_sk.public_key(), - None, - Some(notarized_payment), + &offer, + nft_launcher_id, + notarized_payment.nonce, + notarized_payment.payments[0].puzzle_hash, )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); - - let sec_conds = sec_conds.extend(conds).reserve_fee(1); let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; - let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds.extend(conds).extend(nft_assert).reserve_fee(1), &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -230,7 +195,7 @@ pub async fn reward_distributor_stake( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/sync.rs b/src/cli/reward_distributor/sync.rs index e2ce06a4..1849f554 100644 --- a/src/cli/reward_distributor/sync.rs +++ b/src/cli/reward_distributor/sync.rs @@ -1,12 +1,12 @@ use chia::protocol::SpendBundle; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{Offer, SpendContext}, + driver::{decode_offer, Offer, SpendContext}, }; use crate::{ - assets_xch_only, get_coinset_client, get_constants, get_last_onchain_timestamp, - hex_string_to_bytes32, new_sk, no_assets, parse_amount, parse_one_sided_offer, + assets_xch_only, create_security_coin, get_coinset_client, get_constants, + get_last_onchain_timestamp, hex_string_to_bytes32, no_assets, parse_amount, spend_security_coin, sync_distributor, wait_for_coin, yes_no_prompt, CliError, Db, RewardDistributorSyncAction, SageClient, }; @@ -59,10 +59,9 @@ pub async fn reward_distributor_sync( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let offer = parse_one_sided_offer(&mut ctx, offer, security_coin_sk.public_key(), None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; let sec_conds = distributor .new_action::() @@ -71,14 +70,13 @@ pub async fn reward_distributor_sync( let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, - offer.security_base_conditions.extend(sec_conds), + security_coin, + sec_conds, &security_coin_sk, get_constants(testnet11), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -86,7 +84,7 @@ pub async fn reward_distributor_sync( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/reward_distributor/unstake.rs b/src/cli/reward_distributor/unstake.rs index 9837252e..f18cdf79 100644 --- a/src/cli/reward_distributor/unstake.rs +++ b/src/cli/reward_distributor/unstake.rs @@ -1,22 +1,28 @@ use chia::{ clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}, - protocol::{Bytes32, SpendBundle}, + protocol::{Bytes32, Coin, SpendBundle}, +}; +use chia_puzzle_types::{ + offer::{NotarizedPayment, Payment, SettlementPaymentsSolution}, + standard::StandardArgs, + Memos, }; -use chia_puzzle_types::standard::StandardArgs; use chia_wallet_sdk::{ coinset::ChiaRpcClient, - driver::{HashedPtr, Nft, Offer, Puzzle, SpendContext, SpendWithConditions, StandardLayer}, - types::Conditions, + driver::{ + decode_offer, HashedPtr, Nft, Offer, Puzzle, Spend, SpendContext, SpendWithConditions, + StandardLayer, + }, + types::{puzzles::SettlementPayment, Conditions}, utils::Address, }; use crate::{ assets_xch_only, find_entry_slots, get_coinset_client, get_last_onchain_timestamp, get_prefix, hex_string_to_bytes32, hex_string_to_pubkey, hex_string_to_signature, no_assets, parse_amount, - parse_one_sided_offer, prompt_for_value, spend_to_coin_spend, sync_distributor, wait_for_coin, - yes_no_prompt, CliError, Db, NonceWrapperArgs, RewardDistributorStakeActionArgs, - RewardDistributorSyncAction, RewardDistributorUnstakeAction, SageClient, - NONCE_WRAPPER_PUZZLE_HASH, + prompt_for_value, spend_to_coin_spend, sync_distributor, wait_for_coin, yes_no_prompt, + CliError, Db, NonceWrapperArgs, RewardDistributorStakeActionArgs, RewardDistributorSyncAction, + RewardDistributorUnstakeAction, SageClient, NONCE_WRAPPER_PUZZLE_HASH, }; pub async fn reward_distributor_unstake( @@ -164,7 +170,32 @@ pub async fn reward_distributor_unstake( .await?; println!("Offer with id {} generated.", offer_resp.offer_id); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let xch_settlement_coin = offer.offered_coins().xch[0]; + let security_coin_puzzle_hash: Bytes32 = + StandardArgs::curry_tree_hash(custody_public_key).into(); + let notarized_payment = NotarizedPayment { + nonce: xch_settlement_coin.coin_id(), + payments: vec![Payment::new( + security_coin_puzzle_hash, + xch_settlement_coin.amount, + Memos::None, + )], + }; + let settlement_puzzle = ctx.alloc_mod::()?; + let settlement_solution = ctx.alloc(&SettlementPaymentsSolution { + notarized_payments: vec![notarized_payment], + })?; + ctx.spend( + xch_settlement_coin, + Spend::new(settlement_puzzle, settlement_solution), + )?; + + let security_coin = Coin::new( + xch_settlement_coin.coin_id(), + security_coin_puzzle_hash, + xch_settlement_coin.amount, + ); let sec_conds = if also_sync { distributor @@ -178,8 +209,6 @@ pub async fn reward_distributor_unstake( let (conds, last_payment_amount) = distributor .new_action::() .spend(&mut ctx, &mut distributor, entry_slot, locked_nft)?; - let offer = parse_one_sided_offer(&mut ctx, offer, custody_public_key, None, None)?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); println!( "Last reward payment amount: {:.3} CATs", @@ -192,16 +221,16 @@ pub async fn reward_distributor_unstake( // security coin has custody puzzle! println!("Signing custody coin..."); - let security_coin_spend = StandardLayer::new(custody_public_key) - .spend_with_conditions(&mut ctx, offer.security_base_conditions.extend(sec_conds))?; - ctx.spend(offer.security_coin, security_coin_spend)?; + let security_coin_spend = + StandardLayer::new(custody_public_key).spend_with_conditions(&mut ctx, sec_conds)?; + ctx.spend(security_coin, security_coin_spend)?; let security_coin_sig = hex_string_to_signature( &sage .sign_coin_spends( vec![spend_to_coin_spend( &mut ctx, - offer.security_coin, + security_coin, security_coin_spend, )?], false, @@ -213,8 +242,7 @@ pub async fn reward_distributor_unstake( .replace("0x", ""), )?; - let spend_bundle = - SpendBundle::new(ctx.take(), offer.aggregated_signature + &security_coin_sig); + let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); @@ -222,7 +250,7 @@ pub async fn reward_distributor_unstake( println!("Transaction submitted; status='{}'", resp.status); - wait_for_coin(&client, offer.security_coin.coin_id(), true).await?; + wait_for_coin(&client, security_coin.coin_id(), true).await?; println!("Confirmed!"); Ok(()) diff --git a/src/cli/verifications/broadcast_launch.rs b/src/cli/verifications/broadcast_launch.rs index ea21afa7..bdcd774e 100644 --- a/src/cli/verifications/broadcast_launch.rs +++ b/src/cli/verifications/broadcast_launch.rs @@ -11,7 +11,7 @@ use chia_puzzle_types::{ }; use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH}; use chia_wallet_sdk::{ - driver::{decompress_offer_bytes, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, + driver::{decompress_offer, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, utils::Address, }; diff --git a/src/drivers.rs b/src/drivers.rs index 67bdb096..c956a3e5 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -587,7 +587,7 @@ pub fn spend_settlement_nft( #[allow(clippy::type_complexity)] pub fn launch_dig_reward_distributor( ctx: &mut SpendContext, - offer: Offer, + offer: &Offer, first_epoch_start: u64, cat_refund_puzzle_hash: Bytes32, constants: RewardDistributorConstants, @@ -2525,7 +2525,7 @@ mod tests { let first_epoch_start = 1234; let (_, security_sk, mut registry, first_epoch_slot) = launch_dig_reward_distributor( ctx, - offer, + &offer, first_epoch_start, Bytes32::default(), constants, From 22c48128d2fe5142f2ba4658a8c438faf79313ba Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 15:24:23 +0300 Subject: [PATCH 54/65] two tests failing :| --- Cargo.lock | 27 ++++------- Cargo.toml | 2 +- src/cli/reward_distributor/stake.rs | 2 +- src/cli/verifications/broadcast_launch.rs | 2 +- src/cli/verifications/create_offer.rs | 47 +++++-------------- src/cli/xchandles/update.rs | 2 +- src/drivers.rs | 16 +++---- src/layers/actions/catalog/register.rs | 2 +- .../actions/reward_distributor/unstake.rs | 2 +- 9 files changed, 36 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2fd3269..aa30851c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -957,8 +957,7 @@ dependencies = [ [[package]] name = "chia-sdk-client" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d25008d098783a160e6377b91de2badf10dc5d150082e6b82b00b9ea7438f7b" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "chia-protocol 0.26.0", "chia-sdk-types 0.27.0", @@ -990,8 +989,7 @@ dependencies = [ [[package]] name = "chia-sdk-coinset" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3b8d9098ad904ffa99da65f07cce7815cc26fea2af9a0676c4f35f1b556d08" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "chia-protocol 0.26.0", "hex", @@ -1015,8 +1013,7 @@ dependencies = [ [[package]] name = "chia-sdk-derive" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d236375a71503031ddfe2865e06a4f7a5322e8b69d02a328e6d40bd207e89ae5" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "convert_case", "quote", @@ -1056,8 +1053,7 @@ dependencies = [ [[package]] name = "chia-sdk-driver" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9313e2cc8eac6137a82bc9077bf0ccadee0c757fcbe6ffbbd32f4f496939f96" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "bech32", "bigdecimal", @@ -1105,8 +1101,7 @@ dependencies = [ [[package]] name = "chia-sdk-signer" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61dfbd5b426741ef2df174f2db25e5204e9ef9b92d363892bf3f8c03cc8d23b" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "chia-bls 0.26.0", "chia-consensus 0.26.0", @@ -1157,8 +1152,7 @@ dependencies = [ [[package]] name = "chia-sdk-test" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ce29dee62c3223efe89619578b2b849d3ea661328e36a098c1d673da6b06f1" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "anyhow", "bip39", @@ -1204,8 +1198,7 @@ dependencies = [ [[package]] name = "chia-sdk-types" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b3145393e2d0854a8fb3e3de2167e5eaf1b110ac05c6276331ca18c50e814f1" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "chia-bls 0.26.0", "chia-consensus 0.26.0", @@ -1241,8 +1234,7 @@ dependencies = [ [[package]] name = "chia-sdk-utils" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1e8d1c895e2bac75c22a3aadd2c5787efaec1db6992a66351f16141298adad" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "bech32", "chia-protocol 0.26.0", @@ -1426,8 +1418,7 @@ dependencies = [ [[package]] name = "chia-wallet-sdk" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52b0d2fda6bc51251d53408fa67c32a959a7eff9e812006ccc769e94e04e67a8" +source = "git+https://github.com/xch-dev/chia-wallet-sdk.git?rev=2a056f03b92077fc0ce808ca2e7c01d707d04c43#2a056f03b92077fc0ce808ca2e7c01d707d04c43" dependencies = [ "chia-bls 0.26.0", "chia-protocol 0.26.0", diff --git a/Cargo.toml b/Cargo.toml index 1c2bc149..e4d55453 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ futures-util = "0.3.31" axum = { version = "0.8.3", features = ["macros"]} tower-http = { version = "0.6.2", features = ["cors"] } futures = "0.3.31" -chia-wallet-sdk = { version="0.27.0", features=["offer-compression"] } +chia-wallet-sdk = { git = "https://github.com/xch-dev/chia-wallet-sdk.git", rev = "2a056f03b92077fc0ce808ca2e7c01d707d04c43", features=["offer-compression"] } sage-api = { version = "0.10.3", git = "https://github.com/xch-dev/sage.git" } chia-puzzles = "0.20.1" diff --git a/src/cli/reward_distributor/stake.rs b/src/cli/reward_distributor/stake.rs index 22b07212..aace8fc7 100644 --- a/src/cli/reward_distributor/stake.rs +++ b/src/cli/reward_distributor/stake.rs @@ -166,7 +166,7 @@ pub async fn reward_distributor_stake( .spend( &mut ctx, &mut distributor, - current_nft.clone(), + *current_nft, nft_launcher_proof, custody_puzzle_hash, )?; diff --git a/src/cli/verifications/broadcast_launch.rs b/src/cli/verifications/broadcast_launch.rs index bdcd774e..ea21afa7 100644 --- a/src/cli/verifications/broadcast_launch.rs +++ b/src/cli/verifications/broadcast_launch.rs @@ -11,7 +11,7 @@ use chia_puzzle_types::{ }; use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH}; use chia_wallet_sdk::{ - driver::{decompress_offer, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, + driver::{decompress_offer_bytes, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, utils::Address, }; diff --git a/src/cli/verifications/create_offer.rs b/src/cli/verifications/create_offer.rs index 4ac67716..142b2098 100644 --- a/src/cli/verifications/create_offer.rs +++ b/src/cli/verifications/create_offer.rs @@ -4,22 +4,18 @@ use chia::{ protocol::{Bytes32, SpendBundle}, traits::Streamable, }; -use chia_puzzle_types::{ - offer::{NotarizedPayment, Payment}, - Memos, -}; -use chia_puzzles::SETTLEMENT_PAYMENT_HASH; +use chia_puzzle_types::Memos; use chia_wallet_sdk::{ - driver::{compress_offer_bytes, Offer, SpendContext}, - types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, + driver::{compress_offer_bytes, decode_offer, Offer, SpendContext}, + types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; use clvm_traits::clvm_list; use clvmr::serde::node_to_bytes; use crate::{ - assets_xch_and_cat, get_coinset_client, get_latest_data_for_asset_id, hex_string_to_bytes32, - new_sk, no_assets, parse_amount, parse_one_sided_offer, spend_security_coin, yes_no_prompt, - CliError, SageClient, VerificationAsserter, VerifiedData, + assets_xch_and_cat, create_security_coin, get_coinset_client, get_latest_data_for_asset_id, + hex_string_to_bytes32, no_assets, parse_amount, spend_security_coin, yes_no_prompt, CliError, + SageClient, VerificationAsserter, VerifiedData, }; pub async fn verifications_create_offer( @@ -78,35 +74,18 @@ pub async fn verifications_create_offer( ); let verification_asserter_puzzle_hash: Bytes32 = verification_asserter.tree_hash().into(); - let offer = Offer::decode(&offer_resp.offer).map_err(CliError::Offer)?; - let security_coin_sk = new_sk()?; - let hint = ctx.hint(SETTLEMENT_PAYMENT_HASH.into())?; - let offer = parse_one_sided_offer( - &mut ctx, - offer, - security_coin_sk.public_key(), - Some(NotarizedPayment { - nonce: Bytes32::default(), - payments: vec![Payment::new( - SETTLEMENT_PAYMENT_HASH.into(), - payment_amount, - hint, - )], - }), - None, - )?; - offer.coin_spends.into_iter().for_each(|cs| ctx.insert(cs)); + let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; + let (security_coin_sk, security_coin) = + create_security_coin(&mut ctx, offer.offered_coins().xch[0])?; - let security_coin_conditions = offer - .security_base_conditions + let security_coin_conditions = Conditions::new() .reserve_fee(1) - .assert_concurrent_spend(offer.created_cat.unwrap().coin.coin_id()) .create_coin(verification_asserter_puzzle_hash, 0, Memos::None) .assert_concurrent_puzzle(verification_asserter_puzzle_hash); let security_coin_sig = spend_security_coin( &mut ctx, - offer.security_coin, + security_coin, security_coin_conditions, &security_coin_sk, if testnet11 { @@ -116,10 +95,10 @@ pub async fn verifications_create_offer( }, )?; - let whole_sig = offer.aggregated_signature + &security_coin_sig; let data = clvm_list!( asset_id, - SpendBundle::new(ctx.take(), whole_sig) + offer + .take(SpendBundle::new(ctx.take(), security_coin_sig)) .to_bytes() .map_err(|_| CliError::Custom( "Verification request serialization error 2".to_string() diff --git a/src/cli/xchandles/update.rs b/src/cli/xchandles/update.rs index 96f85580..8e3ddb48 100644 --- a/src/cli/xchandles/update.rs +++ b/src/cli/xchandles/update.rs @@ -156,7 +156,7 @@ pub async fn xchandles_update( &security_coin_sk, get_constants(testnet11), )?; - nft.spend(&mut ctx, nft_inner_spend)?; + let _new_nft = nft.spend(&mut ctx, nft_inner_spend)?; let _new_registry = registry.finish_spend(&mut ctx)?; diff --git a/src/drivers.rs b/src/drivers.rs index c956a3e5..8db33dd4 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -519,9 +519,9 @@ pub fn spend_settlement_cats( )); let mut cat_spends = Vec::with_capacity(settlement_cats.len()); - for (i, cat) in settlement_cats.into_iter().enumerate() { + for (i, cat) in settlement_cats.iter().enumerate() { cat_spends.push(CatSpend { - cat: cat.clone(), + cat: *cat, spend: Spend::new( settlement_inner_puzzle, if i == 0 { @@ -2653,7 +2653,7 @@ mod tests { ); let nft_inner_spend = StandardLayer::new(nft_bls.pk).delegated_inner_spend(ctx, nft_inner_spend)?; - nft.spend(ctx, nft_inner_spend)?; + let _new_nft = nft.spend(ctx, nft_inner_spend)?; let nft_inner_spend = Spend::new( ctx.alloc_mod::()?, @@ -2661,7 +2661,7 @@ mod tests { notarized_payments: vec![notarized_payment], })?, ); - offer_nft.spend(ctx, nft_inner_spend)?; + let _new_offer_nft = offer_nft.spend(ctx, nft_inner_spend)?; // sim.spend_coins(spends, &[nft_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "stake_nft", &[nft_bls.sk.clone()])?; @@ -3186,8 +3186,8 @@ mod tests { StandardLayer::new(nft2_bls.pk).delegated_inner_spend(ctx, nfts_inner_spend)?; let nft3_inner_spend = StandardLayer::new(nft3_bls.pk).delegated_inner_spend(ctx, nfts_inner_spend)?; - nft2.spend(ctx, nft2_inner_spend)?; - nft3.spend(ctx, nft3_inner_spend)?; + let _new_nft2 = nft2.spend(ctx, nft2_inner_spend)?; + let _new_nft3 = nft3.spend(ctx, nft3_inner_spend)?; let nft2_inner_spend = Spend::new( ctx.alloc_mod::()?, @@ -3195,7 +3195,7 @@ mod tests { notarized_payments: vec![notarized_payment2], })?, ); - offer2_nft.spend(ctx, nft2_inner_spend)?; + let _new_offer2_nft = offer2_nft.spend(ctx, nft2_inner_spend)?; let nft3_inner_spend = Spend::new( ctx.alloc_mod::()?, @@ -3203,7 +3203,7 @@ mod tests { notarized_payments: vec![notarized_payment3], })?, ); - offer3_nft.spend(ctx, nft3_inner_spend)?; + let _new_offer3_nft = offer3_nft.spend(ctx, nft3_inner_spend)?; sim.pass_time(250); // sim.spend_coins(spends, &[nft2_bls.sk.clone(), nft3_bls.sk.clone()])?; diff --git a/src/layers/actions/catalog/register.rs b/src/layers/actions/catalog/register.rs index d7c370c8..cb62ba11 100644 --- a/src/layers/actions/catalog/register.rs +++ b/src/layers/actions/catalog/register.rs @@ -160,7 +160,7 @@ impl CatalogRegisterAction { )?; // spend nft launcher - nft.spend(ctx, eve_nft_inner_spend)?; + let _new_nft = nft.spend(ctx, eve_nft_inner_spend)?; // finally, spend self let (left_slot, right_slot) = catalog.actual_neigbors(tail_hash, left_slot, right_slot); diff --git a/src/layers/actions/reward_distributor/unstake.rs b/src/layers/actions/reward_distributor/unstake.rs index c063d697..89df0e6b 100644 --- a/src/layers/actions/reward_distributor/unstake.rs +++ b/src/layers/actions/reward_distributor/unstake.rs @@ -152,7 +152,7 @@ impl RewardDistributorUnstakeAction { }, )?; - locked_nft.spend(ctx, Spend::new(nft_inner_puzzle, nft_inner_solution))?; + let _new_nft = locked_nft.spend(ctx, Spend::new(nft_inner_puzzle, nft_inner_solution))?; // spend entry slot entry_slot.spend(ctx, distributor.info.inner_puzzle_hash().into())?; From 64f8fbe08de90fb616fb78eb89117d5912b18f5f Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 15:40:26 +0300 Subject: [PATCH 55/65] WrongPuzzleHash --- src/benchmarker.rs | 1 + src/cli/reward_distributor/launch.rs | 2 +- src/drivers.rs | 93 +++++++++++++++++++++++----- 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/benchmarker.rs b/src/benchmarker.rs index 40a913c3..eb4dba0a 100644 --- a/src/benchmarker.rs +++ b/src/benchmarker.rs @@ -33,6 +33,7 @@ pub mod tests { key: &str, keys: &[SecretKey], ) -> anyhow::Result<()> { + println!("Adding spends for {}", key); // TODO: debug let sb = SpendBundle::new(ctx.take(), Signature::default()); let sb_conds = get_conditions_from_spendbundle( ctx, diff --git a/src/cli/reward_distributor/launch.rs b/src/cli/reward_distributor/launch.rs index 2e6f2ac5..1c3b1de9 100644 --- a/src/cli/reward_distributor/launch.rs +++ b/src/cli/reward_distributor/launch.rs @@ -83,7 +83,7 @@ pub async fn reward_distributor_launch( let mut ctx = SpendContext::new(); let offer = Offer::from_spend_bundle(&mut ctx, &decode_offer(&offer_resp.offer)?)?; - let (sig, _sk, reward_distributor, _slot) = launch_dig_reward_distributor( + let (sig, _sk, reward_distributor, _slot, _change_cat) = launch_dig_reward_distributor( &mut ctx, &offer, first_epoch_start_timestamp, diff --git a/src/drivers.rs b/src/drivers.rs index 8db33dd4..9ec72858 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -599,36 +599,74 @@ pub fn launch_dig_reward_distributor( SecretKey, RewardDistributor, Slot, + Cat, ), DriverError, > { + println!("before create_security_coin"); // TODO: debug let (security_coin_sk, security_coin) = create_security_coin(ctx, offer.offered_coins().xch[0])?; + println!("after create_security_coin"); // TODO: debug offer .spend_bundle() .coin_spends .iter() .for_each(|cs| ctx.insert(cs.clone())); + println!("after insert coin_spends"); // TODO: debug + println!("before launcher"); // TODO: debug let reward_distributor_hint: Bytes32 = "Reward Distributor v1".tree_hash().into(); let launcher_memos = ctx.memos(&(reward_distributor_hint, (comment, ())))?; let launcher = Launcher::with_memos(security_coin.coin_id(), 1, launcher_memos); let launcher_coin = launcher.coin(); let launcher_id = launcher_coin.coin_id(); + println!("after launcher"); // TODO: debug let controller_singleton_struct_hash: Bytes32 = SingletonStruct::new(launcher_id).tree_hash().into(); let reserve_inner_ph: Bytes32 = P2DelegatedBySingletonLayerArgs::curry_tree_hash(controller_singleton_struct_hash, 0) .into(); + println!("after reserve_inner_ph"); // TODO: debug + + let total_cat_amount = offer + .offered_coins() + .cats + .get(&constants.reserve_asset_id) + .map(|cs| cs.iter().map(|c| c.coin.amount).sum::()) + .unwrap_or(1); + println!("after total_cat_amount, {}", total_cat_amount); // TODO: debug + + let interim_cat_puzzle = clvm_quote!(Conditions::new() + .create_coin(reserve_inner_ph, 0, ctx.hint(reserve_inner_ph)?) + .create_coin( + cat_refund_puzzle_hash, + total_cat_amount, + ctx.hint(cat_refund_puzzle_hash)? + )); + let interim_cat_puzzle = ctx.alloc(&interim_cat_puzzle)?; + let interim_cat_puzzle_hash = ctx.tree_hash(interim_cat_puzzle); + println!("after interim_cat_puzzle_hash, {}", interim_cat_puzzle_hash); // TODO: debug let (created_cats, mut security_coin_conditions) = spend_settlement_cats( ctx, - &offer, + offer, constants.reserve_asset_id, constants.launcher_id, - vec![(reserve_inner_ph, 0), (cat_refund_puzzle_hash, 1)], + vec![(interim_cat_puzzle_hash.into(), total_cat_amount)], )?; + println!("after spend_settlement_cats"); // TODO: debug + + let interim_cat = created_cats[0]; + let created_cats = Cat::spend_all( + ctx, + &[CatSpend { + cat: interim_cat, + spend: Spend::new(interim_cat_puzzle, NodePtr::NIL), + hidden: false, + }], + )?; + println!("after spend_all"); // TODO: debug // Spend intermediary coin and create registry let target_info = RewardDistributorInfo::new( @@ -649,6 +687,7 @@ pub fn launch_dig_reward_distributor( slot_value, ); let slot_puzzle_hash = Slot::::puzzle_hash(&slot_info); + println!("after slot_puzzle_hash"); // TODO: debug let slot_hint: Bytes32 = first_epoch_start.tree_hash().into(); let slot_memos = ctx.hint(slot_hint)?; @@ -657,12 +696,14 @@ pub fn launch_dig_reward_distributor( .create_coin(slot_puzzle_hash.into(), 0, slot_memos) .create_coin(target_inner_puzzle_hash.into(), 1, launcher_memos)) .to_clvm(ctx)?; + println!("after eve_singleton_inner_puzzle"); // TODO: debug let eve_singleton_inner_puzzle_hash = ctx.tree_hash(eve_singleton_inner_puzzle); let eve_singleton_proof = Proof::Eve(EveProof { parent_parent_coin_info: launcher_coin.parent_coin_info, parent_amount: launcher_coin.amount, }); + println!("after eve_singleton_proof"); // TODO: debug let (launch_conditions, eve_coin) = launcher.with_singleton_amount(1).spend( ctx, @@ -670,6 +711,7 @@ pub fn launch_dig_reward_distributor( (first_epoch_start, target_info.constants), )?; security_coin_conditions = security_coin_conditions.extend(launch_conditions); + println!("after launch_conditions"); // TODO: debug let eve_coin_solution = SingletonSolution { lineage_proof: eve_singleton_proof, @@ -678,10 +720,12 @@ pub fn launch_dig_reward_distributor( } .to_clvm(ctx)?; + println!("before eve_singleton_puzzle"); // TODO: debug let eve_singleton_puzzle = ctx.curry(SingletonArgs::new(launcher_id, eve_singleton_inner_puzzle))?; let eve_singleton_spend = Spend::new(eve_singleton_puzzle, eve_coin_solution); ctx.spend(eve_coin, eve_singleton_spend)?; + println!("after eve_singleton_puzzle"); // TODO: debug let new_registry_coin = Coin::new( eve_coin.coin_id(), @@ -693,12 +737,14 @@ pub fn launch_dig_reward_distributor( parent_inner_puzzle_hash: eve_singleton_inner_puzzle_hash.into(), parent_amount: 1, }); + println!("after new_proof"); // TODO: debug let slot_proof = SlotProof { parent_parent_info: eve_coin.parent_coin_info, parent_inner_puzzle_hash: eve_singleton_inner_puzzle_hash.into(), }; let slot = Slot::new(slot_proof, slot_info); + println!("after slot"); // TODO: debug // this creates the launcher & secures the spend let security_coin_conditions = @@ -716,7 +762,8 @@ pub fn launch_dig_reward_distributor( ); let registry = RewardDistributor::new(new_registry_coin, new_proof, target_info, reserve); - // Spend security coin + println!("after registry"); // TODO: debug + // Spend security coin let security_coin_sig = spend_security_coin( ctx, security_coin, @@ -725,12 +772,14 @@ pub fn launch_dig_reward_distributor( consensus_constants, )?; - // Finally, return the data + println!("before security_coin_sig"); // TODO: debug + // Finally, return the data Ok(( security_coin_sig + &offer.spend_bundle().aggregated_signature, security_coin_sk, registry, slot, + created_cats[1], // refund cat )) } @@ -2419,8 +2468,10 @@ mod tests { )?; cat_minter_p2.spend(ctx, cat_minter.coin, issue_cat)?; - let mut source_cat = source_cat[0]; + let source_cat = source_cat[0]; + println!("before spend_coins 1"); // TODO: debug sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; + println!("after spend_coins 1"); // TODO: debug // Launch manager singleton let ( @@ -2431,6 +2482,7 @@ mod tests { manager_or_did_singleton_inner_puzzle_hash, manager_or_did_singleton_puzzle, ) = launch_test_singleton(ctx, &mut sim)?; + println!("after launch_test_singleton"); // TODO: debug // setup config let constants = RewardDistributorConstants::without_launcher_id( @@ -2459,6 +2511,7 @@ mod tests { Memos::None, ), )?; + println!("after offer_spend"); // TODO: debug let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; @@ -2476,6 +2529,7 @@ mod tests { solution: NodePtr::NIL, }, )?; + println!("after source_cat_inner_spend"); // TODO: debug source_cat.spend( ctx, SingleCatSpend { @@ -2491,18 +2545,21 @@ mod tests { revoke: false, }, )?; + println!("after source_cat.spend"); // TODO: debug let spends = ctx.take(); let cat_offer_spend = spends .iter() .find(|s| s.coin.coin_id() == source_cat.coin.coin_id()) .unwrap() .clone(); + println!("after source_cat.spend"); // TODO: debug for spend in spends { if spend.coin.coin_id() != source_cat.coin.coin_id() { ctx.insert(spend); } } + println!("before sign_standard_transaction"); // TODO: debug let agg_sig = sign_standard_transaction( ctx, launcher_bls.coin, @@ -2510,6 +2567,7 @@ mod tests { &launcher_bls.sk, &TESTNET11_CONSTANTS, )?; + println!("after sign_standard_transaction"); // TODO: debug let offer = Offer::from_spend_bundle( ctx, &SpendBundle { @@ -2520,18 +2578,22 @@ mod tests { aggregated_signature: agg_sig, }, )?; + println!("after Offer::from_spend_bundle"); // TODO: debug // Launch the reward distributor let first_epoch_start = 1234; - let (_, security_sk, mut registry, first_epoch_slot) = launch_dig_reward_distributor( - ctx, - &offer, - first_epoch_start, - Bytes32::default(), - constants, - &TESTNET11_CONSTANTS, - "yak yak yak", - )?; + println!("before launch_dig_reward_distributor"); // TODO: debug + let (_, security_sk, mut registry, first_epoch_slot, mut source_cat) = + launch_dig_reward_distributor( + ctx, + &offer, + first_epoch_start, + Bytes32::default(), + constants, + &TESTNET11_CONSTANTS, + "yak yak yak", + )?; + println!("after launch_dig_reward_distributor"); // TODO: debug // sim.spend_coins( // ctx.take(), @@ -2552,9 +2614,6 @@ mod tests { ], )?; - source_cat = source_cat - .child(SETTLEMENT_PAYMENT_HASH.into(), source_cat.coin.amount) - .child(cat_minter.puzzle_hash, source_cat.coin.amount); assert!(sim.coin_state(source_cat.coin.coin_id()).is_some()); let nft_bls = sim.bls(1); From 49dcfaadeb1550f3306466493d4ff3a618fee6e6 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 15:49:56 +0300 Subject: [PATCH 56/65] tests passing now --- src/benchmarker.rs | 1 - src/drivers.rs | 41 +++++------------------------------------ 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/src/benchmarker.rs b/src/benchmarker.rs index eb4dba0a..40a913c3 100644 --- a/src/benchmarker.rs +++ b/src/benchmarker.rs @@ -33,7 +33,6 @@ pub mod tests { key: &str, keys: &[SecretKey], ) -> anyhow::Result<()> { - println!("Adding spends for {}", key); // TODO: debug let sb = SpendBundle::new(ctx.take(), Signature::default()); let sb_conds = get_conditions_from_spendbundle( ctx, diff --git a/src/drivers.rs b/src/drivers.rs index 9ec72858..83756a3d 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -603,31 +603,25 @@ pub fn launch_dig_reward_distributor( ), DriverError, > { - println!("before create_security_coin"); // TODO: debug let (security_coin_sk, security_coin) = create_security_coin(ctx, offer.offered_coins().xch[0])?; - println!("after create_security_coin"); // TODO: debug offer .spend_bundle() .coin_spends .iter() .for_each(|cs| ctx.insert(cs.clone())); - println!("after insert coin_spends"); // TODO: debug - println!("before launcher"); // TODO: debug let reward_distributor_hint: Bytes32 = "Reward Distributor v1".tree_hash().into(); let launcher_memos = ctx.memos(&(reward_distributor_hint, (comment, ())))?; let launcher = Launcher::with_memos(security_coin.coin_id(), 1, launcher_memos); let launcher_coin = launcher.coin(); let launcher_id = launcher_coin.coin_id(); - println!("after launcher"); // TODO: debug let controller_singleton_struct_hash: Bytes32 = SingletonStruct::new(launcher_id).tree_hash().into(); let reserve_inner_ph: Bytes32 = P2DelegatedBySingletonLayerArgs::curry_tree_hash(controller_singleton_struct_hash, 0) .into(); - println!("after reserve_inner_ph"); // TODO: debug let total_cat_amount = offer .offered_coins() @@ -635,7 +629,6 @@ pub fn launch_dig_reward_distributor( .get(&constants.reserve_asset_id) .map(|cs| cs.iter().map(|c| c.coin.amount).sum::()) .unwrap_or(1); - println!("after total_cat_amount, {}", total_cat_amount); // TODO: debug let interim_cat_puzzle = clvm_quote!(Conditions::new() .create_coin(reserve_inner_ph, 0, ctx.hint(reserve_inner_ph)?) @@ -646,7 +639,6 @@ pub fn launch_dig_reward_distributor( )); let interim_cat_puzzle = ctx.alloc(&interim_cat_puzzle)?; let interim_cat_puzzle_hash = ctx.tree_hash(interim_cat_puzzle); - println!("after interim_cat_puzzle_hash, {}", interim_cat_puzzle_hash); // TODO: debug let (created_cats, mut security_coin_conditions) = spend_settlement_cats( ctx, @@ -655,7 +647,6 @@ pub fn launch_dig_reward_distributor( constants.launcher_id, vec![(interim_cat_puzzle_hash.into(), total_cat_amount)], )?; - println!("after spend_settlement_cats"); // TODO: debug let interim_cat = created_cats[0]; let created_cats = Cat::spend_all( @@ -666,7 +657,6 @@ pub fn launch_dig_reward_distributor( hidden: false, }], )?; - println!("after spend_all"); // TODO: debug // Spend intermediary coin and create registry let target_info = RewardDistributorInfo::new( @@ -687,7 +677,6 @@ pub fn launch_dig_reward_distributor( slot_value, ); let slot_puzzle_hash = Slot::::puzzle_hash(&slot_info); - println!("after slot_puzzle_hash"); // TODO: debug let slot_hint: Bytes32 = first_epoch_start.tree_hash().into(); let slot_memos = ctx.hint(slot_hint)?; @@ -696,14 +685,12 @@ pub fn launch_dig_reward_distributor( .create_coin(slot_puzzle_hash.into(), 0, slot_memos) .create_coin(target_inner_puzzle_hash.into(), 1, launcher_memos)) .to_clvm(ctx)?; - println!("after eve_singleton_inner_puzzle"); // TODO: debug let eve_singleton_inner_puzzle_hash = ctx.tree_hash(eve_singleton_inner_puzzle); let eve_singleton_proof = Proof::Eve(EveProof { parent_parent_coin_info: launcher_coin.parent_coin_info, parent_amount: launcher_coin.amount, }); - println!("after eve_singleton_proof"); // TODO: debug let (launch_conditions, eve_coin) = launcher.with_singleton_amount(1).spend( ctx, @@ -711,7 +698,6 @@ pub fn launch_dig_reward_distributor( (first_epoch_start, target_info.constants), )?; security_coin_conditions = security_coin_conditions.extend(launch_conditions); - println!("after launch_conditions"); // TODO: debug let eve_coin_solution = SingletonSolution { lineage_proof: eve_singleton_proof, @@ -720,12 +706,10 @@ pub fn launch_dig_reward_distributor( } .to_clvm(ctx)?; - println!("before eve_singleton_puzzle"); // TODO: debug let eve_singleton_puzzle = ctx.curry(SingletonArgs::new(launcher_id, eve_singleton_inner_puzzle))?; let eve_singleton_spend = Spend::new(eve_singleton_puzzle, eve_coin_solution); ctx.spend(eve_coin, eve_singleton_spend)?; - println!("after eve_singleton_puzzle"); // TODO: debug let new_registry_coin = Coin::new( eve_coin.coin_id(), @@ -737,14 +721,12 @@ pub fn launch_dig_reward_distributor( parent_inner_puzzle_hash: eve_singleton_inner_puzzle_hash.into(), parent_amount: 1, }); - println!("after new_proof"); // TODO: debug let slot_proof = SlotProof { parent_parent_info: eve_coin.parent_coin_info, parent_inner_puzzle_hash: eve_singleton_inner_puzzle_hash.into(), }; let slot = Slot::new(slot_proof, slot_info); - println!("after slot"); // TODO: debug // this creates the launcher & secures the spend let security_coin_conditions = @@ -762,8 +744,7 @@ pub fn launch_dig_reward_distributor( ); let registry = RewardDistributor::new(new_registry_coin, new_proof, target_info, reserve); - println!("after registry"); // TODO: debug - // Spend security coin + // Spend security coin let security_coin_sig = spend_security_coin( ctx, security_coin, @@ -772,8 +753,7 @@ pub fn launch_dig_reward_distributor( consensus_constants, )?; - println!("before security_coin_sig"); // TODO: debug - // Finally, return the data + // Finally, return the data Ok(( security_coin_sig + &offer.spend_bundle().aggregated_signature, security_coin_sk, @@ -2469,9 +2449,7 @@ mod tests { cat_minter_p2.spend(ctx, cat_minter.coin, issue_cat)?; let source_cat = source_cat[0]; - println!("before spend_coins 1"); // TODO: debug sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; - println!("after spend_coins 1"); // TODO: debug // Launch manager singleton let ( @@ -2482,7 +2460,6 @@ mod tests { manager_or_did_singleton_inner_puzzle_hash, manager_or_did_singleton_puzzle, ) = launch_test_singleton(ctx, &mut sim)?; - println!("after launch_test_singleton"); // TODO: debug // setup config let constants = RewardDistributorConstants::without_launcher_id( @@ -2511,7 +2488,6 @@ mod tests { Memos::None, ), )?; - println!("after offer_spend"); // TODO: debug let puzzle_reveal = ctx.serialize(&offer_spend.puzzle)?; let solution = ctx.serialize(&offer_spend.solution)?; @@ -2529,7 +2505,6 @@ mod tests { solution: NodePtr::NIL, }, )?; - println!("after source_cat_inner_spend"); // TODO: debug source_cat.spend( ctx, SingleCatSpend { @@ -2545,21 +2520,18 @@ mod tests { revoke: false, }, )?; - println!("after source_cat.spend"); // TODO: debug let spends = ctx.take(); let cat_offer_spend = spends .iter() .find(|s| s.coin.coin_id() == source_cat.coin.coin_id()) .unwrap() .clone(); - println!("after source_cat.spend"); // TODO: debug for spend in spends { if spend.coin.coin_id() != source_cat.coin.coin_id() { ctx.insert(spend); } } - println!("before sign_standard_transaction"); // TODO: debug let agg_sig = sign_standard_transaction( ctx, launcher_bls.coin, @@ -2567,7 +2539,6 @@ mod tests { &launcher_bls.sk, &TESTNET11_CONSTANTS, )?; - println!("after sign_standard_transaction"); // TODO: debug let offer = Offer::from_spend_bundle( ctx, &SpendBundle { @@ -2578,22 +2549,19 @@ mod tests { aggregated_signature: agg_sig, }, )?; - println!("after Offer::from_spend_bundle"); // TODO: debug // Launch the reward distributor let first_epoch_start = 1234; - println!("before launch_dig_reward_distributor"); // TODO: debug let (_, security_sk, mut registry, first_epoch_slot, mut source_cat) = launch_dig_reward_distributor( ctx, &offer, first_epoch_start, - Bytes32::default(), + source_cat.info.p2_puzzle_hash, constants, &TESTNET11_CONSTANTS, "yak yak yak", )?; - println!("after launch_dig_reward_distributor"); // TODO: debug // sim.spend_coins( // ctx.take(), @@ -2752,6 +2720,7 @@ mod tests { .collect::>(); // spend reserve and source cat together so deltas add up + let hint = ctx.hint(cat_minter.puzzle_hash)?; let source_cat_spend = CatSpend::new( source_cat, cat_minter_p2.spend_with_conditions( @@ -2759,7 +2728,7 @@ mod tests { secure_conditions.create_coin( cat_minter.puzzle_hash, source_cat.coin.amount - rewards_to_add, - Memos::None, + hint, ), )?, ); From d5b5d5f07cd98743ec880176e219242379dca544 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 17:00:22 +0300 Subject: [PATCH 57/65] expected atom still :| --- src/cli/verifications/broadcast_launch.rs | 213 +++++++--------------- src/cli/verifications/create_offer.rs | 44 ++--- 2 files changed, 85 insertions(+), 172 deletions(-) diff --git a/src/cli/verifications/broadcast_launch.rs b/src/cli/verifications/broadcast_launch.rs index ea21afa7..ce43f7a7 100644 --- a/src/cli/verifications/broadcast_launch.rs +++ b/src/cli/verifications/broadcast_launch.rs @@ -1,27 +1,21 @@ -use bech32::Variant; use chia::{ clvm_utils::ToTreeHash, - protocol::{Bytes, Bytes32, Coin, SpendBundle}, - traits::Streamable, + protocol::{Bytes32, Coin}, }; -use chia_puzzle_types::{ - cat::CatArgs, - offer::{NotarizedPayment, Payment, SettlementPaymentsSolution}, - LineageProof, -}; -use chia_puzzles::{CAT_PUZZLE_HASH, SETTLEMENT_PAYMENT_HASH}; +use chia_puzzle_types::LineageProof; use chia_wallet_sdk::{ - driver::{decompress_offer_bytes, Cat, CatInfo, CatSpend, HashedPtr, Launcher, Puzzle, Spend}, - types::{announcement_id, puzzles::SettlementPayment, Condition, Conditions}, + driver::{decode_offer, Launcher, Offer}, + types::Conditions, utils::Address, }; -use clvm_traits::clvm_quote; -use clvmr::{serde::node_from_bytes, NodePtr}; +use clvm_traits::{clvm_quote, match_quote}; +use clvmr::NodePtr; use crate::{ get_constants, get_latest_data_for_asset_id, hex_string_to_bytes32, - multisig_broadcast_thing_finish, multisig_broadcast_thing_start, yes_no_prompt, CliError, - MedievalVault, Verification, VerificationAsserter, VerificationLauncherKVList, VerifiedData, + multisig_broadcast_thing_finish, multisig_broadcast_thing_start, spend_settlement_cats, + yes_no_prompt, CliError, MedievalVault, Verification, VerificationAsserter, + VerificationLauncherKVList, VerifiedData, }; #[allow(clippy::too_many_arguments)] @@ -105,23 +99,40 @@ pub async fn verifications_broadcast_launch( ); verification.spend(&mut ctx, None)?; - let (hrp, data, variant) = bech32::decode(&request_offer)?; - if variant != Variant::Bech32m || hrp.as_str() != "verificationrequest" { + let offer = Offer::from_spend_bundle( + &mut ctx, + &decode_offer(&request_offer.replace("verificationrequest1", "offer1"))?, + )?; + + let special_parent = Bytes32::from([1; 32]); + let special_coin_spend = offer + .spend_bundle() + .coin_spends + .iter() + .find(|cs| cs.coin.parent_coin_info == special_parent) + .ok_or(CliError::Custom("Special coin spend not found".to_string()))?; + offer.spend_bundle().coin_spends.iter().for_each(|cs| { + if cs.coin.parent_coin_info != special_parent { + ctx.insert(cs.clone()) + }; + }); + signature_from_signers += &offer.spend_bundle().aggregated_signature; + + let asset_id_verif = special_coin_spend.coin.puzzle_hash; + if asset_id_verif != asset_id { return Err(CliError::Custom( - "Invalid verification request offer provided".to_string(), + "Verification request offer made for another asset id :(".to_string(), )); } - let bytes = bech32::convert_bits(&data, 5, 8, false)?; - let decompressed = decompress_offer_bytes(&bytes)?; - let ptr = node_from_bytes(&mut ctx, &decompressed)?; - let (asset_id_verif, (spend_bundle_bytes, ())) = - ctx.extract::<(Bytes32, (Bytes, ()))>(ptr)?; - if asset_id_verif != asset_id { + + let special_puzzle = ctx.alloc(&special_coin_spend.puzzle_reveal)?; + let (_thing, data_verif) = ctx.extract::(special_puzzle)?; + if data_verif != verified_data { return Err(CliError::Custom( - "Verification request offer made for another asset id :(".to_string(), + "Verification request offer made for a different version of verified data" + .to_string(), )); } - let spend_bundle = SpendBundle::from_bytes(&spend_bundle_bytes).unwrap(); let verification_asserter = VerificationAsserter::from( launcher_id, @@ -136,129 +147,39 @@ pub async fn verifications_broadcast_launch( )?)? .puzzle_hash; - let mut payment_sent = false; - let mut verification_asserter_spent = false; let mut conds = Conditions::new(); - for coin_spend in spend_bundle.coin_spends.into_iter() { - let puzzle_ptr = ctx.alloc(&coin_spend.puzzle_reveal)?; - let solution_ptr = ctx.alloc(&coin_spend.solution)?; - let output = ctx.run(puzzle_ptr, solution_ptr)?; - let output = ctx.extract::(output)?; - - let puzzle = Puzzle::parse(&ctx, puzzle_ptr); - match puzzle { - Puzzle::Curried(puzzle) => { - if puzzle.mod_hash == CAT_PUZZLE_HASH.into() { - let spent_cat_args = ctx.extract::>(puzzle.args)?; - let payment_cat_asset_id = spent_cat_args.asset_id; - let offer_puzzle_hash: Bytes32 = CatArgs::curry_tree_hash( - payment_cat_asset_id, - SETTLEMENT_PAYMENT_HASH.into(), - ) - .into(); - - if let Some(cc) = output.iter().find_map(|c| match c { - Condition::CreateCoin(cc) => { - if cc.puzzle_hash == offer_puzzle_hash { - Some(cc) - } else { - None - } - } - _ => None, - }) { - yes_no_prompt(format!("{} CAT mojos (asset id: {}) will be transferred to the specified recipient. Continue?", cc.amount, hex::encode(payment_cat_asset_id)).as_str())?; - let hint = ctx.hint(recipient_puzzle_hash)?; - let notarized_payment = NotarizedPayment { - nonce: coin_spend.coin.coin_id(), - payments: vec![Payment::new( - recipient_puzzle_hash, - cc.amount, - hint, - )], - }; - - let offer_cat = Cat::new( - Coin::new(coin_spend.coin.coin_id(), offer_puzzle_hash, cc.amount), - Some(LineageProof { - parent_parent_coin_info: coin_spend.coin.parent_coin_info, - parent_inner_puzzle_hash: spent_cat_args - .inner_puzzle - .tree_hash() - .into(), - parent_amount: coin_spend.coin.amount, - }), - CatInfo::new( - payment_cat_asset_id, - None, - SETTLEMENT_PAYMENT_HASH.into(), - ), - ); - - let offer_cat_inner_solution = - ctx.alloc(&SettlementPaymentsSolution { - notarized_payments: vec![notarized_payment.clone()], - })?; - - let offer_cat_spend = CatSpend::new( - offer_cat, - Spend::new( - ctx.alloc_mod::()?, - offer_cat_inner_solution, - ), - ); - - Cat::spend_all(&mut ctx, &[offer_cat_spend])?; - - payment_sent = true; - let notarized_payment_ptr = ctx.alloc(¬arized_payment)?; - let msg: Bytes32 = ctx.tree_hash(notarized_payment_ptr).into(); - conds = conds.assert_puzzle_announcement(announcement_id( - offer_puzzle_hash, - msg, - )); - } - } - } - Puzzle::Raw(_puzzle) => { - if let Some(cc) = output.iter().find_map(|c| match c { - Condition::CreateCoin(cc) => { - if cc.puzzle_hash == verification_asserter_puzzle_hash { - Some(cc) - } else { - None - } - } - _ => None, - }) { - verification_asserter.spend( - &mut ctx, - Coin::new(coin_spend.coin.coin_id(), cc.puzzle_hash, cc.amount), - verifier_proof, - launcher_coin.amount, - comment.clone(), - )?; - verification_asserter_spent = true; - } - } - }; - - ctx.insert(coin_spend); - } - - if !payment_sent { - return Err(CliError::Custom( - "Payment in offer could not be found".to_string(), - )); - } - if !verification_asserter_spent { - return Err(CliError::Custom( - "Verification asserter could not be found in offer - it is likely invalid" - .to_string(), - )); + for (asset_id, cats) in offer.offered_coins().cats.iter() { + let total_cat_amount = cats.iter().map(|c| c.coin.amount).sum::(); + println!( + "Offer contains {} CAT mojos (asset id: {})", + total_cat_amount, + hex::encode(asset_id) + ); + let (_new_cats, assert_cond) = spend_settlement_cats( + &mut ctx, + &offer, + *asset_id, + recipient_puzzle_hash, + vec![(recipient_puzzle_hash, total_cat_amount)], + )?; + conds = conds.extend(assert_cond); } - signature_from_signers += &spend_bundle.aggregated_signature; + let solution_ptr = ctx.alloc(&special_coin_spend.solution)?; + let (verification_asserter_parent, ()) = ctx.extract::<(Bytes32, ())>(solution_ptr)?; + verification_asserter.spend( + &mut ctx, + Coin::new( + verification_asserter_parent, + verification_asserter_puzzle_hash, + 0, + ), + verifier_proof, + launcher_coin.amount, + comment.clone(), + )?; + + yes_no_prompt("Last check - continue?")?; Some(conds) } else { None diff --git a/src/cli/verifications/create_offer.rs b/src/cli/verifications/create_offer.rs index 142b2098..2c374b33 100644 --- a/src/cli/verifications/create_offer.rs +++ b/src/cli/verifications/create_offer.rs @@ -1,15 +1,13 @@ -use bech32::{u5, Variant}; use chia::{ clvm_utils::ToTreeHash, - protocol::{Bytes32, SpendBundle}, - traits::Streamable, + protocol::{Bytes, Bytes32, Coin, CoinSpend, Program, SpendBundle}, }; use chia_puzzle_types::Memos; use chia_wallet_sdk::{ - driver::{compress_offer_bytes, decode_offer, Offer, SpendContext}, + driver::{decode_offer, encode_offer, Offer, SpendContext}, types::{Conditions, MAINNET_CONSTANTS, TESTNET11_CONSTANTS}, }; -use clvm_traits::clvm_list; +use clvm_traits::{clvm_list, clvm_quote}; use clvmr::serde::node_to_bytes; use crate::{ @@ -95,28 +93,22 @@ pub async fn verifications_create_offer( }, )?; - let data = clvm_list!( - asset_id, - offer - .take(SpendBundle::new(ctx.take(), security_coin_sig)) - .to_bytes() - .map_err(|_| CliError::Custom( - "Verification request serialization error 2".to_string() - ))?, + let latest_data_bytes = ctx.alloc(&clvm_quote!(latest_data))?; + let latest_data_bytes: Bytes = node_to_bytes(&ctx, latest_data_bytes)?.into(); + let solution_bytes = ctx.alloc(&clvm_list!(security_coin.coin_id()))?; + let solution_bytes: Bytes = node_to_bytes(&ctx, solution_bytes)?.into(); + ctx.insert(CoinSpend::new( + Coin::new(Bytes32::new([1; 32]), asset_id, 0), + Program::new(latest_data_bytes), + Program::new(solution_bytes), + )); + let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + + let verification_request = encode_offer(&sb)?; + println!( + "Verification request: {}", + verification_request.replace("offer1", "verificationrequest1") ); - let data = ctx.alloc(&data)?; - - let bytes = node_to_bytes(&ctx, data)? - .to_bytes() - .map_err(|_| CliError::Custom("Verification request serialization error 3".to_string()))?; - let bytes = compress_offer_bytes(&bytes)?; - let bytes = bech32::convert_bits(&bytes, 8, 5, true)? - .into_iter() - .map(u5::try_from_u8) - .collect::, bech32::Error>>()?; - let verification_request = bech32::encode("verificationrequest", bytes, Variant::Bech32m)?; - - println!("Verification request: {}", verification_request); Ok(()) } From bcf6adf9004667aa0e99f297b447921b7279ba58 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 17:09:24 +0300 Subject: [PATCH 58/65] almost working --- src/cli/multisig/broadcast_thing.rs | 6 ++++-- src/cli/verifications/broadcast_launch.rs | 19 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/cli/multisig/broadcast_thing.rs b/src/cli/multisig/broadcast_thing.rs index e2e07fe0..09d1761b 100644 --- a/src/cli/multisig/broadcast_thing.rs +++ b/src/cli/multisig/broadcast_thing.rs @@ -11,8 +11,9 @@ use chia_wallet_sdk::{ use crate::{ assets_xch_only, create_security_coin, get_coinset_client, hex_string_to_bytes32, hex_string_to_signature, no_assets, parse_amount, print_medieval_vault_configuration, - spend_security_coin, sync_multisig_singleton, wait_for_coin, yes_no_prompt, CliError, - MedievalVault, MultisigSingleton, SageClient, StateSchedulerHintedState, + print_spend_bundle_to_file, spend_security_coin, sync_multisig_singleton, wait_for_coin, + yes_no_prompt, CliError, MedievalVault, MultisigSingleton, SageClient, + StateSchedulerHintedState, }; pub async fn multisig_broadcast_thing_start( @@ -128,6 +129,7 @@ pub async fn multisig_broadcast_thing_finish( )); println!("Submitting transaction..."); + print_spend_bundle_to_file(sb.coin_spends.clone(), sb.aggregated_signature, "sb.debug")?; // todo: debug let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); diff --git a/src/cli/verifications/broadcast_launch.rs b/src/cli/verifications/broadcast_launch.rs index ce43f7a7..17c43615 100644 --- a/src/cli/verifications/broadcast_launch.rs +++ b/src/cli/verifications/broadcast_launch.rs @@ -8,13 +8,13 @@ use chia_wallet_sdk::{ types::Conditions, utils::Address, }; -use clvm_traits::{clvm_quote, match_quote}; -use clvmr::NodePtr; +use clvm_traits::clvm_quote; +use clvmr::{serde::node_from_bytes, NodePtr}; use crate::{ get_constants, get_latest_data_for_asset_id, hex_string_to_bytes32, multisig_broadcast_thing_finish, multisig_broadcast_thing_start, spend_settlement_cats, - yes_no_prompt, CliError, MedievalVault, Verification, VerificationAsserter, + yes_no_prompt, CatNftMetadata, CliError, MedievalVault, Verification, VerificationAsserter, VerificationLauncherKVList, VerifiedData, }; @@ -125,12 +125,11 @@ pub async fn verifications_broadcast_launch( )); } - let special_puzzle = ctx.alloc(&special_coin_spend.puzzle_reveal)?; - let (_thing, data_verif) = ctx.extract::(special_puzzle)?; - if data_verif != verified_data { + let special_puzzle = node_from_bytes(&mut ctx, &special_coin_spend.puzzle_reveal)?; + let (_thing, nft_metadata_verif) = ctx.extract::<(u64, CatNftMetadata)>(special_puzzle)?; + if latest_data != nft_metadata_verif { return Err(CliError::Custom( - "Verification request offer made for a different version of verified data" - .to_string(), + "Verification request offer made for a different version of metadata".to_string(), )); } @@ -165,7 +164,7 @@ pub async fn verifications_broadcast_launch( conds = conds.extend(assert_cond); } - let solution_ptr = ctx.alloc(&special_coin_spend.solution)?; + let solution_ptr = node_from_bytes(&mut ctx, &special_coin_spend.solution)?; let (verification_asserter_parent, ()) = ctx.extract::<(Bytes32, ())>(solution_ptr)?; verification_asserter.spend( &mut ctx, @@ -179,7 +178,7 @@ pub async fn verifications_broadcast_launch( comment.clone(), )?; - yes_no_prompt("Last check - continue?")?; + yes_no_prompt("Accept the payments above?")?; Some(conds) } else { None From 25510f4333de5b2885031355ad24931056412272 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 17:41:11 +0300 Subject: [PATCH 59/65] worksss --- src/cli/multisig/broadcast_thing.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cli/multisig/broadcast_thing.rs b/src/cli/multisig/broadcast_thing.rs index 09d1761b..e2e07fe0 100644 --- a/src/cli/multisig/broadcast_thing.rs +++ b/src/cli/multisig/broadcast_thing.rs @@ -11,9 +11,8 @@ use chia_wallet_sdk::{ use crate::{ assets_xch_only, create_security_coin, get_coinset_client, hex_string_to_bytes32, hex_string_to_signature, no_assets, parse_amount, print_medieval_vault_configuration, - print_spend_bundle_to_file, spend_security_coin, sync_multisig_singleton, wait_for_coin, - yes_no_prompt, CliError, MedievalVault, MultisigSingleton, SageClient, - StateSchedulerHintedState, + spend_security_coin, sync_multisig_singleton, wait_for_coin, yes_no_prompt, CliError, + MedievalVault, MultisigSingleton, SageClient, StateSchedulerHintedState, }; pub async fn multisig_broadcast_thing_start( @@ -129,7 +128,6 @@ pub async fn multisig_broadcast_thing_finish( )); println!("Submitting transaction..."); - print_spend_bundle_to_file(sb.coin_spends.clone(), sb.aggregated_signature, "sb.debug")?; // todo: debug let resp = client.push_tx(sb).await?; println!("Transaction submitted; status='{}'", resp.status); From 1078b3c77712ae97f091d25e20e55018f5459a9a Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 18:23:56 +0300 Subject: [PATCH 60/65] finally working --- .../reward_distributor/sync_distributor.rs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index 125d4730..6fd9e32a 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -5,7 +5,7 @@ use chia::{ }; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{CatLayer, DriverError, Layer, Puzzle, SpendContext}, + driver::{CatLayer, DriverError, HashedPtr, Layer, Puzzle, SingletonLayer, SpendContext}, }; use clvmr::NodePtr; @@ -13,7 +13,7 @@ use crate::{ CliError, Db, P2DelegatedBySingletonLayerArgs, Reserve, RewardDistributor, RewardDistributorCommitmentSlotValue, RewardDistributorConstants, RewardDistributorEntrySlotValue, RewardDistributorRewardSlotValue, RewardDistributorSlotNonce, - Slot, + Slot, SlotInfo, SlotProof, }; pub async fn sync_distributor( @@ -284,7 +284,29 @@ pub async fn find_reward_slot( let Some(distributor) = RewardDistributor::from_spend(ctx, &distributor_spent, None, constants)? else { - continue; + // eve spend + let slot_value = RewardDistributorRewardSlotValue { + epoch_start, + next_epoch_initialized: false, + rewards: 0, + }; + let slot_info = SlotInfo::::from_value( + constants.launcher_id, + RewardDistributorSlotNonce::REWARD.to_u64(), + slot_value, + ); + + let puzzle_ptr = ctx.alloc(&distributor_spent.puzzle_reveal)?; + let puzzle = Puzzle::parse(ctx, puzzle_ptr); + let puzzle = SingletonLayer::::parse_puzzle(ctx, puzzle)?.unwrap(); + let slot = Slot::::new( + SlotProof { + parent_parent_info: distributor_spent.coin.parent_coin_info, + parent_inner_puzzle_hash: puzzle.inner_puzzle.tree_hash().into(), + }, + slot_info, + ); + return Ok(slot); }; if let Some(slot) = distributor From 7eca6646a2f35e3e243ec015126283dfba9a4ba7 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 18:26:50 +0300 Subject: [PATCH 61/65] update comment --- puzzles/actions/xchandles/refund.clsp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/puzzles/actions/xchandles/refund.clsp b/puzzles/actions/xchandles/refund.clsp index 6210687c..7b4c3b92 100644 --- a/puzzles/actions/xchandles/refund.clsp +++ b/puzzles/actions/xchandles/refund.clsp @@ -96,7 +96,8 @@ ) ; not (b) (= precommit_amount (f (a precommited_pricing_puzzle_reveal precommited_pricing_puzzle_solution))) - ) ; slot spend needed if (a), (b), and (c) are not met - we need (d) + ) ; slot spend needed if the precommit coin looks valid after checking (a), (b), (c) & it could be used + ; to register a handle unless we're in situation (d) (a precommited_cat_maker_reveal (c From af42a9c9c8c142e09c341f682498223dd7f4dd80 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 18:41:31 +0300 Subject: [PATCH 62/65] RBF not working isit --- src/cli/reward_distributor/initiate_payout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/reward_distributor/initiate_payout.rs b/src/cli/reward_distributor/initiate_payout.rs index cee3ae21..6fea3b8a 100644 --- a/src/cli/reward_distributor/initiate_payout.rs +++ b/src/cli/reward_distributor/initiate_payout.rs @@ -44,7 +44,7 @@ pub async fn reward_distributor_initiate_payout( ); } - println!("Finding reward slot..."); + println!("Finding entry slot..."); let slot = find_entry_slots( &mut ctx, &client, From 7b33e9ddff4f28fa49da0e4481e70844de06940d Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 19:01:18 +0300 Subject: [PATCH 63/65] more work needed --- src/cli/reward_distributor/sync_distributor.rs | 10 ++++++++++ src/primitives/catalog_registry.rs | 13 +++++++++++-- src/primitives/reward_distributor.rs | 15 +++++++++++++-- src/primitives/xchandles_registry.rs | 13 +++++++++++-- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index 6fd9e32a..ddd55100 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -252,6 +252,16 @@ pub async fn mempool_distributor_maybe( parent_id_to_look_for = distributor.coin.coin_id(); } + mempool_item + .spend_bundle + .coin_spends + .into_iter() + .for_each(|coin_spend| { + if coin_spend.coin != distributor.coin { + ctx.insert(coin_spend); + } + }); + distributor.set_pending_signature(mempool_item.spend_bundle.aggregated_signature); Ok(distributor) } diff --git a/src/primitives/catalog_registry.rs b/src/primitives/catalog_registry.rs index 2ccc7c8e..e4e6765a 100644 --- a/src/primitives/catalog_registry.rs +++ b/src/primitives/catalog_registry.rs @@ -1,4 +1,5 @@ use chia::{ + bls::Signature, clvm_utils::ToTreeHash, protocol::{Bytes32, Coin, CoinSpend}, puzzles::{singleton::SingletonSolution, LineageProof, Proof}, @@ -24,6 +25,8 @@ pub struct CatalogPendingSpendInfo { pub spent_slots: Vec, pub latest_state: (NodePtr, CatalogRegistryState), + + pub signature: Signature, } impl CatalogPendingSpendInfo { @@ -33,6 +36,7 @@ impl CatalogPendingSpendInfo { created_slots: vec![], spent_slots: vec![], latest_state: (NodePtr::NIL, latest_state), + signature: Signature::default(), } } } @@ -150,9 +154,14 @@ impl CatalogRegistry { created_slots, spent_slots, latest_state: state_incl_ephemeral, + signature: Signature::default(), }) } + pub fn set_pending_signature(&mut self, signature: Signature) { + self.pending_spend.signature = signature; + } + pub fn from_spend( ctx: &mut SpendContext, spend: &CoinSpend, @@ -240,7 +249,7 @@ impl Registry for CatalogRegistry { } impl CatalogRegistry { - pub fn finish_spend(self, ctx: &mut SpendContext) -> Result { + pub fn finish_spend(self, ctx: &mut SpendContext) -> Result<(Self, Signature), DriverError> { let layers = self.info.into_layers(); let puzzle = layers.construct_puzzle(ctx)?; @@ -277,7 +286,7 @@ impl CatalogRegistry { let my_spend = Spend::new(puzzle, solution); ctx.spend(self.coin, my_spend)?; - Ok(child) + Ok((child, self.pending_spend.signature)) } pub fn new_action(&self) -> A diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index c67c27e8..7e3a52b4 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -1,4 +1,5 @@ use chia::{ + bls::Signature, clvm_utils::{tree_hash, ToTreeHash}, protocol::{Bytes32, Coin, CoinSpend}, puzzles::{ @@ -44,6 +45,8 @@ pub struct RewardDistributorPendingSpendInfo { pub created_entry_slots: Vec, pub latest_state: (NodePtr, RewardDistributorState), + + pub signature: Signature, } impl RewardDistributorPendingSpendInfo { @@ -57,6 +60,7 @@ impl RewardDistributorPendingSpendInfo { spent_commitment_slots: vec![], spent_entry_slots: vec![], latest_state: (NodePtr::NIL, latest_state), + signature: Signature::default(), } } @@ -74,6 +78,8 @@ impl RewardDistributorPendingSpendInfo { self.created_entry_slots.extend(delta.created_entry_slots); self.latest_state = delta.latest_state; + + // do not change pending signature } } @@ -244,6 +250,7 @@ impl RewardDistributor { created_commitment_slots, created_entry_slots, latest_state: new_state_and_ephemeral, + signature: Signature::default(), }) } @@ -502,6 +509,10 @@ impl RewardDistributor { Ok(Some((new_distributor, slot))) } + + pub fn set_pending_signature(&mut self, signature: Signature) { + self.pending_spend.signature = signature; + } } impl Registry for RewardDistributor { @@ -514,7 +525,7 @@ impl RewardDistributor { self, ctx: &mut SpendContext, other_cat_spends: Vec, - ) -> Result { + ) -> Result<(Self, Signature), DriverError> { let layers = self.info.into_layers(ctx)?; let puzzle = layers.construct_puzzle(ctx)?; @@ -566,7 +577,7 @@ impl RewardDistributor { cat_spends.push(cat_spend); Cat::spend_all(ctx, &cat_spends)?; - Ok(child) + Ok((child, self.pending_spend.signature)) } pub fn new_action(&self) -> A diff --git a/src/primitives/xchandles_registry.rs b/src/primitives/xchandles_registry.rs index 9e2883c6..776411bb 100644 --- a/src/primitives/xchandles_registry.rs +++ b/src/primitives/xchandles_registry.rs @@ -1,4 +1,5 @@ use chia::{ + bls::Signature, clvm_utils::ToTreeHash, protocol::{Bytes32, Coin, CoinSpend}, puzzles::{singleton::SingletonSolution, LineageProof, Proof}, @@ -26,6 +27,8 @@ pub struct XchandlesPendingSpendInfo { pub created_slots: Vec, pub latest_state: (NodePtr, XchandlesRegistryState), + + pub signature: Signature, } impl XchandlesPendingSpendInfo { @@ -35,6 +38,7 @@ impl XchandlesPendingSpendInfo { created_slots: vec![], spent_slots: vec![], latest_state: (NodePtr::NIL, latest_state), + signature: Signature::default(), } } } @@ -205,6 +209,7 @@ impl XchandlesRegistry { created_slots, spent_slots, latest_state: state_incl_ephemeral, + signature: Signature::default(), }) } @@ -236,6 +241,10 @@ impl XchandlesRegistry { })) } + pub fn set_pending_signature(&mut self, signature: Signature) { + self.pending_spend.signature = signature; + } + pub fn child_lineage_proof(&self) -> LineageProof { LineageProof { parent_parent_coin_info: self.coin.parent_coin_info, @@ -390,7 +399,7 @@ impl XchandlesRegistry { } impl XchandlesRegistry { - pub fn finish_spend(self, ctx: &mut SpendContext) -> Result { + pub fn finish_spend(self, ctx: &mut SpendContext) -> Result<(Self, Signature), DriverError> { let layers = self.info.into_layers(); let puzzle = layers.construct_puzzle(ctx)?; @@ -427,7 +436,7 @@ impl XchandlesRegistry { let my_spend = Spend::new(puzzle, solution); ctx.spend(self.coin, my_spend)?; - Ok(child) + Ok((child, self.pending_spend.signature)) } pub fn new_action(&self) -> A From ed2d93a22b30654e63fb29d7e49097a0a1b6bd2e Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 19:11:31 +0300 Subject: [PATCH 64/65] tests passing; still need pending CAT logic --- .../catalog/broadcast_catalog_state_update.rs | 4 +- src/cli/catalog/continue_launch.rs | 7 ++- src/cli/catalog/register.rs | 7 ++- src/cli/catalog/sync.rs | 10 ++++ src/cli/catalog/unroll_state_scheduler.rs | 7 ++- src/cli/reward_distributor/add_rewards.rs | 7 ++- .../broadcast_entry_update.rs | 4 +- .../reward_distributor/clawback_rewards.rs | 4 +- src/cli/reward_distributor/commit_rewards.rs | 7 ++- src/cli/reward_distributor/initiate_payout.rs | 7 ++- src/cli/reward_distributor/new_epoch.rs | 7 ++- src/cli/reward_distributor/stake.rs | 7 ++- src/cli/reward_distributor/sync.rs | 7 ++- src/cli/reward_distributor/unstake.rs | 7 ++- src/cli/xchandles/continue_launch.rs | 7 ++- src/cli/xchandles/expire.rs | 7 ++- src/cli/xchandles/extend.rs | 7 ++- src/cli/xchandles/register.rs | 7 ++- src/cli/xchandles/sync.rs | 10 ++++ src/cli/xchandles/unroll_state_scheduler.rs | 7 ++- src/cli/xchandles/update.rs | 7 ++- src/drivers.rs | 58 +++++++++---------- 22 files changed, 135 insertions(+), 67 deletions(-) diff --git a/src/cli/catalog/broadcast_catalog_state_update.rs b/src/cli/catalog/broadcast_catalog_state_update.rs index e3c0e8fa..497298b8 100644 --- a/src/cli/catalog/broadcast_catalog_state_update.rs +++ b/src/cli/catalog/broadcast_catalog_state_update.rs @@ -90,12 +90,12 @@ pub async fn catalog_broadcast_state_update( medieval_vault_inner_ph.into(), )?; catalog.insert_action_spend(&mut ctx, inner_spend)?; - let mut _new_catalog = catalog.finish_spend(&mut ctx)?; + let (_new_catalog, pending_sig) = catalog.finish_spend(&mut ctx)?; multisig_broadcast_thing_finish( client, &mut ctx, - signature_from_signers, + signature_from_signers + &pending_sig, fee_str, testnet11, medieval_vault_coin_id, diff --git a/src/cli/catalog/continue_launch.rs b/src/cli/catalog/continue_launch.rs index 92ddde72..3e6d6fa2 100644 --- a/src/cli/catalog/continue_launch.rs +++ b/src/cli/catalog/continue_launch.rs @@ -506,7 +506,7 @@ pub async fn catalog_continue_launch( security_coin_conditions = security_coin_conditions.extend(sec_conds); } - let _new_catalog = catalog.finish_spend(&mut ctx)?; + let (_new_catalog, pending_sig) = catalog.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -520,7 +520,10 @@ pub async fn catalog_continue_launch( }, )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; diff --git a/src/cli/catalog/register.rs b/src/cli/catalog/register.rs index 9a52d753..fdcc9fdb 100644 --- a/src/cli/catalog/register.rs +++ b/src/cli/catalog/register.rs @@ -381,7 +381,7 @@ pub async fn catalog_register( )? }; - let _new_catalog = catalog.finish_spend(&mut ctx)?; + let (_new_catalog, pending_sig) = catalog.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -391,7 +391,10 @@ pub async fn catalog_register( get_constants(testnet11), )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); if log { diff --git a/src/cli/catalog/sync.rs b/src/cli/catalog/sync.rs index 89c1c39c..37d2b6c4 100644 --- a/src/cli/catalog/sync.rs +++ b/src/cli/catalog/sync.rs @@ -308,5 +308,15 @@ pub async fn mempool_catalog_maybe( parent_id_to_look_for = catalog.coin.coin_id(); } + mempool_item + .spend_bundle + .coin_spends + .into_iter() + .for_each(|coin_spend| { + if coin_spend.coin != catalog.coin { + ctx.insert(coin_spend); + } + }); + catalog.set_pending_signature(mempool_item.spend_bundle.aggregated_signature); Ok(catalog) } diff --git a/src/cli/catalog/unroll_state_scheduler.rs b/src/cli/catalog/unroll_state_scheduler.rs index 0059cd4a..aca3f04a 100644 --- a/src/cli/catalog/unroll_state_scheduler.rs +++ b/src/cli/catalog/unroll_state_scheduler.rs @@ -92,7 +92,7 @@ pub async fn catalog_unroll_state_scheduler( catalog.insert_action_spend(&mut ctx, catalog_action_spend)?; let catalog_inner_ph = catalog.info.inner_puzzle_hash(); - let _new_catalog = catalog.finish_spend(&mut ctx)?; + let (_new_catalog, pending_sig) = catalog.finish_spend(&mut ctx)?; let offer_resp = sage .make_offer(no_assets(), assets_xch_only(1), fee, None, None, false) @@ -121,7 +121,10 @@ pub async fn catalog_unroll_state_scheduler( state_scheduler.spend(&mut ctx, catalog_inner_ph.into())?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; diff --git a/src/cli/reward_distributor/add_rewards.rs b/src/cli/reward_distributor/add_rewards.rs index 54da62b7..2d086131 100644 --- a/src/cli/reward_distributor/add_rewards.rs +++ b/src/cli/reward_distributor/add_rewards.rs @@ -98,7 +98,7 @@ pub async fn reward_distributor_add_rewards( ))?[0]; let offer_puzzle = ctx.alloc_mod::()?; - let _new_distributor = distributor.finish_spend( + let (_new_distributor, pending_sig) = distributor.finish_spend( &mut ctx, vec![CatSpend { cat: settlement_cat, @@ -115,7 +115,10 @@ pub async fn reward_distributor_add_rewards( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/broadcast_entry_update.rs b/src/cli/reward_distributor/broadcast_entry_update.rs index db5f735c..cad740ee 100644 --- a/src/cli/reward_distributor/broadcast_entry_update.rs +++ b/src/cli/reward_distributor/broadcast_entry_update.rs @@ -140,12 +140,12 @@ pub async fn reward_distributor_broadcast_entry_update( medieval_vault_inner_ph.into(), )?; } - let mut _new_distributor = reward_distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = reward_distributor.finish_spend(&mut ctx, vec![])?; multisig_broadcast_thing_finish( client, &mut ctx, - signature_from_signers, + signature_from_signers + &pending_sig, fee_str, testnet11, medieval_vault_coin_id, diff --git a/src/cli/reward_distributor/clawback_rewards.rs b/src/cli/reward_distributor/clawback_rewards.rs index ae496846..9d36cf47 100644 --- a/src/cli/reward_distributor/clawback_rewards.rs +++ b/src/cli/reward_distributor/clawback_rewards.rs @@ -86,7 +86,7 @@ pub async fn reward_distributor_clawback_rewards( let (send_message_conds, returned_amount) = distributor .new_action::() .spend(&mut ctx, &mut distributor, commitment_slot, reward_slot)?; - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; println!("Returned amount: {} CAT mojos", returned_amount); @@ -125,7 +125,7 @@ pub async fn reward_distributor_clawback_rewards( let spend_bundle = offer.take(SpendBundle::new( ctx.take(), - security_coin_sig + &message_sig, + security_coin_sig + &message_sig + &pending_sig, )); println!("Submitting transaction..."); diff --git a/src/cli/reward_distributor/commit_rewards.rs b/src/cli/reward_distributor/commit_rewards.rs index c8e04d9c..b8040436 100644 --- a/src/cli/reward_distributor/commit_rewards.rs +++ b/src/cli/reward_distributor/commit_rewards.rs @@ -86,7 +86,7 @@ pub async fn reward_distributor_commit_rewards( "Reward CAT not found in offer".to_string(), ))?[0]; let offer_puzzle = ctx.alloc_mod::()?; - let _new_distributor = distributor.finish_spend( + let (_new_distributor, pending_sig) = distributor.finish_spend( &mut ctx, vec![CatSpend { cat: settlement_cat, @@ -103,7 +103,10 @@ pub async fn reward_distributor_commit_rewards( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/initiate_payout.rs b/src/cli/reward_distributor/initiate_payout.rs index 6fea3b8a..347af80a 100644 --- a/src/cli/reward_distributor/initiate_payout.rs +++ b/src/cli/reward_distributor/initiate_payout.rs @@ -87,7 +87,7 @@ pub async fn reward_distributor_initiate_payout( .new_action::() .spend(&mut ctx, &mut distributor, slot)?; sec_conds = sec_conds.extend(new_conds); - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; println!("Payout amount: {} CAT mojos", payout_amount); @@ -99,7 +99,10 @@ pub async fn reward_distributor_initiate_payout( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/new_epoch.rs b/src/cli/reward_distributor/new_epoch.rs index 9cd2cb2e..6af9b8f6 100644 --- a/src/cli/reward_distributor/new_epoch.rs +++ b/src/cli/reward_distributor/new_epoch.rs @@ -68,7 +68,7 @@ pub async fn reward_distributor_new_epoch( let (sec_conds, fee) = distributor .new_action::() .spend(&mut ctx, &mut distributor, reward_slot)?; - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; println!("Fee for new epoch: {} CAT mojos", fee); @@ -80,7 +80,10 @@ pub async fn reward_distributor_new_epoch( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/stake.rs b/src/cli/reward_distributor/stake.rs index aace8fc7..fb3c4e78 100644 --- a/src/cli/reward_distributor/stake.rs +++ b/src/cli/reward_distributor/stake.rs @@ -178,7 +178,7 @@ pub async fn reward_distributor_stake( notarized_payment.payments[0].puzzle_hash, )?; - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; let security_coin_sig = spend_security_coin( &mut ctx, security_coin, @@ -187,7 +187,10 @@ pub async fn reward_distributor_stake( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/sync.rs b/src/cli/reward_distributor/sync.rs index 1849f554..90f6eb90 100644 --- a/src/cli/reward_distributor/sync.rs +++ b/src/cli/reward_distributor/sync.rs @@ -66,7 +66,7 @@ pub async fn reward_distributor_sync( let sec_conds = distributor .new_action::() .spend(&mut ctx, &mut distributor, update_time)?; - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -76,7 +76,10 @@ pub async fn reward_distributor_sync( get_constants(testnet11), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/reward_distributor/unstake.rs b/src/cli/reward_distributor/unstake.rs index f18cdf79..2b6958c2 100644 --- a/src/cli/reward_distributor/unstake.rs +++ b/src/cli/reward_distributor/unstake.rs @@ -217,7 +217,7 @@ pub async fn reward_distributor_unstake( let sec_conds = sec_conds.extend(conds).reserve_fee(1); - let _new_distributor = distributor.finish_spend(&mut ctx, vec![])?; + let (_new_distributor, pending_sig) = distributor.finish_spend(&mut ctx, vec![])?; // security coin has custody puzzle! println!("Signing custody coin..."); @@ -242,7 +242,10 @@ pub async fn reward_distributor_unstake( .replace("0x", ""), )?; - let spend_bundle = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let spend_bundle = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let client = get_coinset_client(testnet11); diff --git a/src/cli/xchandles/continue_launch.rs b/src/cli/xchandles/continue_launch.rs index ea46925c..36c9b5fe 100644 --- a/src/cli/xchandles/continue_launch.rs +++ b/src/cli/xchandles/continue_launch.rs @@ -509,7 +509,7 @@ pub async fn xchandles_continue_launch( security_coin_conditions = security_coin_conditions.extend(sec_conds); } - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -523,7 +523,10 @@ pub async fn xchandles_continue_launch( }, )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = client.push_tx(sb).await?; diff --git a/src/cli/xchandles/expire.rs b/src/cli/xchandles/expire.rs index 4ac132a0..c5774b64 100644 --- a/src/cli/xchandles/expire.rs +++ b/src/cli/xchandles/expire.rs @@ -346,7 +346,7 @@ pub async fn xchandles_expire( )? }; - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -356,7 +356,10 @@ pub async fn xchandles_expire( get_constants(testnet11), )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; diff --git a/src/cli/xchandles/extend.rs b/src/cli/xchandles/extend.rs index f85fe339..c480016f 100644 --- a/src/cli/xchandles/extend.rs +++ b/src/cli/xchandles/extend.rs @@ -127,7 +127,7 @@ pub async fn xchandles_extend( notarized_payment.payments[0].amount, )], )?; - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -137,7 +137,10 @@ pub async fn xchandles_extend( get_constants(testnet11), )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; diff --git a/src/cli/xchandles/register.rs b/src/cli/xchandles/register.rs index dbde8672..ddcce544 100644 --- a/src/cli/xchandles/register.rs +++ b/src/cli/xchandles/register.rs @@ -348,7 +348,7 @@ pub async fn xchandles_register( )? }; - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -358,7 +358,10 @@ pub async fn xchandles_register( get_constants(testnet11), )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); if log { diff --git a/src/cli/xchandles/sync.rs b/src/cli/xchandles/sync.rs index 739c9ff4..44a29738 100644 --- a/src/cli/xchandles/sync.rs +++ b/src/cli/xchandles/sync.rs @@ -219,5 +219,15 @@ pub async fn mempool_registry_maybe( parent_id_to_look_for = registry.coin.coin_id(); } + mempool_item + .spend_bundle + .coin_spends + .into_iter() + .for_each(|coin_spend| { + if coin_spend.coin != registry.coin { + ctx.insert(coin_spend); + } + }); + registry.set_pending_signature(mempool_item.spend_bundle.aggregated_signature); Ok(registry) } diff --git a/src/cli/xchandles/unroll_state_scheduler.rs b/src/cli/xchandles/unroll_state_scheduler.rs index 7f515b2b..efffa025 100644 --- a/src/cli/xchandles/unroll_state_scheduler.rs +++ b/src/cli/xchandles/unroll_state_scheduler.rs @@ -127,7 +127,7 @@ pub async fn xchandles_unroll_state_scheduler( registry.insert_action_spend(&mut ctx, registry_action_spend)?; let registry_inner_ph = registry.info.inner_puzzle_hash(); - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let offer_resp = sage .make_offer(no_assets(), assets_xch_only(1), fee, None, None, false) @@ -156,7 +156,10 @@ pub async fn xchandles_unroll_state_scheduler( state_scheduler.spend(&mut ctx, registry_inner_ph.into())?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; diff --git a/src/cli/xchandles/update.rs b/src/cli/xchandles/update.rs index 8e3ddb48..7532feb5 100644 --- a/src/cli/xchandles/update.rs +++ b/src/cli/xchandles/update.rs @@ -158,7 +158,7 @@ pub async fn xchandles_update( )?; let _new_nft = nft.spend(&mut ctx, nft_inner_spend)?; - let _new_registry = registry.finish_spend(&mut ctx)?; + let (_new_registry, pending_sig) = registry.finish_spend(&mut ctx)?; let security_coin_sig = spend_security_coin( &mut ctx, @@ -168,7 +168,10 @@ pub async fn xchandles_update( get_constants(testnet11), )?; - let sb = offer.take(SpendBundle::new(ctx.take(), security_coin_sig + &nft_sig)); + let sb = offer.take(SpendBundle::new( + ctx.take(), + security_coin_sig + &nft_sig + &pending_sig, + )); println!("Submitting transaction..."); let resp = cli.push_tx(sb).await?; diff --git a/src/drivers.rs b/src/drivers.rs index 83756a3d..060001dd 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -1025,7 +1025,7 @@ mod tests { assert_eq!(spent_slots.len(), 0); } - let new_catalog = catalog.finish_spend(ctx)?; + let (new_catalog, _) = catalog.finish_spend(ctx)?; ensure_conditions_met(ctx, sim, secure_cond, 0)?; @@ -1284,7 +1284,7 @@ mod tests { )?; catalog.insert_action_spend(ctx, action_spend)?; - catalog = catalog.finish_spend(ctx)?; + catalog = catalog.finish_spend(ctx)?.0; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "update_price", &[user_bls.sk.clone()])?; }; @@ -1314,7 +1314,7 @@ mod tests { assert_eq!(spent_slots[0], left_slot.info.value); assert_eq!(spent_slots[1], right_slot.info.value); - catalog = catalog.finish_spend(ctx)?; + catalog = catalog.finish_spend(ctx)?.0; ensure_conditions_met(ctx, &mut sim, secure_cond.clone(), 1)?; @@ -1523,7 +1523,7 @@ mod tests { ); } - let new_registry = registry.finish_spend(ctx)?; + let (new_registry, _) = registry.finish_spend(ctx)?; ensure_conditions_met(ctx, sim, secure_cond.clone(), 0)?; @@ -1833,7 +1833,7 @@ mod tests { )?; registry.insert_action_spend(ctx, action_spend)?; - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "update_price", &[user_bls.sk.clone()])?; }; @@ -1868,7 +1868,7 @@ mod tests { .iter() .map(|s| registry.created_slot_value_to_slot(s.clone())) .collect::>(); - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; sim.pass_time(100); // registration start was at timestamp 100 // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; @@ -1905,7 +1905,7 @@ mod tests { .tree_hash() .into() ); - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "oracle", &[user_bls.sk.clone()])?; @@ -1986,7 +1986,7 @@ mod tests { payment_cat_amount -= pay_for_extension; payment_cat = payment_cat.child(minter_bls.puzzle_hash, payment_cat_amount); - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; // sim.spend_coins(spends, &[user_bls.sk.clone(), minter_bls.sk.clone()])?; benchmark.add_spends( @@ -2029,7 +2029,7 @@ mod tests { .tree_hash() .into() ); - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "update", &[user_bls.sk.clone()])?; @@ -2155,7 +2155,7 @@ mod tests { .tree_hash() .into() ); - registry = registry.finish_spend(ctx)?; + registry = registry.finish_spend(ctx)?.0; // sim.spend_coins(ctx.take(), &[user_bls.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "expire", &[user_bls.sk.clone()])?; @@ -2601,7 +2601,7 @@ mod tests { registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; (manager_or_did_coin, manager_or_did_singleton_proof) = spend_manager_singleton( ctx, @@ -2664,7 +2664,7 @@ mod tests { registry.pending_spend.created_entry_slots[0], RewardDistributorSlotNonce::ENTRY, ); - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; ensure_conditions_met(ctx, &mut sim, sec_conds, 0)?; @@ -2733,7 +2733,7 @@ mod tests { )?, ); - registry = registry.finish_spend(ctx, vec![source_cat_spend])?; + registry = registry.finish_spend(ctx, vec![source_cat_spend])?.0; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; source_cat = source_cat.child( @@ -2791,7 +2791,7 @@ mod tests { )?, ); - registry = registry.finish_spend(ctx, vec![source_cat_spend])?; + registry = registry.finish_spend(ctx, vec![source_cat_spend])?.0; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; @@ -2853,7 +2853,7 @@ mod tests { )?, ); - registry = registry.finish_spend(ctx, vec![source_cat_spend])?; + registry = registry.finish_spend(ctx, vec![source_cat_spend])?.0; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; @@ -2904,7 +2904,7 @@ mod tests { let claimer_coin = sim.new_coin(cat_minter.puzzle_hash, 0); cat_minter_p2.spend(ctx, claimer_coin, withdraw_incentives_conditions)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.set_next_timestamp(first_epoch_start)?; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends( @@ -2955,7 +2955,7 @@ mod tests { ensure_conditions_met(ctx, &mut sim, new_epoch_conditions, 0)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.pass_time(100); // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "new_epoch", &[])?; @@ -2999,7 +2999,7 @@ mod tests { )?; ensure_conditions_met(ctx, &mut sim, sync_conditions, 0)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.pass_time(400); // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "sync", &[])?; @@ -3025,7 +3025,7 @@ mod tests { )?; ensure_conditions_met(ctx, &mut sim, sync_conditions, 0)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "sync", &[])?; assert!(registry.info.state.round_time_info.last_update == first_epoch_start + 500); @@ -3062,7 +3062,7 @@ mod tests { )?, ); - registry = registry.finish_spend(ctx, vec![source_cat_spend])?; + registry = registry.finish_spend(ctx, vec![source_cat_spend])?.0; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "add_incentives", &[cat_minter.sk.clone()])?; @@ -3110,7 +3110,7 @@ mod tests { manager_conditions, )?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.pass_time(250); // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "add_entry", &[])?; @@ -3193,7 +3193,7 @@ mod tests { registry.pending_spend.created_entry_slots[1], RewardDistributorSlotNonce::ENTRY, ); - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; ensure_conditions_met(ctx, &mut sim, sec_conds2.extend(sec_conds3), 0)?; @@ -3255,7 +3255,7 @@ mod tests { )?; ensure_conditions_met(ctx, &mut sim, sync_conditions, 0)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "sync", &[])?; assert!(registry.info.state.round_time_info.last_update == first_epoch_start + 750); @@ -3292,7 +3292,7 @@ mod tests { StandardLayer::new(nft2_bls.pk).spend(ctx, nft2_bls.coin, custody2_conds)?; StandardLayer::new(nft3_bls.pk).spend(ctx, nft3_bls.coin, custody3_conds)?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; // sim.spend_coins(spends, &[nft2_bls.sk.clone(), nft3_bls.sk.clone()])?; benchmark.add_spends( @@ -3338,7 +3338,7 @@ mod tests { remove_entry_manager_conditions, )?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "remove_entry", &[])?; let payout_coin_id = reserve_cat @@ -3401,7 +3401,7 @@ mod tests { 0, )?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.set_next_timestamp(update_time)?; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "sync_and_new_epoch", &[])?; @@ -3451,7 +3451,7 @@ mod tests { )?, ); - registry = registry.finish_spend(ctx, vec![source_cat_spend])?; + registry = registry.finish_spend(ctx, vec![source_cat_spend])?.0; // sim.spend_coins(ctx.take(), &[cat_minter.sk.clone()])?; benchmark.add_spends(ctx, &mut sim, "commit_incentives", &[cat_minter.sk.clone()])?; let _source_cat = source_cat.child( @@ -3503,7 +3503,7 @@ mod tests { 0, )?; - registry = registry.finish_spend(ctx, vec![])?; + registry = registry.finish_spend(ctx, vec![])?.0; sim.set_next_timestamp(update_time)?; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "sync", &[])?; @@ -3524,7 +3524,7 @@ mod tests { ensure_conditions_met(ctx, &mut sim, payout_conditions.extend(sync_conditions), 0)?; - let _registry = registry.finish_spend(ctx, vec![])?; + let _registry = registry.finish_spend(ctx, vec![])?.0; sim.set_next_timestamp(update_time)?; // sim.spend_coins(ctx.take(), &[])?; benchmark.add_spends(ctx, &mut sim, "initiate_payout", &[])?; From 2cc3c5e34a6aec7cd756c6361b58af0f8727f061 Mon Sep 17 00:00:00 2001 From: Yak Date: Mon, 30 Jun 2025 20:33:06 +0300 Subject: [PATCH 65/65] nice RBF system for distributor as well --- .../reward_distributor/sync_distributor.rs | 85 +++++++++++++++++-- src/primitives/reward_distributor.rs | 9 ++ 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/cli/reward_distributor/sync_distributor.rs b/src/cli/reward_distributor/sync_distributor.rs index ddd55100..575620e2 100644 --- a/src/cli/reward_distributor/sync_distributor.rs +++ b/src/cli/reward_distributor/sync_distributor.rs @@ -1,11 +1,15 @@ use chia::{ clvm_utils::ToTreeHash, - protocol::Bytes32, + protocol::{Bytes32, CoinSpend}, puzzles::{cat::CatArgs, singleton::SingletonStruct, LineageProof}, }; +use chia_puzzle_types::cat::CatSolution; use chia_wallet_sdk::{ coinset::{ChiaRpcClient, CoinsetClient}, - driver::{CatLayer, DriverError, HashedPtr, Layer, Puzzle, SingletonLayer, SpendContext}, + driver::{ + Cat, CatInfo, CatLayer, CatSpend, DriverError, HashedPtr, Layer, Puzzle, SingletonLayer, + Spend, SpendContext, + }, }; use clvmr::NodePtr; @@ -252,19 +256,84 @@ pub async fn mempool_distributor_maybe( parent_id_to_look_for = distributor.coin.coin_id(); } - mempool_item + let reserve_spend = mempool_item + .spend_bundle + .coin_spends + .iter() + .find(|coin_spend| coin_spend.coin == distributor.reserve.coin) + .ok_or(DriverError::Custom("Reserve spend not found".to_string()))? + .clone(); + let spends_to_add: Vec = mempool_item .spend_bundle .coin_spends .into_iter() - .for_each(|coin_spend| { - if coin_spend.coin != distributor.coin { - ctx.insert(coin_spend); - } - }); + .filter(|coin_spend| { + coin_spend.coin != distributor.coin && coin_spend.coin != distributor.reserve.coin + }) + .collect(); + + // CATs spent with reserve are stored in the pending spend info item + // since they need to be spent to form a ring (in finish_spend) + let mut other_cats = Vec::new(); + #[allow(unused_assignments)] + let (mut cat_spend, mut cat_solution) = spend_to_cat_spend(ctx, reserve_spend)?; + loop { + let cat_to_find = cat_solution.prev_coin_id; + if cat_to_find == distributor.reserve.coin.coin_id() { + break; + } + + let cat_coin_spend = spends_to_add + .iter() + .find(|coin_spend| coin_spend.coin.coin_id() == cat_to_find) + .ok_or(DriverError::Custom("CAT spend not found".to_string()))? + .clone(); + (cat_spend, cat_solution) = spend_to_cat_spend(ctx, cat_coin_spend)?; + other_cats.push(cat_spend); + } + + // finally, set things up for RBF + spends_to_add.into_iter().for_each(|coin_spend| { + if other_cats + .iter() + .all(|cat_spend| cat_spend.cat.coin != coin_spend.coin) + { + ctx.insert(coin_spend); + } + }); distributor.set_pending_signature(mempool_item.spend_bundle.aggregated_signature); + distributor.set_pending_other_cats(other_cats); + Ok(distributor) } +pub fn spend_to_cat_spend( + ctx: &mut SpendContext, + spend: CoinSpend, +) -> Result<(CatSpend, CatSolution), DriverError> { + let puzzle_ptr = ctx.alloc(&spend.puzzle_reveal)?; + let solution_ptr = ctx.alloc(&spend.solution)?; + + let puzzle = Puzzle::parse(ctx, puzzle_ptr); + let cat = CatLayer::::parse_puzzle(ctx, puzzle)? + .ok_or(DriverError::Custom("Not a CAT".to_string()))?; + + let solution = ctx.extract::>(solution_ptr)?; + + Ok(( + CatSpend { + cat: Cat::new( + spend.coin, + solution.lineage_proof, + CatInfo::new(cat.asset_id, None, cat.inner_puzzle.tree_hash().into()), + ), + spend: Spend::new(cat.inner_puzzle.ptr(), solution.inner_puzzle_solution), + hidden: false, + }, + solution, + )) +} + pub async fn find_reward_slot( ctx: &mut SpendContext, client: &CoinsetClient, diff --git a/src/primitives/reward_distributor.rs b/src/primitives/reward_distributor.rs index 7e3a52b4..ff623502 100644 --- a/src/primitives/reward_distributor.rs +++ b/src/primitives/reward_distributor.rs @@ -47,6 +47,7 @@ pub struct RewardDistributorPendingSpendInfo { pub latest_state: (NodePtr, RewardDistributorState), pub signature: Signature, + pub other_cats: Vec, } impl RewardDistributorPendingSpendInfo { @@ -61,6 +62,7 @@ impl RewardDistributorPendingSpendInfo { spent_entry_slots: vec![], latest_state: (NodePtr::NIL, latest_state), signature: Signature::default(), + other_cats: vec![], } } @@ -80,6 +82,7 @@ impl RewardDistributorPendingSpendInfo { self.latest_state = delta.latest_state; // do not change pending signature + // or other cats } } @@ -251,6 +254,7 @@ impl RewardDistributor { created_entry_slots, latest_state: new_state_and_ephemeral, signature: Signature::default(), + other_cats: vec![], }) } @@ -513,6 +517,10 @@ impl RewardDistributor { pub fn set_pending_signature(&mut self, signature: Signature) { self.pending_spend.signature = signature; } + + pub fn set_pending_other_cats(&mut self, other_cats: Vec) { + self.pending_spend.other_cats = other_cats; + } } impl Registry for RewardDistributor { @@ -575,6 +583,7 @@ impl RewardDistributor { let mut cat_spends = other_cat_spends; cat_spends.push(cat_spend); + cat_spends.extend(self.pending_spend.other_cats); Cat::spend_all(ctx, &cat_spends)?; Ok((child, self.pending_spend.signature))