chialisp 0.5.0

tools for working with chialisp language; compiler, repl, python and wasm bindings
Documentation
; 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
      )
    )
  )

)