; This puzzle is intended to go inside of a taproot section of a standard inner puzzle. It does not, however, ; concern itself with re-creating the coin it is a part of. Since this is likely inside of a singleton, this will result ; in an error unless some higher puzzle takes care of recreation. ; ; Curried into this puzzle are 2 things: ; 1) Some info for constructing a bridge. A bridge from this puzzle's perspective is a singleton(state_layer(*)) puzzle ; stack, where the state_layer has a metadata of a single "height" integer and the updater accepts a solution of ; ((new_metadata new_metadata_updater_ph) conditions) - likely `11`. ; ; 2) A root of "validations". Each validation is (height . puzzle_hash) pair which signifies a vote on a payment to be ; made mapped to a height on another blockchain (for example). The validator will make an announcement such that the ; bridge's height is updated to the maximum height of the validations revealed + 1 (the next height to be validated) ; and the bridge creates a coin with amount 0 and the specified puzzle hash. ; ; The validations are stored in a binary tree and to spend this coin, one must provide a reveal of that binary tree ; all the way down to the validation pairs within. However, if the spender does not wish to announce all of the pairs ; in the tree, the can instead just reveal the necessary branch hashes to prove the other pairs' inclusion in the ; curried in root. For example, consider the following validation tree: ; 0xVALIDATION_ROOT ; / \ ; / \ ; 0xbranch1 0xbranch2 ; / \ / \ ; (0 . 0x...) (1 . 0x...) (2 . 0x...) (3 . 0x...) ; ; If the spender only wished to validate heights 0-1, they would provide the following reveal: ; 0xVALIDATION_ROOT ; / \ ; / \ ; 0xbranch1 0xbranch2 ; / \ ; (0 . 0x...) (1 . 0x...) ; ; And later, if they wished to validate height 2, they would provide the following tree: ; 0xVALIDATION_ROOT ; / \ ; / \ ; 0xbranch1 0xbranch2 ; / \ ; (2 . 0x...) 0xpair_hash3 (mod ( BRIDGE_SINGLETON_STRUCT NFT_STATE_LAYER_MOD_HASH ; The metadata should be a single integer and the updater is supplied in solution VALIDATION_ROOT ; A binary tree of (height . secure_the_bag_ph) pairs bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount validations_proof ; A reveal of the validation tree, with un-needed pairs already pre-hashed ) (include *standard-cl-22*) (include condition_codes.clib) (include curry.clib) (include sha256tree.clib) (include utility_macros.clib) (defconstant ONE 1) (defun-inline calculate_singleton_puzzle_hash ( (@ BRIDGE_SINGLETON_STRUCT (SINGLETON_MOD_HASH . (LAUNCHER_ID . SINGLETON_LAUNCHER_HASH)) ) NFT_STATE_LAYER_MOD_HASH bridge_height bridge_metadata_updater_hash bridge_inner_puzhash ) (curry_mod_hash_with_hashes SINGLETON_MOD_HASH (sha256tree BRIDGE_SINGLETON_STRUCT) (curry_mod_hash_with_hashes NFT_STATE_LAYER_MOD_HASH (sha256 ONE NFT_STATE_LAYER_MOD_HASH) (sha256 ONE bridge_height) (sha256 ONE bridge_metadata_updater_hash) bridge_inner_puzhash ) ) ) ; utility function that turns the output of two calls to collapse_tree_and_note_leaf_info into a single return value (defun branch_hash_and_merge_info ((TREE1 PAYMENTS1 TOTAL1 MIN1 MAX1) (TREE2 PAYMENTS2 TOTAL2 MIN2 MAX2)) (list (sha256 TWO TREE1 TREE2) (merge_list PAYMENTS1 PAYMENTS2) (+ TOTAL1 TOTAL2) (min MIN1 MIN2) (max MAX1 MAX2) ) ) (defun collapse_tree_and_note_leaf_info (TREE PAYMENTS TOTAL MIN_HEIGHT MAX_HEIGHT) (if (l TREE) (if (or (l (f TREE)) (l (r TREE))) ; If either side is a cons, we have not reached a leaf pair yet (branch_hash_and_merge_info (collapse_tree_and_note_leaf_info (f TREE) () 0 MIN_HEIGHT MAX_HEIGHT) ; we favor right because merge_list merges from left (collapse_tree_and_note_leaf_info (r TREE) PAYMENTS TOTAL MIN_HEIGHT MAX_HEIGHT) ) (branch_hash_and_merge_info (list (sha256 ONE (f TREE)) () 0 MIN_HEIGHT MAX_HEIGHT) (list (sha256 ONE (r TREE)) (c (r TREE) PAYMENTS) (+ TOTAL 1) (f TREE) (f TREE)) ) ) (list TREE PAYMENTS TOTAL MIN_HEIGHT MAX_HEIGHT) ; All atoms that we reach must be pre-hashed subtrees ) ) (defun assert_root_and_calculate_delegated_puzzle_hash ( VALIDATION_ROOT bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount (ROOT PAYMENTS TOTAL MIN_HEIGHT MAX_HEIGHT) ) (assert (= VALIDATION_ROOT ROOT) ; Given the tree is honestly constructed, this ensures that a sequential set of integer heights was revealed (= TOTAL (- MAX_HEIGHT MIN_HEIGHT)) ; You must reveal the current height of the bridge (no skipping heights) (= bridge_height MIN_HEIGHT) ; You cannot reveal heights less than the current height of the bridge (no double dipping) (not (> bridge_height MAX_HEIGHT)) ; then ; manual sha256tree expansion of: ; (q . ; ( ; (-24 bridge_metadata_updater_hash ((max_height bridge_metadata_updater_hash) ())) ; . ; (calculate_output_conditions_hash ...) ; ) ; ) (sha256 TWO (sha256_one_one) (sha256 TWO (sha256 TWO (sha256 ONE -24) (sha256 TWO bridge_metadata_updater_hash (sha256 TWO (sha256 TWO (sha256 TWO (sha256 ONE MAX_HEIGHT) (sha256 TWO (sha256 ONE bridge_metadata_updater_hash) (sha256_one) ) ) (sha256 TWO (sha256_one) ; empty list of conditions (sha256_one) ) ) (sha256_one) ) ) ) (calculate_output_conditions_hash bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount PAYMENTS ) ) ) ) ) (defun calculate_output_conditions_hash ( bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount PAYMENTS ) (if PAYMENTS ; manual sha256tree expansion of ((CREATE_COIN (f PAYMENTS) 0) . (calculate_output_conditions_hash ...)) (sha256 TWO (sha256 TWO (sha256 ONE CREATE_COIN) (sha256 TWO (sha256 ONE (f PAYMENTS)) (sha256 TWO (sha256_one) (sha256_one) ) ) ) (calculate_output_conditions_hash bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount (r PAYMENTS) ) ) ; else ; manual sha256tree expansion of: ; ( ; (CREATE_PUZZLE_ANNOUNCEMENT bridge_height) ; (ASSERT_MY_AMOUNT bridge_amount) ; (CREATE_COIN bridge_inner_puzhash bridge_amount) ; ) (sha256 TWO (sha256 TWO (sha256 ONE CREATE_PUZZLE_ANNOUNCEMENT) (sha256 TWO (sha256 ONE bridge_height) (sha256_one) ) ) (sha256 TWO (sha256 TWO (sha256 ONE ASSERT_MY_AMOUNT) (sha256 TWO (sha256 ONE bridge_amount) (sha256_one) ) ) (sha256 TWO (sha256 TWO (sha256 ONE CREATE_COIN) (sha256 TWO (sha256 ONE bridge_inner_puzhash) (sha256 TWO (sha256 ONE bridge_amount) (sha256_one) ) ) ) (sha256_one) ) ) ) ) ) ; final conditions (list ; An announcement to the bridge of the delegated puzzle it should run (list CREATE_PUZZLE_ANNOUNCEMENT (sha256 (f (r BRIDGE_SINGLETON_STRUCT)) (assert_root_and_calculate_delegated_puzzle_hash VALIDATION_ROOT bridge_height bridge_metadata_updater_hash bridge_inner_puzhash bridge_amount (collapse_tree_and_note_leaf_info validations_proof () 0 bridge_height bridge_height) ) ) ) ; Asserting an announcement from the delegated puzzle the bridge is running (list ASSERT_PUZZLE_ANNOUNCEMENT (sha256 (calculate_singleton_puzzle_hash BRIDGE_SINGLETON_STRUCT NFT_STATE_LAYER_MOD_HASH bridge_height bridge_metadata_updater_hash bridge_inner_puzhash ) bridge_height ) ) ) )