chia-blockchain/chia/wallet/puzzles/chialisp_deserialisation.clvm

62 lines
2.0 KiB
Plaintext

(mod (input)
(defconstant MAX_SINGLE_BYTE 0x7F)
(defconstant MAX_TWO_BYTE 0xbf)
(defconstant MAX_THREE_BYTE 0xdf)
(defconstant MAX_FOUR_BYTE 0xef)
(defconstant MAX_FIVE_BYTE 0xf7)
(defconstant MAX_SIX_BYTE 0xfb)
(defconstant CONS_BOX_MARKER 0xFF)
(defun sexp_from_stream (input_stream)
(if (= (substr input_stream 0 1) CONS_BOX_MARKER)
(cons_sexp_from_stream (sexp_from_stream (substr input_stream 1)))
(atom_from_stream (substr input_stream 1) (substr input_stream 0 1))
)
)
(defun cons_sexp_from_stream (left_sexp_with_input)
(cons_return (f left_sexp_with_input) (sexp_from_stream (f (r left_sexp_with_input))))
)
(defun cons_return (left_sexp right_sexp_with_input)
(list (c left_sexp (f right_sexp_with_input)) (f (r right_sexp_with_input)))
)
(defun atom_from_stream (input_file input_bits)
(if (= input_bits (quote 0x80))
(list () input_file)
(if (>s input_bits MAX_SINGLE_BYTE)
(atom_from_stream_part_two (get_bitcount input_bits input_file))
(list input_bits input_file)
)
)
)
; Note that we reject any serialized atom here with more than 3 bytes of
; encoded length prefix, even though the Rust and Python CLVM interpreters
; and deserializers support more.
; This allows 4 + 8 + 8 = 20 bits = 1MB atoms
; Also note that this does not limit intermediate atom length. Those limits
; are implemented in the clvm interpreters theselves
(defun-inline get_bitcount (input_bits input_file)
(if (>s input_bits MAX_TWO_BYTE)
(if (>s input_bits MAX_THREE_BYTE)
(x)
;three byte length prefix
(list (concat (logand (quote 0x1f) input_bits) (substr input_file 0 1)) (substr input_file 1))
)
;two byte length prefix
(list (logand (quote 0x3f) input_bits) input_file)
)
)
(defun atom_from_stream_part_two ((size_to_read input_file))
(list (substr input_file 0 size_to_read) (substr input_file size_to_read))
)
; main
(f (sexp_from_stream input))
)