From e208354caf8bbbdeaa710ef58c1d502a99b1c262 Mon Sep 17 00:00:00 2001 From: yakuhito Date: Fri, 9 Aug 2024 11:50:04 +0300 Subject: [PATCH] add launcher id hint to memos --- src/drivers.rs | 29 ++++++++++++++++++++++++----- src/puzzles_info.rs | 33 ++++++++++++++++++++++++++++----- src/wallet.rs | 16 ++++++++++++---- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/drivers.rs b/src/drivers.rs index dba71ff..5028607 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -286,11 +286,12 @@ pub trait LauncherExt { } pub fn get_memos( + launcher_id: Bytes32, owner_puzzle_hash: TreeHash, delegated_puzzles: Vec, ) -> Vec { - let hint: Bytes32 = owner_puzzle_hash.into(); - let mut memos: Vec = vec![hint.into()]; + let owner_puzzle_hash: Bytes32 = owner_puzzle_hash.into(); + let mut memos: Vec = vec![launcher_id.into(), owner_puzzle_hash.into()]; for delegated_puzzle in delegated_puzzles { match delegated_puzzle.puzzle_info { @@ -350,7 +351,14 @@ impl LauncherExt for Launcher { } .tree_hash(); - let mut memos = get_memos(info.owner_puzzle_hash, info.delegated_puzzles.clone()); + let mut memos = get_memos( + Bytes32::default(), + info.owner_puzzle_hash, + info.delegated_puzzles.clone(), + ) + .into_iter() + .skip(1) + .collect(); if info.delegated_puzzles.len() == 0 { memos = vec![]; } @@ -385,6 +393,7 @@ impl LauncherExt for Launcher { // - just re-create store (no hints needed) // - change delegated puzzles (hints needed) pub fn get_owner_create_coin_condition( + launcher_id: Bytes32, new_inner_puzzle_hash: &Bytes32, new_delegated_puzzles: &Vec, hint_delegated_puzzles: bool, @@ -401,6 +410,7 @@ pub fn get_owner_create_coin_condition( puzzle_hash: new_puzzle_hash, memos: if hint_delegated_puzzles { get_memos( + launcher_id, new_inner_puzzle_hash.clone().into(), new_delegated_puzzles.clone(), ) @@ -901,7 +911,11 @@ pub mod tests { let new_merkle_root_condition = NewMerkleRootCondition { new_merkle_root, - memos: get_memos(owner_puzzle_hash.into(), delegated_puzzles), + memos: get_memos( + datastore_info.launcher_id, + owner_puzzle_hash.into(), + delegated_puzzles, + ), } .to_clvm(ctx.allocator_mut()) .unwrap(); @@ -1254,7 +1268,11 @@ pub mod tests { let new_merkle_root_condition = NewMerkleRootCondition { new_merkle_root, - memos: get_memos(owner_puzzle_hash.into(), dst_delegated_puzzles.clone()), + memos: get_memos( + src_datastore_info.launcher_id, + owner_puzzle_hash.into(), + dst_delegated_puzzles.clone(), + ), } .to_clvm(ctx.allocator_mut()) .unwrap(); @@ -1544,6 +1562,7 @@ pub mod tests { } owner_output_conds = owner_output_conds.condition(get_owner_create_coin_condition( + src_datastore_info.launcher_id, if also_change_owner { &owner2_puzzle_hash } else { diff --git a/src/puzzles_info.rs b/src/puzzles_info.rs index 9a09002..80ca02f 100644 --- a/src/puzzles_info.rs +++ b/src/puzzles_info.rs @@ -419,14 +419,30 @@ impl DataStoreInfo { let mut memos = memos.clone(); println!("memos clone: {:?}", memos); // todo: debug - if memos.len() == 3 && memos[0] == launcher_id.into() && memos[1] == metadata.root_hash.into() { + if memos.len() == 0 { + // no hints; owner puzzle hash is the inner puzzle hash + return Ok(DataStoreInfo { + coin, + launcher_id, + proof, + metadata, + owner_puzzle_hash: fallback_owner_ph, + delegated_puzzles: vec![], + }); + } + + if memos.drain(0..1).next().unwrap() != launcher_id.into() { + return Err(ParseError::MissingHint); + } + + if memos.len() == 2 && memos[0] == metadata.root_hash.into() { println!("vanilla store using old memo format detected"); // todo: debug return Ok(DataStoreInfo { coin, launcher_id, proof, metadata, - owner_puzzle_hash: Bytes32::from_bytes(&memos[2]).map_err(|_| ParseError::MissingHint)?, + owner_puzzle_hash: Bytes32::from_bytes(&memos[1]).map_err(|_| ParseError::MissingHint)?, delegated_puzzles: vec![], }); } @@ -510,8 +526,10 @@ impl DataStoreInfo { }; println!("building datastore info..."); // todo: debug - println!("memos: {:?}", solution.key_value_list.memos); // todo: debug println!("calling build_datastore_info..."); // todo: debug + let mut memos: Vec = vec![launcher_id.into()]; + memos.extend(solution.key_value_list.memos); + println!("memos: {:?}", memos); // todo: debug match DataStoreInfo::build_datastore_info( allocator, new_coin, @@ -519,7 +537,7 @@ impl DataStoreInfo { proof, metadata, solution.key_value_list.state_layer_inner_puzzle_hash, - &solution.key_value_list.memos, + &memos, ) { Ok(info) => Ok(info), Err(err) => Err(err), @@ -911,7 +929,11 @@ mod tests { let new_merkle_root_condition = NewMerkleRootCondition { new_merkle_root, - memos: get_memos(owner_puzzle_hash.into(), vec![].clone()), + memos: get_memos( + src_datastore_info.launcher_id, + owner_puzzle_hash.into(), + vec![].clone(), + ), } .to_clvm(ctx.allocator_mut()) .unwrap(); @@ -992,6 +1014,7 @@ mod tests { } let mut owner_output_conds = Conditions::new().condition(get_owner_create_coin_condition( + src_datastore_info.launcher_id, &src_datastore_info.owner_puzzle_hash, &dst_delegated_puzzles, true, diff --git a/src/wallet.rs b/src/wallet.rs index 7cab80f..418d58d 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -404,9 +404,12 @@ pub fn update_store_ownership( let mut ctx = SpendContext::new(); let update_condition: Condition = match inner_spend_info { - DataStoreInnerSpendInfo::Owner(_) => { - get_owner_create_coin_condition(&new_owner_puzzle_hash, &new_delegated_puzzles, true) - } + DataStoreInnerSpendInfo::Owner(_) => get_owner_create_coin_condition( + store_info.launcher_id, + &new_owner_puzzle_hash, + &new_delegated_puzzles, + true, + ), DataStoreInnerSpendInfo::Admin(_) => { let leaves: Vec = new_delegated_puzzles .clone() @@ -418,7 +421,11 @@ pub fn update_store_ownership( let new_merkle_root_condition = NewMerkleRootCondition { new_merkle_root, - memos: get_memos(new_owner_puzzle_hash.into(), new_delegated_puzzles), + memos: get_memos( + store_info.launcher_id, + new_owner_puzzle_hash.into(), + new_delegated_puzzles, + ), } .to_clvm(ctx.allocator_mut()) .map_err(|err| Error::ToClvm(err))?; @@ -470,6 +477,7 @@ pub fn update_store_metadata( DataStoreInnerSpendInfo::Owner(_) => Conditions::new() .condition(Condition::Other(new_metadata_condition)) .condition(get_owner_create_coin_condition( + store_info.launcher_id, &store_info.owner_puzzle_hash, &store_info.delegated_puzzles, false,